diff --git a/compiler/erg_common/config.rs b/compiler/erg_common/config.rs index 104bb1a5..5b7a058c 100644 --- a/compiler/erg_common/config.rs +++ b/compiler/erg_common/config.rs @@ -126,6 +126,7 @@ pub struct ErgConfig { pub py_server_timeout: u64, pub quiet_startup: bool, pub input: Input, + /// module name to be executed pub module: &'static str, /// verbosity level for system messages. /// * 0: display errors diff --git a/compiler/erg_compiler/builder.rs b/compiler/erg_compiler/builder.rs new file mode 100644 index 00000000..297fc388 --- /dev/null +++ b/compiler/erg_compiler/builder.rs @@ -0,0 +1,57 @@ +use erg_common::config::{ErgConfig, Input}; +use erg_common::traits::Stream; + +use erg_parser::ast::VarName; +use erg_parser::builder::ASTBuilder; + +use crate::error::{CompileError, CompileErrors, TyCheckErrors}; +// use crate::hir::HIR; +use crate::check::Checker; +use crate::mod_cache::SharedModuleCache; + +#[derive(Debug)] +pub struct HIRBuilder { + checker: Checker, + mod_cache: SharedModuleCache, +} + +impl HIRBuilder { + fn convert(&self, errs: TyCheckErrors) -> CompileErrors { + errs.into_iter() + .map(|e| CompileError::new(e.core, self.checker.cfg.input.clone(), e.caused_by)) + .collect::>() + .into() + } + + pub fn new(cfg: ErgConfig, mod_cache: SharedModuleCache) -> Self { + Self { + checker: Checker::new(cfg, mod_cache.clone()), + mod_cache, + } + } + + pub fn build_and_cache(&mut self, var_name: VarName) -> Result<(), CompileErrors> { + let mut ast_builder = ASTBuilder::new(self.checker.cfg.copy()); + let ast = ast_builder.build()?; + let (hir, ctx) = self + .checker + .check(ast, "exec") + .map_err(|errs| self.convert(errs))?; + self.mod_cache.register(var_name, Some(hir), ctx); + Ok(()) + } + + pub fn build_and_cache_main(&mut self, src: String, mode: &str) -> Result<(), CompileErrors> { + let mut cfg = self.checker.cfg.copy(); + cfg.input = Input::Str(src); + let mut ast_builder = ASTBuilder::new(cfg); + let ast = ast_builder.build()?; + let (hir, ctx) = self + .checker + .check(ast, mode) + .map_err(|errs| self.convert(errs))?; + let name = VarName::from_static(""); + self.mod_cache.register(name, Some(hir), ctx); + Ok(()) + } +} diff --git a/compiler/erg_compiler/checker.rs b/compiler/erg_compiler/check.rs similarity index 61% rename from compiler/erg_compiler/checker.rs rename to compiler/erg_compiler/check.rs index 9b8f6d2a..551079cc 100644 --- a/compiler/erg_compiler/checker.rs +++ b/compiler/erg_compiler/check.rs @@ -5,36 +5,61 @@ use erg_common::traits::Runnable; use erg_parser::ast::AST; use erg_parser::builder::ASTBuilder; +use crate::context::Context; use crate::effectcheck::SideEffectChecker; use crate::error::{TyCheckError, TyCheckErrors}; use crate::hir::HIR; use crate::lower::ASTLowerer; +use crate::mod_cache::SharedModuleCache; use crate::ownercheck::OwnershipChecker; /// Summarize lowering, side-effect checking, and ownership checking #[derive(Debug)] pub struct Checker { - cfg: ErgConfig, + pub cfg: ErgConfig, lowerer: ASTLowerer, ownership_checker: OwnershipChecker, } -impl Runnable for Checker { +impl Checker { + pub fn new(cfg: ErgConfig, mod_cache: SharedModuleCache) -> Self { + Self { + cfg, + lowerer: ASTLowerer::new(mod_cache), + ownership_checker: OwnershipChecker::new(), + } + } + + pub fn check(&mut self, ast: AST, mode: &str) -> Result<(HIR, Context), TyCheckErrors> { + let (hir, ctx, warns) = self.lowerer.lower(ast, mode)?; + if self.cfg.verbose >= 2 { + warns.fmt_all_stderr(); + } + let effect_checker = SideEffectChecker::new(); + let hir = effect_checker.check(hir)?; + let hir = self.ownership_checker.check(hir)?; + Ok((hir, ctx)) + } +} + +pub struct CheckerRunner { + checker: Checker, +} + +impl Runnable for CheckerRunner { type Err = TyCheckError; type Errs = TyCheckErrors; const NAME: &'static str = "Erg type-checker"; fn new(cfg: ErgConfig) -> Self { Self { - ownership_checker: OwnershipChecker::new(), - lowerer: ASTLowerer::new(), - cfg, + checker: Checker::new(cfg, SharedModuleCache::new()), } } #[inline] fn cfg(&self) -> &ErgConfig { - &self.cfg + &self.checker.cfg } #[inline] @@ -43,30 +68,17 @@ impl Runnable for Checker { fn clear(&mut self) {} fn exec(&mut self) -> Result<(), Self::Errs> { - let mut builder = ASTBuilder::new(self.cfg.copy()); + let mut builder = ASTBuilder::new(self.cfg().copy()); let ast = builder.build()?; - let hir = self.check(ast, "exec")?; + let (hir, _) = self.checker.check(ast, "exec")?; println!("{hir}"); Ok(()) } fn eval(&mut self, src: String) -> Result { - let mut builder = ASTBuilder::new(self.cfg.copy()); - let ast = builder.build_with_input(src)?; - let hir = self.check(ast, "eval")?; + let mut builder = ASTBuilder::new(self.cfg().copy()); + let ast = builder.build_with_str(src)?; + let (hir, _) = self.checker.check(ast, "eval")?; Ok(hir.to_string()) } } - -impl Checker { - pub fn check(&mut self, ast: AST, mode: &str) -> Result { - let (hir, warns) = self.lowerer.lower(ast, mode)?; - if self.cfg.verbose >= 2 { - warns.fmt_all_stderr(); - } - let effect_checker = SideEffectChecker::new(); - let hir = effect_checker.check(hir)?; - let hir = self.ownership_checker.check(hir)?; - Ok(hir) - } -} diff --git a/compiler/erg_compiler/compile.rs b/compiler/erg_compiler/compile.rs index f9a65afd..1e411c1b 100644 --- a/compiler/erg_compiler/compile.rs +++ b/compiler/erg_compiler/compile.rs @@ -3,16 +3,16 @@ //! コンパイラーを定義する use std::path::Path; -use erg_common::config::{ErgConfig, Input}; +use erg_common::config::ErgConfig; use erg_common::log; use erg_common::traits::{Runnable, Stream}; use erg_type::codeobj::CodeObj; -use erg_parser::builder::ASTBuilder; - -use crate::checker::Checker; +use crate::builder::HIRBuilder; use crate::codegen::CodeGenerator; -use crate::error::{CompileError, CompileErrors, TyCheckErrors}; +use crate::error::{CompileError, CompileErrors}; +use crate::link::Linker; +use crate::mod_cache::SharedModuleCache; /// * registered as global -> Global /// * defined in the toplevel scope (and called in the inner scope) -> Global @@ -91,7 +91,7 @@ impl AccessKind { #[derive(Debug)] pub struct Compiler { cfg: ErgConfig, - checker: Checker, + mod_cache: SharedModuleCache, code_generator: CodeGenerator, } @@ -101,9 +101,10 @@ impl Runnable for Compiler { const NAME: &'static str = "Erg compiler"; fn new(cfg: ErgConfig) -> Self { + let mod_cache = SharedModuleCache::new(); Self { - checker: Checker::new(cfg.copy()), code_generator: CodeGenerator::new(cfg.copy()), + mod_cache, cfg, } } @@ -133,13 +134,6 @@ impl Runnable for Compiler { } impl Compiler { - fn convert(&self, errs: TyCheckErrors) -> CompileErrors { - errs.into_iter() - .map(|e| CompileError::new(e.core, self.input().clone(), e.caused_by)) - .collect::>() - .into() - } - pub fn compile_and_dump_as_pyc>( &mut self, src: String, @@ -154,14 +148,9 @@ impl Compiler { pub fn compile(&mut self, src: String, mode: &str) -> Result { log!(info "the compiling process has started."); - let mut cfg = self.cfg.copy(); - cfg.input = Input::Str(src); - let mut ast_builder = ASTBuilder::new(cfg); - let ast = ast_builder.build()?; - let hir = self - .checker - .check(ast, mode) - .map_err(|errs| self.convert(errs))?; + let mut hir_builder = HIRBuilder::new(self.cfg.copy(), self.mod_cache.clone()); + hir_builder.build_and_cache_main(src, mode)?; + let hir = Linker::link(self.mod_cache.clone()); let codeobj = self.code_generator.emit(hir); log!(info "code object:\n{}", codeobj.code_info()); log!( diff --git a/compiler/erg_compiler/context/initialize/mod.rs b/compiler/erg_compiler/context/initialize/mod.rs index 1d2ea802..67e40645 100644 --- a/compiler/erg_compiler/context/initialize/mod.rs +++ b/compiler/erg_compiler/context/initialize/mod.rs @@ -1783,13 +1783,13 @@ impl Context { ctx } - pub fn new_main_module() -> Self { + pub fn new_main_module(mod_cache: SharedModuleCache) -> Self { Context::new( "".into(), ContextKind::Module, vec![], Some(Context::init_builtins()), - Some(SharedModuleCache::new()), + Some(mod_cache), Context::TOP_LEVEL, ) } diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index 5d36221e..c5e38c6d 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -238,6 +238,7 @@ impl From for ContextKind { DefKind::Class | DefKind::Inherit => Self::Class, DefKind::Trait | DefKind::Subsume => Self::Trait, DefKind::StructuralTrait => Self::StructuralTrait, + DefKind::Module => Self::Module, DefKind::Other => Self::Instant, } } diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index d3871ec4..411b98fd 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -1,5 +1,7 @@ use std::option::Option; // conflicting to Type::Option +use erg_common::config::{ErgConfig, Input}; +use erg_common::error::MultiErrorDisplay; use erg_common::traits::{Locational, Stream}; use erg_common::vis::Visibility; use erg_common::Str; @@ -14,11 +16,12 @@ use erg_type::value::{GenTypeObj, TypeKind, TypeObj, ValueObj}; use erg_type::{HasType, ParamTy, SubrType, TyBound, Type}; use Type::*; +use crate::builder::HIRBuilder; use crate::context::{ClassDefType, Context, DefaultInfo, RegistrationMode, TraitInstance}; use crate::error::readable_name; use crate::error::{TyCheckError, TyCheckResult}; use crate::hir; -use crate::mod_cache::ModuleEntry; +use crate::mod_cache::SharedModuleCache; use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind}; use Mutability::*; use RegistrationMode::*; @@ -763,56 +766,55 @@ impl Context { match mod_name { hir::Expr::Lit(lit) => { if self.subtype_of(&lit.value.class(), &Str) { - let name = enum_unwrap!(lit.value.clone(), ValueObj::Str); - if let Some(mod_cache) = self.mod_cache.as_mut() { - match &name[..] { + let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); + if let Some(mod_cache) = self.mod_cache.as_ref() { + match &__name__[..] { "importlib" => { mod_cache.register( var_name.clone(), - ModuleEntry::builtin(Self::init_py_importlib_mod()), + None, + Self::init_py_importlib_mod(), ); } "io" => { - mod_cache.register( - var_name.clone(), - ModuleEntry::builtin(Self::init_py_io_mod()), - ); + mod_cache.register(var_name.clone(), None, Self::init_py_io_mod()); } "math" => { mod_cache.register( var_name.clone(), - ModuleEntry::builtin(Self::init_py_math_mod()), + None, + Self::init_py_math_mod(), ); } "random" => { mod_cache.register( var_name.clone(), - ModuleEntry::builtin(Self::init_py_random_mod()), + None, + Self::init_py_random_mod(), ); } "socket" => { mod_cache.register( var_name.clone(), - ModuleEntry::builtin(Self::init_py_socket_mod()), + None, + Self::init_py_socket_mod(), ); } "sys" => { - mod_cache.register( - var_name.clone(), - ModuleEntry::builtin(Self::init_py_sys_mod()), - ); + mod_cache.register(var_name.clone(), None, Self::init_py_sys_mod()); } "time" => { mod_cache.register( var_name.clone(), - ModuleEntry::builtin(Self::init_py_time_mod()), + None, + Self::init_py_time_mod(), ); } - other => todo!("importing {other}"), + _ => self.import_user_module(var_name, __name__, mod_cache), } } else { // maybe unreachable - todo!("importing {name} in the builtin module") + todo!("importing {__name__} in the builtin module") } } else { return Err(TyCheckError::type_mismatch_error( @@ -839,6 +841,17 @@ impl Context { Ok(()) } + fn import_user_module(&self, var_name: &VarName, __name__: Str, mod_cache: &SharedModuleCache) { + let cfg = ErgConfig { + input: Input::File(format!("{__name__}.er")), + ..ErgConfig::default() + }; + let mut hir_builder = HIRBuilder::new(cfg, mod_cache.clone()); + if let Err(errs) = hir_builder.build_and_cache(var_name.clone()) { + errs.fmt_all_stderr(); + } + } + pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) { self.bounds.push(TyBound::subtype_of(sub, sup)); } diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index 244eb059..a041a595 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -1332,6 +1332,7 @@ impl Def { DefKind::Other } } + Some("import") => DefKind::Module, _ => DefKind::Other, }, _ => DefKind::Other, diff --git a/compiler/erg_compiler/lib.rs b/compiler/erg_compiler/lib.rs index 795219c4..71b29231 100644 --- a/compiler/erg_compiler/lib.rs +++ b/compiler/erg_compiler/lib.rs @@ -3,7 +3,8 @@ extern crate erg_common; pub extern crate erg_parser; -mod checker; +mod builder; +mod check; mod compile; pub use compile::*; mod codegen; @@ -11,8 +12,10 @@ pub mod context; pub mod effectcheck; pub mod error; pub mod hir; +pub mod link; pub mod lower; pub mod mod_cache; +// pub mod name_resolve; pub mod optimize; pub mod ownercheck; pub mod varinfo; diff --git a/compiler/erg_compiler/link.rs b/compiler/erg_compiler/link.rs new file mode 100644 index 00000000..14564a09 --- /dev/null +++ b/compiler/erg_compiler/link.rs @@ -0,0 +1,19 @@ +use erg_common::traits::Stream; + +use crate::hir::{Expr, HIR}; +use crate::mod_cache::SharedModuleCache; + +pub struct Linker {} + +impl Linker { + pub fn link(mod_cache: SharedModuleCache) -> HIR { + let mut main_mod_hir = mod_cache.remove("").unwrap().hir.unwrap(); + for chunk in main_mod_hir.module.iter_mut() { + match chunk { + Expr::Def(def) if def.def_kind().is_module() => {} + _ => {} + } + } + main_mod_hir + } +} diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 857b85e7..bff3b3fc 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -27,6 +27,7 @@ use crate::error::{ }; use crate::hir; use crate::hir::HIR; +use crate::mod_cache::SharedModuleCache; use crate::varinfo::VarKind; use Visibility::*; @@ -48,7 +49,7 @@ impl Runnable for ASTLowererRunner { fn new(cfg: ErgConfig) -> Self { Self { cfg, - lowerer: ASTLowerer::new(), + lowerer: ASTLowerer::new(SharedModuleCache::new()), } } @@ -63,7 +64,7 @@ impl Runnable for ASTLowererRunner { fn exec(&mut self) -> Result<(), Self::Errs> { let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let ast = ast_builder.build()?; - let (hir, warns) = self + let (hir, _, warns) = self .lowerer .lower(ast, "exec") .map_err(|errs| self.convert(errs))?; @@ -77,8 +78,8 @@ impl Runnable for ASTLowererRunner { fn eval(&mut self, src: String) -> Result { let mut ast_builder = ASTBuilder::new(self.cfg.copy()); - let ast = ast_builder.build_with_input(src)?; - let (hir, _) = self + let ast = ast_builder.build_with_str(src)?; + let (hir, ..) = self .lowerer .lower(ast, "eval") .map_err(|errs| self.convert(errs))?; @@ -105,14 +106,14 @@ pub struct ASTLowerer { impl Default for ASTLowerer { fn default() -> Self { - Self::new() + Self::new(SharedModuleCache::new()) } } impl ASTLowerer { - pub fn new() -> Self { + pub fn new(mod_cache: SharedModuleCache) -> Self { Self { - ctx: Context::new_main_module(), + ctx: Context::new_main_module(mod_cache), errs: LowerErrors::empty(), warns: LowerWarnings::empty(), } @@ -1008,7 +1009,11 @@ impl ASTLowerer { Ok(hir::Block::new(hir_block)) } - pub fn lower(&mut self, ast: AST, mode: &str) -> Result<(HIR, LowerWarnings), LowerErrors> { + pub fn lower( + &mut self, + ast: AST, + mode: &str, + ) -> Result<(HIR, Context, LowerWarnings), LowerErrors> { log!(info "the AST lowering process has started."); log!(info "the type-checking process has started."); let mut module = hir::Module::with_capacity(ast.module.len()); @@ -1035,7 +1040,11 @@ impl ASTLowerer { if self.errs.is_empty() { log!(info "HIR:\n{hir}"); log!(info "the AST lowering process has completed."); - Ok((hir, LowerWarnings::from(self.warns.take_all()))) + Ok(( + hir, + self.ctx.pop()?, + LowerWarnings::from(self.warns.take_all()), + )) } else { log!(err "the AST lowering process has failed."); Err(LowerErrors::from(self.errs.take_all())) diff --git a/compiler/erg_compiler/mod_cache.rs b/compiler/erg_compiler/mod_cache.rs index 25499462..5e490860 100644 --- a/compiler/erg_compiler/mod_cache.rs +++ b/compiler/erg_compiler/mod_cache.rs @@ -27,24 +27,24 @@ impl ModId { #[derive(Debug)] pub struct ModuleEntry { - _id: ModId, // builtin == 0, __main__ == 1 - _hir: Option, + id: ModId, // builtin == 0, __main__ == 1 + pub hir: Option, ctx: Rc, } impl ModuleEntry { pub fn new(id: ModId, hir: Option, ctx: Context) -> Self { Self { - _id: id, - _hir: hir, + id, + hir, ctx: Rc::new(ctx), } } pub fn builtin(ctx: Context) -> Self { Self { - _id: ModId::builtin(), - _hir: None, + id: ModId::builtin(), + hir: None, ctx: Rc::new(ctx), } } @@ -53,11 +53,15 @@ impl ModuleEntry { #[derive(Debug, Default)] pub struct ModuleCache { cache: Dict, + last_id: usize, } impl ModuleCache { pub fn new() -> Self { - Self { cache: Dict::new() } + Self { + cache: Dict::new(), + last_id: 0, + } } pub fn get(&self, name: &Q) -> Option<&ModuleEntry> @@ -67,7 +71,10 @@ impl ModuleCache { self.cache.get(name) } - pub fn register(&mut self, name: VarName, entry: ModuleEntry) { + pub fn register(&mut self, name: VarName, hir: Option, ctx: Context) { + self.last_id += 1; + let id = ModId::new(self.last_id); + let entry = ModuleEntry::new(id, hir, ctx); self.cache.insert(name, entry); } @@ -77,6 +84,20 @@ impl ModuleCache { { self.cache.remove(name) } + + pub fn remove_by_id(&mut self, id: ModId) -> Option { + if let Some(name) = self.cache.iter().find_map(|(name, ent)| { + if ent.id == id { + Some(name.clone()) + } else { + None + } + }) { + self.remove(&name) + } else { + None + } + } } #[derive(Debug, Clone, Default)] @@ -102,14 +123,18 @@ impl SharedModuleCache { ref_.get(name).map(|entry| entry.ctx.as_ref()) } - pub fn register(&self, name: VarName, entry: ModuleEntry) { - self.0.borrow_mut().register(name, entry); + pub fn register(&self, name: VarName, hir: Option, ctx: Context) { + self.0.borrow_mut().register(name, hir, ctx); } - pub fn remove(&mut self, name: &Q) -> Option + pub fn remove(&self, name: &Q) -> Option where VarName: Borrow, { self.0.borrow_mut().remove(name) } + + pub fn remove_by_id(&self, id: ModId) -> Option { + self.0.borrow_mut().remove_by_id(id) + } } diff --git a/compiler/erg_parser/reorder.rs b/compiler/erg_compiler/reorder.rs similarity index 100% rename from compiler/erg_parser/reorder.rs rename to compiler/erg_compiler/reorder.rs diff --git a/compiler/erg_compiler/tests/test.rs b/compiler/erg_compiler/tests/test.rs index a137e2eb..fa286655 100644 --- a/compiler/erg_compiler/tests/test.rs +++ b/compiler/erg_compiler/tests/test.rs @@ -1,15 +1,16 @@ use erg_compiler::context::Context; +use erg_compiler::mod_cache::SharedModuleCache; #[test] fn test_subtyping() -> Result<(), ()> { - let context = Context::new_main_module(); + let context = Context::new_main_module(SharedModuleCache::new()); context.test_refinement_subtyping()?; Ok(()) } #[test] fn test_instantiation_and_generalization() -> Result<(), ()> { - let context = Context::new_main_module(); + let context = Context::new_main_module(SharedModuleCache::new()); context.test_instantiation_and_generalization()?; Ok(()) } diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index d5f1b4be..dc1cc275 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -2839,6 +2839,7 @@ pub enum DefKind { Trait, Subsume, StructuralTrait, + Module, Other, } @@ -2846,6 +2847,10 @@ impl DefKind { pub const fn is_trait(&self) -> bool { matches!(self, Self::Trait | Self::Subsume | Self::StructuralTrait) } + + pub fn is_module(&self) -> bool { + matches!(self, Self::Module) + } } #[derive(Clone, Debug, PartialEq, Eq, Hash)] diff --git a/compiler/erg_parser/builder.rs b/compiler/erg_parser/builder.rs index 3659863f..bd7c24c9 100644 --- a/compiler/erg_parser/builder.rs +++ b/compiler/erg_parser/builder.rs @@ -6,9 +6,8 @@ use crate::ast::AST; use crate::desugar::Desugarer; use crate::error::ParserRunnerErrors; use crate::parse::ParserRunner; -use crate::reorder::Reorderer; -/// Summarize parsing, desugaring, and reordering +/// Summarize parsing and desugaring pub struct ASTBuilder { runner: ParserRunner, } @@ -27,24 +26,16 @@ impl ASTBuilder { let mut desugarer = Desugarer::new(); let module = desugarer.desugar(module); let ast = AST::new(Str::ever(self.runner.cfg().module), module); - let reorderer = Reorderer::new(); - let ast = reorderer - .reorder(ast) - .map_err(|errs| ParserRunnerErrors::convert(self.runner.input(), errs))?; Ok(ast) } - pub fn build_with_input(&mut self, src: String) -> Result { - let module = self.runner.parse_with_input(src)?; + pub fn build_with_str(&mut self, src: String) -> Result { + let module = self.runner.parse_with_str(src)?; let mut desugarer = Desugarer::new(); let module = desugarer.desugar(module); let mut desugarer = Desugarer::new(); let module = desugarer.desugar(module); let ast = AST::new(Str::ever(self.runner.cfg().module), module); - let reorderer = Reorderer::new(); - let ast = reorderer - .reorder(ast) - .map_err(|errs| ParserRunnerErrors::convert(self.runner.input(), errs))?; Ok(ast) } } diff --git a/compiler/erg_parser/lib.rs b/compiler/erg_parser/lib.rs index e2fcd877..731424cf 100644 --- a/compiler/erg_parser/lib.rs +++ b/compiler/erg_parser/lib.rs @@ -9,7 +9,6 @@ pub mod desugar; pub mod error; pub mod lex; pub mod parse; -pub mod reorder; pub mod token; pub use parse::{Parser, ParserRunner}; diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index f11cbdfd..92d76591 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -193,7 +193,7 @@ impl Runnable for ParserRunner { } fn eval(&mut self, src: String) -> Result { - let ast = self.parse_with_input(src)?; + let ast = self.parse_with_str(src)?; Ok(format!("{ast}")) } } @@ -212,7 +212,6 @@ impl ParserRunner { self.parse_token_stream(ts) } - /// Parses with default configuration pub fn parse_with_default_config(input: Input) -> Result { let cfg = ErgConfig { input, @@ -222,7 +221,7 @@ impl ParserRunner { self_.parse() } - pub fn parse_with_input(&mut self, src: String) -> Result { + pub fn parse_with_str(&mut self, src: String) -> Result { let ts = Lexer::new(Input::Str(src)) .lex() .map_err(|errs| ParserRunnerErrors::convert(self.input(), errs))?; diff --git a/doc/JA/compiler/architecture.md b/doc/JA/compiler/architecture.md index abafdcef..0e4a7f8e 100644 --- a/doc/JA/compiler/architecture.md +++ b/doc/JA/compiler/architecture.md @@ -16,15 +16,22 @@ * `Parser` は `Lexer` と同様に `Parser::new` と `Parser::from_str` の 2 つのコンストラクタを持ち、`Parser::parse` は `AST` を返す。 * `AST`は`Vec`のラッパー型で、「抽象構文木」を表す。 -### 2.5 `AST`の脱糖 +### 2.1 `AST`の脱糖 * ネストされた変数を展開 (`Desugarer::desugar_nest_vars_pattern`) * 複数パターン定義構文をmatchへ変換 (`Desugarer::desugar_multiple_pattern_def`) -## 3. 型チェックと推論、 `AST` -> `HIR` を変換 (compiler/lower.rs) +## 3. `AST` -> `HIR` (compiler/lower.rs) + +## 3.1 名前解決 + +* 型推論の前に全てのAST(importされたモジュール含む)を走査し、名前解決を行う +* 定数の循環検査や並び替えなどが行われるほか、型推論のためのContextが作成される(ただし、このContextに登録された変数の情報ははまだ殆どが未確定) + +### 3.2 型チェックと推論 (compiler/lower.rs) * `HIR` は、すべての変数の型情報を持っており、「高レベルの中間表現」を表す。 -* `ASTLowerer は Parser や Lexer と同じように構築できる。 +* `ASTLowerer` は Parser や Lexer と同じように構築できる。 * `ASTLowerer::lower` は、エラーが発生しなければ、`HIR` と `CompileWarnings` のタプルを出力する。 * `ASTLowerer` は `Compiler` によって所有されている。 `ASTLowerer` は従来の構造体とは異なり、文脈を保持し、1 回限りの使い捨てではない。 * 型推論の結果が不完全な場合(未知の型変数がある場合)、名前解決時にエラーが発生する。