mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Add artifact.rs
This commit is contained in:
parent
7f674da751
commit
8ca4b7bd6e
6 changed files with 99 additions and 45 deletions
25
compiler/erg_compiler/artifact.rs
Normal file
25
compiler/erg_compiler/artifact.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
use crate::error::CompileErrors;
|
||||||
|
use crate::hir::HIR;
|
||||||
|
|
||||||
|
pub struct CompleteArtifact {
|
||||||
|
pub hir: HIR,
|
||||||
|
pub warns: CompileErrors,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompleteArtifact {
|
||||||
|
pub const fn new(hir: HIR, warns: CompileErrors) -> Self {
|
||||||
|
Self { hir, warns }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IncompleteArtifact {
|
||||||
|
pub hir: Option<HIR>,
|
||||||
|
pub errors: CompileErrors,
|
||||||
|
pub warns: CompileErrors,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IncompleteArtifact {
|
||||||
|
pub const fn new(hir: Option<HIR>, errors: CompileErrors, warns: CompileErrors) -> Self {
|
||||||
|
Self { hir, errors, warns }
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ use erg_common::Str;
|
||||||
use erg_parser::ast::AST;
|
use erg_parser::ast::AST;
|
||||||
use erg_parser::build_ast::ASTBuilder;
|
use erg_parser::build_ast::ASTBuilder;
|
||||||
|
|
||||||
|
use crate::artifact::{CompleteArtifact, IncompleteArtifact};
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::effectcheck::SideEffectChecker;
|
use crate::effectcheck::SideEffectChecker;
|
||||||
use crate::error::{CompileError, CompileErrors};
|
use crate::error::{CompileError, CompileErrors};
|
||||||
|
@ -48,7 +49,7 @@ impl Runnable for HIRBuilder {
|
||||||
fn exec(&mut self) -> Result<i32, Self::Errs> {
|
fn exec(&mut self) -> Result<i32, Self::Errs> {
|
||||||
let mut builder = ASTBuilder::new(self.cfg().copy());
|
let mut builder = ASTBuilder::new(self.cfg().copy());
|
||||||
let ast = builder.build(self.input().read())?;
|
let ast = builder.build(self.input().read())?;
|
||||||
let hir = self.check(ast, "exec").map_err(|(_, errs)| errs)?;
|
let hir = self.check(ast, "exec").map_err(|arti| arti.errors)?;
|
||||||
println!("{hir}");
|
println!("{hir}");
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +57,7 @@ impl Runnable for HIRBuilder {
|
||||||
fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
|
fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
|
||||||
let mut builder = ASTBuilder::new(self.cfg().copy());
|
let mut builder = ASTBuilder::new(self.cfg().copy());
|
||||||
let ast = builder.build(src)?;
|
let ast = builder.build(src)?;
|
||||||
let hir = self.check(ast, "eval").map_err(|(_, errs)| errs)?;
|
let hir = self.check(ast, "eval").map_err(|arti| arti.errors)?;
|
||||||
Ok(hir.to_string())
|
Ok(hir.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,29 +75,32 @@ impl HIRBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check(&mut self, ast: AST, mode: &str) -> Result<HIR, (Option<HIR>, CompileErrors)> {
|
pub fn check(&mut self, ast: AST, mode: &str) -> Result<HIR, IncompleteArtifact> {
|
||||||
let (hir, warns) = self.lowerer.lower(ast, mode)?;
|
let artifact = self.lowerer.lower(ast, mode)?;
|
||||||
if self.cfg().verbose >= 2 {
|
if self.cfg().verbose >= 2 {
|
||||||
warns.fmt_all_stderr();
|
artifact.warns.fmt_all_stderr();
|
||||||
}
|
}
|
||||||
let effect_checker = SideEffectChecker::new(self.cfg().clone());
|
let effect_checker = SideEffectChecker::new(self.cfg().clone());
|
||||||
let hir = effect_checker
|
let hir = effect_checker.check(artifact.hir).map_err(|(hir, errs)| {
|
||||||
.check(hir)
|
IncompleteArtifact::new(Some(hir), errs, CompileErrors::empty())
|
||||||
.map_err(|(hir, errs)| (Some(hir), errs))?;
|
})?;
|
||||||
let hir = self
|
let hir = self.ownership_checker.check(hir).map_err(|(hir, errs)| {
|
||||||
.ownership_checker
|
IncompleteArtifact::new(Some(hir), errs, CompileErrors::empty())
|
||||||
.check(hir)
|
})?;
|
||||||
.map_err(|(hir, errs)| (Some(hir), errs))?;
|
|
||||||
Ok(hir)
|
Ok(hir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&mut self, src: String, mode: &str) -> Result<HIR, (Option<HIR>, CompileErrors)> {
|
pub fn build(
|
||||||
|
&mut self,
|
||||||
|
src: String,
|
||||||
|
mode: &str,
|
||||||
|
) -> Result<CompleteArtifact, IncompleteArtifact> {
|
||||||
let mut ast_builder = ASTBuilder::new(self.cfg().copy());
|
let mut ast_builder = ASTBuilder::new(self.cfg().copy());
|
||||||
let ast = ast_builder
|
let ast = ast_builder.build(src).map_err(|errs| {
|
||||||
.build(src)
|
IncompleteArtifact::new(None, CompileErrors::from(errs), CompileErrors::empty())
|
||||||
.map_err(|errs| (None, CompileErrors::from(errs)))?;
|
})?;
|
||||||
let hir = self.check(ast, mode)?;
|
let hir = self.check(ast, mode)?;
|
||||||
Ok(hir)
|
Ok(CompleteArtifact::new(hir, CompileErrors::empty()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_mod_ctx(&mut self) -> Context {
|
pub fn pop_mod_ctx(&mut self) -> Context {
|
||||||
|
|
|
@ -193,9 +193,12 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_link_desugar(&mut self, src: String, mode: &str) -> Result<HIR, CompileErrors> {
|
fn build_link_desugar(&mut self, src: String, mode: &str) -> Result<HIR, CompileErrors> {
|
||||||
let hir = self.builder.build(src, mode).map_err(|(_, errs)| errs)?;
|
let artifact = self
|
||||||
|
.builder
|
||||||
|
.build(src, mode)
|
||||||
|
.map_err(|artifact| artifact.errors)?;
|
||||||
let linker = Linker::new(&self.cfg, &self.mod_cache);
|
let linker = Linker::new(&self.cfg, &self.mod_cache);
|
||||||
let hir = linker.link(hir);
|
let hir = linker.link(artifact.hir);
|
||||||
Ok(HIRDesugarer::desugar(hir))
|
Ok(HIRDesugarer::desugar(hir))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1071,14 +1071,14 @@ impl Context {
|
||||||
let mut builder =
|
let mut builder =
|
||||||
HIRBuilder::new_with_cache(cfg, __name__, mod_cache.clone(), py_mod_cache.clone());
|
HIRBuilder::new_with_cache(cfg, __name__, mod_cache.clone(), py_mod_cache.clone());
|
||||||
match builder.build(src, "exec") {
|
match builder.build(src, "exec") {
|
||||||
Ok(hir) => {
|
Ok(artifact) => {
|
||||||
mod_cache.register(path.clone(), Some(hir), builder.pop_mod_ctx());
|
mod_cache.register(path.clone(), Some(artifact.hir), builder.pop_mod_ctx());
|
||||||
}
|
}
|
||||||
Err((maybe_hir, errs)) => {
|
Err(artifact) => {
|
||||||
if let Some(hir) = maybe_hir {
|
if let Some(hir) = artifact.hir {
|
||||||
mod_cache.register(path, Some(hir), builder.pop_mod_ctx());
|
mod_cache.register(path, Some(hir), builder.pop_mod_ctx());
|
||||||
}
|
}
|
||||||
return Err(errs);
|
return Err(artifact.errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(path)
|
Ok(path)
|
||||||
|
@ -1168,15 +1168,15 @@ impl Context {
|
||||||
py_mod_cache.clone(),
|
py_mod_cache.clone(),
|
||||||
);
|
);
|
||||||
match builder.build(src, "declare") {
|
match builder.build(src, "declare") {
|
||||||
Ok(hir) => {
|
Ok(artifact) => {
|
||||||
let ctx = builder.pop_mod_ctx();
|
let ctx = builder.pop_mod_ctx();
|
||||||
py_mod_cache.register(path.clone(), Some(hir), ctx);
|
py_mod_cache.register(path.clone(), Some(artifact.hir), ctx);
|
||||||
}
|
}
|
||||||
Err((maybe_hir, errs)) => {
|
Err(artifact) => {
|
||||||
if let Some(hir) = maybe_hir {
|
if let Some(hir) = artifact.hir {
|
||||||
py_mod_cache.register(path, Some(hir), builder.pop_mod_ctx());
|
py_mod_cache.register(path, Some(hir), builder.pop_mod_ctx());
|
||||||
}
|
}
|
||||||
return Err(errs);
|
return Err(artifact.errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(path)
|
Ok(path)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
extern crate erg_common;
|
extern crate erg_common;
|
||||||
pub extern crate erg_parser;
|
pub extern crate erg_parser;
|
||||||
|
|
||||||
|
pub mod artifact;
|
||||||
pub mod build_hir;
|
pub mod build_hir;
|
||||||
mod compile;
|
mod compile;
|
||||||
pub use compile::*;
|
pub use compile::*;
|
||||||
|
|
|
@ -18,6 +18,7 @@ use erg_parser::build_ast::ASTBuilder;
|
||||||
use erg_parser::token::{Token, TokenKind};
|
use erg_parser::token::{Token, TokenKind};
|
||||||
use erg_parser::Parser;
|
use erg_parser::Parser;
|
||||||
|
|
||||||
|
use crate::artifact::{CompleteArtifact, IncompleteArtifact};
|
||||||
use crate::context::instantiate::TyVarCache;
|
use crate::context::instantiate::TyVarCache;
|
||||||
use crate::ty::constructors::{
|
use crate::ty::constructors::{
|
||||||
array_mut, array_t, free_var, func, mono, poly, proc, set_mut, set_t, ty_tp,
|
array_mut, array_t, free_var, func, mono, poly, proc, set_mut, set_t, ty_tp,
|
||||||
|
@ -90,19 +91,23 @@ impl Runnable for ASTLowerer {
|
||||||
fn exec(&mut self) -> Result<i32, Self::Errs> {
|
fn exec(&mut self) -> Result<i32, Self::Errs> {
|
||||||
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
||||||
let ast = ast_builder.build(self.input().read())?;
|
let ast = ast_builder.build(self.input().read())?;
|
||||||
let (hir, warns) = self.lower(ast, "exec").map_err(|(_, errs)| errs)?;
|
let artifact = self
|
||||||
|
.lower(ast, "exec")
|
||||||
|
.map_err(|artifact| artifact.errors)?;
|
||||||
if self.cfg.verbose >= 2 {
|
if self.cfg.verbose >= 2 {
|
||||||
warns.fmt_all_stderr();
|
artifact.warns.fmt_all_stderr();
|
||||||
}
|
}
|
||||||
println!("{hir}");
|
println!("{}", artifact.hir);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
|
fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
|
||||||
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
||||||
let ast = ast_builder.build(src)?;
|
let ast = ast_builder.build(src)?;
|
||||||
let (hir, ..) = self.lower(ast, "eval").map_err(|(_, errs)| errs)?;
|
let artifact = self
|
||||||
Ok(format!("{hir}"))
|
.lower(ast, "eval")
|
||||||
|
.map_err(|artifact| artifact.errors)?;
|
||||||
|
Ok(format!("{}", artifact.hir))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1781,25 +1786,30 @@ impl ASTLowerer {
|
||||||
HIR::new(ast.name, module)
|
HIR::new(ast.name, module)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower(
|
pub fn lower(&mut self, ast: AST, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
|
||||||
&mut self,
|
|
||||||
ast: AST,
|
|
||||||
mode: &str,
|
|
||||||
) -> Result<(HIR, LowerWarnings), (Option<HIR>, LowerErrors)> {
|
|
||||||
log!(info "the AST lowering process has started.");
|
log!(info "the AST lowering process has started.");
|
||||||
log!(info "the type-checking process has started.");
|
log!(info "the type-checking process has started.");
|
||||||
let ast = Reorderer::new(self.cfg.clone())
|
let ast = Reorderer::new(self.cfg.clone())
|
||||||
.reorder(ast)
|
.reorder(ast)
|
||||||
.map_err(|errs| (None, errs))?;
|
.map_err(|errs| {
|
||||||
|
IncompleteArtifact::new(None, errs, LowerWarnings::from(self.warns.take_all()))
|
||||||
|
})?;
|
||||||
if mode == "declare" {
|
if mode == "declare" {
|
||||||
let hir = self.declare_module(ast);
|
let hir = self.declare_module(ast);
|
||||||
if self.errs.is_empty() {
|
if self.errs.is_empty() {
|
||||||
log!(info "HIR:\n{hir}");
|
log!(info "HIR:\n{hir}");
|
||||||
log!(info "the declaring process has completed.");
|
log!(info "the declaring process has completed.");
|
||||||
return Ok((hir, LowerWarnings::from(self.warns.take_all())));
|
return Ok(CompleteArtifact::new(
|
||||||
|
hir,
|
||||||
|
LowerWarnings::from(self.warns.take_all()),
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
log!(err "the declaring process has failed.");
|
log!(err "the declaring process has failed.");
|
||||||
return Err((Some(hir), LowerErrors::from(self.errs.take_all())));
|
return Err(IncompleteArtifact::new(
|
||||||
|
Some(hir),
|
||||||
|
LowerErrors::from(self.errs.take_all()),
|
||||||
|
LowerWarnings::from(self.warns.take_all()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut module = hir::Module::with_capacity(ast.module.len());
|
let mut module = hir::Module::with_capacity(ast.module.len());
|
||||||
|
@ -1829,7 +1839,11 @@ impl ASTLowerer {
|
||||||
Err((hir, errs)) => {
|
Err((hir, errs)) => {
|
||||||
self.errs.extend(errs.into_iter());
|
self.errs.extend(errs.into_iter());
|
||||||
log!(err "the resolving process has failed. errs: {}", self.errs.len());
|
log!(err "the resolving process has failed. errs: {}", self.errs.len());
|
||||||
return Err((Some(hir), LowerErrors::from(self.errs.take_all())));
|
return Err(IncompleteArtifact::new(
|
||||||
|
Some(hir),
|
||||||
|
LowerErrors::from(self.errs.take_all()),
|
||||||
|
LowerWarnings::from(self.warns.take_all()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// TODO: recursive check
|
// TODO: recursive check
|
||||||
|
@ -1840,10 +1854,17 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
if self.errs.is_empty() {
|
if self.errs.is_empty() {
|
||||||
log!(info "the AST lowering process has completed.");
|
log!(info "the AST lowering process has completed.");
|
||||||
Ok((hir, LowerWarnings::from(self.warns.take_all())))
|
Ok(CompleteArtifact::new(
|
||||||
|
hir,
|
||||||
|
LowerWarnings::from(self.warns.take_all()),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
log!(err "the AST lowering process has failed. errs: {}", self.errs.len());
|
log!(err "the AST lowering process has failed. errs: {}", self.errs.len());
|
||||||
Err((Some(hir), LowerErrors::from(self.errs.take_all())))
|
Err(IncompleteArtifact::new(
|
||||||
|
Some(hir),
|
||||||
|
LowerErrors::from(self.errs.take_all()),
|
||||||
|
LowerWarnings::from(self.warns.take_all()),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue