Skip to content

Commit 1762588

Browse files
committed
feat: add erg_compiler::compile_with_dependencies
1 parent 121738d commit 1762588

File tree

7 files changed

+71
-7
lines changed

7 files changed

+71
-7
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/erg_common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ crossterm = { optional = true, version = "0.25.0" }
3434
parking_lot = "0.12"
3535
thread_local = "1.1"
3636
pyo3 = { workspace = true, optional = true }
37+
erg_proc_macros = { workspace = true }
3738

3839
[lib]
3940
path = "lib.rs"

crates/erg_common/config.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ use crate::normalize_path;
1515
use crate::python_util::{detect_magic_number, get_python_version, PythonVersion};
1616
use crate::serialize::{get_magic_num_from_bytes, get_ver_from_magic_num};
1717

18+
#[cfg(not(feature = "pylib"))]
19+
use erg_proc_macros::{new, pyclass, pymethods};
20+
#[cfg(feature = "pylib")]
21+
use pyo3::prelude::*;
22+
1823
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1924
pub enum ErgMode {
2025
Lex,
@@ -92,6 +97,7 @@ impl From<&str> for TranspileTarget {
9297
}
9398
}
9499

100+
#[pyclass]
95101
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
96102
pub struct Package {
97103
pub name: &'static str,
@@ -116,6 +122,19 @@ impl Package {
116122
}
117123
}
118124

125+
#[pymethods]
126+
impl Package {
127+
#[new]
128+
fn _new(name: String, as_name: String, version: String, path: Option<String>) -> Self {
129+
Self {
130+
name: Box::leak(name.into_boxed_str()),
131+
as_name: Box::leak(as_name.into_boxed_str()),
132+
version: Box::leak(version.into_boxed_str()),
133+
path: path.map(|s| Box::leak(s.into_boxed_str()) as &'static str),
134+
}
135+
}
136+
}
137+
119138
#[derive(Debug, Clone)]
120139
pub struct ErgConfig {
121140
pub mode: ErgMode,

crates/erg_compiler/error/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ impl From<CompileErrors> for ParseErrors {
614614
#[cfg(feature = "pylib")]
615615
impl std::convert::From<CompileErrors> for pyo3::PyErr {
616616
fn from(errs: CompileErrors) -> pyo3::PyErr {
617-
pyo3::exceptions::PyOSError::new_err(errs[0].to_string())
617+
pyo3::exceptions::PyOSError::new_err(format!("{} errors occurred\n{errs}", errs.len()))
618618
}
619619
}
620620

crates/erg_compiler/lib.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ pub mod transpile;
2727
pub mod ty;
2828
pub mod varinfo;
2929

30+
#[allow(unused)]
31+
use erg_common::config::Package;
32+
3033
pub use build_hir::{GenericHIRBuilder, HIRBuilder};
3134
pub use erg_parser::build_ast::ASTBuilder;
3235
pub use transpile::Transpiler;
@@ -36,16 +39,22 @@ use pyo3::prelude::*;
3639
#[cfg(feature = "pylib")]
3740
use pyo3::types::{IntoPyDict, PyBytes};
3841

39-
/// compile(code: str, mode: str) -> code
42+
/// compile_with_dependencies(code: str, mode: str, pkgs: list[Package]) -> code
4043
/// --
4144
///
4245
/// compile an Erg code as a module at runtime
4346
#[cfg(feature = "pylib")]
4447
#[pyfunction]
45-
#[pyo3(name = "compile")]
46-
fn _compile(py: Python<'_>, code: String, mode: &str) -> Result<PyObject, error::CompileErrors> {
48+
#[pyo3(name = "compile_with_dependencies")]
49+
fn _compile_with_dependencies(
50+
py: Python<'_>,
51+
code: String,
52+
mode: &str,
53+
pkgs: Vec<Package>,
54+
) -> Result<PyObject, error::CompileErrors> {
4755
use erg_common::{config::ErgConfig, traits::Runnable};
48-
let cfg = ErgConfig::string(code);
56+
let mut cfg = ErgConfig::string(code);
57+
cfg.packages = pkgs;
4958
let mut compiler = Compiler::new(cfg);
5059
let src = compiler.cfg_mut().input.read();
5160
let code = compiler
@@ -59,6 +68,17 @@ fn _compile(py: Python<'_>, code: String, mode: &str) -> Result<PyObject, error:
5968
Ok(code.into())
6069
}
6170

71+
/// compile(code: str, mode: str) -> code
72+
/// --
73+
///
74+
/// compile an Erg code as a module at runtime
75+
#[cfg(feature = "pylib")]
76+
#[pyfunction]
77+
#[pyo3(name = "compile")]
78+
fn _compile(py: Python<'_>, code: String, mode: &str) -> Result<PyObject, error::CompileErrors> {
79+
_compile_with_dependencies(py, code, mode, vec![])
80+
}
81+
6282
/// compile_ast(ast: erg_parser.AST, mode: str) -> code
6383
/// --
6484
///
@@ -99,6 +119,22 @@ fn _compile_file(py: Python<'_>, path: String) -> Result<PyObject, error::Compil
99119
_compile(py, code, "exec")
100120
}
101121

122+
/// compile_file_with_dependencies(path: str, pkgs: list[Package]) -> code
123+
/// --
124+
///
125+
/// compile an Erg file as a module at runtime
126+
#[cfg(feature = "pylib")]
127+
#[pyfunction]
128+
#[pyo3(name = "compile_file_with_dependencies")]
129+
fn _compile_file_with_dependencies(
130+
py: Python<'_>,
131+
path: String,
132+
pkgs: Vec<Package>,
133+
) -> Result<PyObject, error::CompileErrors> {
134+
let code = std::fs::read_to_string(&path).unwrap_or_else(|err| panic!("{err}, path: {path}"));
135+
_compile_with_dependencies(py, code, "exec", pkgs)
136+
}
137+
102138
/// exec(code: str) -> module
103139
/// --
104140
///
@@ -145,9 +181,12 @@ fn _import(py: Python<'_>, name: String) -> Result<PyObject, error::CompileError
145181
#[cfg(feature = "pylib")]
146182
#[pymodule]
147183
fn erg_compiler(py: Python<'_>, m: &PyModule) -> PyResult<()> {
184+
m.add_class::<Package>()?;
148185
m.add_function(wrap_pyfunction!(_compile, m)?)?;
186+
m.add_function(wrap_pyfunction!(_compile_with_dependencies, m)?)?;
149187
m.add_function(wrap_pyfunction!(_compile_ast, m)?)?;
150188
m.add_function(wrap_pyfunction!(_compile_file, m)?)?;
189+
m.add_function(wrap_pyfunction!(_compile_file_with_dependencies, m)?)?;
151190
m.add_function(wrap_pyfunction!(_exec, m)?)?;
152191
m.add_function(wrap_pyfunction!(_exec_ast, m)?)?;
153192
m.add_function(wrap_pyfunction!(_import, m)?)?;

crates/erg_proc_macros/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ homepage.workspace = true
1111
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1212

1313
[dependencies]
14-
erg_common = { workspace = true }
1514
syn = { version = "1.0", features = ["full"] }
1615
quote = "1.0"
1716

crates/erg_proc_macros/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ pub fn setter(_attr: TokenStream, item: TokenStream) -> TokenStream {
100100
item
101101
}
102102

103+
/// dummy attribute
104+
#[proc_macro_attribute]
105+
pub fn new(_attr: TokenStream, item: TokenStream) -> TokenStream {
106+
item
107+
}
108+
103109
fn args_to_owned(args: &PathArguments) -> PathArguments {
104110
match args {
105111
PathArguments::AngleBracketed(args) => {

0 commit comments

Comments
 (0)