From bc52b448e2b9fedb7cf29caffe33c04fa3526f47 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Tue, 29 Nov 2022 00:39:57 +0900 Subject: [PATCH] Add ErrorArtifact --- compiler/erg_compiler/artifact.rs | 32 ++++++++++++++++++++++++++++++ compiler/erg_compiler/compile.rs | 29 ++++++++++++++++----------- compiler/erg_compiler/transpile.rs | 23 ++++++++++++--------- src/dummy.rs | 15 ++++++++++---- 4 files changed, 74 insertions(+), 25 deletions(-) diff --git a/compiler/erg_compiler/artifact.rs b/compiler/erg_compiler/artifact.rs index fa9ee902..b5a5b629 100644 --- a/compiler/erg_compiler/artifact.rs +++ b/compiler/erg_compiler/artifact.rs @@ -44,3 +44,35 @@ impl IncompleteArtifact { } } } + +#[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 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 } + } +} diff --git a/compiler/erg_compiler/compile.rs b/compiler/erg_compiler/compile.rs index 5e69b785..ad118c71 100644 --- a/compiler/erg_compiler/compile.rs +++ b/compiler/erg_compiler/compile.rs @@ -8,7 +8,7 @@ use erg_common::error::MultiErrorDisplay; use erg_common::log; use erg_common::traits::{Runnable, Stream}; -use crate::artifact::CompleteArtifact; +use crate::artifact::{CompleteArtifact, ErrorArtifact}; use crate::context::ContextProvider; use crate::ty::codeobj::CodeObj; @@ -144,13 +144,21 @@ impl Runnable for Compiler { fn exec(&mut self) -> Result { 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(); Ok(0) } fn eval(&mut self, src: String) -> Result { - 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(); Ok(arti.object.code_info(Some(self.code_generator.py_version))) } @@ -180,7 +188,7 @@ impl Compiler { pyc_path: P, src: String, mode: &str, - ) -> Result { + ) -> Result { let arti = self.compile(src, mode)?; arti.object .dump_as_pyc(pyc_path, self.cfg.py_magic_num) @@ -193,7 +201,7 @@ impl Compiler { pyc_path: P, src: String, mode: &str, - ) -> Result>, CompileErrors> { + ) -> Result>, ErrorArtifact> { let arti = self.eval_compile(src, mode)?; let (code, last) = arti.object; code.dump_as_pyc(pyc_path, self.cfg.py_magic_num) @@ -205,7 +213,7 @@ impl Compiler { &mut self, src: String, mode: &str, - ) -> Result, CompileErrors> { + ) -> Result, ErrorArtifact> { log!(info "the compiling process has started."); let arti = self.build_link_desugar(src, mode)?; let codeobj = self.code_generator.emit(arti.object); @@ -218,7 +226,7 @@ impl Compiler { &mut self, src: String, mode: &str, - ) -> Result)>, CompileErrors> { + ) -> Result)>, ErrorArtifact> { log!(info "the compiling process has started."); let arti = self.build_link_desugar(src, mode)?; let last = arti.object.module.last().cloned(); @@ -232,11 +240,8 @@ impl Compiler { &mut self, src: String, mode: &str, - ) -> Result { - let artifact = self - .builder - .build(src, mode) - .map_err(|artifact| artifact.errors)?; + ) -> Result { + let artifact = self.builder.build(src, mode)?; let linker = Linker::new(&self.cfg, &self.mod_cache); let hir = linker.link(artifact.object); let desugared = HIRDesugarer::desugar(hir); diff --git a/compiler/erg_compiler/transpile.rs b/compiler/erg_compiler/transpile.rs index e7ab245a..0c634938 100644 --- a/compiler/erg_compiler/transpile.rs +++ b/compiler/erg_compiler/transpile.rs @@ -10,7 +10,7 @@ use erg_common::Str; use erg_parser::ast::{ParamPattern, VarName}; use erg_parser::token::TokenKind; -use crate::artifact::CompleteArtifact; +use crate::artifact::{CompleteArtifact, ErrorArtifact}; use crate::build_hir::HIRBuilder; use crate::context::{Context, ContextProvider}; use crate::desugar_hir::HIRDesugarer; @@ -80,7 +80,12 @@ impl Runnable for Transpiler { fn exec(&mut self) -> Result { 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(); let mut f = File::create(&path).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 { - 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(); Ok(artifact.object.code) } @@ -113,7 +121,7 @@ impl Transpiler { &mut self, src: String, mode: &str, - ) -> Result, CompileErrors> { + ) -> Result, ErrorArtifact> { log!(info "the transpiling process has started."); let artifact = self.build_link_desugar(src, mode)?; let script = self.script_generator.transpile(artifact.object); @@ -126,11 +134,8 @@ impl Transpiler { &mut self, src: String, mode: &str, - ) -> Result { - let artifact = self - .builder - .build(src, mode) - .map_err(|artifact| artifact.errors)?; + ) -> Result { + let artifact = self.builder.build(src, mode)?; let linker = Linker::new(&self.cfg, &self.mod_cache); let hir = linker.link(artifact.object); let desugared = HIRDesugarer::desugar(hir); diff --git a/src/dummy.rs b/src/dummy.rs index 05d4c64e..bd9292fb 100644 --- a/src/dummy.rs +++ b/src/dummy.rs @@ -125,9 +125,13 @@ impl Runnable for DummyVM { .last() .unwrap() .replace(".er", ".pyc"); - let warns = - self.compiler - .compile_and_dump_as_pyc(&filename, self.input().read(), "exec")?; + let warns = self + .compiler + .compile_and_dump_as_pyc(&filename, self.input().read(), "exec") + .map_err(|eart| { + eart.warns.fmt_all_stderr(); + eart.errors + })?; warns.fmt_all_stderr(); let code = exec_pyc(&filename, self.cfg().py_command, &self.cfg().runtime_args); remove_file(&filename).unwrap(); @@ -137,11 +141,14 @@ impl Runnable for DummyVM { fn eval(&mut self, src: String) -> Result { let arti = self .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 mut res = warns.to_string(); + // Tell the REPL server to execute the code res += &match self.stream.as_mut().unwrap().write("load".as_bytes()) { Result::Ok(_) => { + // read the result from the REPL server let mut buf = [0; 1024]; match self.stream.as_mut().unwrap().read(&mut buf) { Result::Ok(n) => {