Add artifact.rs

This commit is contained in:
Shunsuke Shibayama 2022-10-29 17:27:21 +09:00
parent 7f674da751
commit 8ca4b7bd6e
6 changed files with 99 additions and 45 deletions

View 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 }
}
}

View file

@ -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 {

View file

@ -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))
} }
} }

View file

@ -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)

View file

@ -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::*;

View file

@ -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()),
))
} }
} }
} }