Add ErrorArtifact

This commit is contained in:
Shunsuke Shibayama 2022-11-29 00:39:57 +09:00
parent c77bb8b336
commit bc52b448e2
4 changed files with 74 additions and 25 deletions

View file

@ -44,3 +44,35 @@ impl<Inner> IncompleteArtifact<Inner> {
} }
} }
} }
#[derive(Debug)]
pub struct ErrorArtifact {
pub errors: CompileErrors,
pub warns: CompileErrors,
}
impl fmt::Display for ErrorArtifact {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if !self.warns.is_empty() {
writeln!(f, "{}", self.warns)?;
}
write!(f, "{}", self.errors)
}
}
impl std::error::Error for ErrorArtifact {}
impl From<IncompleteArtifact> for ErrorArtifact {
fn from(artifact: IncompleteArtifact) -> Self {
Self {
errors: artifact.errors,
warns: artifact.warns,
}
}
}
impl ErrorArtifact {
pub const fn new(errors: CompileErrors, warns: CompileErrors) -> Self {
Self { errors, warns }
}
}

View file

@ -8,7 +8,7 @@ use erg_common::error::MultiErrorDisplay;
use erg_common::log; use erg_common::log;
use erg_common::traits::{Runnable, Stream}; use erg_common::traits::{Runnable, Stream};
use crate::artifact::CompleteArtifact; use crate::artifact::{CompleteArtifact, ErrorArtifact};
use crate::context::ContextProvider; use crate::context::ContextProvider;
use crate::ty::codeobj::CodeObj; use crate::ty::codeobj::CodeObj;
@ -144,13 +144,21 @@ impl Runnable for Compiler {
fn exec(&mut self) -> Result<i32, Self::Errs> { fn exec(&mut self) -> Result<i32, Self::Errs> {
let path = self.input().filename().replace(".er", ".pyc"); let path = self.input().filename().replace(".er", ".pyc");
let warns = self.compile_and_dump_as_pyc(path, self.input().read(), "exec")?; let warns = self
.compile_and_dump_as_pyc(path, self.input().read(), "exec")
.map_err(|eart| {
eart.warns.fmt_all_stderr();
eart.errors
})?;
warns.fmt_all_stderr(); warns.fmt_all_stderr();
Ok(0) Ok(0)
} }
fn eval(&mut self, src: String) -> Result<String, CompileErrors> { fn eval(&mut self, src: String) -> Result<String, CompileErrors> {
let arti = self.compile(src, "eval")?; let arti = self.compile(src, "eval").map_err(|eart| {
eart.warns.fmt_all_stderr();
eart.errors
})?;
arti.warns.fmt_all_stderr(); arti.warns.fmt_all_stderr();
Ok(arti.object.code_info(Some(self.code_generator.py_version))) Ok(arti.object.code_info(Some(self.code_generator.py_version)))
} }
@ -180,7 +188,7 @@ impl Compiler {
pyc_path: P, pyc_path: P,
src: String, src: String,
mode: &str, mode: &str,
) -> Result<CompileWarnings, CompileErrors> { ) -> Result<CompileWarnings, ErrorArtifact> {
let arti = self.compile(src, mode)?; let arti = self.compile(src, mode)?;
arti.object arti.object
.dump_as_pyc(pyc_path, self.cfg.py_magic_num) .dump_as_pyc(pyc_path, self.cfg.py_magic_num)
@ -193,7 +201,7 @@ impl Compiler {
pyc_path: P, pyc_path: P,
src: String, src: String,
mode: &str, mode: &str,
) -> Result<CompleteArtifact<Option<Expr>>, CompileErrors> { ) -> Result<CompleteArtifact<Option<Expr>>, ErrorArtifact> {
let arti = self.eval_compile(src, mode)?; let arti = self.eval_compile(src, mode)?;
let (code, last) = arti.object; let (code, last) = arti.object;
code.dump_as_pyc(pyc_path, self.cfg.py_magic_num) code.dump_as_pyc(pyc_path, self.cfg.py_magic_num)
@ -205,7 +213,7 @@ impl Compiler {
&mut self, &mut self,
src: String, src: String,
mode: &str, mode: &str,
) -> Result<CompleteArtifact<CodeObj>, CompileErrors> { ) -> Result<CompleteArtifact<CodeObj>, ErrorArtifact> {
log!(info "the compiling process has started."); log!(info "the compiling process has started.");
let arti = self.build_link_desugar(src, mode)?; let arti = self.build_link_desugar(src, mode)?;
let codeobj = self.code_generator.emit(arti.object); let codeobj = self.code_generator.emit(arti.object);
@ -218,7 +226,7 @@ impl Compiler {
&mut self, &mut self,
src: String, src: String,
mode: &str, mode: &str,
) -> Result<CompleteArtifact<(CodeObj, Option<Expr>)>, CompileErrors> { ) -> Result<CompleteArtifact<(CodeObj, Option<Expr>)>, ErrorArtifact> {
log!(info "the compiling process has started."); log!(info "the compiling process has started.");
let arti = self.build_link_desugar(src, mode)?; let arti = self.build_link_desugar(src, mode)?;
let last = arti.object.module.last().cloned(); let last = arti.object.module.last().cloned();
@ -232,11 +240,8 @@ impl Compiler {
&mut self, &mut self,
src: String, src: String,
mode: &str, mode: &str,
) -> Result<CompleteArtifact, CompileErrors> { ) -> Result<CompleteArtifact, ErrorArtifact> {
let artifact = self let artifact = self.builder.build(src, mode)?;
.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(artifact.object); let hir = linker.link(artifact.object);
let desugared = HIRDesugarer::desugar(hir); let desugared = HIRDesugarer::desugar(hir);

View file

@ -10,7 +10,7 @@ use erg_common::Str;
use erg_parser::ast::{ParamPattern, VarName}; use erg_parser::ast::{ParamPattern, VarName};
use erg_parser::token::TokenKind; use erg_parser::token::TokenKind;
use crate::artifact::CompleteArtifact; use crate::artifact::{CompleteArtifact, ErrorArtifact};
use crate::build_hir::HIRBuilder; use crate::build_hir::HIRBuilder;
use crate::context::{Context, ContextProvider}; use crate::context::{Context, ContextProvider};
use crate::desugar_hir::HIRDesugarer; use crate::desugar_hir::HIRDesugarer;
@ -80,7 +80,12 @@ impl Runnable for Transpiler {
fn exec(&mut self) -> Result<i32, Self::Errs> { fn exec(&mut self) -> Result<i32, Self::Errs> {
let path = self.input().filename().replace(".er", ".py"); let path = self.input().filename().replace(".er", ".py");
let artifact = self.transpile(self.input().read(), "exec")?; let artifact = self
.transpile(self.input().read(), "exec")
.map_err(|eart| {
eart.warns.fmt_all_stderr();
eart.errors
})?;
artifact.warns.fmt_all_stderr(); artifact.warns.fmt_all_stderr();
let mut f = File::create(&path).unwrap(); let mut f = File::create(&path).unwrap();
f.write_all(artifact.object.code.as_bytes()).unwrap(); f.write_all(artifact.object.code.as_bytes()).unwrap();
@ -88,7 +93,10 @@ impl Runnable for Transpiler {
} }
fn eval(&mut self, src: String) -> Result<String, CompileErrors> { fn eval(&mut self, src: String) -> Result<String, CompileErrors> {
let artifact = self.transpile(src, "eval")?; let artifact = self.transpile(src, "eval").map_err(|eart| {
eart.warns.fmt_all_stderr();
eart.errors
})?;
artifact.warns.fmt_all_stderr(); artifact.warns.fmt_all_stderr();
Ok(artifact.object.code) Ok(artifact.object.code)
} }
@ -113,7 +121,7 @@ impl Transpiler {
&mut self, &mut self,
src: String, src: String,
mode: &str, mode: &str,
) -> Result<CompleteArtifact<PyScript>, CompileErrors> { ) -> Result<CompleteArtifact<PyScript>, ErrorArtifact> {
log!(info "the transpiling process has started."); log!(info "the transpiling process has started.");
let artifact = self.build_link_desugar(src, mode)?; let artifact = self.build_link_desugar(src, mode)?;
let script = self.script_generator.transpile(artifact.object); let script = self.script_generator.transpile(artifact.object);
@ -126,11 +134,8 @@ impl Transpiler {
&mut self, &mut self,
src: String, src: String,
mode: &str, mode: &str,
) -> Result<CompleteArtifact, CompileErrors> { ) -> Result<CompleteArtifact, ErrorArtifact> {
let artifact = self let artifact = self.builder.build(src, mode)?;
.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(artifact.object); let hir = linker.link(artifact.object);
let desugared = HIRDesugarer::desugar(hir); let desugared = HIRDesugarer::desugar(hir);

View file

@ -125,9 +125,13 @@ impl Runnable for DummyVM {
.last() .last()
.unwrap() .unwrap()
.replace(".er", ".pyc"); .replace(".er", ".pyc");
let warns = let warns = self
self.compiler .compiler
.compile_and_dump_as_pyc(&filename, self.input().read(), "exec")?; .compile_and_dump_as_pyc(&filename, self.input().read(), "exec")
.map_err(|eart| {
eart.warns.fmt_all_stderr();
eart.errors
})?;
warns.fmt_all_stderr(); warns.fmt_all_stderr();
let code = exec_pyc(&filename, self.cfg().py_command, &self.cfg().runtime_args); let code = exec_pyc(&filename, self.cfg().py_command, &self.cfg().runtime_args);
remove_file(&filename).unwrap(); remove_file(&filename).unwrap();
@ -137,11 +141,14 @@ impl Runnable for DummyVM {
fn eval(&mut self, src: String) -> Result<String, EvalErrors> { fn eval(&mut self, src: String) -> Result<String, EvalErrors> {
let arti = self let arti = self
.compiler .compiler
.eval_compile_and_dump_as_pyc("o.pyc", src, "eval")?; .eval_compile_and_dump_as_pyc("o.pyc", src, "eval")
.map_err(|eart| eart.errors)?;
let (last, warns) = (arti.object, arti.warns); let (last, warns) = (arti.object, arti.warns);
let mut res = warns.to_string(); let mut res = warns.to_string();
// Tell the REPL server to execute the code
res += &match self.stream.as_mut().unwrap().write("load".as_bytes()) { res += &match self.stream.as_mut().unwrap().write("load".as_bytes()) {
Result::Ok(_) => { Result::Ok(_) => {
// read the result from the REPL server
let mut buf = [0; 1024]; let mut buf = [0; 1024];
match self.stream.as_mut().unwrap().read(&mut buf) { match self.stream.as_mut().unwrap().read(&mut buf) {
Result::Ok(n) => { Result::Ok(n) => {