diff --git a/compiler/erg_compiler/artifact.rs b/compiler/erg_compiler/artifact.rs new file mode 100644 index 00000000..fda4ac16 --- /dev/null +++ b/compiler/erg_compiler/artifact.rs @@ -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, + pub errors: CompileErrors, + pub warns: CompileErrors, +} + +impl IncompleteArtifact { + pub const fn new(hir: Option, errors: CompileErrors, warns: CompileErrors) -> Self { + Self { hir, errors, warns } + } +} diff --git a/compiler/erg_compiler/build_hir.rs b/compiler/erg_compiler/build_hir.rs index 02315a7d..c73f3116 100644 --- a/compiler/erg_compiler/build_hir.rs +++ b/compiler/erg_compiler/build_hir.rs @@ -6,6 +6,7 @@ use erg_common::Str; use erg_parser::ast::AST; use erg_parser::build_ast::ASTBuilder; +use crate::artifact::{CompleteArtifact, IncompleteArtifact}; use crate::context::Context; use crate::effectcheck::SideEffectChecker; use crate::error::{CompileError, CompileErrors}; @@ -48,7 +49,7 @@ impl Runnable for HIRBuilder { fn exec(&mut self) -> Result { let mut builder = ASTBuilder::new(self.cfg().copy()); 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}"); Ok(0) } @@ -56,7 +57,7 @@ impl Runnable for HIRBuilder { fn eval(&mut self, src: String) -> Result { let mut builder = ASTBuilder::new(self.cfg().copy()); 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()) } } @@ -74,29 +75,32 @@ impl HIRBuilder { } } - pub fn check(&mut self, ast: AST, mode: &str) -> Result, CompileErrors)> { - let (hir, warns) = self.lowerer.lower(ast, mode)?; + pub fn check(&mut self, ast: AST, mode: &str) -> Result { + let artifact = self.lowerer.lower(ast, mode)?; if self.cfg().verbose >= 2 { - warns.fmt_all_stderr(); + artifact.warns.fmt_all_stderr(); } let effect_checker = SideEffectChecker::new(self.cfg().clone()); - let hir = effect_checker - .check(hir) - .map_err(|(hir, errs)| (Some(hir), errs))?; - let hir = self - .ownership_checker - .check(hir) - .map_err(|(hir, errs)| (Some(hir), errs))?; + let hir = effect_checker.check(artifact.hir).map_err(|(hir, errs)| { + IncompleteArtifact::new(Some(hir), errs, CompileErrors::empty()) + })?; + let hir = self.ownership_checker.check(hir).map_err(|(hir, errs)| { + IncompleteArtifact::new(Some(hir), errs, CompileErrors::empty()) + })?; Ok(hir) } - pub fn build(&mut self, src: String, mode: &str) -> Result, CompileErrors)> { + pub fn build( + &mut self, + src: String, + mode: &str, + ) -> Result { let mut ast_builder = ASTBuilder::new(self.cfg().copy()); - let ast = ast_builder - .build(src) - .map_err(|errs| (None, CompileErrors::from(errs)))?; + let ast = ast_builder.build(src).map_err(|errs| { + IncompleteArtifact::new(None, CompileErrors::from(errs), CompileErrors::empty()) + })?; let hir = self.check(ast, mode)?; - Ok(hir) + Ok(CompleteArtifact::new(hir, CompileErrors::empty())) } pub fn pop_mod_ctx(&mut self) -> Context { diff --git a/compiler/erg_compiler/compile.rs b/compiler/erg_compiler/compile.rs index 778868f1..a6536395 100644 --- a/compiler/erg_compiler/compile.rs +++ b/compiler/erg_compiler/compile.rs @@ -193,9 +193,12 @@ impl Compiler { } fn build_link_desugar(&mut self, src: String, mode: &str) -> Result { - 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 hir = linker.link(hir); + let hir = linker.link(artifact.hir); Ok(HIRDesugarer::desugar(hir)) } } diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index 61041c89..58e97393 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -1071,14 +1071,14 @@ impl Context { let mut builder = HIRBuilder::new_with_cache(cfg, __name__, mod_cache.clone(), py_mod_cache.clone()); match builder.build(src, "exec") { - Ok(hir) => { - mod_cache.register(path.clone(), Some(hir), builder.pop_mod_ctx()); + Ok(artifact) => { + mod_cache.register(path.clone(), Some(artifact.hir), builder.pop_mod_ctx()); } - Err((maybe_hir, errs)) => { - if let Some(hir) = maybe_hir { + Err(artifact) => { + if let Some(hir) = artifact.hir { mod_cache.register(path, Some(hir), builder.pop_mod_ctx()); } - return Err(errs); + return Err(artifact.errors); } } Ok(path) @@ -1168,15 +1168,15 @@ impl Context { py_mod_cache.clone(), ); match builder.build(src, "declare") { - Ok(hir) => { + Ok(artifact) => { 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)) => { - if let Some(hir) = maybe_hir { + Err(artifact) => { + if let Some(hir) = artifact.hir { py_mod_cache.register(path, Some(hir), builder.pop_mod_ctx()); } - return Err(errs); + return Err(artifact.errors); } } Ok(path) diff --git a/compiler/erg_compiler/lib.rs b/compiler/erg_compiler/lib.rs index 19740e29..d3013842 100644 --- a/compiler/erg_compiler/lib.rs +++ b/compiler/erg_compiler/lib.rs @@ -3,6 +3,7 @@ extern crate erg_common; pub extern crate erg_parser; +pub mod artifact; pub mod build_hir; mod compile; pub use compile::*; diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index e5fd47fd..9a8a5458 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -18,6 +18,7 @@ use erg_parser::build_ast::ASTBuilder; use erg_parser::token::{Token, TokenKind}; use erg_parser::Parser; +use crate::artifact::{CompleteArtifact, IncompleteArtifact}; use crate::context::instantiate::TyVarCache; use crate::ty::constructors::{ 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 { let mut ast_builder = ASTBuilder::new(self.cfg.copy()); 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 { - warns.fmt_all_stderr(); + artifact.warns.fmt_all_stderr(); } - println!("{hir}"); + println!("{}", artifact.hir); Ok(0) } fn eval(&mut self, src: String) -> Result { let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let ast = ast_builder.build(src)?; - let (hir, ..) = self.lower(ast, "eval").map_err(|(_, errs)| errs)?; - Ok(format!("{hir}")) + let artifact = self + .lower(ast, "eval") + .map_err(|artifact| artifact.errors)?; + Ok(format!("{}", artifact.hir)) } } @@ -1781,25 +1786,30 @@ impl ASTLowerer { HIR::new(ast.name, module) } - pub fn lower( - &mut self, - ast: AST, - mode: &str, - ) -> Result<(HIR, LowerWarnings), (Option, LowerErrors)> { + pub fn lower(&mut self, ast: AST, mode: &str) -> Result { log!(info "the AST lowering process has started."); log!(info "the type-checking process has started."); let ast = Reorderer::new(self.cfg.clone()) .reorder(ast) - .map_err(|errs| (None, errs))?; + .map_err(|errs| { + IncompleteArtifact::new(None, errs, LowerWarnings::from(self.warns.take_all())) + })?; if mode == "declare" { let hir = self.declare_module(ast); if self.errs.is_empty() { log!(info "HIR:\n{hir}"); 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 { 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()); @@ -1829,7 +1839,11 @@ impl ASTLowerer { Err((hir, errs)) => { self.errs.extend(errs.into_iter()); 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 @@ -1840,10 +1854,17 @@ impl ASTLowerer { } if self.errs.is_empty() { 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 { 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()), + )) } } }