mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 02:39:20 +00:00
feat: add erg_compiler/erg_parser
type decls
This commit is contained in:
parent
f834585083
commit
30a6f84e5f
11 changed files with 186 additions and 25 deletions
|
@ -33,33 +33,33 @@ pub use transpile::Transpiler;
|
|||
|
||||
#[cfg(feature = "pylib")]
|
||||
use pyo3::prelude::*;
|
||||
#[cfg(feature = "pylib")]
|
||||
use pyo3::types::{IntoPyDict, PyBytes};
|
||||
|
||||
/// compile(code: str) -> code
|
||||
/// compile(code: str, mode: str) -> code
|
||||
/// --
|
||||
///
|
||||
/// compile an Erg code as a module at runtime
|
||||
#[cfg(feature = "pylib")]
|
||||
#[pyfunction]
|
||||
#[pyo3(name = "compile")]
|
||||
fn _compile(py: Python<'_>, code: String) -> Result<PyObject, error::CompileErrors> {
|
||||
use erg_common::config::ErgConfig;
|
||||
use pyo3::types::{IntoPyDict, PyBytes};
|
||||
fn _compile(py: Python<'_>, code: String, mode: &str) -> Result<PyObject, error::CompileErrors> {
|
||||
use erg_common::{config::ErgConfig, traits::Runnable};
|
||||
let cfg = ErgConfig::string(code);
|
||||
let mut compiler = Compiler::new(cfg);
|
||||
let src = compiler.cfg_mut().input.read();
|
||||
let code = compiler
|
||||
.compile_module()
|
||||
.compile(src, mode)
|
||||
.map(|art| art.object)
|
||||
.map_err(|iart| iart.errors)?;
|
||||
let bytes = code.into_bytes(py.version().parse().unwrap());
|
||||
let dict = [("bytes", PyBytes::new(py, &bytes))].into_py_dict(py);
|
||||
py.run("import marshal", None, None).unwrap();
|
||||
Ok(py
|
||||
.eval("marshal.loads(bytes)", None, Some(dict))
|
||||
.unwrap()
|
||||
.into())
|
||||
let code = py.eval("marshal.loads(bytes)", None, Some(dict)).unwrap();
|
||||
Ok(code.into())
|
||||
}
|
||||
|
||||
/// compile_ast(ast: erg_parser.AST) -> code
|
||||
/// compile_ast(ast: erg_parser.AST, mode: str) -> code
|
||||
/// --
|
||||
///
|
||||
/// compile an Erg AST as a module at runtime
|
||||
|
@ -69,13 +69,13 @@ fn _compile(py: Python<'_>, code: String) -> Result<PyObject, error::CompileErro
|
|||
fn _compile_ast(
|
||||
py: Python<'_>,
|
||||
ast: erg_parser::ast::AST,
|
||||
mode: &str,
|
||||
) -> Result<PyObject, error::CompileErrors> {
|
||||
use erg_common::config::ErgConfig;
|
||||
use pyo3::types::{IntoPyDict, PyBytes};
|
||||
let cfg = ErgConfig::default();
|
||||
let mut compiler = Compiler::new(cfg);
|
||||
let code = compiler
|
||||
.compile_ast(ast, "exec")
|
||||
.compile_ast(ast, mode)
|
||||
.map(|art| art.object)
|
||||
.map_err(|iart| iart.errors)?;
|
||||
let bytes = code.into_bytes(py.version().parse().unwrap());
|
||||
|
@ -95,21 +95,34 @@ fn _compile_ast(
|
|||
#[pyfunction]
|
||||
#[pyo3(name = "compile_file")]
|
||||
fn _compile_file(py: Python<'_>, path: String) -> Result<PyObject, error::CompileErrors> {
|
||||
let code = std::fs::read_to_string(path)?;
|
||||
_compile(py, code)
|
||||
let code = std::fs::read_to_string(&path).unwrap_or_else(|err| panic!("{err}, path: {path}"));
|
||||
_compile(py, code, "exec")
|
||||
}
|
||||
|
||||
/// exec_module(code: str) -> module
|
||||
/// exec(code: str) -> module
|
||||
/// --
|
||||
///
|
||||
/// compile and execute an Erg code as a module at runtime
|
||||
#[cfg(feature = "pylib")]
|
||||
#[pyfunction]
|
||||
#[pyo3(name = "exec_module")]
|
||||
fn _exec_module(py: Python<'_>, code: String) -> Result<PyObject, error::CompileErrors> {
|
||||
use pyo3::types::IntoPyDict;
|
||||
#[pyo3(name = "exec")]
|
||||
fn _exec(py: Python<'_>, code: String) -> Result<PyObject, error::CompileErrors> {
|
||||
let code = _compile(py, code, "exec")?;
|
||||
let module = pyo3::types::PyModule::new(py, "<erg>").unwrap();
|
||||
let dic = [("code", code), ("dict", PyObject::from(module.dict()))].into_py_dict(py);
|
||||
py.run("exec(code, dict)", None, Some(dic)).unwrap();
|
||||
Ok(module.into())
|
||||
}
|
||||
|
||||
let code = _compile(py, code)?;
|
||||
/// exec_ast(ast: erg_parser.AST) -> module
|
||||
/// --
|
||||
///
|
||||
/// compile and execute an Erg AST as a module at runtime
|
||||
#[cfg(feature = "pylib")]
|
||||
#[pyfunction]
|
||||
#[pyo3(name = "exec_ast")]
|
||||
fn _exec_ast(py: Python<'_>, ast: erg_parser::ast::AST) -> Result<PyObject, error::CompileErrors> {
|
||||
let code = _compile_ast(py, ast, "exec")?;
|
||||
let module = pyo3::types::PyModule::new(py, "<erg>").unwrap();
|
||||
let dic = [("code", code), ("dict", PyObject::from(module.dict()))].into_py_dict(py);
|
||||
py.run("exec(code, dict)", None, Some(dic)).unwrap();
|
||||
|
@ -125,8 +138,8 @@ fn _exec_module(py: Python<'_>, code: String) -> Result<PyObject, error::Compile
|
|||
#[pyo3(name = "__import__")]
|
||||
fn _import(py: Python<'_>, name: String) -> Result<PyObject, error::CompileErrors> {
|
||||
let path = format!("{name}.er");
|
||||
let code = std::fs::read_to_string(path)?;
|
||||
_exec_module(py, code)
|
||||
let code = std::fs::read_to_string(&path).unwrap_or_else(|err| panic!("{err}, path: {path}"));
|
||||
_exec(py, code)
|
||||
}
|
||||
|
||||
#[cfg(feature = "pylib")]
|
||||
|
@ -135,12 +148,25 @@ fn erg_compiler(py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
m.add_function(wrap_pyfunction!(_compile, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(_compile_ast, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(_compile_file, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(_exec_module, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(_exec, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(_exec_ast, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(_import, m)?)?;
|
||||
|
||||
use crate::erg_parser::erg_parser;
|
||||
let parser = PyModule::new(py, "erg_parser")?;
|
||||
erg_parser(py, parser)?;
|
||||
m.add_submodule(parser)?;
|
||||
|
||||
py.run(
|
||||
"\
|
||||
import sys
|
||||
sys.modules['erg_compiler.erg_parser'] = erg_parser
|
||||
sys.modules['erg_compiler.erg_parser.ast'] = erg_parser.ast
|
||||
sys.modules['erg_compiler.erg_parser.expr'] = erg_parser.expr
|
||||
",
|
||||
None,
|
||||
Some(m.dict()),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue