Add ASTLowererRunner

* add `--mode lower`
This commit is contained in:
Shunsuke Shibayama 2022-09-11 11:56:41 +09:00
parent 64d57641c9
commit a636a1d843
5 changed files with 104 additions and 13 deletions

View file

@ -6,13 +6,12 @@ pub extern crate erg_parser;
mod compile;
pub use compile::*;
mod codegen;
pub mod context;
pub mod effectcheck;
pub mod error;
pub mod hir;
pub mod link;
pub mod lower;
pub use lower::ASTLowerer;
pub mod context;
pub mod optimize;
pub mod ownercheck;
pub mod varinfo;

View file

@ -1,15 +1,19 @@
//! implements `ASTLowerer`.
//!
//! ASTLowerer(ASTからHIRへの変換器)を実装
use erg_common::error::Location;
use erg_common::traits::{Locational, Stream};
use erg_common::config::{ErgConfig, Input};
use erg_common::error::{Location, MultiErrorDisplay};
use erg_common::traits::{Locational, Runnable, Stream};
use erg_common::vis::Visibility;
use erg_common::{enum_unwrap, fmt_option, fn_name, get_hash, log, switch_lang, Str};
use erg_parser::ast;
use erg_parser::ast::AST;
use erg_parser::error::ParserRunnerErrors;
use erg_parser::lex::Lexer;
use erg_parser::token::{Token, TokenKind};
use erg_parser::Parser;
use erg_type::constructors::{array, array_mut, free_var, func, mono, poly, proc, quant};
use erg_type::free::Constraint;
use erg_type::typaram::TyParam;
@ -17,9 +21,12 @@ use erg_type::value::{TypeObj, ValueObj};
use erg_type::{HasType, ParamTy, Type};
use crate::context::{Context, ContextKind, RegistrationMode};
use crate::error::{LowerError, LowerErrors, LowerResult, LowerWarnings};
use crate::error::{
CompileError, CompileErrors, LowerError, LowerErrors, LowerResult, LowerWarnings,
};
use crate::hir;
use crate::hir::HIR;
use crate::link::Linker;
use crate::varinfo::VarKind;
use Visibility::*;
@ -51,6 +58,83 @@ macro_rules! check_inheritable {
};
}
pub struct ASTLowererRunner {
cfg: ErgConfig,
lowerer: ASTLowerer,
}
impl Runnable for ASTLowererRunner {
type Err = CompileError;
type Errs = CompileErrors;
const NAME: &'static str = "Erg lowerer";
fn new(cfg: ErgConfig) -> Self {
Self {
cfg,
lowerer: ASTLowerer::new(),
}
}
#[inline]
fn input(&self) -> &Input {
&self.cfg.input
}
#[inline]
fn finish(&mut self) {}
fn clear(&mut self) {
self.lowerer.errs.clear();
self.lowerer.warns.clear();
}
fn exec(&mut self) -> Result<(), Self::Errs> {
let ts = Lexer::new(self.input().clone())
.lex()
.map_err(|errs| ParserRunnerErrors::convert(self.input(), errs))?;
let ast = Parser::new(ts)
.parse(Str::ever(self.cfg.module))
.map_err(|errs| ParserRunnerErrors::convert(self.input(), errs))?;
let linker = Linker::new();
let ast = linker.link(ast).map_err(|errs| self.convert(errs))?;
let (hir, warns) = self
.lowerer
.lower(ast, "exec")
.map_err(|errs| self.convert(errs))?;
if self.cfg.verbose >= 2 {
let warns = self.convert(warns);
warns.fmt_all_stderr();
}
println!("{hir}");
Ok(())
}
fn eval(&mut self, src: Str) -> Result<String, CompileErrors> {
let ts = Lexer::new(Input::Str(src))
.lex()
.map_err(|errs| ParserRunnerErrors::convert(self.input(), errs))?;
let ast = Parser::new(ts)
.parse(Str::ever(self.cfg.module))
.map_err(|errs| ParserRunnerErrors::convert(self.input(), errs))?;
let linker = Linker::new();
let ast = linker.link(ast).map_err(|errs| self.convert(errs))?;
let (hir, _) = self
.lowerer
.lower(ast, "eval")
.map_err(|errs| self.convert(errs))?;
Ok(format!("{hir}"))
}
}
impl ASTLowererRunner {
fn convert(&self, errs: LowerErrors) -> CompileErrors {
errs.into_iter()
.map(|e| CompileError::new(e.core, self.input().clone(), e.caused_by))
.collect::<Vec<_>>()
.into()
}
}
/// Singleton that checks types of an AST, and convert (lower) it into a HIR
#[derive(Debug)]
pub struct ASTLowerer {
@ -59,6 +143,12 @@ pub struct ASTLowerer {
warns: LowerWarnings,
}
impl Default for ASTLowerer {
fn default() -> Self {
Self::new()
}
}
impl ASTLowerer {
pub fn new() -> Self {
Self {
@ -806,9 +896,3 @@ impl ASTLowerer {
}
}
}
impl Default for ASTLowerer {
fn default() -> Self {
Self::new()
}
}

View file

@ -8,6 +8,7 @@ use std::thread;
use erg_common::config::ErgConfig;
use erg_common::traits::Runnable;
use erg_compiler::lower::ASTLowererRunner;
use erg_compiler::Compiler;
use erg_parser::lex::LexerRunner;
@ -24,6 +25,9 @@ fn run() {
"parse" => {
ParserRunner::run(cfg);
}
"lower" => {
ASTLowererRunner::run(cfg);
}
"compile" | "exec" => {
Compiler::run(cfg);
}

View file

@ -82,7 +82,7 @@ pub struct Parser {
}
impl Parser {
const fn new(ts: TokenStream) -> Self {
pub const fn new(ts: TokenStream) -> Self {
Self {
counter: DefId(0),
level: 0,

View file

@ -11,6 +11,7 @@ use erg_common::traits::Runnable;
use erg_parser::lex::LexerRunner;
use erg_parser::ParserRunner;
use erg_compiler::lower::ASTLowererRunner;
use erg_compiler::Compiler;
use erg_type::deserialize::Deserializer;
@ -26,6 +27,9 @@ fn run() {
"parse" => {
ParserRunner::run(cfg);
}
"lower" => {
ASTLowererRunner::run(cfg);
}
"compile" => {
Compiler::run(cfg);
}