use erg_common::config::ErgConfig; use erg_common::traits::{ExitStatus, Runnable}; use erg_common::Str; use crate::ast::AST; use crate::desugar::Desugarer; use crate::error::{CompleteArtifact, IncompleteArtifact, ParserRunnerError, ParserRunnerErrors}; use crate::parse::ParserRunner; /// Summarize parsing and desugaring #[derive(Debug, Default)] pub struct ASTBuilder { runner: ParserRunner, } impl Runnable for ASTBuilder { type Err = ParserRunnerError; type Errs = ParserRunnerErrors; const NAME: &'static str = "Erg AST builder"; #[inline] fn new(cfg: ErgConfig) -> Self { Self { runner: ParserRunner::new(cfg), } } #[inline] fn cfg(&self) -> &ErgConfig { self.runner.cfg() } #[inline] fn cfg_mut(&mut self) -> &mut ErgConfig { self.runner.cfg_mut() } #[inline] fn finish(&mut self) {} #[inline] fn initialize(&mut self) {} #[inline] fn clear(&mut self) {} fn exec(&mut self) -> Result { let src = self.cfg_mut().input.read(); let artifact = self.build(src).map_err(|iart| iart.errors)?; println!("{}", artifact.ast); Ok(ExitStatus::OK) } fn eval(&mut self, src: String) -> Result { let artifact = self.build(src).map_err(|iart| iart.errors)?; Ok(format!("{}", artifact.ast)) } } impl ASTBuilder { pub fn build( &mut self, src: String, ) -> Result< CompleteArtifact, IncompleteArtifact, > { let name = Str::from(self.runner.cfg().input.filename()); let mut desugarer = Desugarer::new(); let artifact = self.runner.parse(src).map_err(|iart| { iart.map_mod(|module| { let module = desugarer.desugar(module); AST::new(name.clone(), module) }) })?; let module = desugarer.desugar(artifact.ast); let ast = AST::new(name, module); Ok(CompleteArtifact::new( ast, ParserRunnerErrors::convert(self.input(), artifact.warns), )) } pub fn build_without_desugaring( &mut self, src: String, ) -> Result< CompleteArtifact, IncompleteArtifact, > { let name = Str::from(self.runner.cfg().input.filename()); let artifact = self .runner .parse(src) .map_err(|iart| iart.map_mod(|module| AST::new(name.clone(), module)))?; let ast = AST::new(name, artifact.ast); Ok(CompleteArtifact::new( ast, ParserRunnerErrors::convert(self.input(), artifact.warns), )) } }