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::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<i32, Self::Errs> {
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<String, Self::Errs> {
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<HIR, (Option<HIR>, CompileErrors)> {
let (hir, warns) = self.lowerer.lower(ast, mode)?;
pub fn check(&mut self, ast: AST, mode: &str) -> Result<HIR, IncompleteArtifact> {
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<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 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 {

View file

@ -193,9 +193,12 @@ impl Compiler {
}
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 hir = linker.link(hir);
let hir = linker.link(artifact.hir);
Ok(HIRDesugarer::desugar(hir))
}
}

View file

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

View file

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

View file

@ -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<i32, Self::Errs> {
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<String, Self::Errs> {
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<HIR>, LowerErrors)> {
pub fn lower(&mut self, ast: AST, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
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()),
))
}
}
}