From 3210fcbf00f9700128ff48a2a4c4d6cdd6297cfb Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Fri, 23 Sep 2022 13:24:19 +0900 Subject: [PATCH 01/38] Update Cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 29718167..d3c1d6c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "erg" version = "0.5.1" description = "The Erg programming language" -authors = ["Shunsuke Shibayama "] +authors = ["erg-lang team "] license = "MIT OR Apache-2.0" edition = "2021" repository = "https://github.com/erg-lang/erg" From 438ae9c2d688b82c544d9ac1cc40bd52a7c513e9 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 01:32:21 +0900 Subject: [PATCH 02/38] Add Context::dir --- compiler/erg_compiler/context/mod.rs | 13 +++++++++++++ compiler/erg_compiler/tests/test.rs | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index ecba6227..935a4a5b 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -637,3 +637,16 @@ impl Context { } } } + +/// for language server +impl Context { + pub fn dir(&self) -> Vec<(&VarName, &VarInfo)> { + let mut vars: Vec<_> = self.locals.iter().collect(); + if let Some(outer) = self.get_outer() { + vars.extend(outer.dir()); + } else { + vars.extend(self.get_builtins().unwrap().locals.iter()); + } + vars + } +} diff --git a/compiler/erg_compiler/tests/test.rs b/compiler/erg_compiler/tests/test.rs index a0494de1..a2522b49 100644 --- a/compiler/erg_compiler/tests/test.rs +++ b/compiler/erg_compiler/tests/test.rs @@ -30,3 +30,13 @@ fn test_resolve_trait_inner1() -> Result<(), ()> { Ok(()) } */ + +#[test] +fn test_dir() -> Result<(), ()> { + let context = Context::new_module("", SharedModuleCache::new()); + let vars = context.dir(); + for (name, vi) in vars.into_iter() { + println!("{name}: {vi}"); + } + Ok(()) +} From 10360269f5bb3ffea900fd3a210923c602b6f39b Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 02:16:11 +0900 Subject: [PATCH 03/38] Update inquire.rs --- compiler/erg_compiler/context/inquire.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index 12f234a8..3c72ed31 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -1148,12 +1148,16 @@ impl Context { .rec_get_mono_type("Record"); } Type::Mono { path, name } => { - if let Some(ctx) = self.mod_cache.as_ref().unwrap().ref_ctx(path) { - if let Some((t, ctx)) = ctx.rec_get_mono_type(name) { + if self.mod_name() == path { + if let Some((t, ctx)) = self.rec_get_mono_type(name) { return Some((t, ctx)); } - } else if self.mod_name() == path { - if let Some((t, ctx)) = self.rec_get_mono_type(name) { + } else if let Some(ctx) = self + .mod_cache + .as_ref() + .and_then(|cache| cache.ref_ctx(path)) + { + if let Some((t, ctx)) = ctx.rec_get_mono_type(name) { return Some((t, ctx)); } } From 50524e4d0b735a775ee34aefb818756400d2c304 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 03:30:10 +0900 Subject: [PATCH 04/38] Update version (v0.5.2) --- Cargo.lock | 10 +++++----- Cargo.toml | 10 +++++----- compiler/erg_common/Cargo.toml | 2 +- compiler/erg_compiler/Cargo.toml | 8 ++++---- compiler/erg_parser/Cargo.toml | 4 ++-- compiler/erg_type/Cargo.toml | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5dc08ce..483f8ba3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "erg" -version = "0.5.1" +version = "0.5.2" dependencies = [ "erg_common", "erg_compiler", @@ -25,14 +25,14 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.5.1" +version = "0.5.2" dependencies = [ "atty", ] [[package]] name = "erg_compiler" -version = "0.5.1" +version = "0.5.2" dependencies = [ "erg_common", "erg_parser", @@ -41,14 +41,14 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.5.1" +version = "0.5.2" dependencies = [ "erg_common", ] [[package]] name = "erg_type" -version = "0.5.1" +version = "0.5.2" dependencies = [ "erg_common", "erg_parser", diff --git a/Cargo.toml b/Cargo.toml index d3c1d6c5..33ebf910 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg" -version = "0.5.1" +version = "0.5.2" description = "The Erg programming language" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -46,10 +46,10 @@ traditional_chinese = [ ] [dependencies] -erg_common = { version = "0.5.1", path = "./compiler/erg_common" } -erg_parser = { version = "0.5.1", path = "./compiler/erg_parser" } -erg_compiler = { version = "0.5.1", path = "./compiler/erg_compiler" } -erg_type = { version = "0.5.1", path = "./compiler/erg_type" } +erg_common = { version = "0.5.2", path = "./compiler/erg_common" } +erg_parser = { version = "0.5.2", path = "./compiler/erg_parser" } +erg_compiler = { version = "0.5.2", path = "./compiler/erg_compiler" } +erg_type = { version = "0.5.2", path = "./compiler/erg_type" } # [workspace] # member = ["cm", "dyne"] diff --git a/compiler/erg_common/Cargo.toml b/compiler/erg_common/Cargo.toml index b5f7cc66..1e7961bc 100644 --- a/compiler/erg_common/Cargo.toml +++ b/compiler/erg_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_common" -version = "0.5.1" +version = "0.5.2" description = "A common components library of Erg" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" diff --git a/compiler/erg_compiler/Cargo.toml b/compiler/erg_compiler/Cargo.toml index 76466c52..b45bc016 100644 --- a/compiler/erg_compiler/Cargo.toml +++ b/compiler/erg_compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_compiler" -version = "0.5.1" +version = "0.5.2" description = "Centimetre: the Erg compiler" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -17,9 +17,9 @@ simplified_chinese = [ "erg_common/simplified_chinese", "erg_parser/simplified_c traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditional_chinese", "erg_type/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.1", path = "../erg_common" } -erg_parser = { version = "0.5.1", path = "../erg_parser" } -erg_type = { version = "0.5.1", path = "../erg_type" } +erg_common = { version = "0.5.2", path = "../erg_common" } +erg_parser = { version = "0.5.2", path = "../erg_parser" } +erg_type = { version = "0.5.2", path = "../erg_type" } [lib] path = "lib.rs" diff --git a/compiler/erg_parser/Cargo.toml b/compiler/erg_parser/Cargo.toml index ab24ca0a..3cfe97ea 100644 --- a/compiler/erg_parser/Cargo.toml +++ b/compiler/erg_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_parser" -version = "0.5.1" +version = "0.5.2" description = "The Erg parser" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.1", path = "../erg_common" } +erg_common = { version = "0.5.2", path = "../erg_common" } [lib] path = "lib.rs" diff --git a/compiler/erg_type/Cargo.toml b/compiler/erg_type/Cargo.toml index 161c7fe7..f72c35ce 100644 --- a/compiler/erg_type/Cargo.toml +++ b/compiler/erg_type/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_type" -version = "0.5.1" +version = "0.5.2" description = "APIs for Erg types" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -18,8 +18,8 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.1", path = "../erg_common" } -erg_parser = { version = "0.5.1", path = "../erg_parser" } +erg_common = { version = "0.5.2", path = "../erg_common" } +erg_parser = { version = "0.5.2", path = "../erg_parser" } [lib] path = "lib.rs" From 62760d1d5e442e6090720805d964ec3e43b7839b Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 13:07:50 +0900 Subject: [PATCH 05/38] Update mod.rs --- compiler/erg_compiler/context/mod.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index 935a4a5b..893e2144 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -19,6 +19,7 @@ use std::option::Option; // conflicting to Type::Option use erg_common::astr::AtomicStr; use erg_common::dict::Dict; +use erg_common::error::Location; use erg_common::impl_display_from_debug; use erg_common::traits::{Locational, Stream}; use erg_common::vis::Visibility; @@ -649,4 +650,21 @@ impl Context { } vars } + + pub fn get_var_info(&self, name: &str) -> TyCheckResult<&VarInfo> { + if let Some(vi) = self.get_current_scope_var(name) { + Ok(vi) + } else { + if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { + return parent.get_var_info(name); + } + Err(TyCheckError::no_var_error( + line!() as usize, + Location::Unknown, + self.caused_by(), + name, + self.get_similar_name(name), + )) + } + } } From 40fd927f0a3deab509d46c4c760a1c9d33228bb9 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 13:11:08 +0900 Subject: [PATCH 06/38] Update mod.rs --- compiler/erg_compiler/context/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index 893e2144..29694be1 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -651,9 +651,9 @@ impl Context { vars } - pub fn get_var_info(&self, name: &str) -> TyCheckResult<&VarInfo> { - if let Some(vi) = self.get_current_scope_var(name) { - Ok(vi) + pub fn get_var_info(&self, name: &str) -> TyCheckResult<(&VarName, &VarInfo)> { + if let Some(info) = self.get_local_kv(name) { + Ok(info) } else { if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { return parent.get_var_info(name); From 7b820f34ad3a8128af5b303778ac7297888600bf Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 15:43:07 +0900 Subject: [PATCH 07/38] Update version (v0.5.3) --- Cargo.toml | 8 ++++---- compiler/erg_common/Cargo.toml | 2 +- compiler/erg_compiler/Cargo.toml | 8 ++++---- compiler/erg_parser/Cargo.toml | 4 ++-- compiler/erg_type/Cargo.toml | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 33ebf910..4bb8de5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,10 +46,10 @@ traditional_chinese = [ ] [dependencies] -erg_common = { version = "0.5.2", path = "./compiler/erg_common" } -erg_parser = { version = "0.5.2", path = "./compiler/erg_parser" } -erg_compiler = { version = "0.5.2", path = "./compiler/erg_compiler" } -erg_type = { version = "0.5.2", path = "./compiler/erg_type" } +erg_common = { version = "0.5.3", path = "./compiler/erg_common" } +erg_parser = { version = "0.5.3", path = "./compiler/erg_parser" } +erg_compiler = { version = "0.5.3", path = "./compiler/erg_compiler" } +erg_type = { version = "0.5.3", path = "./compiler/erg_type" } # [workspace] # member = ["cm", "dyne"] diff --git a/compiler/erg_common/Cargo.toml b/compiler/erg_common/Cargo.toml index 1e7961bc..cc733cda 100644 --- a/compiler/erg_common/Cargo.toml +++ b/compiler/erg_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_common" -version = "0.5.2" +version = "0.5.3" description = "A common components library of Erg" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" diff --git a/compiler/erg_compiler/Cargo.toml b/compiler/erg_compiler/Cargo.toml index b45bc016..84283266 100644 --- a/compiler/erg_compiler/Cargo.toml +++ b/compiler/erg_compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_compiler" -version = "0.5.2" +version = "0.5.3" description = "Centimetre: the Erg compiler" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -17,9 +17,9 @@ simplified_chinese = [ "erg_common/simplified_chinese", "erg_parser/simplified_c traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditional_chinese", "erg_type/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.2", path = "../erg_common" } -erg_parser = { version = "0.5.2", path = "../erg_parser" } -erg_type = { version = "0.5.2", path = "../erg_type" } +erg_common = { version = "0.5.3", path = "../erg_common" } +erg_parser = { version = "0.5.3", path = "../erg_parser" } +erg_type = { version = "0.5.3", path = "../erg_type" } [lib] path = "lib.rs" diff --git a/compiler/erg_parser/Cargo.toml b/compiler/erg_parser/Cargo.toml index 3cfe97ea..e3bb6baf 100644 --- a/compiler/erg_parser/Cargo.toml +++ b/compiler/erg_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_parser" -version = "0.5.2" +version = "0.5.3" description = "The Erg parser" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.2", path = "../erg_common" } +erg_common = { version = "0.5.3", path = "../erg_common" } [lib] path = "lib.rs" diff --git a/compiler/erg_type/Cargo.toml b/compiler/erg_type/Cargo.toml index f72c35ce..eeadc748 100644 --- a/compiler/erg_type/Cargo.toml +++ b/compiler/erg_type/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_type" -version = "0.5.2" +version = "0.5.3" description = "APIs for Erg types" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -18,8 +18,8 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.2", path = "../erg_common" } -erg_parser = { version = "0.5.2", path = "../erg_parser" } +erg_common = { version = "0.5.3", path = "../erg_common" } +erg_parser = { version = "0.5.3", path = "../erg_parser" } [lib] path = "lib.rs" From 9e1dbc1649e525e243cb7710cf707116ca34dfe6 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 15:45:46 +0900 Subject: [PATCH 08/38] Update Cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4bb8de5d..a3aeda53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg" -version = "0.5.2" +version = "0.5.3" description = "The Erg programming language" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" From 3e0c8a3d237e9615a90ff727c0c5dbea510fa5ff Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 15:52:43 +0900 Subject: [PATCH 09/38] Update control.er --- examples/control.er | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/control.er b/examples/control.er index 7fc6d0a7..979fc495 100644 --- a/examples/control.er +++ b/examples/control.er @@ -18,7 +18,7 @@ sum = match a: (i: Int) -> i _ -> panic "unknown object" -for! 0..1000, i => +for! 0..<1000, i => print! "i = {i}" if i >= 100: do return break() From 104c8bc777422b2c435c3a060e4cce05d7b3afcf Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 15:52:50 +0900 Subject: [PATCH 10/38] Update Cargo.lock --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 483f8ba3..3b27310e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "erg" -version = "0.5.2" +version = "0.5.3" dependencies = [ "erg_common", "erg_compiler", @@ -25,14 +25,14 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.5.2" +version = "0.5.3" dependencies = [ "atty", ] [[package]] name = "erg_compiler" -version = "0.5.2" +version = "0.5.3" dependencies = [ "erg_common", "erg_parser", @@ -41,14 +41,14 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.5.2" +version = "0.5.3" dependencies = [ "erg_common", ] [[package]] name = "erg_type" -version = "0.5.2" +version = "0.5.3" dependencies = [ "erg_common", "erg_parser", From 8541d38c7ca9d8341a839a298bbb155843161095 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 15:57:51 +0900 Subject: [PATCH 11/38] Update compare.rs --- compiler/erg_compiler/context/compare.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/compiler/erg_compiler/context/compare.rs b/compiler/erg_compiler/context/compare.rs index 11114539..65d114ef 100644 --- a/compiler/erg_compiler/context/compare.rs +++ b/compiler/erg_compiler/context/compare.rs @@ -619,7 +619,11 @@ impl Context { pub(crate) fn cyclic_supertype_of(&self, lhs: &FreeTyVar, rhs: &Type) -> bool { // if `rhs` is {S: Str | ... }, `defined_rhs` will be Str - let (defined_rhs, _) = self.get_nominal_type_ctx(rhs).unwrap(); + let defined_rhs = if let Some((defined_rhs, _)) = self.get_nominal_type_ctx(rhs) { + defined_rhs + } else { + return false; + }; if let Some(super_traits) = self.get_nominal_super_trait_ctxs(rhs) { for (sup_trait, _) in super_traits { if self.sup_conforms(lhs, defined_rhs, sup_trait) { @@ -846,18 +850,25 @@ impl Context { | (Pred::GreaterEqual { .. }, Pred::LessEqual { .. }) | (Pred::NotEqual { .. }, Pred::Equal { .. }) => false, (Pred::Equal { rhs, .. }, Pred::Equal { rhs: rhs2, .. }) - | (Pred::NotEqual { rhs, .. }, Pred::NotEqual { rhs: rhs2, .. }) => { - self.try_cmp(rhs, rhs2).unwrap().is_eq() - } + | (Pred::NotEqual { rhs, .. }, Pred::NotEqual { rhs: rhs2, .. }) => self + .try_cmp(rhs, rhs2) + .map(|ord| ord.is_eq()) + .unwrap_or(false), // {T >= 0} :> {T >= 1}, {T >= 0} :> {T == 1} ( Pred::GreaterEqual { rhs, .. }, Pred::GreaterEqual { rhs: rhs2, .. } | Pred::Equal { rhs: rhs2, .. }, - ) => self.try_cmp(rhs, rhs2).unwrap().is_le(), + ) => self + .try_cmp(rhs, rhs2) + .map(|ord| ord.is_le()) + .unwrap_or(false), ( Pred::LessEqual { rhs, .. }, Pred::LessEqual { rhs: rhs2, .. } | Pred::Equal { rhs: rhs2, .. }, - ) => self.try_cmp(rhs, rhs2).unwrap().is_ge(), + ) => self + .try_cmp(rhs, rhs2) + .map(|ord| ord.is_ge()) + .unwrap_or(false), (lhs @ (Pred::GreaterEqual { .. } | Pred::LessEqual { .. }), Pred::And(l, r)) => { self.is_super_pred_of(lhs, l) || self.is_super_pred_of(lhs, r) } From eaff38205d44feb307155c78c4f382d5b4b8e4e8 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sat, 24 Sep 2022 17:16:20 +0800 Subject: [PATCH 12/38] Update 00_basic.md --- doc/EN/syntax/00_basic.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/EN/syntax/00_basic.md b/doc/EN/syntax/00_basic.md index 7bfd3987..330731d6 100644 --- a/doc/EN/syntax/00_basic.md +++ b/doc/EN/syntax/00_basic.md @@ -3,11 +3,11 @@ > __Warning__: This document is incomplete. It has not been proofread (style, correct links, mistranslation, etc.). Also, Erg's syntax may be change destructively during version 0.*, and the documentation may not have been updated accordingly. Please be aware of this beforehand. > If you find any errors in this document, please report then to [here form](https://forms.gle/HtLYRfYzWCAaeTGb6) or [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new). We would appreciate your suggestions. > -> [The Erg Book Japanese edition](https://erg-lang.github.io/the-erg-book/JA/) +> [Erg Book日本語訳](https://erg-lang.github.io/the-erg-book/JA/) > -> [The Erg Book simplified Chinese edition](https://erg-lang.github.io/the-erg-book/zh_CN/) +> [Erg Book繁體中文翻譯](https://erg-lang.github.io/the-erg-book/zh_CN/) > -> [The Erg Book traditional Chinese edition](https://erg-lang.github.io/the-erg-book/zh_TW/) +> [Erg Book简体中文翻译](https://erg-lang.github.io/the-erg-book/zh_TW/) This document describes the basic syntax of Erg. The [Standard API](../API/index.md) and [internal documents for Erg contributors](../dev_guide/index.md) are located in another directory. From f1b2fe99d667c75a71a7c69c9b8342c99353ca32 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sat, 24 Sep 2022 17:16:40 +0800 Subject: [PATCH 13/38] Update 00_basic.md --- doc/EN/syntax/00_basic.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/EN/syntax/00_basic.md b/doc/EN/syntax/00_basic.md index 330731d6..f3e39ed6 100644 --- a/doc/EN/syntax/00_basic.md +++ b/doc/EN/syntax/00_basic.md @@ -3,11 +3,11 @@ > __Warning__: This document is incomplete. It has not been proofread (style, correct links, mistranslation, etc.). Also, Erg's syntax may be change destructively during version 0.*, and the documentation may not have been updated accordingly. Please be aware of this beforehand. > If you find any errors in this document, please report then to [here form](https://forms.gle/HtLYRfYzWCAaeTGb6) or [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new). We would appreciate your suggestions. > -> [Erg Book日本語訳](https://erg-lang.github.io/the-erg-book/JA/) +> [Erg Book 日本語訳](https://erg-lang.github.io/the-erg-book/JA/) > -> [Erg Book繁體中文翻譯](https://erg-lang.github.io/the-erg-book/zh_CN/) +> [Erg Book 繁體中文翻譯](https://erg-lang.github.io/the-erg-book/zh_CN/) > -> [Erg Book简体中文翻译](https://erg-lang.github.io/the-erg-book/zh_TW/) +> [Erg Book 简体中文翻译](https://erg-lang.github.io/the-erg-book/zh_TW/) This document describes the basic syntax of Erg. The [Standard API](../API/index.md) and [internal documents for Erg contributors](../dev_guide/index.md) are located in another directory. From 8efae686530f1e7212484edfc706fd88925dd274 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sat, 24 Sep 2022 17:17:47 +0800 Subject: [PATCH 14/38] Updata commit hash --- doc/JA/syntax/00_basic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/JA/syntax/00_basic.md b/doc/JA/syntax/00_basic.md index 3837deb6..25a2bc12 100644 --- a/doc/JA/syntax/00_basic.md +++ b/doc/JA/syntax/00_basic.md @@ -1,6 +1,6 @@ # 基本事項 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3D31ccb6924c3051f73458c69ca2c7f2cc5a93a694)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=31ccb6924c3051f73458c69ca2c7f2cc5a93a694) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3Df1b2fe99d667c75a71a7c69c9b8342c99353ca32)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=f1b2fe99d667c75a71a7c69c9b8342c99353ca32) > __Warning__: 本ドキュメントは未完成です。校正(文体、正しいリンクが張られているか、など)がなされていません。また、Ergの文法はバージョン0.*の間に破壊的変更が加えられる可能性があり、それに伴うドキュメントの更新が追いついていない可能性があります。予めご了承ください。 > また、本ドキュメントの誤りを見つけた場合は、[こちらのフォーム](https://forms.gle/HtLYRfYzWCAaeTGb6)または[GitHubリポジトリ](https://github.com/mtshiba/TheErgBook/issues/new)から修正の提案をしていただけると幸いです。 From 4d2cc7c76c49845498379889407e38928373147e Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sat, 24 Sep 2022 17:18:01 +0800 Subject: [PATCH 15/38] Updata commit hash --- doc/zh_CN/syntax/00_basic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index d9dfaef0..dbdb036e 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -1,6 +1,6 @@ # 基本 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3D31ccb6924c3051f73458c69ca2c7f2cc5a93a694)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=31ccb6924c3051f73458c69ca2c7f2cc5a93a694) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3Df1b2fe99d667c75a71a7c69c9b8342c99353ca32)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=f1b2fe99d667c75a71a7c69c9b8342c99353ca32) > __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。 > 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。 From ce8125379ec68ec0fa50526cc25d3983e7c7262a Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sat, 24 Sep 2022 17:18:12 +0800 Subject: [PATCH 16/38] Updata commit hash --- doc/zh_TW/syntax/00_basic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md index ecef0cdb..733b54c2 100644 --- a/doc/zh_TW/syntax/00_basic.md +++ b/doc/zh_TW/syntax/00_basic.md @@ -1,6 +1,6 @@ # 基本 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3D31ccb6924c3051f73458c69ca2c7f2cc5a93a694)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=31ccb6924c3051f73458c69ca2c7f2cc5a93a694) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3Df1b2fe99d667c75a71a7c69c9b8342c99353ca32)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=f1b2fe99d667c75a71a7c69c9b8342c99353ca32) > __Warning__:本文檔不完整。 它未經校對(樣式、正確鏈接、誤譯等)。 此外,Erg 的語法可能在版本 0.* 期間發生破壞性更改,并且文檔可能沒有相應更新。 請事先了解這一點。 > 如果您在本文檔中發現任何錯誤,請報告至 [此處的表單](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我們將不勝感激您的建議。 From f6e1a7b11783d7f4c78f4e1e1ba6cda048747fc8 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 24 Sep 2022 19:15:55 +0900 Subject: [PATCH 17/38] Remove `unwrap`s --- compiler/erg_compiler/context/compare.rs | 6 +- .../context/initialize/const_func.rs | 66 ++++++++++++++++--- compiler/erg_compiler/context/inquire.rs | 12 ++-- compiler/erg_compiler/effectcheck.rs | 4 +- compiler/erg_compiler/error.rs | 8 +-- compiler/erg_compiler/link.rs | 4 +- compiler/erg_type/value.rs | 8 ++- 7 files changed, 79 insertions(+), 29 deletions(-) diff --git a/compiler/erg_compiler/context/compare.rs b/compiler/erg_compiler/context/compare.rs index 65d114ef..6dfa9127 100644 --- a/compiler/erg_compiler/context/compare.rs +++ b/compiler/erg_compiler/context/compare.rs @@ -911,7 +911,7 @@ impl Context { #[inline] fn type_of(&self, p: &TyParam) -> Type { - self.get_tp_t(p).unwrap() + self.get_tp_t(p).unwrap_or(Type::Obj) } // sup/inf({±∞}) = ±∞ではあるが、Inf/NegInfにはOrdを実装しない @@ -926,7 +926,7 @@ impl Context { if lhs == &refine.var => { if let Some(max) = &maybe_max { - if self.try_cmp(rhs, max).unwrap() == Greater { + if self.try_cmp(rhs, max) == Some(Greater) { maybe_max = Some(rhs.clone()); } } else { @@ -954,7 +954,7 @@ impl Context { if lhs == &refine.var => { if let Some(min) = &maybe_min { - if self.try_cmp(rhs, min).unwrap() == Less { + if self.try_cmp(rhs, min) == Some(Less) { maybe_min = Some(rhs.clone()); } } else { diff --git a/compiler/erg_compiler/context/initialize/const_func.rs b/compiler/erg_compiler/context/initialize/const_func.rs index 081984f0..aa5aed54 100644 --- a/compiler/erg_compiler/context/initialize/const_func.rs +++ b/compiler/erg_compiler/context/initialize/const_func.rs @@ -3,7 +3,7 @@ use std::mem; use erg_common::Str; use erg_common::astr::AtomicStr; -use erg_common::color::{RED, RESET}; +use erg_common::color::{RED, RESET, YELLOW}; use erg_common::error::{ErrorCore, ErrorKind, Location}; use erg_type::constructors::{and, builtin_mono, mono}; use erg_type::value::{EvalValueResult, TypeKind, TypeObj, ValueObj}; @@ -18,20 +18,32 @@ pub fn class_func( let require = args.remove_left_or_key("Requirement").ok_or_else(|| { ErrorCore::new( line!() as usize, - ErrorKind::KeyError, + ErrorKind::TypeError, Location::Unknown, AtomicStr::from(format!("{RED}Requirement{RESET} is not passed")), None, ) })?; - let require = require.as_type().unwrap(); + let require = if let Some(t) = require.as_type() { + t + } else { + return Err(ErrorCore::new( + line!() as usize, + ErrorKind::TypeError, + Location::Unknown, + AtomicStr::from(format!( + "non-type object {RED}{require}{RESET} is passed to {YELLOW}Requirement{RESET}", + )), + None, + )); + }; let impls = args.remove_left_or_key("Impl"); let impls = impls.map(|v| v.as_type().unwrap()); let t = mono(mod_name, __name__.unwrap_or(Str::ever(""))); Ok(ValueObj::gen_t(TypeKind::Class, t, require, impls, None)) } -/// Super: Type, Impl := Type, Additional := Type -> ClassType +/// Super: ClassType, Impl := Type, Additional := Type -> ClassType pub fn inherit_func( mut args: ValueArgs, mod_name: Str, @@ -46,7 +58,19 @@ pub fn inherit_func( None, ) })?; - let sup = sup.as_type().unwrap(); + let sup = if let Some(t) = sup.as_type() { + t + } else { + return Err(ErrorCore::new( + line!() as usize, + ErrorKind::TypeError, + Location::Unknown, + AtomicStr::from(format!( + "non-class object {RED}{sup}{RESET} is passed to {YELLOW}Super{RESET}", + )), + None, + )); + }; let impls = args.remove_left_or_key("Impl"); let impls = impls.map(|v| v.as_type().unwrap()); let additional = args.remove_left_or_key("Additional"); @@ -97,7 +121,7 @@ pub fn inheritable_func( } } -/// Requirement: Type, Impl := Type -> ClassType +/// Requirement: Type, Impl := Type -> TraitType pub fn trait_func( mut args: ValueArgs, mod_name: Str, @@ -112,14 +136,26 @@ pub fn trait_func( None, ) })?; - let require = require.as_type().unwrap(); + let require = if let Some(t) = require.as_type() { + t + } else { + return Err(ErrorCore::new( + line!() as usize, + ErrorKind::TypeError, + Location::Unknown, + AtomicStr::from(format!( + "non-type object {RED}{require}{RESET} is passed to {YELLOW}Requirement{RESET}", + )), + None, + )); + }; let impls = args.remove_left_or_key("Impl"); let impls = impls.map(|v| v.as_type().unwrap()); let t = mono(mod_name, __name__.unwrap_or(Str::ever(""))); Ok(ValueObj::gen_t(TypeKind::Trait, t, require, impls, None)) } -/// Super: Type, Impl := Type, Additional := Type -> ClassType +/// Super: TraitType, Impl := Type, Additional := Type -> TraitType pub fn subsume_func( mut args: ValueArgs, mod_name: Str, @@ -134,7 +170,19 @@ pub fn subsume_func( None, ) })?; - let sup = sup.as_type().unwrap(); + let sup = if let Some(t) = sup.as_type() { + t + } else { + return Err(ErrorCore::new( + line!() as usize, + ErrorKind::TypeError, + Location::Unknown, + AtomicStr::from(format!( + "non-trait object {RED}{sup}{RESET} is passed to {YELLOW}Super{RESET}", + )), + None, + )); + }; let impls = args.remove_left_or_key("Impl"); let impls = impls.map(|v| v.as_type().unwrap()); let additional = args.remove_left_or_key("Additional"); diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index 3c72ed31..fdf727ea 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -1427,14 +1427,12 @@ impl Context { let insts = self.rec_get_trait_impls(&sup.name()); let candidates = insts.into_iter().filter_map(move |inst| { if self.supertype_of(&inst.sup_trait, &sup) { - Some( - self.eval_t_params( - mono_proj(inst.sub_type, rhs), - self.level, - Location::Unknown, - ) - .unwrap(), + self.eval_t_params( + mono_proj(inst.sub_type, rhs), + self.level, + Location::Unknown, ) + .ok() } else { None } diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index dd8fa883..1984044b 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -58,7 +58,7 @@ impl SideEffectChecker { /// /// However, it is not permitted to cause side effects within an instant block in a function /// (side effects are allowed in instant blocks in procedures and modules) - fn in_context_se_allowed(&self) -> bool { + fn in_context_effects_allowed(&self) -> bool { // if toplevel if self.block_stack.len() == 1 { return true; @@ -255,7 +255,7 @@ impl SideEffectChecker { .as_ref() .map(|name| name.is_procedural()) .unwrap_or(false)) - && !self.in_context_se_allowed() + && !self.in_context_effects_allowed() { self.errs.push(EffectError::has_effect( line!() as usize, diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index a993cdac..7be0f54e 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -995,19 +995,19 @@ passed keyword args: {RED}{kw_args_len}{RESET}" switch_lang!( "japanese" => format!( "{RED}{name}{RESET}は{}行目ですでに移動されています", - moved_loc.ln_begin().unwrap() + moved_loc.ln_begin().unwrap_or(0) ), "simplified_chinese" => format!( "{RED}{name}{RESET}已移至第{}行", - moved_loc.ln_begin().unwrap() + moved_loc.ln_begin().unwrap_or(0) ), "traditional_chinese" => format!( "{RED}{name}{RESET}已移至第{}行", - moved_loc.ln_begin().unwrap() + moved_loc.ln_begin().unwrap_or(0) ), "english" => format!( "{RED}{name}{RESET} was moved in line {}", - moved_loc.ln_begin().unwrap() + moved_loc.ln_begin().unwrap_or(0) ), ), None, diff --git a/compiler/erg_compiler/link.rs b/compiler/erg_compiler/link.rs index dc498f4a..56b54c54 100644 --- a/compiler/erg_compiler/link.rs +++ b/compiler/erg_compiler/link.rs @@ -43,7 +43,7 @@ impl Linker { let code = Expr::Code(Block::new(Vec::from(hir.module))); let module_type = Expr::Accessor(Accessor::private_with_line( Str::ever("#ModuleType"), - def.ln_begin().unwrap(), + def.ln_begin().unwrap_or(0), )); let args = Args::new(vec![PosArg::new(mod_name.clone())], None, vec![], None); @@ -59,7 +59,7 @@ impl Linker { )); let exec = Expr::Accessor(Accessor::public_with_line( Str::ever("exec"), - mod_def.ln_begin().unwrap(), + mod_def.ln_begin().unwrap_or(0), )); let module = Expr::Accessor(Accessor::Ident(def.sig.ident().clone())); let __dict__ = Identifier::public("__dict__"); diff --git a/compiler/erg_type/value.rs b/compiler/erg_type/value.rs index ae492471..58997796 100644 --- a/compiler/erg_type/value.rs +++ b/compiler/erg_type/value.rs @@ -802,8 +802,12 @@ pub mod value_set { // false -> SyntaxError pub fn is_homogeneous(set: &Set) -> bool { - let l_first = set.iter().next().unwrap().class(); - set.iter().all(|c| c.class() == l_first) + if let Some(first) = set.iter().next() { + let l_first = first.class(); + set.iter().all(|c| c.class() == l_first) + } else { + true + } } pub fn inner_class(set: &Set) -> Type { From 6cfb0d1544922e19676a04a941ca0cdfd73ffdf5 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 25 Sep 2022 18:43:45 +0900 Subject: [PATCH 18/38] Prohibit inner scope type definition --- compiler/erg_compiler/build_hir.rs | 4 ---- compiler/erg_compiler/error.rs | 18 ++++++++++++++++++ compiler/erg_compiler/lower.rs | 11 ++++++++++- compiler/erg_parser/ast.rs | 9 +++++++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/compiler/erg_compiler/build_hir.rs b/compiler/erg_compiler/build_hir.rs index c651687d..f2bc48a1 100644 --- a/compiler/erg_compiler/build_hir.rs +++ b/compiler/erg_compiler/build_hir.rs @@ -13,7 +13,6 @@ use crate::hir::HIR; use crate::lower::ASTLowerer; use crate::mod_cache::SharedModuleCache; use crate::ownercheck::OwnershipChecker; -use crate::reorder::Reorderer; /// Summarize lowering, side-effect checking, and ownership checking #[derive(Debug)] @@ -99,9 +98,6 @@ impl HIRBuilder { pub fn build(&mut self, src: String, mode: &str) -> Result { let mut ast_builder = ASTBuilder::new(self.cfg().copy()); let ast = ast_builder.build(src)?; - let ast = Reorderer::new() - .reorder(ast) - .map_err(|errs| self.convert(errs))?; let hir = self.check(ast, mode)?; Ok(hir) } diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index 7be0f54e..d9f353ff 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -1296,6 +1296,24 @@ passed keyword args: {RED}{kw_args_len}{RESET}" pub fn file_error(errno: usize, desc: String, loc: Location, caused_by: AtomicStr) -> Self { Self::new(ErrorCore::new(errno, IoError, loc, desc, None), caused_by) } + + pub fn inner_typedef_error(errno: usize, loc: Location, caused_by: AtomicStr) -> Self { + Self::new( + ErrorCore::new( + errno, + TypeError, + loc, + switch_lang!( + "japanese" => format!("型はトップレベルで定義されなければなりません"), + "simplified_chinese" => format!("类型必须在顶层定义"), + "traditional_chinese" => format!("類型必須在頂層定義"), + "english" => format!("types must be defined at the top level"), + ), + None, + ), + caused_by, + ) + } } #[derive(Debug)] diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index fa0a7fae..6e22fcc4 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -30,6 +30,7 @@ use crate::error::{ use crate::hir; use crate::hir::HIR; use crate::mod_cache::SharedModuleCache; +use crate::reorder::Reorderer; use crate::varinfo::VarKind; use Visibility::*; @@ -533,6 +534,14 @@ impl ASTLowerer { fn lower_def(&mut self, def: ast::Def) -> LowerResult { log!(info "entered {}({})", fn_name!(), def.sig); + if def.def_kind().is_class_or_trait() && self.ctx.kind != ContextKind::Module { + self.ctx.decls.remove(def.sig.ident().unwrap().inspect()); + return Err(LowerError::inner_typedef_error( + line!() as usize, + def.loc(), + self.ctx.caused_by(), + )); + } let name = if let Some(name) = def.sig.name_as_str() { name } else { @@ -589,7 +598,6 @@ impl ASTLowerer { } } let id = body.id; - // TODO: cover all VarPatterns self.ctx .outer .as_mut() @@ -994,6 +1002,7 @@ impl ASTLowerer { pub fn lower(&mut self, ast: AST, mode: &str) -> Result<(HIR, LowerWarnings), LowerErrors> { log!(info "the AST lowering process has started."); log!(info "the type-checking process has started."); + let ast = Reorderer::new().reorder(ast)?; let mut module = hir::Module::with_capacity(ast.module.len()); self.ctx.preregister(ast.module.block())?; for chunk in ast.module.into_iter() { diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index 1504fa24..03898900 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -2842,6 +2842,7 @@ pub enum DefKind { Subsume, StructuralTrait, Module, + /// type alias included Other, } @@ -2850,6 +2851,14 @@ impl DefKind { matches!(self, Self::Trait | Self::Subsume | Self::StructuralTrait) } + pub const fn is_class(&self) -> bool { + matches!(self, Self::Class | Self::Inherit) + } + + pub const fn is_class_or_trait(&self) -> bool { + self.is_class() || self.is_trait() + } + pub fn is_module(&self) -> bool { matches!(self, Self::Module) } From 9ccfdadf226d2d4fca986abac40b5bc7cb63c8b6 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 25 Sep 2022 20:05:52 +0900 Subject: [PATCH 19/38] Add TypeAscription --- compiler/erg_compiler/context/tyvar.rs | 1 + compiler/erg_compiler/hir.rs | 50 ++++++++++++++++++++++++-- compiler/erg_compiler/lower.rs | 20 +++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index 6721fa22..2c708388 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -489,6 +489,7 @@ impl Context { } Ok(()) } + hir::Expr::TypeAsc(tasc) => self.resolve_expr_t(&mut tasc.expr), hir::Expr::Code(chunks) | hir::Expr::Compound(chunks) => { for chunk in chunks.iter_mut() { self.resolve_expr_t(chunk)?; diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index 32b08fee..29497f77 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -1485,6 +1485,49 @@ impl AttrDef { } } +#[derive(Debug, Clone)] +pub struct TypeAscription { + pub expr: Box, + pub spec: TypeSpec, +} + +impl NestedDisplay for TypeAscription { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + writeln!(f, "{}: {}", self.expr, self.spec) + } +} + +impl_display_from_nested!(TypeAscription); +impl_locational!(TypeAscription, expr, spec); + +impl HasType for TypeAscription { + #[inline] + fn ref_t(&self) -> &Type { + self.expr.ref_t() + } + #[inline] + fn ref_mut_t(&mut self) -> &mut Type { + self.expr.ref_mut_t() + } + #[inline] + fn signature_t(&self) -> Option<&Type> { + self.expr.signature_t() + } + #[inline] + fn signature_mut_t(&mut self) -> Option<&mut Type> { + self.expr.signature_mut_t() + } +} + +impl TypeAscription { + pub fn new(expr: Expr, spec: TypeSpec) -> Self { + Self { + expr: Box::new(expr), + spec, + } + } +} + #[derive(Debug, Clone)] pub enum Expr { Lit(Literal), @@ -1502,14 +1545,15 @@ pub enum Expr { Def(Def), ClassDef(ClassDef), AttrDef(AttrDef), + TypeAsc(TypeAscription), Code(Block), // code object Compound(Block), // compound statement } -impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound); +impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound, TypeAsc); impl_display_from_nested!(Expr); -impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound); -impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound); +impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound, TypeAsc); +impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound, TypeAsc); impl Expr { pub fn receiver_t(&self) -> Option<&Type> { diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 6e22fcc4..26297ab3 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -968,6 +968,25 @@ impl ASTLowerer { } } + fn lower_type_asc(&mut self, tasc: ast::TypeAscription) -> LowerResult { + log!(info "entered {}({tasc})", fn_name!()); + let t = self.ctx.instantiate_typespec( + &tasc.t_spec, + None, + &mut None, + RegistrationMode::Normal, + )?; + let expr = self.lower_expr(*tasc.expr)?; + self.ctx.sub_unify( + expr.ref_t(), + &t, + Some(expr.loc()), + None, + Some(&Str::from(expr.to_string())), + )?; + Ok(hir::TypeAscription::new(expr, tasc.t_spec)) + } + // Call.obj == Accessor cannot be type inferred by itself (it can only be inferred with arguments) // so turn off type checking (check=false) fn lower_expr(&mut self, expr: ast::Expr) -> LowerResult { @@ -985,6 +1004,7 @@ impl ASTLowerer { ast::Expr::Lambda(lambda) => Ok(hir::Expr::Lambda(self.lower_lambda(lambda)?)), ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)), ast::Expr::ClassDef(defs) => Ok(hir::Expr::ClassDef(self.lower_class_def(defs)?)), + ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.lower_type_asc(tasc)?)), other => todo!("{other}"), } } From 93388ddf80bc7e690e090625056aa561074d00f5 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 25 Sep 2022 21:05:12 +0900 Subject: [PATCH 20/38] Fix inferring bugs --- compiler/erg_compiler/context/instantiate.rs | 72 +++++++++----------- compiler/erg_type/free.rs | 1 + 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 23a414e1..f7645de3 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -113,15 +113,7 @@ impl TyVarContext { if defined_params_len < given_params_len { panic!() } - let inst_non_defaults = params - .into_iter() - .map(|tp| { - let name = tp.tvar_name().unwrap(); - let tp = self.instantiate_qtp(tp); - self.push_or_init_typaram(&name, &tp); - tp - }) - .collect(); + let inst_non_defaults = self.instantiate_params(params); let mut inst_defaults = vec![]; for template in temp_defaults .iter() @@ -133,41 +125,45 @@ impl TyVarContext { } poly(name, [inst_non_defaults, inst_defaults].concat()) } else { - poly( - name, - params - .into_iter() - .map(|p| { - if let Some(name) = p.tvar_name() { - let tp = self.instantiate_qtp(p); - self.push_or_init_typaram(&name, &tp); - tp - } else { - p - } - }) - .collect(), - ) + poly(name, self.instantiate_params(params)) + } + } + + fn instantiate_params(&mut self, params: Vec) -> Vec { + params + .into_iter() + .map(|p| { + if let Some(name) = p.tvar_name() { + let tp = self.instantiate_qtp(p); + self.push_or_init_typaram(&name, &tp); + tp + } else { + p + } + }) + .collect() + } + + fn instantiate_bound_type(&mut self, mid: &Type, sub_or_sup: Type, ctx: &Context) -> Type { + match sub_or_sup { + Type::Poly { name, params } => self.instantiate_poly(mid.name(), &name, params, ctx), + Type::MonoProj { lhs, rhs } => { + let lhs = if lhs.has_qvar() { + self.instantiate_qvar(*lhs) + } else { + *lhs + }; + mono_proj(lhs, rhs) + } + other => other, } } fn instantiate_bound(&mut self, bound: TyBound, ctx: &Context) { match bound { TyBound::Sandwiched { sub, mid, sup } => { - let sub_instance = match sub { - Type::Poly { name, params } => { - self.instantiate_poly(mid.name(), &name, params, ctx) - } - Type::MonoProj { lhs, rhs } => mono_proj(self.instantiate_qvar(*lhs), rhs), - sub => sub, - }; - let sup_instance = match sup { - Type::Poly { name, params } => { - self.instantiate_poly(mid.name(), &name, params, ctx) - } - Type::MonoProj { lhs, rhs } => mono_proj(self.instantiate_qvar(*lhs), rhs), - sup => sup, - }; + let sub_instance = self.instantiate_bound_type(&mid, sub, ctx); + let sup_instance = self.instantiate_bound_type(&mid, sup, ctx); let name = mid.name(); let constraint = Constraint::new_sandwiched(sub_instance, sup_instance, Cyclicity::Not); diff --git a/compiler/erg_type/free.rs b/compiler/erg_type/free.rs index 4dea787a..b5f167b9 100644 --- a/compiler/erg_type/free.rs +++ b/compiler/erg_type/free.rs @@ -632,6 +632,7 @@ impl Free { pub fn unbound_name(&self) -> Option { match &*self.borrow() { FreeKind::NamedUnbound { name, .. } => Some(name.clone()), + FreeKind::Unbound { id, .. } => Some(Str::from(id.to_string())), _ => None, } } From d11b05ecff6981fcfc23f227a2adeb77f01accc7 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 25 Sep 2022 21:32:49 +0900 Subject: [PATCH 21/38] Fix inferring bugs --- compiler/erg_compiler/context/compare.rs | 4 ++-- compiler/erg_compiler/context/instantiate.rs | 10 ++++++++-- compiler/erg_type/lib.rs | 1 + compiler/erg_type/typaram.rs | 2 ++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/erg_compiler/context/compare.rs b/compiler/erg_compiler/context/compare.rs index 6dfa9127..2d9fa91f 100644 --- a/compiler/erg_compiler/context/compare.rs +++ b/compiler/erg_compiler/context/compare.rs @@ -606,10 +606,10 @@ impl Context { self.poly_supertype_of(lhs, lparams, rparams) } (MonoQVar(name), r) | (PolyQVar { name, .. }, r) => { - panic!("Not instantiated type variable: {name}, r: {r}") + panic!("internal error: not instantiated type variable: '{name}, r: {r}") } (l, MonoQVar(name)) | (l, PolyQVar { name, .. }) => { - panic!("Not instantiated type variable: {name}, l: {l}") + panic!("internal error: not instantiated type variable: '{name}, l: {l}") } (MonoProj { .. }, _) => todo!(), (_, MonoProj { .. }) => todo!(), diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index f7645de3..6a6d9f5c 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -133,6 +133,7 @@ impl TyVarContext { params .into_iter() .map(|p| { + erg_common::log!(err "p: {p}, {:?}", p.tvar_name()); if let Some(name) = p.tvar_name() { let tp = self.instantiate_qtp(p); self.push_or_init_typaram(&name, &tp); @@ -243,7 +244,7 @@ impl TyVarContext { } } TyParam::Type(t) => { - if let Type::MonoQVar(n) = *t { + if let Some(n) = t.as_ref().tvar_name() { if let Some(t) = self.get_typaram(&n) { t.clone() } else if let Some(t) = self.get_tyvar(&n) { @@ -254,7 +255,7 @@ impl TyVarContext { TyParam::t(tv) } } else { - todo!("{t}") + unreachable!("{t}") } } TyParam::UnaryOp { op, val } => { @@ -336,6 +337,7 @@ impl TyVarContext { } } +/// TODO: this struct will be removed when const functions are implemented. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ConstTemplate { Obj(ValueObj), @@ -766,6 +768,9 @@ impl Context { let t = Self::instantiate_t(*t, tv_ctx, loc)?; Ok(TyParam::t(t)) } + TyParam::FreeVar(fv) if fv.is_linked() => { + Self::instantiate_tp(fv.crack().clone(), tv_ctx, loc) + } p @ (TyParam::Value(_) | TyParam::Mono(_) | TyParam::FreeVar(_)) => Ok(p), other => todo!("{other}"), } @@ -867,6 +872,7 @@ impl Context { Quantified(_) => { panic!("a quantified type should not be instantiated, instantiate the inner type") } + FreeVar(fv) if fv.is_linked() => Self::instantiate_t(fv.crack().clone(), tv_ctx, loc), other if other.is_monomorphic() => Ok(other), other => todo!("{other}"), } diff --git a/compiler/erg_type/lib.rs b/compiler/erg_type/lib.rs index 1176d89f..20c2538c 100644 --- a/compiler/erg_type/lib.rs +++ b/compiler/erg_type/lib.rs @@ -1817,6 +1817,7 @@ impl Type { pub fn tvar_name(&self) -> Option { match self { + Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(), Self::FreeVar(fv) => fv.unbound_name(), Self::MonoQVar(name) => Some(name.clone()), _ => None, diff --git a/compiler/erg_type/typaram.rs b/compiler/erg_type/typaram.rs index 2be0a1bd..a96cfe37 100644 --- a/compiler/erg_type/typaram.rs +++ b/compiler/erg_type/typaram.rs @@ -509,6 +509,7 @@ impl TyParam { pub fn name(&self) -> Option { match self { Self::Type(t) => Some(t.name()), + Self::FreeVar(fv) if fv.is_linked() => fv.crack().name(), Self::Mono(name) => Some(name.clone()), Self::MonoQVar(name) => Some(name.clone()), _ => None, @@ -518,6 +519,7 @@ impl TyParam { pub fn tvar_name(&self) -> Option { match self { Self::Type(t) => t.tvar_name(), + Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(), Self::FreeVar(fv) => fv.unbound_name(), Self::MonoQVar(name) => Some(name.clone()), _ => None, From e2b4b3fb073c566b91cbcc3f337989c66a0e80d1 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 25 Sep 2022 21:39:47 +0900 Subject: [PATCH 22/38] Update instantiate.rs --- compiler/erg_compiler/context/instantiate.rs | 52 ++++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 6a6d9f5c..73710e60 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -391,22 +391,16 @@ impl Context { .map(|t| enum_unwrap!(t, Type::Subr)); let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?; let mut tv_ctx = TyVarContext::new(self.level, bounds, self); - let non_defaults = sig - .params - .non_defaults - .iter() - .enumerate() - .map(|(n, p)| { - let opt_decl_t = opt_decl_sig_t - .as_ref() - .and_then(|subr| subr.non_default_params.get(n)); - ParamTy::pos( - p.inspect().cloned(), - self.instantiate_param_sig_t(p, opt_decl_t, &mut Some(&mut tv_ctx), mode) - .unwrap(), - ) - }) - .collect::>(); + let mut non_defaults = vec![]; + for (n, p) in sig.params.non_defaults.iter().enumerate() { + let opt_decl_t = opt_decl_sig_t + .as_ref() + .and_then(|subr| subr.non_default_params.get(n)); + non_defaults.push(ParamTy::pos( + p.inspect().cloned(), + self.instantiate_param_sig_t(p, opt_decl_t, &mut Some(&mut tv_ctx), mode)?, + )); + } let var_args = if let Some(var_args) = sig.params.var_args.as_ref() { let opt_decl_t = opt_decl_sig_t .as_ref() @@ -417,22 +411,16 @@ impl Context { } else { None }; - let defaults = sig - .params - .defaults - .iter() - .enumerate() - .map(|(n, p)| { - let opt_decl_t = opt_decl_sig_t - .as_ref() - .and_then(|subr| subr.default_params.get(n)); - ParamTy::kw( - p.inspect().unwrap().clone(), - self.instantiate_param_sig_t(p, opt_decl_t, &mut Some(&mut tv_ctx), mode) - .unwrap(), - ) - }) - .collect(); + let mut defaults = vec![]; + for (n, p) in sig.params.defaults.iter().enumerate() { + let opt_decl_t = opt_decl_sig_t + .as_ref() + .and_then(|subr| subr.default_params.get(n)); + defaults.push(ParamTy::kw( + p.inspect().unwrap().clone(), + self.instantiate_param_sig_t(p, opt_decl_t, &mut Some(&mut tv_ctx), mode)?, + )); + } let spec_return_t = if let Some(s) = sig.return_t_spec.as_ref() { let opt_decl_t = opt_decl_sig_t .as_ref() From 7fad8d9eee1ce3b6f5d4285804207822e37d9730 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 25 Sep 2022 21:43:48 +0900 Subject: [PATCH 23/38] Update version (nightly) --- Cargo.lock | 10 +++++----- Cargo.toml | 10 +++++----- compiler/erg_common/Cargo.toml | 2 +- compiler/erg_compiler/Cargo.toml | 8 ++++---- compiler/erg_parser/Cargo.toml | 4 ++-- compiler/erg_type/Cargo.toml | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b27310e..b5fdc796 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "erg" -version = "0.5.3" +version = "0.5.4-nightly.0" dependencies = [ "erg_common", "erg_compiler", @@ -25,14 +25,14 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.5.3" +version = "0.5.4-nightly.0" dependencies = [ "atty", ] [[package]] name = "erg_compiler" -version = "0.5.3" +version = "0.5.4-nightly.0" dependencies = [ "erg_common", "erg_parser", @@ -41,14 +41,14 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.5.3" +version = "0.5.4-nightly.0" dependencies = [ "erg_common", ] [[package]] name = "erg_type" -version = "0.5.3" +version = "0.5.4-nightly.0" dependencies = [ "erg_common", "erg_parser", diff --git a/Cargo.toml b/Cargo.toml index a3aeda53..ebe28454 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg" -version = "0.5.3" +version = "0.5.4-nightly.0" description = "The Erg programming language" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -46,10 +46,10 @@ traditional_chinese = [ ] [dependencies] -erg_common = { version = "0.5.3", path = "./compiler/erg_common" } -erg_parser = { version = "0.5.3", path = "./compiler/erg_parser" } -erg_compiler = { version = "0.5.3", path = "./compiler/erg_compiler" } -erg_type = { version = "0.5.3", path = "./compiler/erg_type" } +erg_common = { version = "0.5.4-nightly.0", path = "./compiler/erg_common" } +erg_parser = { version = "0.5.4-nightly.0", path = "./compiler/erg_parser" } +erg_compiler = { version = "0.5.4-nightly.0", path = "./compiler/erg_compiler" } +erg_type = { version = "0.5.4-nightly.0", path = "./compiler/erg_type" } # [workspace] # member = ["cm", "dyne"] diff --git a/compiler/erg_common/Cargo.toml b/compiler/erg_common/Cargo.toml index cc733cda..386cc21f 100644 --- a/compiler/erg_common/Cargo.toml +++ b/compiler/erg_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_common" -version = "0.5.3" +version = "0.5.4-nightly.0" description = "A common components library of Erg" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" diff --git a/compiler/erg_compiler/Cargo.toml b/compiler/erg_compiler/Cargo.toml index 84283266..fc4c8f4b 100644 --- a/compiler/erg_compiler/Cargo.toml +++ b/compiler/erg_compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_compiler" -version = "0.5.3" +version = "0.5.4-nightly.0" description = "Centimetre: the Erg compiler" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -17,9 +17,9 @@ simplified_chinese = [ "erg_common/simplified_chinese", "erg_parser/simplified_c traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditional_chinese", "erg_type/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.3", path = "../erg_common" } -erg_parser = { version = "0.5.3", path = "../erg_parser" } -erg_type = { version = "0.5.3", path = "../erg_type" } +erg_common = { version = "0.5.4-nightly.0", path = "../erg_common" } +erg_parser = { version = "0.5.4-nightly.0", path = "../erg_parser" } +erg_type = { version = "0.5.4-nightly.0", path = "../erg_type" } [lib] path = "lib.rs" diff --git a/compiler/erg_parser/Cargo.toml b/compiler/erg_parser/Cargo.toml index e3bb6baf..7a42a60b 100644 --- a/compiler/erg_parser/Cargo.toml +++ b/compiler/erg_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_parser" -version = "0.5.3" +version = "0.5.4-nightly.0" description = "The Erg parser" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.3", path = "../erg_common" } +erg_common = { version = "0.5.4-nightly.0", path = "../erg_common" } [lib] path = "lib.rs" diff --git a/compiler/erg_type/Cargo.toml b/compiler/erg_type/Cargo.toml index eeadc748..ba8fc4f0 100644 --- a/compiler/erg_type/Cargo.toml +++ b/compiler/erg_type/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_type" -version = "0.5.3" +version = "0.5.4-nightly.0" description = "APIs for Erg types" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -18,8 +18,8 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.3", path = "../erg_common" } -erg_parser = { version = "0.5.3", path = "../erg_parser" } +erg_common = { version = "0.5.4-nightly.0", path = "../erg_common" } +erg_parser = { version = "0.5.4-nightly.0", path = "../erg_parser" } [lib] path = "lib.rs" From 792c0ca3b421322d636dc2cebd39ba2f70a6fef6 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 25 Sep 2022 23:43:31 +0900 Subject: [PATCH 24/38] impl Error for CompileError --- compiler/erg_common/error.rs | 13 +++++++++++++ compiler/erg_compiler/error.rs | 7 ++++++- compiler/erg_parser/error.rs | 4 +++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/compiler/erg_common/error.rs b/compiler/erg_common/error.rs index 3914b602..61fee15b 100644 --- a/compiler/erg_common/error.rs +++ b/compiler/erg_common/error.rs @@ -564,6 +564,19 @@ pub trait ErrorDisplay { } } +#[macro_export] +macro_rules! impl_display_and_error { + ($Strc: ident) => { + impl std::fmt::Display for $Strc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + $crate::error::ErrorDisplay::format(self, f) + } + } + + impl std::error::Error for $Strc {} + }; +} + pub trait MultiErrorDisplay: Stream { fn fmt_all_stderr(&self) { for err in self.iter() { diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index d9f353ff..02d903de 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -8,7 +8,10 @@ use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiEr use erg_common::set::Set; use erg_common::traits::{Locational, Stream}; use erg_common::vis::Visibility; -use erg_common::{fmt_iter, fmt_option_map, fmt_vec, impl_stream_for_wrapper, switch_lang, Str}; +use erg_common::{ + fmt_iter, fmt_option_map, fmt_vec, impl_display_and_error, impl_stream_for_wrapper, + switch_lang, Str, +}; use erg_parser::error::{ParserRunnerError, ParserRunnerErrors}; @@ -100,6 +103,8 @@ pub struct CompileError { pub caused_by: AtomicStr, } +impl_display_and_error!(CompileError); + impl From for CompileError { fn from(err: ParserRunnerError) -> Self { Self { diff --git a/compiler/erg_parser/error.rs b/compiler/erg_parser/error.rs index 07e7cbf9..e0696e5a 100644 --- a/compiler/erg_parser/error.rs +++ b/compiler/erg_parser/error.rs @@ -6,7 +6,7 @@ use erg_common::color::{RED, RESET}; use erg_common::config::Input; use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay}; use erg_common::traits::Stream; -use erg_common::{impl_stream_for_wrapper, switch_lang}; +use erg_common::{impl_display_and_error, impl_stream_for_wrapper, switch_lang}; #[derive(Debug)] pub struct LexError(ErrorCore); @@ -144,6 +144,8 @@ pub struct ParserRunnerError { pub input: Input, } +impl_display_and_error!(ParserRunnerError); + impl ErrorDisplay for ParserRunnerError { fn core(&self) -> &ErrorCore { &self.core From 56d23936de896aebe1c6fb3f1a2ce5fd8661d6c7 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 00:28:43 +0900 Subject: [PATCH 25/38] Update parse.rs --- compiler/erg_parser/parse.rs | 175 ++++++++++++++++++++++++++++++----- 1 file changed, 151 insertions(+), 24 deletions(-) diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index e0c7f4ed..b006a9da 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -362,7 +362,10 @@ impl Parser { if self.cur_is(Newline) { self.skip(); } else { - todo!() + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } self.level -= 1; @@ -863,13 +866,24 @@ impl Parser { if self.cur_is(Indent) { self.skip(); } else { - todo!() + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } while self.cur_is(Newline) { self.skip(); } let first = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?; - let first = option_enum_unwrap!(first, Expr::Def).unwrap_or_else(|| todo!()); + let first = if let Some(fst) = option_enum_unwrap!(first, Expr::Def) { + fst + } else { + // self.restore(); + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); + }; let mut defs = vec![first]; loop { match self.peek() { @@ -894,7 +908,12 @@ impl Parser { } } } - _ => todo!(), + _ => { + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); + } } } let defs = RecordAttrs::from(defs); @@ -912,7 +931,7 @@ impl Parser { let op = match &do_symbol.inspect()[..] { "do" => Token::from_str(FuncArrow, "->"), "do!" => Token::from_str(ProcArrow, "=>"), - _ => todo!(), + _ => unreachable!(), }; if self.cur_is(Colon) { self.lpop(); @@ -1058,8 +1077,13 @@ impl Parser { let pack = DataPack::new(maybe_class, vis, args); stack.push(ExprOrOp::Expr(Expr::DataPack(pack))); } - BraceContainer::Dict(dict) => todo!("{dict}"), - BraceContainer::Set(set) => todo!("{set}"), + BraceContainer::Dict(_) | BraceContainer::Set(_) => { + // self.restore(other); + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); + } } } other => { @@ -1344,7 +1368,15 @@ impl Parser { Some(t) if t.is(AtSign) => { let decos = self.opt_reduce_decorators()?; let expr = self.try_reduce_chunk(false)?; - let mut def = option_enum_unwrap!(expr, Expr::Def).unwrap_or_else(|| todo!()); + let mut def = if let Some(def) = option_enum_unwrap!(expr, Expr::Def) { + def + } else { + // self.restore(other); + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); + }; match def.sig { Signature::Subr(mut subr) => { subr.decorators = decos; @@ -1509,7 +1541,15 @@ impl Parser { ArrayInner::WithLength(elem, len) => { Array::WithLength(ArrayWithLength::new(l_sqbr, r_sqbr, elem, len)) } - ArrayInner::Comprehension { .. } => todo!(), + ArrayInner::Comprehension { .. } => { + self.level -= 1; + self.errs.push(ParseError::feature_error( + line!() as usize, + Location::concat(&l_sqbr, &r_sqbr), + "array comprehension", + )); + return Err(()); + } }; self.level -= 1; Ok(arr) @@ -1525,7 +1565,10 @@ impl Parser { if self.cur_is(Indent) { self.skip(); } else { - todo!() + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } let first = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?; @@ -1576,7 +1619,12 @@ impl Parser { let attrs = RecordAttrs::from(attrs); return Ok(NormalRecord::new(l_brace, r_brace, attrs)); } else { - todo!() + // TODO: not closed + // self.restore(other); + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } Some(term) if term.is(RBrace) => { @@ -1587,10 +1635,24 @@ impl Parser { } Some(_) => { let def = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?; - let def = option_enum_unwrap!(def, Expr::Def).unwrap_or_else(|| todo!()); + let def = if let Some(def) = option_enum_unwrap!(def, Expr::Def) { + def + } else { + // self.restore(other); + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); + }; attrs.push(def); } - _ => todo!(), + _ => { + // self.restore(other); + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); + } } } } @@ -1603,7 +1665,12 @@ impl Parser { debug_call_info!(self); let first = match first { Accessor::Ident(ident) => ident, - other => todo!("{other}"), // syntax error + other => { + self.level -= 1; + let err = ParseError::simple_syntax_error(line!() as usize, other.loc()); + self.errs.push(err); + return Err(()); + } }; let mut idents = vec![first]; loop { @@ -1618,7 +1685,11 @@ impl Parser { self.level -= 1; return Ok(ShortenedRecord::new(l_brace, r_brace, idents)); } else { - todo!() + // self.restore(other); + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } Some(term) if term.is(RBrace) => { @@ -1630,11 +1701,22 @@ impl Parser { let acc = self.try_reduce_acc(false).map_err(|_| self.stack_dec())?; let acc = match acc { Accessor::Ident(ident) => ident, - other => todo!("{other}"), // syntax error + other => { + self.level -= 1; + let err = + ParseError::simple_syntax_error(line!() as usize, other.loc()); + self.errs.push(err); + return Err(()); + } }; idents.push(acc); } - _ => todo!(), + _ => { + self.level -= 1; + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); + } } } } @@ -1669,7 +1751,12 @@ impl Parser { args.push_pos(PosArg::new(other)); } }, - PosOrKwArg::Kw(_arg) => todo!(), + PosOrKwArg::Kw(arg) => { + self.level -= 1; + let err = ParseError::simple_syntax_error(line!() as usize, arg.loc()); + self.errs.push(err); + return Err(()); + } } } _ => { @@ -1808,7 +1895,22 @@ impl Parser { self.level -= 1; Ok(pat) } - _ => todo!(), + Array::Comprehension(arr) => { + self.level -= 1; + let err = ParseError::simple_syntax_error(line!() as usize, arr.loc()); + self.errs.push(err); + Err(()) + } + Array::WithLength(arr) => { + self.level -= 1; + let err = ParseError::feature_error( + line!() as usize, + arr.loc(), + "array-with-length pattern", + ); + self.errs.push(err); + Err(()) + } } } @@ -1876,7 +1978,13 @@ impl Parser { Signature::Var(var) => { vars.push(var); } - other => todo!("{other}"), + other => { + self.level -= 1; + let err = + ParseError::simple_syntax_error(line!() as usize, other.loc()); + self.errs.push(err); + return Err(()); + } } } let tuple = VarTuplePattern::new(paren, vars); @@ -1995,7 +2103,11 @@ impl Parser { let bound = TypeBoundSpec::non_default(lhs.name.into_token(), spec_with_op); Ok(bound) } - other => todo!("{other}"), + other => { + let err = ParseError::simple_syntax_error(line!() as usize, other.loc()); + self.errs.push(err); + Err(()) + } } } @@ -2150,7 +2262,12 @@ impl Parser { self.level -= 1; Ok(ParamArrayPattern::new(arr.l_sqbr, params, arr.r_sqbr)) } - _ => todo!(), + other => { + self.level -= 1; + let err = ParseError::feature_error(line!() as usize, other.loc(), "?"); + self.errs.push(err); + Err(()) + } } } @@ -2368,7 +2485,12 @@ impl Parser { self.level -= 1; Ok(TypeSpec::Array(array)) } - other => todo!("{other}"), + other => { + self.level -= 1; + let err = ParseError::simple_syntax_error(line!() as usize, other.loc()); + self.errs.push(err); + Err(()) + } } } @@ -2386,7 +2508,12 @@ impl Parser { .map_err(|_| self.stack_dec())?; TypeSpec::type_app(spec, tapp.type_args) } - other => todo!("{other}"), + other => { + self.level -= 1; + let err = ParseError::simple_syntax_error(line!() as usize, other.loc()); + self.errs.push(err); + return Err(()); + } }; self.level -= 1; Ok(t_spec) From a83702240444feab31c5a21c004b3039b463b904 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 00:31:34 +0900 Subject: [PATCH 26/38] Update version (nightly) --- Cargo.lock | 10 +++++----- Cargo.toml | 10 +++++----- compiler/erg_common/Cargo.toml | 2 +- compiler/erg_compiler/Cargo.toml | 8 ++++---- compiler/erg_parser/Cargo.toml | 4 ++-- compiler/erg_type/Cargo.toml | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5fdc796..f4e255e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "erg" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" dependencies = [ "erg_common", "erg_compiler", @@ -25,14 +25,14 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" dependencies = [ "atty", ] [[package]] name = "erg_compiler" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" dependencies = [ "erg_common", "erg_parser", @@ -41,14 +41,14 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" dependencies = [ "erg_common", ] [[package]] name = "erg_type" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" dependencies = [ "erg_common", "erg_parser", diff --git a/Cargo.toml b/Cargo.toml index ebe28454..144fd519 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" description = "The Erg programming language" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -46,10 +46,10 @@ traditional_chinese = [ ] [dependencies] -erg_common = { version = "0.5.4-nightly.0", path = "./compiler/erg_common" } -erg_parser = { version = "0.5.4-nightly.0", path = "./compiler/erg_parser" } -erg_compiler = { version = "0.5.4-nightly.0", path = "./compiler/erg_compiler" } -erg_type = { version = "0.5.4-nightly.0", path = "./compiler/erg_type" } +erg_common = { version = "0.5.4-nightly.1", path = "./compiler/erg_common" } +erg_parser = { version = "0.5.4-nightly.1", path = "./compiler/erg_parser" } +erg_compiler = { version = "0.5.4-nightly.1", path = "./compiler/erg_compiler" } +erg_type = { version = "0.5.4-nightly.1", path = "./compiler/erg_type" } # [workspace] # member = ["cm", "dyne"] diff --git a/compiler/erg_common/Cargo.toml b/compiler/erg_common/Cargo.toml index 386cc21f..24fa1757 100644 --- a/compiler/erg_common/Cargo.toml +++ b/compiler/erg_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_common" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" description = "A common components library of Erg" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" diff --git a/compiler/erg_compiler/Cargo.toml b/compiler/erg_compiler/Cargo.toml index fc4c8f4b..cec49a60 100644 --- a/compiler/erg_compiler/Cargo.toml +++ b/compiler/erg_compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_compiler" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" description = "Centimetre: the Erg compiler" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -17,9 +17,9 @@ simplified_chinese = [ "erg_common/simplified_chinese", "erg_parser/simplified_c traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditional_chinese", "erg_type/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4-nightly.0", path = "../erg_common" } -erg_parser = { version = "0.5.4-nightly.0", path = "../erg_parser" } -erg_type = { version = "0.5.4-nightly.0", path = "../erg_type" } +erg_common = { version = "0.5.4-nightly.1", path = "../erg_common" } +erg_parser = { version = "0.5.4-nightly.1", path = "../erg_parser" } +erg_type = { version = "0.5.4-nightly.1", path = "../erg_type" } [lib] path = "lib.rs" diff --git a/compiler/erg_parser/Cargo.toml b/compiler/erg_parser/Cargo.toml index 7a42a60b..20151dd0 100644 --- a/compiler/erg_parser/Cargo.toml +++ b/compiler/erg_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_parser" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" description = "The Erg parser" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4-nightly.0", path = "../erg_common" } +erg_common = { version = "0.5.4-nightly.1", path = "../erg_common" } [lib] path = "lib.rs" diff --git a/compiler/erg_type/Cargo.toml b/compiler/erg_type/Cargo.toml index ba8fc4f0..a75baedf 100644 --- a/compiler/erg_type/Cargo.toml +++ b/compiler/erg_type/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_type" -version = "0.5.4-nightly.0" +version = "0.5.4-nightly.1" description = "APIs for Erg types" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -18,8 +18,8 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4-nightly.0", path = "../erg_common" } -erg_parser = { version = "0.5.4-nightly.0", path = "../erg_parser" } +erg_common = { version = "0.5.4-nightly.1", path = "../erg_common" } +erg_parser = { version = "0.5.4-nightly.1", path = "../erg_parser" } [lib] path = "lib.rs" From f1b8b5a6b814451bd4f6d1c5e9829cbb5e2da4be Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 01:04:42 +0900 Subject: [PATCH 27/38] Fix inferring bugs --- compiler/erg_compiler/context/instantiate.rs | 9 ++++++++- compiler/erg_compiler/context/tyvar.rs | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 73710e60..20145775 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -133,7 +133,6 @@ impl TyVarContext { params .into_iter() .map(|p| { - erg_common::log!(err "p: {p}, {:?}", p.tvar_name()); if let Some(name) = p.tvar_name() { let tp = self.instantiate_qtp(p); self.push_or_init_typaram(&name, &tp); @@ -861,6 +860,14 @@ impl Context { panic!("a quantified type should not be instantiated, instantiate the inner type") } FreeVar(fv) if fv.is_linked() => Self::instantiate_t(fv.crack().clone(), tv_ctx, loc), + FreeVar(fv) => { + let (sub, sup) = fv.get_bound_types().unwrap(); + let sub = Self::instantiate_t(sub, tv_ctx, loc)?; + let sup = Self::instantiate_t(sup, tv_ctx, loc)?; + let new_constraint = Constraint::new_sandwiched(sub, sup, fv.cyclicity()); + fv.update_constraint(new_constraint); + Ok(FreeVar(fv)) + } other if other.is_monomorphic() => Ok(other), other => todo!("{other}"), } diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index 2c708388..839b5ce3 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -166,6 +166,10 @@ impl Context { .collect::>(); poly(name, params) } + MonoProj { lhs, rhs } => { + let lhs = self.generalize_t_inner(*lhs, bounds, lazy_inits); + mono_proj(lhs, rhs) + } // REVIEW: その他何でもそのまま通していいのか? other => other, } From 334b9d9f3a272c5699d8c4f5df4effb52db64db1 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 01:21:06 +0900 Subject: [PATCH 28/38] Improve error output --- compiler/erg_compiler/context/register.rs | 8 +++---- compiler/erg_compiler/lower.rs | 29 +++++++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index d9aa7d0b..ccbde688 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -624,7 +624,7 @@ impl Context { .push((ClassDefType::Simple(gen.t.clone()), methods)); self.register_gen_mono_type(ident, gen, ctx, Const); } else { - todo!() + todo!("polymorphic type definition is not supported yet"); } } TypeKind::Subclass => { @@ -668,7 +668,7 @@ impl Context { todo!("super class not found") } } else { - todo!() + todo!("polymorphic type definition is not supported yet"); } } TypeKind::Trait => { @@ -688,7 +688,7 @@ impl Context { } self.register_gen_mono_type(ident, gen, ctx, Const); } else { - todo!() + todo!("polymorphic type definition is not supported yet"); } } TypeKind::Subtrait => { @@ -717,7 +717,7 @@ impl Context { } self.register_gen_mono_type(ident, gen, ctx, Const); } else { - todo!() + todo!("polymorphic type definition is not supported yet"); } } other => todo!("{other:?}"), diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 26297ab3..35d3d949 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -543,26 +543,32 @@ impl ASTLowerer { )); } let name = if let Some(name) = def.sig.name_as_str() { - name + name.clone() } else { - "" + Str::ever("") }; - if self.ctx.registered_info(name, def.sig.is_const()).is_some() { + if self + .ctx + .registered_info(&name, def.sig.is_const()) + .is_some() + { return Err(LowerError::reassign_error( line!() as usize, def.sig.loc(), self.ctx.caused_by(), - name, + &name, )); } let kind = ContextKind::from(def.def_kind()); - self.ctx.grow(name, kind, def.sig.vis())?; + self.ctx.grow(&name, kind, def.sig.vis())?; let res = match def.sig { ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body), ast::Signature::Var(sig) => self.lower_var_def(sig, def.body), }; // TODO: Context上の関数に型境界情報を追加 self.pop_append_errs(); + // remove from decls regardless of success or failure to lower + self.ctx.decls.remove(&name); res } @@ -1035,10 +1041,19 @@ impl ASTLowerer { } } } - self.ctx.check_decls()?; + self.ctx.check_decls().unwrap_or_else(|mut errs| { + self.errs.append(&mut errs); + }); let hir = HIR::new(ast.name, module); log!(info "HIR (not resolved, current errs: {}):\n{hir}", self.errs.len()); - let hir = self.ctx.resolve(hir)?; + let hir = match self.ctx.resolve(hir) { + Ok(hir) => hir, + Err(err) => { + self.errs.push(err); + log!(err "the AST lowering process has failed."); + return Err(LowerErrors::from(self.errs.take_all())); + } + }; // TODO: recursive check for chunk in hir.module.iter() { if let Err(e) = self.use_check(chunk, mode) { From 0d05a715f8e9d5f70d64fbd5b35b4651eb6aa1d6 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 11:26:54 +0900 Subject: [PATCH 29/38] Update 32_integration_with_Python.md --- doc/EN/syntax/32_integration_with_Python.md | 36 ++++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/doc/EN/syntax/32_integration_with_Python.md b/doc/EN/syntax/32_integration_with_Python.md index 945379a2..e4df93fe 100644 --- a/doc/EN/syntax/32_integration_with_Python.md +++ b/doc/EN/syntax/32_integration_with_Python.md @@ -22,20 +22,20 @@ print(foo.public) print(foo.private) # AttributeError: ``` -## Import from Python +## import from Python -All objects imported from Python are by default of type `Object`. Since no comparisons can be made at this point, it is necessary to refine the type. +By default, all objects imported from Python are of type `Object`. Since no comparison is possible with this type, it is necessary to narrow down the type. -## Type Specification in the Standard Library +## Type specification in the standard library -All APIs in the Python standard library are type specified by the Erg development team. +All APIs in the Python standard library are type-specified by the Erg development team. ```python time = pyimport "time" time.sleep! 1 ``` -## Type Specification for User Scripts +## Type specification for user scripts Create a `foo.d.er` file that types the Python `foo` module. Type hints on the Python side are ignored since they are not 100% guaranteed. @@ -47,30 +47,34 @@ def bar(x): ... def baz(): ... +class C: + ... ... -``` -```python +````python # foo.d.er -foo = pyimport "foo" -.X = declare foo.'X', Int -.bar = declare foo.'bar', Int -> Int -.baz! = declare foo.'baz', () => Int +.X: Int +.bar!: Int => Int +.foo! = baz!: () => Int # aliasing +.C!: Class ``` +No syntax other than declarations and definitions (aliasing) are allowed in ``d.er``. + +Note that all Python functions can only be registered as procedures, and all classes as variable classes. + ```python foo = pyimport "foo" -assert foo.bar(1) in Int +assert foo.bar!(1) in Int ``` -This ensures type safety by performing type checking at runtime. The ``declare`` function works roughly as follows. +This ensures type safety by performing type checking at runtime. The checking mechanism generally works as follows. ```python -declare|S: Subroutine| sub!: S, T = - # Actually, => can be cast to a function without block side effects +decl_proc proc!: Proc, T = x => assert x in T.Input - y = sub!(x) + y = proc!(x) assert y in T.Output y ``` From 5916096cc4030ee18c10d0cc22ca82cc534022dd Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 11:27:52 +0900 Subject: [PATCH 30/38] Update 32_integration_with_Python.md --- doc/JA/syntax/32_integration_with_Python.md | 25 ++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/doc/JA/syntax/32_integration_with_Python.md b/doc/JA/syntax/32_integration_with_Python.md index 997f5504..1303ae0b 100644 --- a/doc/JA/syntax/32_integration_with_Python.md +++ b/doc/JA/syntax/32_integration_with_Python.md @@ -1,6 +1,6 @@ # Pythonとの連携 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/32_integration_with_Python.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/32_integration_with_Python.md%26commit_hash%3D0d05a715f8e9d5f70d64fbd5b35b4651eb6aa1d6)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=0d05a715f8e9d5f70d64fbd5b35b4651eb6aa1d6) ## Pythonへのexport @@ -49,29 +49,34 @@ def bar(x): ... def baz(): ... +class C: + ... ``` ```python # foo.d.er -foo = pyimport "foo" -.X = declare foo.'X', Int -.bar = declare foo.'bar', Int -> Int -.baz! = declare foo.'baz', () => Int +.X: Int +.bar!: Int => Int +.foo! = baz!: () => Int # aliasing +.C!: Class ``` +`d.er`内では宣言と定義(エイリアシング)以外の構文は使えません。 + +Pythonの関数はすべてプロシージャとして、クラスはすべて可変クラスとしてしか登録できないことに注意してください。 + ```python foo = pyimport "foo" -assert foo.bar(1) in Int +assert foo.bar!(1) in Int ``` -これは、実行時に型チェックを行うことで型安全性を担保しています。`declare`関数は概ね以下のように動作します。 +これは、実行時に型チェックを行うことで型安全性を担保しています。チェック機構は概ね以下のように動作します。 ```python -declare|S: Subroutine| sub!: S, T = - # 実は、=>はブロックの副作用がなければ関数にキャストできる +decl_proc proc!: Proc, T = x => assert x in T.Input - y = sub!(x) + y = proc!(x) assert y in T.Output y ``` From 5aae4a69a534cfee20b4f2419044f0d01de32f8c Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 14:03:06 +0900 Subject: [PATCH 31/38] Split cache between Python and Erg modules --- compiler/erg_common/levenshtein.rs | 16 ++ compiler/erg_compiler/build_hir.rs | 10 +- compiler/erg_compiler/compile.rs | 8 +- compiler/erg_compiler/context/eval.rs | 2 + .../erg_compiler/context/initialize/mod.rs | 237 ++++++++++-------- .../context/initialize/py_mods/importlib.rs | 2 +- .../context/initialize/py_mods/io.rs | 4 +- .../context/initialize/py_mods/math.rs | 2 +- .../context/initialize/py_mods/random.rs | 2 +- .../context/initialize/py_mods/socket.rs | 4 +- .../context/initialize/py_mods/sys.rs | 2 +- .../context/initialize/py_mods/time.rs | 2 +- compiler/erg_compiler/context/inquire.rs | 34 +-- compiler/erg_compiler/context/mod.rs | 73 +++++- compiler/erg_compiler/context/register.rs | 208 ++++++++++----- compiler/erg_compiler/error.rs | 36 ++- compiler/erg_compiler/hir.rs | 14 +- compiler/erg_compiler/link.rs | 2 +- compiler/erg_compiler/lower.rs | 16 +- compiler/erg_compiler/mod_cache.rs | 31 ++- compiler/erg_compiler/tests/test.rs | 18 +- compiler/erg_parser/ast.rs | 56 +++-- 22 files changed, 521 insertions(+), 258 deletions(-) diff --git a/compiler/erg_common/levenshtein.rs b/compiler/erg_common/levenshtein.rs index 8d8a674e..6a66a772 100644 --- a/compiler/erg_common/levenshtein.rs +++ b/compiler/erg_common/levenshtein.rs @@ -33,3 +33,19 @@ pub fn levenshtein(lhs: &str, rhs: &str) -> usize { } table[l_len][r_len] } + +pub fn get_similar_name<'a, I: Iterator>( + candidates: I, + name: &str, +) -> Option<&'a str> { + if name.len() <= 1 { + return None; + } + let most_similar_name = candidates.min_by_key(|v| levenshtein(v, name))?; + let len = most_similar_name.len(); + if levenshtein(most_similar_name, name) >= len / 2 { + None + } else { + Some(most_similar_name) + } +} diff --git a/compiler/erg_compiler/build_hir.rs b/compiler/erg_compiler/build_hir.rs index f2bc48a1..6a731770 100644 --- a/compiler/erg_compiler/build_hir.rs +++ b/compiler/erg_compiler/build_hir.rs @@ -27,7 +27,12 @@ impl Runnable for HIRBuilder { const NAME: &'static str = "Erg HIR builder"; fn new(cfg: ErgConfig) -> Self { - HIRBuilder::new_with_cache(cfg, Str::ever(""), SharedModuleCache::new()) + HIRBuilder::new_with_cache( + cfg, + Str::ever(""), + SharedModuleCache::new(), + SharedModuleCache::new(), + ) } #[inline] @@ -61,9 +66,10 @@ impl HIRBuilder { cfg: ErgConfig, mod_name: S, mod_cache: SharedModuleCache, + py_mod_cache: SharedModuleCache, ) -> Self { Self { - lowerer: ASTLowerer::new_with_cache(cfg, mod_name, mod_cache), + lowerer: ASTLowerer::new_with_cache(cfg, mod_name, mod_cache, py_mod_cache), ownership_checker: OwnershipChecker::new(), } } diff --git a/compiler/erg_compiler/compile.rs b/compiler/erg_compiler/compile.rs index bbe4226b..a6f2a8dc 100644 --- a/compiler/erg_compiler/compile.rs +++ b/compiler/erg_compiler/compile.rs @@ -103,8 +103,14 @@ impl Runnable for Compiler { fn new(cfg: ErgConfig) -> Self { let mod_cache = SharedModuleCache::new(); + let py_mod_cache = SharedModuleCache::new(); Self { - builder: HIRBuilder::new_with_cache(cfg.copy(), "", mod_cache.clone()), + builder: HIRBuilder::new_with_cache( + cfg.copy(), + "", + mod_cache.clone(), + py_mod_cache, + ), code_generator: CodeGenerator::new(cfg.copy()), mod_cache, cfg, diff --git a/compiler/erg_compiler/context/eval.rs b/compiler/erg_compiler/context/eval.rs index 5fd44c79..b5df3259 100644 --- a/compiler/erg_compiler/context/eval.rs +++ b/compiler/erg_compiler/context/eval.rs @@ -353,6 +353,7 @@ impl Context { Str::ever(""), 2, self.mod_cache.clone(), + self.py_mod_cache.clone(), self.clone(), ); for attr in record.attrs.iter() { @@ -424,6 +425,7 @@ impl Context { Str::ever(""), 0, self.mod_cache.clone(), + self.py_mod_cache.clone(), self.clone(), ); let return_t = lambda_ctx.eval_const_block(&lambda.body, None)?; diff --git a/compiler/erg_compiler/context/initialize/mod.rs b/compiler/erg_compiler/context/initialize/mod.rs index c42dd7cd..633ef7eb 100644 --- a/compiler/erg_compiler/context/initialize/mod.rs +++ b/compiler/erg_compiler/context/initialize/mod.rs @@ -180,10 +180,10 @@ impl Context { // 型境界はすべて各サブルーチンで定義する // push_subtype_boundなどはユーザー定義APIの型境界決定のために使用する fn init_builtin_traits(&mut self) { - let unpack = Self::mono_trait("Unpack", None, Self::TOP_LEVEL); - let inheritable_type = Self::mono_trait("InheritableType", None, Self::TOP_LEVEL); - let named = Self::mono_trait("Named", None, Self::TOP_LEVEL); - let mut mutable = Self::mono_trait("Mutable", None, Self::TOP_LEVEL); + let unpack = Self::mono_trait("Unpack", None, None, Self::TOP_LEVEL); + let inheritable_type = Self::mono_trait("InheritableType", None, None, Self::TOP_LEVEL); + let named = Self::mono_trait("Named", None, None, Self::TOP_LEVEL); + let mut mutable = Self::mono_trait("Mutable", None, None, Self::TOP_LEVEL); let proj = mono_proj(mono_q("Self"), "ImmutType"); let f_t = func(vec![param_t("old", proj.clone())], None, vec![], proj); let t = pr1_met(ref_mut(mono_q("Self"), None), f_t, NoneType); @@ -193,16 +193,22 @@ impl Context { ); mutable.register_builtin_decl("update!", t, Public); // REVIEW: Immutatable? - let mut immutizable = Self::mono_trait("Immutizable", None, Self::TOP_LEVEL); + let mut immutizable = Self::mono_trait("Immutizable", None, None, Self::TOP_LEVEL); immutizable.register_superclass(builtin_mono("Mutable"), &mutable); immutizable.register_builtin_decl("ImmutType", Type, Public); // REVIEW: Mutatable? - let mut mutizable = Self::mono_trait("Mutizable", None, Self::TOP_LEVEL); + let mut mutizable = Self::mono_trait("Mutizable", None, None, Self::TOP_LEVEL); mutizable.register_builtin_decl("MutType!", Type, Public); - let mut in_ = Self::poly_trait("In", vec![PS::t("T", NonDefault)], None, Self::TOP_LEVEL); + let mut in_ = Self::poly_trait( + "In", + vec![PS::t("T", NonDefault)], + None, + None, + Self::TOP_LEVEL, + ); let params = vec![PS::t("T", NonDefault)]; - let input = Self::poly_trait("Input", params.clone(), None, Self::TOP_LEVEL); - let output = Self::poly_trait("Output", params, None, Self::TOP_LEVEL); + let input = Self::poly_trait("Input", params.clone(), None, None, Self::TOP_LEVEL); + let output = Self::poly_trait("Output", params, None, None, Self::TOP_LEVEL); in_.register_superclass(poly("Input", vec![ty_tp(mono_q("T"))]), &input); let op_t = fn1_met(mono_q("T"), mono_q("I"), Bool); let op_t = quant( @@ -213,7 +219,13 @@ impl Context { // Erg does not have a trait equivalent to `PartialEq` in Rust // This means, Erg's `Float` cannot be compared with other `Float` // use `l - r < EPSILON` to check if two floats are almost equal - let mut eq = Self::poly_trait("Eq", vec![PS::t("R", WithDefault)], None, Self::TOP_LEVEL); + let mut eq = Self::poly_trait( + "Eq", + vec![PS::t("R", WithDefault)], + None, + None, + Self::TOP_LEVEL, + ); eq.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); // __eq__: |Self <: Eq()| Self.(Self) -> Bool let op_t = fn1_met(mono_q("Self"), mono_q("R"), Bool); @@ -229,6 +241,7 @@ impl Context { "PartialOrd", vec![PS::t("R", WithDefault)], None, + None, Self::TOP_LEVEL, ); partial_ord.register_superclass(poly("Eq", vec![ty_tp(mono_q("R"))]), &eq); @@ -245,20 +258,26 @@ impl Context { }, ); partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public); - let mut ord = Self::mono_trait("Ord", None, Self::TOP_LEVEL); + let mut ord = Self::mono_trait("Ord", None, None, Self::TOP_LEVEL); ord.register_superclass(poly("Eq", vec![ty_tp(builtin_mono("Self"))]), &eq); ord.register_superclass( poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]), &partial_ord, ); // FIXME: poly trait - let num = Self::mono_trait("Num", None, Self::TOP_LEVEL); + let num = Self::mono_trait("Num", None, None, Self::TOP_LEVEL); /* vec![ poly("Add", vec![]), poly("Sub", vec![]), poly("Mul", vec![]), ], */ - let mut seq = Self::poly_trait("Seq", vec![PS::t("T", NonDefault)], None, Self::TOP_LEVEL); + let mut seq = Self::poly_trait( + "Seq", + vec![PS::t("T", NonDefault)], + None, + None, + Self::TOP_LEVEL, + ); seq.register_superclass(poly("Output", vec![ty_tp(mono_q("T"))]), &output); let self_t = mono_q("Self"); let t = fn0_met(self_t.clone(), Nat); @@ -278,7 +297,7 @@ impl Context { let r_bound = static_instance("R", Type); let params = vec![PS::t("R", WithDefault)]; let ty_params = vec![ty_tp(mono_q("R"))]; - let mut add = Self::poly_trait("Add", params.clone(), None, Self::TOP_LEVEL); + let mut add = Self::poly_trait("Add", params.clone(), None, None, Self::TOP_LEVEL); // Rについて共変(__add__の型とは関係ない) add.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); let self_bound = subtypeof(mono_q("Self"), poly("Add", ty_params.clone())); @@ -290,7 +309,7 @@ impl Context { let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); add.register_builtin_decl("__add__", op_t, Public); add.register_builtin_decl("Output", Type, Public); - let mut sub = Self::poly_trait("Sub", params.clone(), None, Self::TOP_LEVEL); + let mut sub = Self::poly_trait("Sub", params.clone(), None, None, Self::TOP_LEVEL); sub.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); let op_t = fn1_met( mono_q("Self"), @@ -301,7 +320,7 @@ impl Context { let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); sub.register_builtin_decl("__sub__", op_t, Public); sub.register_builtin_decl("Output", Type, Public); - let mut mul = Self::poly_trait("Mul", params.clone(), None, Self::TOP_LEVEL); + let mut mul = Self::poly_trait("Mul", params.clone(), None, None, Self::TOP_LEVEL); mul.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); let op_t = fn1_met( mono_q("Self"), @@ -312,7 +331,7 @@ impl Context { let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); mul.register_builtin_decl("__mul__", op_t, Public); mul.register_builtin_decl("Output", Type, Public); - let mut div = Self::poly_trait("Div", params, None, Self::TOP_LEVEL); + let mut div = Self::poly_trait("Div", params, None, None, Self::TOP_LEVEL); div.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "Output")); let self_bound = subtypeof(mono_q("Self"), poly("Div", ty_params.clone())); @@ -368,7 +387,7 @@ impl Context { } fn init_builtin_classes(&mut self) { - let mut obj = Self::mono_class("Obj", None, Self::TOP_LEVEL); + let mut obj = Self::mono_class("Obj", None, None, Self::TOP_LEVEL); let t = fn0_met(mono_q("Self"), mono_q("Self")); let t = quant(t, set! {subtypeof(mono_q("Self"), builtin_mono("Obj"))}); obj.register_builtin_impl("clone", t, Const, Public); @@ -383,13 +402,13 @@ impl Context { Immutable, Public, ); - let mut obj_in = Self::methods("In", None, Self::TOP_LEVEL); + let mut obj_in = Self::methods("In", None, None, Self::TOP_LEVEL); obj_in.register_builtin_impl("__in__", fn1_met(Obj, Type, Bool), Const, Public); obj.register_trait(Obj, poly("Eq", vec![ty_tp(Type)]), obj_in); - let mut obj_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); + let mut obj_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); obj_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Obj!"))); obj.register_trait(Obj, builtin_mono("Mutizable"), obj_mutizable); - let mut float = Self::mono_class("Float", None, Self::TOP_LEVEL); + let mut float = Self::mono_class("Float", None, None, Self::TOP_LEVEL); float.register_superclass(Obj, &obj); // TODO: support multi platform float.register_builtin_const("EPSILON", ValueObj::Float(2.220446049250313e-16)); @@ -397,7 +416,7 @@ impl Context { float.register_builtin_impl("Imag", Float, Const, Public); float.register_marker_trait(builtin_mono("Num")); float.register_marker_trait(builtin_mono("Ord")); - let mut float_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); + let mut float_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); float_partial_ord.register_builtin_impl( "__cmp__", fn1_met(Float, Float, builtin_mono("Ordering")), @@ -411,36 +430,36 @@ impl Context { ); // Float doesn't have an `Eq` implementation let op_t = fn1_met(Float, Float, Float); - let mut float_add = Self::methods("Add", None, Self::TOP_LEVEL); + let mut float_add = Self::methods("Add", None, None, Self::TOP_LEVEL); float_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); float_add.register_builtin_const("Output", ValueObj::builtin_t(Float)); float.register_trait(Float, poly("Add", vec![ty_tp(Float)]), float_add); - let mut float_sub = Self::methods("Sub", None, Self::TOP_LEVEL); + let mut float_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL); float_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); float_sub.register_builtin_const("Output", ValueObj::builtin_t(Float)); float.register_trait(Float, poly("Sub", vec![ty_tp(Float)]), float_sub); - let mut float_mul = Self::methods("Mul", None, Self::TOP_LEVEL); + let mut float_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); float_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public); float_mul.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Float)); float.register_trait(Float, poly("Mul", vec![ty_tp(Float)]), float_mul); - let mut float_div = Self::methods("Div", None, Self::TOP_LEVEL); + let mut float_div = Self::methods("Div", None, None, Self::TOP_LEVEL); float_div.register_builtin_impl("__div__", op_t, Const, Public); float_div.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_div.register_builtin_const("ModOutput", ValueObj::builtin_t(Float)); float.register_trait(Float, poly("Div", vec![ty_tp(Float)]), float_div); - let mut float_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); + let mut float_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); float_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Float!"))); float.register_trait(Float, builtin_mono("Mutizable"), float_mutizable); // TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat) - let mut ratio = Self::mono_class("Ratio", None, Self::TOP_LEVEL); + let mut ratio = Self::mono_class("Ratio", None, None, Self::TOP_LEVEL); ratio.register_superclass(Obj, &obj); ratio.register_builtin_impl("Real", Ratio, Const, Public); ratio.register_builtin_impl("Imag", Ratio, Const, Public); ratio.register_marker_trait(builtin_mono("Num")); ratio.register_marker_trait(builtin_mono("Ord")); - let mut ratio_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); + let mut ratio_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); ratio_partial_ord.register_builtin_impl( "__cmp__", fn1_met(Ratio, Ratio, builtin_mono("Ordering")), @@ -452,33 +471,33 @@ impl Context { poly("PartialOrd", vec![ty_tp(Ratio)]), ratio_partial_ord, ); - let mut ratio_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut ratio_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); ratio_eq.register_builtin_impl("__eq__", fn1_met(Ratio, Ratio, Bool), Const, Public); ratio.register_trait(Ratio, poly("Eq", vec![ty_tp(Ratio)]), ratio_eq); let op_t = fn1_met(Ratio, Ratio, Ratio); - let mut ratio_add = Self::methods("Add", None, Self::TOP_LEVEL); + let mut ratio_add = Self::methods("Add", None, None, Self::TOP_LEVEL); ratio_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); ratio_add.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio.register_trait(Ratio, poly("Add", vec![ty_tp(Ratio)]), ratio_add); - let mut ratio_sub = Self::methods("Sub", None, Self::TOP_LEVEL); + let mut ratio_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL); ratio_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); ratio_sub.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio.register_trait(Ratio, poly("Sub", vec![ty_tp(Ratio)]), ratio_sub); - let mut ratio_mul = Self::methods("Mul", None, Self::TOP_LEVEL); + let mut ratio_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); ratio_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public); ratio_mul.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Ratio)); ratio.register_trait(Ratio, poly("Mul", vec![ty_tp(Ratio)]), ratio_mul); - let mut ratio_div = Self::methods("Div", None, Self::TOP_LEVEL); + let mut ratio_div = Self::methods("Div", None, None, Self::TOP_LEVEL); ratio_div.register_builtin_impl("__div__", op_t, Const, Public); ratio_div.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_div.register_builtin_const("ModOutput", ValueObj::builtin_t(Ratio)); ratio.register_trait(Ratio, poly("Div", vec![ty_tp(Ratio)]), ratio_div); - let mut ratio_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); + let mut ratio_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); ratio_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Ratio!"))); ratio.register_trait(Ratio, builtin_mono("Mutizable"), ratio_mutizable); - let mut int = Self::mono_class("Int", None, Self::TOP_LEVEL); + let mut int = Self::mono_class("Int", None, None, Self::TOP_LEVEL); int.register_superclass(Float, &float); // TODO: Float -> Ratio int.register_superclass(Obj, &obj); int.register_marker_trait(builtin_mono("Num")); @@ -487,7 +506,7 @@ impl Context { // class("Rational"), // class("Integral"), int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public); - let mut int_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); + let mut int_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); int_partial_ord.register_builtin_impl( "__partial_cmp__", fn1_met(Int, Int, option(builtin_mono("Ordering"))), @@ -495,30 +514,30 @@ impl Context { Public, ); int.register_trait(Int, poly("PartialOrd", vec![ty_tp(Int)]), int_partial_ord); - let mut int_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut int_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); int_eq.register_builtin_impl("__eq__", fn1_met(Int, Int, Bool), Const, Public); int.register_trait(Int, poly("Eq", vec![ty_tp(Int)]), int_eq); // __div__ is not included in Int (cast to Ratio) let op_t = fn1_met(Int, Int, Int); - let mut int_add = Self::methods("Add", None, Self::TOP_LEVEL); + let mut int_add = Self::methods("Add", None, None, Self::TOP_LEVEL); int_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); int_add.register_builtin_const("Output", ValueObj::builtin_t(Int)); int.register_trait(Int, poly("Add", vec![ty_tp(Int)]), int_add); - let mut int_sub = Self::methods("Sub", None, Self::TOP_LEVEL); + let mut int_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL); int_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); int_sub.register_builtin_const("Output", ValueObj::builtin_t(Int)); int.register_trait(Int, poly("Sub", vec![ty_tp(Int)]), int_sub); - let mut int_mul = Self::methods("Mul", None, Self::TOP_LEVEL); + let mut int_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); int_mul.register_builtin_impl("__mul__", op_t, Const, Public); int_mul.register_builtin_const("Output", ValueObj::builtin_t(Int)); int_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Nat)); int.register_trait(Int, poly("Mul", vec![ty_tp(Int)]), int_mul); - let mut int_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); + let mut int_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); int_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Int!"))); int.register_trait(Int, builtin_mono("Mutizable"), int_mutizable); int.register_builtin_impl("Real", Int, Const, Public); int.register_builtin_impl("Imag", Int, Const, Public); - let mut nat = Self::mono_class("Nat", None, Self::TOP_LEVEL); + let mut nat = Self::mono_class("Nat", None, None, Self::TOP_LEVEL); nat.register_superclass(Int, &int); nat.register_superclass(Float, &float); // TODO: Float -> Ratio nat.register_superclass(Obj, &obj); @@ -538,10 +557,10 @@ impl Context { ); nat.register_marker_trait(builtin_mono("Num")); nat.register_marker_trait(builtin_mono("Ord")); - let mut nat_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut nat_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); nat_eq.register_builtin_impl("__eq__", fn1_met(Nat, Nat, Bool), Const, Public); nat.register_trait(Nat, poly("Eq", vec![ty_tp(Nat)]), nat_eq); - let mut nat_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); + let mut nat_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); nat_partial_ord.register_builtin_impl( "__cmp__", fn1_met(Nat, Nat, builtin_mono("Ordering")), @@ -551,20 +570,20 @@ impl Context { nat.register_trait(Nat, poly("PartialOrd", vec![ty_tp(Nat)]), nat_partial_ord); // __sub__, __div__ is not included in Nat (cast to Int/ Ratio) let op_t = fn1_met(Nat, Nat, Nat); - let mut nat_add = Self::methods("Add", None, Self::TOP_LEVEL); + let mut nat_add = Self::methods("Add", None, None, Self::TOP_LEVEL); nat_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); nat_add.register_builtin_const("Output", ValueObj::builtin_t(Nat)); nat.register_trait(Nat, poly("Add", vec![ty_tp(Nat)]), nat_add); - let mut nat_mul = Self::methods("Mul", None, Self::TOP_LEVEL); + let mut nat_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); nat_mul.register_builtin_impl("__mul__", op_t, Const, Public); nat_mul.register_builtin_const("Output", ValueObj::builtin_t(Nat)); nat.register_trait(Nat, poly("Mul", vec![ty_tp(Nat)]), nat_mul); - let mut nat_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); + let mut nat_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); nat_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Nat!"))); nat.register_trait(Nat, builtin_mono("Mutizable"), nat_mutizable); nat.register_builtin_impl("Real", Nat, Const, Public); nat.register_builtin_impl("Imag", Nat, Const, Public); - let mut bool_ = Self::mono_class("Bool", None, Self::TOP_LEVEL); + let mut bool_ = Self::mono_class("Bool", None, None, Self::TOP_LEVEL); bool_.register_superclass(Nat, &nat); bool_.register_superclass(Int, &int); bool_.register_superclass(Float, &float); // TODO: Float -> Ratio @@ -576,7 +595,7 @@ impl Context { bool_.register_builtin_impl("__or__", fn1_met(Bool, Bool, Bool), Const, Public); bool_.register_marker_trait(builtin_mono("Num")); bool_.register_marker_trait(builtin_mono("Ord")); - let mut bool_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); + let mut bool_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); bool_partial_ord.register_builtin_impl( "__cmp__", fn1_met(Bool, Bool, builtin_mono("Ordering")), @@ -588,18 +607,18 @@ impl Context { poly("PartialOrd", vec![ty_tp(Bool)]), bool_partial_ord, ); - let mut bool_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut bool_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); bool_eq.register_builtin_impl("__eq__", fn1_met(Bool, Bool, Bool), Const, Public); bool_.register_trait(Bool, poly("Eq", vec![ty_tp(Bool)]), bool_eq); - let mut bool_add = Self::methods("Add", None, Self::TOP_LEVEL); + let mut bool_add = Self::methods("Add", None, None, Self::TOP_LEVEL); bool_add.register_builtin_impl("__add__", fn1_met(Bool, Bool, Int), Const, Public); bool_add.register_builtin_const("Output", ValueObj::builtin_t(Nat)); bool_.register_trait(Bool, poly("Add", vec![ty_tp(Bool)]), bool_add); - let mut bool_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); + let mut bool_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); bool_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Bool!"))); bool_.register_trait(Bool, builtin_mono("Mutizable"), bool_mutizable); - let mut str_ = Self::mono_class("Str", None, Self::TOP_LEVEL); + let mut str_ = Self::mono_class("Str", None, None, Self::TOP_LEVEL); str_.register_superclass(Obj, &obj); str_.register_marker_trait(builtin_mono("Ord")); str_.register_builtin_impl( @@ -626,48 +645,49 @@ impl Context { Immutable, Public, ); - let mut str_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut str_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); str_eq.register_builtin_impl("__eq__", fn1_met(Str, Str, Bool), Const, Public); str_.register_trait(Str, poly("Eq", vec![ty_tp(Str)]), str_eq); - let mut str_seq = Self::methods("Seq", None, Self::TOP_LEVEL); + let mut str_seq = Self::methods("Seq", None, None, Self::TOP_LEVEL); str_seq.register_builtin_impl("len", fn0_met(Str, Nat), Const, Public); str_seq.register_builtin_impl("get", fn1_met(Str, Nat, Str), Const, Public); str_.register_trait(Str, poly("Seq", vec![ty_tp(Str)]), str_seq); - let mut str_add = Self::methods("Add", None, Self::TOP_LEVEL); + let mut str_add = Self::methods("Add", None, None, Self::TOP_LEVEL); str_add.register_builtin_impl("__add__", fn1_met(Str, Str, Str), Const, Public); str_add.register_builtin_const("Output", ValueObj::builtin_t(Str)); str_.register_trait(Str, poly("Add", vec![ty_tp(Str)]), str_add); - let mut str_mul = Self::methods("Mul", None, Self::TOP_LEVEL); + let mut str_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); str_mul.register_builtin_impl("__mul__", fn1_met(Str, Nat, Str), Const, Public); str_mul.register_builtin_const("Output", ValueObj::builtin_t(Str)); str_.register_trait(Str, poly("Mul", vec![ty_tp(Nat)]), str_mul); - let mut str_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); + let mut str_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); str_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Str!"))); str_.register_trait(Str, builtin_mono("Mutizable"), str_mutizable); - let mut type_ = Self::mono_class("Type", None, Self::TOP_LEVEL); + let mut type_ = Self::mono_class("Type", None, None, Self::TOP_LEVEL); type_.register_superclass(Obj, &obj); type_.register_builtin_impl("mro", array(Type, TyParam::erased(Nat)), Immutable, Public); type_.register_marker_trait(builtin_mono("Named")); - let mut type_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut type_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); type_eq.register_builtin_impl("__eq__", fn1_met(Type, Type, Bool), Const, Public); type_.register_trait(Type, poly("Eq", vec![ty_tp(Type)]), type_eq); - let mut class_type = Self::mono_class("ClassType", None, Self::TOP_LEVEL); + let mut class_type = Self::mono_class("ClassType", None, None, Self::TOP_LEVEL); class_type.register_superclass(Type, &type_); class_type.register_superclass(Obj, &obj); class_type.register_marker_trait(builtin_mono("Named")); - let mut class_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut class_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); class_eq.register_builtin_impl("__eq__", fn1_met(Class, Class, Bool), Const, Public); class_type.register_trait(Class, poly("Eq", vec![ty_tp(Class)]), class_eq); - let mut module = Self::mono_class("Module", None, Self::TOP_LEVEL); + let mut module = Self::mono_class("Module", None, None, Self::TOP_LEVEL); module.register_superclass(Obj, &obj); module.register_marker_trait(builtin_mono("Named")); - let mut module_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut module_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); module_eq.register_builtin_impl("__eq__", fn1_met(Module, Module, Bool), Const, Public); module.register_trait(Module, poly("Eq", vec![ty_tp(Module)]), module_eq); let mut array_ = Self::poly_class( "Array", vec![PS::t_nd("T"), PS::named_nd("N", Nat)], None, + None, Self::TOP_LEVEL, ); array_.register_superclass(Obj, &obj); @@ -693,7 +713,7 @@ impl Context { )); // [T; N].MutType! = [T; !N] (neither [T!; N] nor [T; N]!) array_.register_builtin_const("MutType!", mut_type); - let mut array_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut array_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); array_eq.register_builtin_impl( "__eq__", fn1_met(array_t.clone(), array_t.clone(), Bool), @@ -704,9 +724,9 @@ impl Context { array_.register_marker_trait(builtin_mono("Mutizable")); array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))])); // TODO: make Tuple6, Tuple7, ... etc. - let mut tuple_ = Self::mono_class("Tuple", None, Self::TOP_LEVEL); + let mut tuple_ = Self::mono_class("Tuple", None, None, Self::TOP_LEVEL); tuple_.register_superclass(Obj, &obj); - let mut tuple_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple_eq.register_builtin_impl( "__eq__", fn1_met(builtin_mono("Tuple"), builtin_mono("Tuple"), Bool), @@ -718,10 +738,11 @@ impl Context { poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]), tuple_eq, ); - let mut tuple1 = Self::poly_class("Tuple1", vec![PS::t_nd("A")], None, Self::TOP_LEVEL); + let mut tuple1 = + Self::poly_class("Tuple1", vec![PS::t_nd("A")], None, None, Self::TOP_LEVEL); tuple1.register_superclass(builtin_mono("Tuple"), &tuple_); tuple1.register_superclass(Obj, &obj); - let mut tuple1_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple1_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple1_eq.register_builtin_impl( "__eq__", fn1_met( @@ -741,11 +762,12 @@ impl Context { "Tuple2", vec![PS::t_nd("A"), PS::t_nd("B")], None, + None, Self::TOP_LEVEL, ); tuple2.register_superclass(builtin_mono("Tuple"), &tuple_); tuple2.register_superclass(Obj, &obj); - let mut tuple2_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple2_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple2_eq.register_builtin_impl( "__eq__", fn1_met( @@ -771,11 +793,12 @@ impl Context { "Tuple3", vec![PS::t_nd("A"), PS::t_nd("B"), PS::t_nd("C")], None, + None, Self::TOP_LEVEL, ); tuple3.register_superclass(builtin_mono("Tuple"), &tuple_); tuple3.register_superclass(Obj, &obj); - let mut tuple3_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple3_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple3_eq.register_builtin_impl( "__eq__", fn1_met( @@ -810,11 +833,12 @@ impl Context { "Tuple4", vec![PS::t_nd("A"), PS::t_nd("B"), PS::t_nd("C"), PS::t_nd("D")], None, + None, Self::TOP_LEVEL, ); tuple4.register_superclass(builtin_mono("Tuple"), &tuple_); tuple4.register_superclass(Obj, &obj); - let mut tuple4_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple4_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple4_eq.register_builtin_impl( "__eq__", fn1_met( @@ -875,11 +899,12 @@ impl Context { PS::t_nd("E"), ], None, + None, Self::TOP_LEVEL, ); tuple5.register_superclass(builtin_mono("Tuple"), &tuple_); tuple5.register_superclass(Obj, &obj); - let mut tuple5_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple5_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple5_eq.register_builtin_impl( "__eq__", fn1_met( @@ -945,11 +970,12 @@ impl Context { PS::t_nd("F"), ], None, + None, Self::TOP_LEVEL, ); tuple6.register_superclass(builtin_mono("Tuple"), &tuple_); tuple6.register_superclass(Obj, &obj); - let mut tuple6_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple6_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple6_eq.register_builtin_impl( "__eq__", fn1_met( @@ -1020,11 +1046,12 @@ impl Context { PS::t_nd("G"), ], None, + None, Self::TOP_LEVEL, ); tuple7.register_superclass(builtin_mono("Tuple"), &tuple_); tuple7.register_superclass(Obj, &obj); - let mut tuple7_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple7_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple7_eq.register_builtin_impl( "__eq__", fn1_met( @@ -1100,11 +1127,12 @@ impl Context { PS::t_nd("H"), ], None, + None, Self::TOP_LEVEL, ); tuple8.register_superclass(builtin_mono("Tuple"), &tuple_); tuple8.register_superclass(Obj, &obj); - let mut tuple8_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut tuple8_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); tuple8_eq.register_builtin_impl( "__eq__", fn1_met( @@ -1171,16 +1199,16 @@ impl Context { ), tuple8_eq, ); - let mut record = Self::mono_class("Record", None, Self::TOP_LEVEL); + let mut record = Self::mono_class("Record", None, None, Self::TOP_LEVEL); record.register_superclass(Obj, &obj); - let mut record_type = Self::mono_class("RecordType", None, Self::TOP_LEVEL); + let mut record_type = Self::mono_class("RecordType", None, None, Self::TOP_LEVEL); record_type.register_superclass(builtin_mono("Record"), &record); record_type.register_superclass(builtin_mono("Type"), &type_); record_type.register_superclass(Obj, &obj); - let mut float_mut = Self::mono_class("Float!", None, Self::TOP_LEVEL); + let mut float_mut = Self::mono_class("Float!", None, None, Self::TOP_LEVEL); float_mut.register_superclass(Float, &float); float_mut.register_superclass(Obj, &obj); - let mut float_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); + let mut float_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); float_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Float)); let f_t = param_t("f", func(vec![param_t("old", Float)], None, vec![], Float)); let t = pr_met( @@ -1196,10 +1224,10 @@ impl Context { builtin_mono("Mutable"), float_mut_mutable, ); - let mut ratio_mut = Self::mono_class("Ratio!", None, Self::TOP_LEVEL); + let mut ratio_mut = Self::mono_class("Ratio!", None, None, Self::TOP_LEVEL); ratio_mut.register_superclass(Ratio, &ratio); ratio_mut.register_superclass(Obj, &obj); - let mut ratio_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); + let mut ratio_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); ratio_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Ratio)); let f_t = param_t( "f", @@ -1223,11 +1251,11 @@ impl Context { builtin_mono("Mutable"), ratio_mut_mutable, ); - let mut int_mut = Self::mono_class("Int!", None, Self::TOP_LEVEL); + let mut int_mut = Self::mono_class("Int!", None, None, Self::TOP_LEVEL); int_mut.register_superclass(Int, &int); int_mut.register_superclass(builtin_mono("Float!"), &float_mut); int_mut.register_superclass(Obj, &obj); - let mut int_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); + let mut int_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); int_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Int)); let f_t = param_t("f", func(vec![param_t("old", Int)], None, vec![], Int)); let t = pr_met( @@ -1243,12 +1271,12 @@ impl Context { builtin_mono("Mutable"), int_mut_mutable, ); - let mut nat_mut = Self::mono_class("Nat!", None, Self::TOP_LEVEL); + let mut nat_mut = Self::mono_class("Nat!", None, None, Self::TOP_LEVEL); nat_mut.register_superclass(Nat, &nat); nat_mut.register_superclass(builtin_mono("Int!"), &int_mut); nat_mut.register_superclass(builtin_mono("Float!"), &float_mut); nat_mut.register_superclass(Obj, &obj); - let mut nat_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); + let mut nat_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); nat_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Nat)); let f_t = param_t("f", func(vec![param_t("old", Nat)], None, vec![], Nat)); let t = pr_met( @@ -1264,13 +1292,13 @@ impl Context { builtin_mono("Mutable"), nat_mut_mutable, ); - let mut bool_mut = Self::mono_class("Bool!", None, Self::TOP_LEVEL); + let mut bool_mut = Self::mono_class("Bool!", None, None, Self::TOP_LEVEL); bool_mut.register_superclass(Bool, &bool_); bool_mut.register_superclass(builtin_mono("Nat!"), &nat_mut); bool_mut.register_superclass(builtin_mono("Int!"), &int_mut); bool_mut.register_superclass(builtin_mono("Float!"), &float_mut); bool_mut.register_superclass(Obj, &obj); - let mut bool_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); + let mut bool_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); bool_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Bool)); let f_t = param_t("f", func(vec![param_t("old", Bool)], None, vec![], Bool)); let t = pr_met( @@ -1286,10 +1314,10 @@ impl Context { builtin_mono("Mutable"), bool_mut_mutable, ); - let mut str_mut = Self::mono_class("Str!", None, Self::TOP_LEVEL); + let mut str_mut = Self::mono_class("Str!", None, None, Self::TOP_LEVEL); str_mut.register_superclass(Str, &str_); str_mut.register_superclass(Obj, &obj); - let mut str_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); + let mut str_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); str_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Str)); let f_t = param_t("f", func(vec![param_t("old", Str)], None, vec![], Str)); let t = pr_met( @@ -1311,6 +1339,7 @@ impl Context { "Array!", vec![PS::t_nd("T"), PS::named_nd("N", builtin_mono("Nat!"))], None, + None, Self::TOP_LEVEL, ); array_mut_.register_superclass(array_t.clone(), &array_); @@ -1364,7 +1393,7 @@ impl Context { vec![], NoneType, ); - let mut array_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); + let mut array_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); array_mut_mutable.register_builtin_impl("update!", t, Immutable, Public); array_mut_.register_trait( array_mut_t.clone(), @@ -1372,10 +1401,10 @@ impl Context { array_mut_mutable, ); let range_t = poly("Range", vec![TyParam::t(mono_q("T"))]); - let mut range = Self::poly_class("Range", vec![PS::t_nd("T")], None, Self::TOP_LEVEL); + let mut range = Self::poly_class("Range", vec![PS::t_nd("T")], None, None, Self::TOP_LEVEL); range.register_superclass(Obj, &obj); range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))])); - let mut range_eq = Self::methods("Eq", None, Self::TOP_LEVEL); + let mut range_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); range_eq.register_builtin_impl( "__eq__", fn1_met(range_t.clone(), range_t.clone(), Bool), @@ -1387,16 +1416,16 @@ impl Context { poly("Eq", vec![ty_tp(range_t.clone())]), range_eq, ); - let mut proc = Self::mono_class("Proc", None, Self::TOP_LEVEL); + let mut proc = Self::mono_class("Proc", None, None, Self::TOP_LEVEL); proc.register_superclass(Obj, &obj); // TODO: lambda proc.register_marker_trait(builtin_mono("Named")); - let mut func = Self::mono_class("Func", None, Self::TOP_LEVEL); + let mut func = Self::mono_class("Func", None, None, Self::TOP_LEVEL); func.register_superclass(builtin_mono("Proc"), &proc); func.register_superclass(Obj, &obj); // TODO: lambda func.register_marker_trait(builtin_mono("Named")); - let mut qfunc = Self::mono_class("QuantifiedFunc", None, Self::TOP_LEVEL); + let mut qfunc = Self::mono_class("QuantifiedFunc", None, None, Self::TOP_LEVEL); qfunc.register_superclass(builtin_mono("Func"), &func); qfunc.register_superclass(Obj, &obj); self.register_builtin_type(Obj, obj, Const); @@ -1780,6 +1809,7 @@ impl Context { params, // super: vec![Type::from(&m..=&n)], None, + None, Self::TOP_LEVEL, ); let op_t = fn1_met( @@ -1787,7 +1817,7 @@ impl Context { Type::from(&o..=&p), Type::from(m.clone() + o.clone()..=n.clone() + p.clone()), ); - let mut interval_add = Self::methods("Add", None, Self::TOP_LEVEL); + let mut interval_add = Self::methods("Add", None, None, Self::TOP_LEVEL); interval_add.register_builtin_impl("__add__", op_t, Const, Public); interval_add.register_builtin_const( "Output", @@ -1798,7 +1828,7 @@ impl Context { poly("Add", vec![TyParam::from(&o..=&p)]), interval_add, ); - let mut interval_sub = Self::methods("Sub", None, Self::TOP_LEVEL); + let mut interval_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL); let op_t = fn1_met( Type::from(&m..=&n), Type::from(&o..=&p), @@ -1823,7 +1853,7 @@ impl Context { pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) { // TODO: capacityを正確に把握する - let mut ctx = Context::module("".into(), None, 40); + let mut ctx = Context::module("".into(), None, None, 40); ctx.init_builtin_funcs(); ctx.init_builtin_const_funcs(); ctx.init_builtin_procs(); @@ -1834,13 +1864,18 @@ impl Context { mod_cache.register(VarName::from_static(""), None, ctx); } - pub fn new_module>(name: S, mod_cache: SharedModuleCache) -> Self { + pub fn new_module>( + name: S, + mod_cache: SharedModuleCache, + py_mod_cache: SharedModuleCache, + ) -> Self { Context::new( name.into(), ContextKind::Module, vec![], None, Some(mod_cache), + Some(py_mod_cache), Context::TOP_LEVEL, ) } diff --git a/compiler/erg_compiler/context/initialize/py_mods/importlib.rs b/compiler/erg_compiler/context/initialize/py_mods/importlib.rs index d4309d75..d84200ce 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/importlib.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/importlib.rs @@ -11,7 +11,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_importlib_mod() -> Self { - let mut importlib = Context::module("importlib".into(), None, 15); + let mut importlib = Context::module("importlib".into(), None, None, 15); importlib.register_builtin_impl("reload!", proc1(Module, NoneType), Immutable, Public); importlib } diff --git a/compiler/erg_compiler/context/initialize/py_mods/io.rs b/compiler/erg_compiler/context/initialize/py_mods/io.rs index ab6e2590..6823676c 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/io.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/io.rs @@ -12,8 +12,8 @@ use Visibility::*; impl Context { pub(crate) fn init_py_io_mod() -> Self { - let mut io = Context::module("io".into(), None, 15); - let mut string_io = Context::mono_class(Str::ever("StringIO!"), None, 0); + let mut io = Context::module("io".into(), None, None, 15); + let mut string_io = Context::mono_class(Str::ever("StringIO!"), None, None, 0); // FIXME: include Obj (pass main_ctx as a param) // string_io.register_superclass(Obj, obj); string_io.register_builtin_impl( diff --git a/compiler/erg_compiler/context/initialize/py_mods/math.rs b/compiler/erg_compiler/context/initialize/py_mods/math.rs index c909c79c..c285c4b8 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/math.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/math.rs @@ -11,7 +11,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_math_mod() -> Self { - let mut math = Context::module("math".into(), None, 10); + let mut math = Context::module("math".into(), None, None, 10); math.register_builtin_impl("pi", Float, Immutable, Public); math.register_builtin_impl("tau", Float, Immutable, Public); math.register_builtin_impl("e", Float, Immutable, Public); diff --git a/compiler/erg_compiler/context/initialize/py_mods/random.rs b/compiler/erg_compiler/context/initialize/py_mods/random.rs index 669b9123..47aee9d6 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/random.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/random.rs @@ -14,7 +14,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_random_mod() -> Self { - let mut random = Context::module("random".into(), None, 10); + let mut random = Context::module("random".into(), None, None, 10); random.register_builtin_impl( "seed!", proc( diff --git a/compiler/erg_compiler/context/initialize/py_mods/socket.rs b/compiler/erg_compiler/context/initialize/py_mods/socket.rs index 1ab33271..f483aece 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/socket.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/socket.rs @@ -12,8 +12,8 @@ use Visibility::*; impl Context { pub(crate) fn init_py_socket_mod() -> Self { - let mut socket = Context::module("socket".into(), None, 15); - let mut sock = Context::mono_class(Str::ever("Socket!"), None, 0); + let mut socket = Context::module("socket".into(), None, None, 15); + let mut sock = Context::mono_class(Str::ever("Socket!"), None, None, 0); // FIXME: include Obj (pass main_ctx as a param) // sock.register_superclass(Obj, obj); sock.register_builtin_impl( diff --git a/compiler/erg_compiler/context/initialize/py_mods/sys.rs b/compiler/erg_compiler/context/initialize/py_mods/sys.rs index 190704d5..fbb81c12 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/sys.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/sys.rs @@ -12,7 +12,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_sys_mod() -> Self { - let mut sys = Context::module("sys".into(), None, 15); + let mut sys = Context::module("sys".into(), None, None, 15); sys.register_builtin_impl("argv", array(Str, TyParam::erased(Nat)), Immutable, Public); sys.register_builtin_impl("byteorder", Str, Immutable, Public); sys.register_builtin_impl( diff --git a/compiler/erg_compiler/context/initialize/py_mods/time.rs b/compiler/erg_compiler/context/initialize/py_mods/time.rs index c4c374ae..fc542b79 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/time.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/time.rs @@ -11,7 +11,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_time_mod() -> Self { - let mut time = Context::module("time".into(), None, 15); + let mut time = Context::module("time".into(), None, None, 15); time.register_builtin_impl("sleep!", proc1(Float, NoneType), Immutable, Public); time.register_builtin_impl("time!", proc0(Float), Immutable, Public); time diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index fdf727ea..f2945add 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -2,7 +2,7 @@ use std::option::Option; // conflicting to Type::Option use erg_common::error::{ErrorCore, ErrorKind, Location}; -use erg_common::levenshtein::levenshtein; +use erg_common::levenshtein::get_similar_name; use erg_common::set::Set; use erg_common::traits::Locational; use erg_common::vis::{Field, Visibility}; @@ -897,33 +897,23 @@ impl Context { } } - pub(crate) fn get_similar_name(&self, name: &str) -> Option<&Str> { + pub(crate) fn get_similar_name(&self, name: &str) -> Option<&str> { let name = readable_name(name); - if name.len() <= 1 { - return None; - } - // TODO: add `.decls` - let most_similar_name = self - .params - .iter() - .filter_map(|(opt_name, _)| opt_name.as_ref()) - .chain(self.locals.keys()) - .min_by_key(|v| levenshtein(readable_name(v.inspect()), name))? - .inspect(); - let len = most_similar_name.len(); - if levenshtein(most_similar_name, name) >= len / 2 { - let outer = self.get_outer().or_else(|| self.get_builtins())?; - outer.get_similar_name(name) - } else { - Some(most_similar_name) - } + // TODO: add decls + get_similar_name( + self.params + .iter() + .filter_map(|(opt_name, _)| opt_name.as_ref().map(|n| &n.inspect()[..])) + .chain(self.locals.keys().map(|name| &name.inspect()[..])), + name, + ) } pub(crate) fn get_similar_attr_from_singular<'a>( &'a self, obj: &hir::Expr, name: &str, - ) -> Option<&'a Str> { + ) -> Option<&'a str> { if let Ok(ctx) = self.get_singular_ctx(obj, &self.name) { if let Some(name) = ctx.get_similar_name(name) { return Some(name); @@ -932,7 +922,7 @@ impl Context { None } - pub(crate) fn get_similar_attr<'a>(&'a self, self_t: &'a Type, name: &str) -> Option<&'a Str> { + pub(crate) fn get_similar_attr<'a>(&'a self, self_t: &'a Type, name: &str) -> Option<&'a str> { for (_, ctx) in self.get_nominal_super_type_ctxs(self_t)? { if let Some(name) = ctx.get_similar_name(name) { return Some(name); diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index 29694be1..e47b17e4 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -239,7 +239,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::Import | DefKind::PyImport => Self::Module, DefKind::Other => Self::Instant, } } @@ -272,6 +272,21 @@ pub enum RegistrationMode { Normal, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ImportKind { + ErgImport, + PyImport, +} + +impl ImportKind { + pub const fn is_erg_import(&self) -> bool { + matches!(self, Self::ErgImport) + } + pub const fn is_py_import(&self) -> bool { + matches!(self, Self::PyImport) + } +} + /// Represents the context of the current scope /// /// Recursive functions/methods are highlighted with the prefix `rec_`, as performance may be significantly degraded. @@ -326,6 +341,7 @@ pub struct Context { // but when used as a fallback to a type, values are traversed instead of accessing by keys pub(crate) patches: Dict, pub(crate) mod_cache: Option, + pub(crate) py_mod_cache: Option, pub(crate) level: usize, } @@ -338,6 +354,7 @@ impl Default for Context { vec![], None, None, + None, Self::TOP_LEVEL, ) } @@ -369,9 +386,10 @@ impl Context { params: Vec, outer: Option, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { - Self::with_capacity(name, kind, params, outer, 0, mod_cache, level) + Self::with_capacity(name, kind, params, outer, 0, mod_cache, py_mod_cache, level) } #[allow(clippy::too_many_arguments)] @@ -382,6 +400,7 @@ impl Context { outer: Option, capacity: usize, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { let mut params_ = Vec::new(); @@ -420,6 +439,7 @@ impl Context { mono_types: Dict::default(), poly_types: Dict::default(), mod_cache, + py_mod_cache, patches: Dict::default(), level, } @@ -431,9 +451,10 @@ impl Context { kind: ContextKind, outer: Option, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { - Self::with_capacity(name, kind, vec![], outer, 0, mod_cache, level) + Self::with_capacity(name, kind, vec![], outer, 0, mod_cache, py_mod_cache, level) } #[inline] @@ -443,53 +464,75 @@ impl Context { params: Vec, outer: Option, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { - Self::with_capacity(name, kind, params, outer, 0, mod_cache, level) + Self::with_capacity(name, kind, params, outer, 0, mod_cache, py_mod_cache, level) } pub fn poly_trait>( name: S, params: Vec, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { let name = name.into(); - Self::poly(name, ContextKind::Trait, params, None, mod_cache, level) + Self::poly( + name, + ContextKind::Trait, + params, + None, + mod_cache, + py_mod_cache, + level, + ) } pub fn poly_class>( name: S, params: Vec, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { let name = name.into(); - Self::poly(name, ContextKind::Class, params, None, mod_cache, level) + Self::poly( + name, + ContextKind::Class, + params, + None, + mod_cache, + py_mod_cache, + level, + ) } #[inline] pub fn mono_trait>( name: S, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { - Self::poly_trait(name, vec![], mod_cache, level) + Self::poly_trait(name, vec![], mod_cache, py_mod_cache, level) } #[inline] pub fn mono_class>( name: S, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { - Self::poly_class(name, vec![], mod_cache, level) + Self::poly_class(name, vec![], mod_cache, py_mod_cache, level) } #[inline] pub fn methods>( name: S, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { Self::with_capacity( @@ -499,6 +542,7 @@ impl Context { None, 2, mod_cache, + py_mod_cache, level, ) } @@ -508,6 +552,7 @@ impl Context { name: S, params: Vec, mod_cache: Option, + py_mod_cache: Option, level: usize, ) -> Self { Self::poly( @@ -516,12 +561,18 @@ impl Context { params, None, mod_cache, + py_mod_cache, level, ) } #[inline] - pub fn module(name: Str, mod_cache: Option, capacity: usize) -> Self { + pub fn module( + name: Str, + mod_cache: Option, + py_mod_cache: Option, + capacity: usize, + ) -> Self { Self::with_capacity( name, ContextKind::Module, @@ -529,6 +580,7 @@ impl Context { None, capacity, mod_cache, + py_mod_cache, Self::TOP_LEVEL, ) } @@ -538,6 +590,7 @@ impl Context { name: Str, capacity: usize, mod_cache: Option, + py_mod_cache: Option, outer: Context, ) -> Self { Self::with_capacity( @@ -547,6 +600,7 @@ impl Context { Some(outer), capacity, mod_cache, + py_mod_cache, Self::TOP_LEVEL, ) } @@ -597,6 +651,7 @@ impl Context { log!(info "{}: current namespace: {name}", fn_name!()); self.outer = Some(Box::new(mem::take(self))); self.mod_cache = self.get_outer().unwrap().mod_cache.clone(); + self.py_mod_cache = self.get_outer().unwrap().py_mod_cache.clone(); self.name = name.into(); self.kind = kind; Ok(()) diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index ccbde688..4beee1f9 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; // conflicting to Type::Option use erg_common::config::{ErgConfig, Input}; use erg_common::error::MultiErrorDisplay; +use erg_common::levenshtein::get_similar_name; use erg_common::traits::{Locational, Stream}; use erg_common::vis::Visibility; use erg_common::Str; @@ -29,6 +30,7 @@ use RegistrationMode::*; use Visibility::*; use super::instantiate::TyVarContext; +use super::ImportKind; impl Context { /// If it is a constant that is defined, there must be no variable of the same name defined across all scopes @@ -611,10 +613,18 @@ impl Context { TypeKind::Class => { if gen.t.is_monomorphic() { // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); - let mut ctx = - Self::mono_class(gen.t.name(), self.mod_cache.clone(), self.level); - let mut methods = - Self::methods(gen.t.name(), self.mod_cache.clone(), self.level); + let mut ctx = Self::mono_class( + gen.t.name(), + self.mod_cache.clone(), + self.py_mod_cache.clone(), + self.level, + ); + let mut methods = Self::methods( + gen.t.name(), + self.mod_cache.clone(), + self.py_mod_cache.clone(), + self.level, + ); let require = gen.require_or_sup.typ().clone(); let new_t = func1(require, gen.t.clone()); methods.register_fixed_auto_impl("__new__", new_t.clone(), Immutable, Private); @@ -631,14 +641,22 @@ impl Context { if gen.t.is_monomorphic() { let super_classes = vec![gen.require_or_sup.typ().clone()]; // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); - let mut ctx = - Self::mono_class(gen.t.name(), self.mod_cache.clone(), self.level); + let mut ctx = Self::mono_class( + gen.t.name(), + self.mod_cache.clone(), + self.py_mod_cache.clone(), + self.level, + ); for sup in super_classes.into_iter() { let (_, sup_ctx) = self.get_nominal_type_ctx(&sup).unwrap(); ctx.register_superclass(sup, sup_ctx); } - let mut methods = - Self::methods(gen.t.name(), self.mod_cache.clone(), self.level); + let mut methods = Self::methods( + gen.t.name(), + self.mod_cache.clone(), + self.py_mod_cache.clone(), + self.level, + ); if let Some(sup) = self.rec_get_const_obj(&gen.require_or_sup.typ().name()) { let sup = enum_unwrap!(sup, ValueObj::Type); let param_t = match sup { @@ -673,8 +691,12 @@ impl Context { } TypeKind::Trait => { if gen.t.is_monomorphic() { - let mut ctx = - Self::mono_trait(gen.t.name(), self.mod_cache.clone(), self.level); + let mut ctx = Self::mono_trait( + gen.t.name(), + self.mod_cache.clone(), + self.py_mod_cache.clone(), + self.level, + ); let require = enum_unwrap!(gen.require_or_sup.as_ref(), TypeObj::Builtin:(Type::Record:(_))); for (field, t) in require.iter() { let muty = if field.is_const() { @@ -695,8 +717,12 @@ impl Context { if gen.t.is_monomorphic() { let super_classes = vec![gen.require_or_sup.typ().clone()]; // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); - let mut ctx = - Self::mono_trait(gen.t.name(), self.mod_cache.clone(), self.level); + let mut ctx = Self::mono_trait( + gen.t.name(), + self.mod_cache.clone(), + self.py_mod_cache.clone(), + self.level, + ); let additional = gen.additional.as_ref().map(|additional| enum_unwrap!(additional.as_ref(), TypeObj::Builtin:(Type::Record:(_)))); if let Some(additional) = additional { for (field, t) in additional.iter() { @@ -764,6 +790,7 @@ impl Context { pub(crate) fn import_mod( &mut self, + kind: ImportKind, current_input: Input, var_name: &VarName, mod_name: &hir::Expr, @@ -771,61 +798,10 @@ 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_ref() { - match &__name__[..] { - "importlib" => { - mod_cache.register( - var_name.clone(), - None, - Self::init_py_importlib_mod(), - ); - } - "io" => { - mod_cache.register(var_name.clone(), None, Self::init_py_io_mod()); - } - "math" => { - mod_cache.register( - var_name.clone(), - None, - Self::init_py_math_mod(), - ); - } - "random" => { - mod_cache.register( - var_name.clone(), - None, - Self::init_py_random_mod(), - ); - } - "socket" => { - mod_cache.register( - var_name.clone(), - None, - Self::init_py_socket_mod(), - ); - } - "sys" => { - mod_cache.register(var_name.clone(), None, Self::init_py_sys_mod()); - } - "time" => { - mod_cache.register( - var_name.clone(), - None, - Self::init_py_time_mod(), - ); - } - _ => self.import_user_module( - current_input, - var_name, - __name__, - lit, - mod_cache, - )?, - } + if kind.is_erg_import() { + self.import_erg_mod(current_input, var_name, lit)?; } else { - // maybe unreachable - todo!("importing {__name__} in the builtin module") + self.import_py_mod(current_input, var_name, lit)?; } } else { return Err(TyCheckError::type_mismatch_error( @@ -852,14 +828,42 @@ impl Context { Ok(()) } - fn import_user_module( + fn import_erg_mod( + &mut self, + current_input: Input, + var_name: &VarName, + lit: &Literal, + ) -> TyCheckResult<()> { + let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); + let mod_cache = self.mod_cache.as_ref().unwrap(); + let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); + #[allow(clippy::match_single_binding)] + match &__name__[..] { + _ => self.import_user_erg_mod( + current_input, + var_name, + __name__, + lit, + mod_cache, + py_mod_cache, + )?, + } + Ok(()) + } + + fn import_user_erg_mod( &self, current_input: Input, var_name: &VarName, __name__: Str, name_lit: &Literal, mod_cache: &SharedModuleCache, + py_mod_cache: &SharedModuleCache, ) -> TyCheckResult<()> { + if let Some((_, entry)) = mod_cache.get_by_name(&__name__) { + mod_cache.register_alias(var_name.clone(), entry); + return Ok(()); + } let mut dir = if let Input::File(mut path) = current_input { path.pop(); path @@ -871,11 +875,18 @@ impl Context { let path = match dir.canonicalize() { Ok(path) => path, Err(err) => { - return Err(TyCheckError::file_error( + return Err(TyCheckError::import_error( line!() as usize, err.to_string(), name_lit.loc(), self.caused_by(), + self.mod_cache.as_ref().unwrap().get_similar_name(&__name__), + self.similar_builtin_py_mod_name(&__name__).or_else(|| { + self.py_mod_cache + .as_ref() + .unwrap() + .get_similar_name(&__name__) + }), )); } }; @@ -884,7 +895,12 @@ impl Context { ..ErgConfig::default() }; let src = cfg.input.read(); - let mut builder = HIRBuilder::new_with_cache(cfg, var_name.inspect(), mod_cache.clone()); + let mut builder = HIRBuilder::new_with_cache( + cfg, + var_name.inspect(), + mod_cache.clone(), + py_mod_cache.clone(), + ); match builder.build(src, "exec") { Ok(hir) => { mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); @@ -896,6 +912,60 @@ impl Context { Ok(()) } + fn import_py_mod( + &mut self, + current_input: Input, + var_name: &VarName, + lit: &Literal, + ) -> TyCheckResult<()> { + let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); + let mod_cache = self.mod_cache.as_ref().unwrap(); + match &__name__[..] { + "importlib" => { + mod_cache.register(var_name.clone(), None, Self::init_py_importlib_mod()); + } + "io" => { + mod_cache.register(var_name.clone(), None, Self::init_py_io_mod()); + } + "math" => { + mod_cache.register(var_name.clone(), None, Self::init_py_math_mod()); + } + "random" => { + mod_cache.register(var_name.clone(), None, Self::init_py_random_mod()); + } + "socket" => { + mod_cache.register(var_name.clone(), None, Self::init_py_socket_mod()); + } + "sys" => { + mod_cache.register(var_name.clone(), None, Self::init_py_sys_mod()); + } + "time" => { + mod_cache.register(var_name.clone(), None, Self::init_py_time_mod()); + } + _ => self.import_user_py_mod(current_input, var_name, lit)?, + } + Ok(()) + } + + fn similar_builtin_py_mod_name(&self, name: &Str) -> Option { + get_similar_name( + ["importlib", "io", "math", "random", "socket", "sys", "time"].into_iter(), + name, + ) + .map(Str::rc) + } + + fn import_user_py_mod( + &self, + _current_input: Input, + _var_name: &VarName, + lit: &Literal, + ) -> TyCheckResult<()> { + let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); + let _mod_cache = self.mod_cache.as_ref().unwrap(); + todo!() + } + 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/error.rs b/compiler/erg_compiler/error.rs index 02d903de..c8f8d7aa 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -416,7 +416,7 @@ impl TyCheckError { loc: Location, caused_by: AtomicStr, name: &str, - similar_name: Option<&Str>, + similar_name: Option<&str>, ) -> Self { let name = readable_name(name); let hint = similar_name.map(|n| { @@ -452,7 +452,7 @@ impl TyCheckError { caused_by: AtomicStr, obj_t: &Type, name: &str, - similar_name: Option<&Str>, + similar_name: Option<&str>, ) -> Self { let hint = similar_name.map(|n| { let n = readable_name(n); @@ -488,7 +488,7 @@ impl TyCheckError { obj_name: &str, obj_t: &Type, name: &str, - similar_name: Option<&Str>, + similar_name: Option<&str>, ) -> Self { let hint = similar_name.map(|n| { let n = readable_name(n); @@ -1298,8 +1298,34 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ) } - pub fn file_error(errno: usize, desc: String, loc: Location, caused_by: AtomicStr) -> Self { - Self::new(ErrorCore::new(errno, IoError, loc, desc, None), caused_by) + pub fn file_error( + errno: usize, + desc: String, + loc: Location, + caused_by: AtomicStr, + hint: Option, + ) -> Self { + Self::new(ErrorCore::new(errno, IoError, loc, desc, hint), caused_by) + } + + pub fn import_error( + errno: usize, + desc: String, + loc: Location, + caused_by: AtomicStr, + similar_erg_mod: Option, + similar_py_mod: Option, + ) -> Self { + let hint = match (similar_erg_mod, similar_py_mod) { + (Some(erg), Some(py)) => Some(format!( + "similar name erg module {YELLOW}{erg}{RESET} and python module {YELLOW}{py}{RESET} exists (to import python modules, use `pyimport`)", + )), + (Some(erg), None) => Some(format!("similar name erg module exists: {YELLOW}{erg}{RESET}")), + (None, Some(py)) => Some(format!("similar name python module exists: {YELLOW}{py}{RESET} (to import python modules, use `pyimport`)")), + (None, None) => None, + }; + let hint = hint.map(AtomicStr::from); + Self::file_error(errno, desc, loc, caused_by, hint) } pub fn inner_typedef_error(errno: usize, loc: Location, caused_by: AtomicStr) -> Self { diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index 29497f77..c065f2de 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -20,6 +20,7 @@ use erg_type::value::{TypeKind, ValueObj}; use erg_type::{impl_t, impl_t_for_enum, HasType, Type}; use crate::context::eval::type_from_token_kind; +use crate::context::ImportKind; use crate::error::readable_name; #[derive(Debug, Clone)] @@ -1006,11 +1007,12 @@ impl Call { } } - pub fn is_import_call(&self) -> bool { - self.obj - .show_acc() - .map(|s| &s[..] == "import" || &s[..] == "pyimport" || &s[..] == "py") - .unwrap_or(false) + pub fn import_kind(&self) -> Option { + self.obj.show_acc().and_then(|s| match &s[..] { + "import" => Some(ImportKind::ErgImport), + "pyimport" | "py" => Some(ImportKind::PyImport), + _ => None, + }) } } @@ -1332,7 +1334,7 @@ impl Def { DefKind::Other } } - Some("import") => DefKind::Module, + Some("import") => DefKind::Import, _ => DefKind::Other, }, _ => DefKind::Other, diff --git a/compiler/erg_compiler/link.rs b/compiler/erg_compiler/link.rs index 56b54c54..f1c00399 100644 --- a/compiler/erg_compiler/link.rs +++ b/compiler/erg_compiler/link.rs @@ -22,7 +22,7 @@ impl Linker { // ↓ // x = ModuleType("mod") // exec(code, x.__dict__) # `code` is the mod's content - Expr::Def(ref def) if def.def_kind().is_module() => { + Expr::Def(ref def) if def.def_kind().is_erg_import() => { // In the case of REPL, entries cannot be used up let hir = if cfg.input.is_repl() { mod_cache diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 35d3d949..f7e9be88 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -49,6 +49,7 @@ impl Default for ASTLowerer { ErgConfig::default(), Str::ever(""), SharedModuleCache::new(), + SharedModuleCache::new(), ) } } @@ -64,7 +65,12 @@ impl Runnable for ASTLowerer { } fn new(cfg: ErgConfig) -> Self { - Self::new_with_cache(cfg, Str::ever(""), SharedModuleCache::new()) + Self::new_with_cache( + cfg, + Str::ever(""), + SharedModuleCache::new(), + SharedModuleCache::new(), + ) } #[inline] @@ -87,7 +93,7 @@ impl Runnable for ASTLowerer { Ok(()) } - fn eval(&mut self, src: String) -> Result { + fn eval(&mut self, src: String) -> Result { let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let ast = ast_builder.build(src)?; let (hir, ..) = self.lower(ast, "eval").map_err(|errs| self.convert(errs))?; @@ -100,10 +106,11 @@ impl ASTLowerer { cfg: ErgConfig, mod_name: S, mod_cache: SharedModuleCache, + py_mod_cache: SharedModuleCache, ) -> Self { Self { cfg, - ctx: Context::new_module(mod_name, mod_cache), + ctx: Context::new_module(mod_name, mod_cache, py_mod_cache), errs: LowerErrors::empty(), warns: LowerWarnings::empty(), } @@ -611,9 +618,10 @@ impl ASTLowerer { .assign_var_sig(&sig, found_body_t, id)?; match block.first().unwrap() { hir::Expr::Call(call) => { - if call.is_import_call() { + if let Some(kind) = call.import_kind() { let current_input = self.input().clone(); self.ctx.outer.as_mut().unwrap().import_mod( + kind, current_input, &ident.name, &call.args.pos_args.first().unwrap().expr, diff --git a/compiler/erg_compiler/mod_cache.rs b/compiler/erg_compiler/mod_cache.rs index 33ed2a08..676bb6c5 100644 --- a/compiler/erg_compiler/mod_cache.rs +++ b/compiler/erg_compiler/mod_cache.rs @@ -4,7 +4,9 @@ use std::hash::Hash; use std::rc::Rc; use erg_common::dict::Dict; +use erg_common::levenshtein::get_similar_name; use erg_common::shared::Shared; +use erg_common::Str; use erg_parser::ast::VarName; @@ -26,7 +28,7 @@ impl ModId { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ModuleEntry { id: ModId, // builtin == 0, __main__ == 1 pub hir: Option, @@ -88,6 +90,12 @@ impl ModuleCache { self.cache.get(name) } + pub fn get_by_name(&self, __name__: &str) -> Option<(&VarName, &ModuleEntry)> { + self.cache + .iter() + .find(|(_, ent)| &ent.ctx.name[..] == __name__) + } + pub fn get_mut(&mut self, name: &Q) -> Option<&mut ModuleEntry> where VarName: Borrow, @@ -102,6 +110,10 @@ impl ModuleCache { self.cache.insert(name, entry); } + pub fn register_alias(&mut self, name: VarName, entry: &ModuleEntry) { + self.cache.insert(name, entry.clone()); + } + pub fn remove(&mut self, name: &Q) -> Option where VarName: Borrow, @@ -122,6 +134,10 @@ impl ModuleCache { None } } + + pub fn get_similar_name(&self, name: &str) -> Option { + get_similar_name(self.cache.iter().map(|(v, _)| &v.inspect()[..]), name).map(Str::rc) + } } #[derive(Debug, Clone, Default)] @@ -148,6 +164,11 @@ impl SharedModuleCache { ref_.get(name) } + pub fn get_by_name(&self, __name__: &str) -> Option<(&VarName, &ModuleEntry)> { + let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() }; + ref_.get_by_name(__name__) + } + pub fn get_mut(&self, name: &Q) -> Option<&mut ModuleEntry> where VarName: Borrow, @@ -175,6 +196,10 @@ impl SharedModuleCache { self.0.borrow_mut().register(name, hir, ctx); } + pub fn register_alias(&self, name: VarName, entry: &ModuleEntry) { + self.0.borrow_mut().register_alias(name, entry); + } + pub fn remove(&self, name: &Q) -> Option where VarName: Borrow, @@ -185,4 +210,8 @@ impl SharedModuleCache { pub fn remove_by_id(&self, id: ModId) -> Option { self.0.borrow_mut().remove_by_id(id) } + + pub fn get_similar_name(&self, name: &str) -> Option { + self.0.borrow().get_similar_name(name) + } } diff --git a/compiler/erg_compiler/tests/test.rs b/compiler/erg_compiler/tests/test.rs index a2522b49..d03f0f44 100644 --- a/compiler/erg_compiler/tests/test.rs +++ b/compiler/erg_compiler/tests/test.rs @@ -3,14 +3,22 @@ use erg_compiler::mod_cache::SharedModuleCache; #[test] fn test_subtyping() -> Result<(), ()> { - let context = Context::new_module("", SharedModuleCache::new()); + let context = Context::new_module( + "", + SharedModuleCache::new(), + SharedModuleCache::new(), + ); context.test_refinement_subtyping()?; Ok(()) } #[test] fn test_instantiation_and_generalization() -> Result<(), ()> { - let context = Context::new_module("", SharedModuleCache::new()); + let context = Context::new_module( + "", + SharedModuleCache::new(), + SharedModuleCache::new(), + ); context.test_instantiation_and_generalization()?; Ok(()) } @@ -33,7 +41,11 @@ fn test_resolve_trait_inner1() -> Result<(), ()> { #[test] fn test_dir() -> Result<(), ()> { - let context = Context::new_module("", SharedModuleCache::new()); + let context = Context::new_module( + "", + SharedModuleCache::new(), + SharedModuleCache::new(), + ); let vars = context.dir(); for (name, vi) in vars.into_iter() { println!("{name}: {vi}"); diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index 03898900..843c5603 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -2841,7 +2841,8 @@ pub enum DefKind { Trait, Subsume, StructuralTrait, - Module, + Import, + PyImport, /// type alias included Other, } @@ -2859,8 +2860,8 @@ impl DefKind { self.is_class() || self.is_trait() } - pub fn is_module(&self) -> bool { - matches!(self, Self::Module) + pub fn is_erg_import(&self) -> bool { + matches!(self, Self::Import) } } @@ -2877,6 +2878,32 @@ impl DefBody { pub const fn new(op: Token, block: Block, id: DefId) -> Self { Self { op, block, id } } + + pub fn def_kind(&self) -> DefKind { + match self.block.first().unwrap() { + Expr::Call(call) => match call.obj.get_name().map(|n| &n[..]) { + Some("Class") => DefKind::Class, + Some("Inherit") => DefKind::Inherit, + Some("Trait") => DefKind::Trait, + Some("Subsume") => DefKind::Subsume, + Some("Inheritable") => { + if let Some(Expr::Call(inner)) = call.args.get_left_or_key("Class") { + match inner.obj.get_name().map(|n| &n[..]) { + Some("Class") => DefKind::Class, + Some("Inherit") => DefKind::Inherit, + _ => DefKind::Other, + } + } else { + DefKind::Other + } + } + Some("import") => DefKind::Import, + Some("pyimport") | Some("py") => DefKind::PyImport, + _ => DefKind::Other, + }, + _ => DefKind::Other, + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -2910,28 +2937,7 @@ impl Def { } pub fn def_kind(&self) -> DefKind { - match self.body.block.first().unwrap() { - Expr::Call(call) => match call.obj.get_name().map(|n| &n[..]) { - Some("Class") => DefKind::Class, - Some("Inherit") => DefKind::Inherit, - Some("Trait") => DefKind::Trait, - Some("Subsume") => DefKind::Subsume, - Some("Inheritable") => { - if let Some(Expr::Call(inner)) = call.args.get_left_or_key("Class") { - match inner.obj.get_name().map(|n| &n[..]) { - Some("Class") => DefKind::Class, - Some("Inherit") => DefKind::Inherit, - _ => DefKind::Other, - } - } else { - DefKind::Other - } - } - Some("import") => DefKind::Module, - _ => DefKind::Other, - }, - _ => DefKind::Other, - } + self.body.def_kind() } } From aacad4fc8e9e1f7b37c78e3243618bffd2ea4d47 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 14:50:28 +0900 Subject: [PATCH 32/38] Fix type ascription bugs --- compiler/erg_compiler/codegen.rs | 5 +- compiler/erg_compiler/context/instantiate.rs | 4 +- compiler/erg_compiler/context/register.rs | 58 ++++++++++++++++++-- compiler/erg_compiler/effectcheck.rs | 7 +++ compiler/erg_compiler/hir.rs | 4 ++ compiler/erg_compiler/lower.rs | 6 +- compiler/erg_compiler/ownercheck.rs | 3 + 7 files changed, 79 insertions(+), 8 deletions(-) diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index 54211383..770c0ef3 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -1619,7 +1619,10 @@ impl CodeGenerator { Expr::Compound(chunks) => { self.emit_frameless_block(chunks, vec![]); } - // Dict, Decl + Expr::TypeAsc(tasc) => { + self.emit_expr(*tasc.expr); + } + // Dict, other => { self.errs.push(CompileError::feature_error( self.cfg.input.clone(), diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 20145775..09c1d9dd 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -529,8 +529,8 @@ impl Context { Ok(decl_t.typ().clone()) } else { let typ = mono(self.mod_name(), Str::rc(other)); - if self.get_nominal_type_ctx(&typ).is_some() { - Ok(typ) + if let Some((defined_t, _)) = self.get_nominal_type_ctx(&typ) { + Ok(defined_t.clone()) } else { Err(TyCheckError::no_var_error( line!() as usize, diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index 4beee1f9..909c01d4 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -839,6 +839,7 @@ impl Context { let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); #[allow(clippy::match_single_binding)] match &__name__[..] { + // TODO: erg builtin modules _ => self.import_user_erg_mod( current_input, var_name, @@ -957,13 +958,62 @@ impl Context { fn import_user_py_mod( &self, - _current_input: Input, - _var_name: &VarName, + current_input: Input, + var_name: &VarName, lit: &Literal, ) -> TyCheckResult<()> { let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); - let _mod_cache = self.mod_cache.as_ref().unwrap(); - todo!() + let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); + if let Some((_, entry)) = py_mod_cache.get_by_name(&__name__) { + py_mod_cache.register_alias(var_name.clone(), entry); + return Ok(()); + } + let mut dir = if let Input::File(mut path) = current_input { + path.pop(); + path + } else { + PathBuf::new() + }; + dir.push(format!("{__name__}.er")); + // TODO: returns an error + let path = match dir.canonicalize() { + Ok(path) => path, + Err(err) => { + return Err(TyCheckError::import_error( + line!() as usize, + err.to_string(), + lit.loc(), + self.caused_by(), + self.mod_cache.as_ref().unwrap().get_similar_name(&__name__), + self.similar_builtin_py_mod_name(&__name__).or_else(|| { + self.py_mod_cache + .as_ref() + .unwrap() + .get_similar_name(&__name__) + }), + )); + } + }; + let cfg = ErgConfig { + input: Input::File(path), + ..ErgConfig::default() + }; + let src = cfg.input.read(); + let mut builder = HIRBuilder::new_with_cache( + cfg, + var_name.inspect(), + py_mod_cache.clone(), + py_mod_cache.clone(), + ); + match builder.build(src, "declare") { + Ok(hir) => { + py_mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); + } + Err(errs) => { + errs.fmt_all_stderr(); + } + } + Ok(()) } pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) { diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index 1984044b..c7893655 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -137,6 +137,9 @@ impl SideEffectChecker { self.path_stack.pop(); self.block_stack.pop(); } + Expr::TypeAsc(tasc) => { + self.check_expr(&tasc.expr); + } other => todo!("{other}"), } } @@ -292,6 +295,9 @@ impl SideEffectChecker { self.path_stack.pop(); self.block_stack.pop(); } + Expr::TypeAsc(type_asc) => { + self.check_expr(&type_asc.expr); + } _ => {} } } @@ -306,6 +312,7 @@ impl SideEffectChecker { // !procedural: !x.y Expr::Accessor(Accessor::Attr(attr)) => attr.ident.is_procedural(), Expr::Accessor(_) => todo!(), + Expr::TypeAsc(tasc) => self.is_procedural(&tasc.expr), _ => false, } } diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index c065f2de..59cde0bc 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -1579,6 +1579,10 @@ impl Expr { _ => None, } } + + pub fn is_type_asc(&self) -> bool { + matches!(self, Expr::TypeAsc(_)) + } } /// Toplevel grammar unit diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index f7e9be88..5635e362 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -146,8 +146,12 @@ impl ASTLowerer { }) } + /// OK: exec `i: Int` + /// OK: exec `i: Int = 1` + /// NG: exec `1 + 2` + /// OK: exec `None` fn use_check(&self, expr: &hir::Expr, mode: &str) -> LowerResult<()> { - if mode != "eval" && !expr.ref_t().is_nonelike() { + if mode != "eval" && !expr.ref_t().is_nonelike() && !expr.is_type_asc() { Err(LowerError::syntax_error( 0, expr.loc(), diff --git a/compiler/erg_compiler/ownercheck.rs b/compiler/erg_compiler/ownercheck.rs index 774e85d7..6e516a32 100644 --- a/compiler/erg_compiler/ownercheck.rs +++ b/compiler/erg_compiler/ownercheck.rs @@ -187,6 +187,9 @@ impl OwnershipChecker { self.check_block(&lambda.body); self.path_stack.pop(); } + Expr::TypeAsc(asc) => { + self.check_expr(&asc.expr, ownership, chunk); + } _ => {} } } From 4d6c7f75902344bca7a4a4c002b26de5ed4a3d5a Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 21:49:33 +0900 Subject: [PATCH 33/38] Add `d.er` syntax --- compiler/erg_compiler/context/inquire.rs | 5 + compiler/erg_compiler/context/mod.rs | 2 +- compiler/erg_compiler/context/register.rs | 4 +- compiler/erg_compiler/error.rs | 18 +++ compiler/erg_compiler/hir.rs | 3 +- compiler/erg_compiler/link.rs | 60 +++++++++- compiler/erg_compiler/lower.rs | 128 ++++++++++++++++++++++ compiler/erg_parser/ast.rs | 22 +++- compiler/erg_parser/parse.rs | 61 ++++++++++- examples/declare.d.er | 2 + examples/declare.py | 2 + examples/use_py.er | 3 + 12 files changed, 295 insertions(+), 15 deletions(-) create mode 100644 examples/declare.d.er create mode 100644 examples/declare.py create mode 100644 examples/use_py.er diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index f2945add..b34f8c3e 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -1259,6 +1259,11 @@ impl Context { self.mod_cache .as_ref() .and_then(|cache| cache.ref_ctx(name)) + .or_else(|| { + self.py_mod_cache + .as_ref() + .and_then(|cache| cache.ref_ctx(name)) + }) } // rec_get_const_localとは違い、位置情報を持たないしエラーとならない diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index e47b17e4..3228b8e9 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -239,7 +239,7 @@ impl From for ContextKind { DefKind::Class | DefKind::Inherit => Self::Class, DefKind::Trait | DefKind::Subsume => Self::Trait, DefKind::StructuralTrait => Self::StructuralTrait, - DefKind::Import | DefKind::PyImport => Self::Module, + DefKind::ErgImport | DefKind::PyImport => Self::Module, DefKind::Other => Self::Instant, } } diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index 909c01d4..48f9f783 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -872,7 +872,6 @@ impl Context { PathBuf::new() }; dir.push(format!("{__name__}.er")); - // TODO: returns an error let path = match dir.canonicalize() { Ok(path) => path, Err(err) => { @@ -974,8 +973,7 @@ impl Context { } else { PathBuf::new() }; - dir.push(format!("{__name__}.er")); - // TODO: returns an error + dir.push(format!("{__name__}.d.er")); let path = match dir.canonicalize() { Ok(path) => path, Err(err) => { diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index c8f8d7aa..646e3a6b 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -1345,6 +1345,24 @@ passed keyword args: {RED}{kw_args_len}{RESET}" caused_by, ) } + + pub fn declare_error(errno: usize, loc: Location, caused_by: AtomicStr) -> Self { + Self::new( + ErrorCore::new( + errno, + SyntaxError, + loc, + switch_lang!( + "japanese" => format!("d.erファイル内では宣言、別名定義のみが許可されています"), + "simplified_chinese" => format!("在d.er文件中只允许声明和别名定义"), + "traditional_chinese" => format!("在d.er文件中只允許聲明和別名定義"), + "english" => format!("declarations and alias definitions are only allowed in d.er files"), + ), + None, + ), + caused_by, + ) + } } #[derive(Debug)] diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index 59cde0bc..f9e8e2e3 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -1334,7 +1334,8 @@ impl Def { DefKind::Other } } - Some("import") => DefKind::Import, + Some("import") => DefKind::ErgImport, + Some("pyimport") | Some("py") => DefKind::PyImport, _ => DefKind::Other, }, _ => DefKind::Other, diff --git a/compiler/erg_compiler/link.rs b/compiler/erg_compiler/link.rs index f1c00399..7a4d2d69 100644 --- a/compiler/erg_compiler/link.rs +++ b/compiler/erg_compiler/link.rs @@ -1,19 +1,26 @@ -use erg_common::config::ErgConfig; +use std::mem; +use std::path::PathBuf; + +use erg_common::config::{ErgConfig, Input}; use erg_common::traits::{Locational, Stream}; use erg_common::Str; use erg_common::{enum_unwrap, log}; use erg_parser::ast::DefId; -use erg_parser::token::Token; +use erg_parser::token::{Token, TokenKind}; +use erg_type::value::ValueObj; use erg_type::Type; -use crate::hir::{Accessor, Args, Block, Call, Def, DefBody, Expr, Identifier, PosArg, HIR}; +use crate::hir::{ + Accessor, Args, Block, Call, Def, DefBody, Expr, Identifier, Literal, PosArg, HIR, +}; use crate::mod_cache::SharedModuleCache; pub struct Linker {} impl Linker { + #[allow(deprecated)] pub fn link(cfg: ErgConfig, mut main: HIR, mod_cache: SharedModuleCache) -> HIR { log!(info "the linking process has started."); for chunk in main.module.iter_mut() { @@ -76,6 +83,53 @@ impl Linker { *chunk = Expr::Compound(compound); } } + // x = pyimport "x" (called from dir "a") + // ↓ + // x = __import__("a.x").x + Expr::Def(def) if def.def_kind().is_py_import() => { + let mut dir = if let Input::File(mut path) = cfg.input.clone() { + path.pop(); + path + } else { + PathBuf::new() + }; + let args = + &mut enum_unwrap!(def.body.block.first_mut().unwrap(), Expr::Call).args; + let mod_name_lit = + enum_unwrap!(args.remove_left_or_key("path").unwrap(), Expr::Lit); + let mod_name_str = enum_unwrap!(mod_name_lit.value.clone(), ValueObj::Str); + let mod_name_str = if let Some(stripped) = mod_name_str.strip_prefix("./") { + stripped + } else { + &mod_name_str + }; + dir.push(mod_name_str); + let mut comps = dir.components(); + let _first = comps.next().unwrap(); + let path = dir.to_string_lossy().replace('/', ".").replace('\\', "."); + let token = Token::new( + TokenKind::StrLit, + path, + mod_name_lit.ln_begin().unwrap(), + mod_name_lit.col_begin().unwrap(), + ); + let mod_name = Expr::Lit(Literal::from(token)); + args.insert_pos(0, PosArg::new(mod_name)); + let expr = def.body.block.first_mut().unwrap(); + let line = expr.ln_begin().unwrap_or(0); + for attr in comps { + *expr = Expr::Accessor(Accessor::attr( + // instead of mem::take(), + mem::replace(expr, Expr::Code(Block::empty())), + Identifier::public_with_line( + Token::dummy(), + Str::rc(attr.as_os_str().to_str().unwrap()), + line, + ), + Type::Uninited, + )); + } + } _ => {} } } diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 5635e362..d5cde8c7 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -1037,10 +1037,138 @@ impl ASTLowerer { Ok(hir::Block::new(hir_block)) } + fn declare_var_alias( + &mut self, + sig: ast::VarSignature, + mut body: ast::DefBody, + ) -> LowerResult { + log!(info "entered {}({sig})", fn_name!()); + if body.block.len() > 1 { + return Err(LowerError::declare_error( + line!() as usize, + body.block.loc(), + self.ctx.caused_by(), + )); + } + let block = hir::Block::new(vec![self.declare_chunk(body.block.remove(0))?]); + let found_body_t = block.ref_t(); + let ident = match &sig.pat { + ast::VarPattern::Ident(ident) => ident, + _ => unreachable!(), + }; + let id = body.id; + self.ctx.assign_var_sig(&sig, found_body_t, id)?; + let ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone()); + let sig = hir::VarSignature::new(ident, found_body_t.clone()); + let body = hir::DefBody::new(body.op, block, body.id); + Ok(hir::Def::new(hir::Signature::Var(sig), body)) + } + + fn declare_alias(&mut self, def: ast::Def) -> LowerResult { + log!(info "entered {}({})", fn_name!(), def.sig); + let name = if let Some(name) = def.sig.name_as_str() { + name.clone() + } else { + Str::ever("") + }; + if self + .ctx + .registered_info(&name, def.sig.is_const()) + .is_some() + { + return Err(LowerError::reassign_error( + line!() as usize, + def.sig.loc(), + self.ctx.caused_by(), + &name, + )); + } + let res = match def.sig { + ast::Signature::Subr(_sig) => todo!(), + ast::Signature::Var(sig) => self.declare_var_alias(sig, def.body), + }; + self.pop_append_errs(); + res + } + + fn declare_type(&mut self, tasc: ast::TypeAscription) -> LowerResult { + log!(info "entered {}({})", fn_name!(), tasc); + match *tasc.expr { + ast::Expr::Accessor(ast::Accessor::Ident(ident)) => { + let t = self.ctx.instantiate_typespec( + &tasc.t_spec, + None, + &mut None, + RegistrationMode::Normal, + )?; + self.ctx.assign_var_sig( + &ast::VarSignature::new(ast::VarPattern::Ident(ident.clone()), None), + &t, + ast::DefId(0), + )?; + let ident = hir::Identifier::new(ident.dot, ident.name, None, t); + Ok(hir::TypeAscription::new( + hir::Expr::Accessor(hir::Accessor::Ident(ident)), + tasc.t_spec, + )) + } + other => Err(LowerError::declare_error( + line!() as usize, + other.loc(), + self.ctx.caused_by(), + )), + } + } + + fn declare_chunk(&mut self, expr: ast::Expr) -> LowerResult { + log!(info "entered {}", fn_name!()); + match expr { + ast::Expr::Def(def) => Ok(hir::Expr::Def(self.declare_alias(def)?)), + ast::Expr::ClassDef(defs) => Err(LowerError::feature_error( + line!() as usize, + defs.loc(), + "class declaration", + self.ctx.caused_by(), + )), + ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.declare_type(tasc)?)), + other => Err(LowerError::declare_error( + line!() as usize, + other.loc(), + self.ctx.caused_by(), + )), + } + } + + fn declare_module(&mut self, ast: AST) -> HIR { + let mut module = hir::Module::with_capacity(ast.module.len()); + for chunk in ast.module.into_iter() { + match self.declare_chunk(chunk) { + Ok(chunk) => { + module.push(chunk); + } + Err(e) => { + self.errs.push(e); + } + } + } + HIR::new(ast.name, module) + } + pub fn lower(&mut self, ast: AST, mode: &str) -> Result<(HIR, LowerWarnings), LowerErrors> { log!(info "the AST lowering process has started."); log!(info "the type-checking process has started."); let ast = Reorderer::new().reorder(ast)?; + if mode == "declare" { + let hir = self.declare_module(ast); + if self.errs.is_empty() { + log!(info "HIR:\n{hir}"); + log!(info "the declaring process has completed."); + return Ok((hir, LowerWarnings::from(self.warns.take_all()))); + } else { + log!(err "the declaring process has failed."); + return Err(LowerErrors::from(self.errs.take_all())); + } + } let mut module = hir::Module::with_capacity(ast.module.len()); self.ctx.preregister(ast.module.block())?; for chunk in ast.module.into_iter() { diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index 843c5603..4c215b1a 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -1511,6 +1511,7 @@ impl ParamTySpec { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct SubrTypeSpec { + pub bounds: TypeBoundSpecs, pub lparen: Option, pub non_defaults: Vec, pub var_args: Option>, @@ -1521,9 +1522,12 @@ pub struct SubrTypeSpec { impl fmt::Display for SubrTypeSpec { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if !self.bounds.is_empty() { + write!(f, "|{}|", self.bounds)?; + } write!( f, - "({}, {}, := {}) {} {}", + "({}, {}, {}) {} {}", fmt_vec(&self.non_defaults), fmt_option!(pre "...", &self.var_args), fmt_vec(&self.defaults), @@ -1535,7 +1539,9 @@ impl fmt::Display for SubrTypeSpec { impl Locational for SubrTypeSpec { fn loc(&self) -> Location { - if let Some(lparen) = &self.lparen { + if !self.bounds.is_empty() { + Location::concat(&self.bounds[0], self.return_t.as_ref()) + } else if let Some(lparen) = &self.lparen { Location::concat(lparen, self.return_t.as_ref()) } else { // FIXME: only default subrs @@ -1546,6 +1552,7 @@ impl Locational for SubrTypeSpec { impl SubrTypeSpec { pub fn new( + bounds: TypeBoundSpecs, lparen: Option, non_defaults: Vec, var_args: Option, @@ -1554,6 +1561,7 @@ impl SubrTypeSpec { return_t: TypeSpec, ) -> Self { Self { + bounds, lparen, non_defaults, var_args: var_args.map(Box::new), @@ -2841,7 +2849,7 @@ pub enum DefKind { Trait, Subsume, StructuralTrait, - Import, + ErgImport, PyImport, /// type alias included Other, @@ -2861,7 +2869,11 @@ impl DefKind { } pub fn is_erg_import(&self) -> bool { - matches!(self, Self::Import) + matches!(self, Self::ErgImport) + } + + pub fn is_py_import(&self) -> bool { + matches!(self, Self::PyImport) } } @@ -2897,7 +2909,7 @@ impl DefBody { DefKind::Other } } - Some("import") => DefKind::Import, + Some("import") => DefKind::ErgImport, Some("pyimport") | Some("py") => DefKind::PyImport, _ => DefKind::Other, }, diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index b006a9da..821b9704 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -2524,9 +2524,66 @@ impl Parser { todo!() } - fn convert_lambda_to_subr_type_spec(&mut self, _lambda: Lambda) -> ParseResult { + fn convert_lambda_to_subr_type_spec( + &mut self, + mut lambda: Lambda, + ) -> ParseResult { debug_call_info!(self); - todo!() + let bounds = lambda.sig.bounds; + let lparen = lambda.sig.params.parens.map(|(l, _)| l); + let mut non_defaults = vec![]; + for param in lambda.sig.params.non_defaults.into_iter() { + let param = match (param.pat, param.t_spec) { + (ParamPattern::VarName(name), Some(t_spec_with_op)) => { + ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec) + } + (ParamPattern::VarName(name), None) => ParamTySpec::anonymous(TypeSpec::PreDeclTy( + PreDeclTypeSpec::Simple(SimpleTypeSpec::new(name, ConstArgs::empty())), + )), + _ => todo!(), + }; + non_defaults.push(param); + } + let var_args = + lambda + .sig + .params + .var_args + .map(|var_args| match (var_args.pat, var_args.t_spec) { + (ParamPattern::VarName(name), Some(t_spec_with_op)) => { + ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec) + } + (ParamPattern::VarName(name), None) => { + ParamTySpec::anonymous(TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple( + SimpleTypeSpec::new(name, ConstArgs::empty()), + ))) + } + _ => todo!(), + }); + let mut defaults = vec![]; + for param in lambda.sig.params.defaults.into_iter() { + let param = match (param.pat, param.t_spec) { + (ParamPattern::VarName(name), Some(t_spec_with_op)) => { + ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec) + } + (ParamPattern::VarName(name), None) => ParamTySpec::anonymous(TypeSpec::PreDeclTy( + PreDeclTypeSpec::Simple(SimpleTypeSpec::new(name, ConstArgs::empty())), + )), + _ => todo!(), + }; + defaults.push(param); + } + let return_t = self.convert_rhs_to_type_spec(lambda.body.remove(0))?; + self.level -= 1; + Ok(SubrTypeSpec::new( + bounds, + lparen, + non_defaults, + var_args, + defaults, + lambda.op, + return_t, + )) } fn convert_array_to_array_type_spec(&mut self, _array: Array) -> ParseResult { diff --git a/examples/declare.d.er b/examples/declare.d.er new file mode 100644 index 00000000..85011cc0 --- /dev/null +++ b/examples/declare.d.er @@ -0,0 +1,2 @@ +.x: Int +.f: Int -> Int diff --git a/examples/declare.py b/examples/declare.py new file mode 100644 index 00000000..a3c9e641 --- /dev/null +++ b/examples/declare.py @@ -0,0 +1,2 @@ +x = 0 +def f(x: int) -> int: return x + 1 diff --git a/examples/use_py.er b/examples/use_py.er new file mode 100644 index 00000000..7d21cc90 --- /dev/null +++ b/examples/use_py.er @@ -0,0 +1,3 @@ +declare = pyimport "declare" + +print! declare.f(declare.x + 1) From 733e758398498eb25e495ea147fe7b15667bc8d8 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 26 Sep 2022 21:51:15 +0900 Subject: [PATCH 34/38] Update version (v0.5.4) --- Cargo.lock | 10 +++++----- Cargo.toml | 10 +++++----- compiler/erg_common/Cargo.toml | 2 +- compiler/erg_compiler/Cargo.toml | 8 ++++---- compiler/erg_parser/Cargo.toml | 4 ++-- compiler/erg_type/Cargo.toml | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4e255e2..2737bdf1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "erg" -version = "0.5.4-nightly.1" +version = "0.5.4" dependencies = [ "erg_common", "erg_compiler", @@ -25,14 +25,14 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.5.4-nightly.1" +version = "0.5.4" dependencies = [ "atty", ] [[package]] name = "erg_compiler" -version = "0.5.4-nightly.1" +version = "0.5.4" dependencies = [ "erg_common", "erg_parser", @@ -41,14 +41,14 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.5.4-nightly.1" +version = "0.5.4" dependencies = [ "erg_common", ] [[package]] name = "erg_type" -version = "0.5.4-nightly.1" +version = "0.5.4" dependencies = [ "erg_common", "erg_parser", diff --git a/Cargo.toml b/Cargo.toml index 144fd519..7df6de73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg" -version = "0.5.4-nightly.1" +version = "0.5.4" description = "The Erg programming language" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -46,10 +46,10 @@ traditional_chinese = [ ] [dependencies] -erg_common = { version = "0.5.4-nightly.1", path = "./compiler/erg_common" } -erg_parser = { version = "0.5.4-nightly.1", path = "./compiler/erg_parser" } -erg_compiler = { version = "0.5.4-nightly.1", path = "./compiler/erg_compiler" } -erg_type = { version = "0.5.4-nightly.1", path = "./compiler/erg_type" } +erg_common = { version = "0.5.4", path = "./compiler/erg_common" } +erg_parser = { version = "0.5.4", path = "./compiler/erg_parser" } +erg_compiler = { version = "0.5.4", path = "./compiler/erg_compiler" } +erg_type = { version = "0.5.4", path = "./compiler/erg_type" } # [workspace] # member = ["cm", "dyne"] diff --git a/compiler/erg_common/Cargo.toml b/compiler/erg_common/Cargo.toml index 24fa1757..51a8acd4 100644 --- a/compiler/erg_common/Cargo.toml +++ b/compiler/erg_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_common" -version = "0.5.4-nightly.1" +version = "0.5.4" description = "A common components library of Erg" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" diff --git a/compiler/erg_compiler/Cargo.toml b/compiler/erg_compiler/Cargo.toml index cec49a60..77998b4e 100644 --- a/compiler/erg_compiler/Cargo.toml +++ b/compiler/erg_compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_compiler" -version = "0.5.4-nightly.1" +version = "0.5.4" description = "Centimetre: the Erg compiler" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -17,9 +17,9 @@ simplified_chinese = [ "erg_common/simplified_chinese", "erg_parser/simplified_c traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditional_chinese", "erg_type/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4-nightly.1", path = "../erg_common" } -erg_parser = { version = "0.5.4-nightly.1", path = "../erg_parser" } -erg_type = { version = "0.5.4-nightly.1", path = "../erg_type" } +erg_common = { version = "0.5.4", path = "../erg_common" } +erg_parser = { version = "0.5.4", path = "../erg_parser" } +erg_type = { version = "0.5.4", path = "../erg_type" } [lib] path = "lib.rs" diff --git a/compiler/erg_parser/Cargo.toml b/compiler/erg_parser/Cargo.toml index 20151dd0..fd5617f9 100644 --- a/compiler/erg_parser/Cargo.toml +++ b/compiler/erg_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_parser" -version = "0.5.4-nightly.1" +version = "0.5.4" description = "The Erg parser" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4-nightly.1", path = "../erg_common" } +erg_common = { version = "0.5.4", path = "../erg_common" } [lib] path = "lib.rs" diff --git a/compiler/erg_type/Cargo.toml b/compiler/erg_type/Cargo.toml index a75baedf..05f13acc 100644 --- a/compiler/erg_type/Cargo.toml +++ b/compiler/erg_type/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_type" -version = "0.5.4-nightly.1" +version = "0.5.4" description = "APIs for Erg types" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -18,8 +18,8 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4-nightly.1", path = "../erg_common" } -erg_parser = { version = "0.5.4-nightly.1", path = "../erg_parser" } +erg_common = { version = "0.5.4", path = "../erg_common" } +erg_parser = { version = "0.5.4", path = "../erg_parser" } [lib] path = "lib.rs" From 0a731bfd93de394763df13abb02341f054ac6c16 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Tue, 27 Sep 2022 09:43:27 +0900 Subject: [PATCH 35/38] Add ErgConfig::with_path --- compiler/erg_common/config.rs | 8 ++++++++ compiler/erg_compiler/context/register.rs | 10 ++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/compiler/erg_common/config.rs b/compiler/erg_common/config.rs index fc1b65a6..02f7b5af 100644 --- a/compiler/erg_common/config.rs +++ b/compiler/erg_common/config.rs @@ -173,6 +173,14 @@ impl Default for ErgConfig { } impl ErgConfig { + pub fn with_path(path: PathBuf) -> Self { + Self { + module: Box::leak(path.to_str().unwrap().to_string().into_boxed_str()), + input: Input::File(path), + ..ErgConfig::default() + } + } + /// cloneのエイリアス(実際のcloneコストは低いので) #[inline] pub fn copy(&self) -> Self { diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index 48f9f783..a772ba7f 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -890,10 +890,7 @@ impl Context { )); } }; - let cfg = ErgConfig { - input: Input::File(path), - ..ErgConfig::default() - }; + let cfg = ErgConfig::with_path(path); let src = cfg.input.read(); let mut builder = HIRBuilder::new_with_cache( cfg, @@ -992,10 +989,7 @@ impl Context { )); } }; - let cfg = ErgConfig { - input: Input::File(path), - ..ErgConfig::default() - }; + let cfg = ErgConfig::with_path(path); let src = cfg.input.read(); let mut builder = HIRBuilder::new_with_cache( cfg, From f983db15066cfd93b8405f087450e02a00a5bac9 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Tue, 27 Sep 2022 09:43:57 +0900 Subject: [PATCH 36/38] Update version (nightly) --- Cargo.lock | 10 +++++----- Cargo.toml | 10 +++++----- compiler/erg_common/Cargo.toml | 2 +- compiler/erg_compiler/Cargo.toml | 8 ++++---- compiler/erg_parser/Cargo.toml | 4 ++-- compiler/erg_type/Cargo.toml | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2737bdf1..6adb64fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "erg" -version = "0.5.4" +version = "0.5.5-nightly.0" dependencies = [ "erg_common", "erg_compiler", @@ -25,14 +25,14 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.5.4" +version = "0.5.5-nightly.0" dependencies = [ "atty", ] [[package]] name = "erg_compiler" -version = "0.5.4" +version = "0.5.5-nightly.0" dependencies = [ "erg_common", "erg_parser", @@ -41,14 +41,14 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.5.4" +version = "0.5.5-nightly.0" dependencies = [ "erg_common", ] [[package]] name = "erg_type" -version = "0.5.4" +version = "0.5.5-nightly.0" dependencies = [ "erg_common", "erg_parser", diff --git a/Cargo.toml b/Cargo.toml index 7df6de73..5853e05a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg" -version = "0.5.4" +version = "0.5.5-nightly.0" description = "The Erg programming language" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -46,10 +46,10 @@ traditional_chinese = [ ] [dependencies] -erg_common = { version = "0.5.4", path = "./compiler/erg_common" } -erg_parser = { version = "0.5.4", path = "./compiler/erg_parser" } -erg_compiler = { version = "0.5.4", path = "./compiler/erg_compiler" } -erg_type = { version = "0.5.4", path = "./compiler/erg_type" } +erg_common = { version = "0.5.5-nightly.0", path = "./compiler/erg_common" } +erg_parser = { version = "0.5.5-nightly.0", path = "./compiler/erg_parser" } +erg_compiler = { version = "0.5.5-nightly.0", path = "./compiler/erg_compiler" } +erg_type = { version = "0.5.5-nightly.0", path = "./compiler/erg_type" } # [workspace] # member = ["cm", "dyne"] diff --git a/compiler/erg_common/Cargo.toml b/compiler/erg_common/Cargo.toml index 51a8acd4..fb3240ca 100644 --- a/compiler/erg_common/Cargo.toml +++ b/compiler/erg_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_common" -version = "0.5.4" +version = "0.5.5-nightly.0" description = "A common components library of Erg" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" diff --git a/compiler/erg_compiler/Cargo.toml b/compiler/erg_compiler/Cargo.toml index 77998b4e..cb5fcb27 100644 --- a/compiler/erg_compiler/Cargo.toml +++ b/compiler/erg_compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_compiler" -version = "0.5.4" +version = "0.5.5-nightly.0" description = "Centimetre: the Erg compiler" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -17,9 +17,9 @@ simplified_chinese = [ "erg_common/simplified_chinese", "erg_parser/simplified_c traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditional_chinese", "erg_type/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4", path = "../erg_common" } -erg_parser = { version = "0.5.4", path = "../erg_parser" } -erg_type = { version = "0.5.4", path = "../erg_type" } +erg_common = { version = "0.5.5-nightly.0", path = "../erg_common" } +erg_parser = { version = "0.5.5-nightly.0", path = "../erg_parser" } +erg_type = { version = "0.5.5-nightly.0", path = "../erg_type" } [lib] path = "lib.rs" diff --git a/compiler/erg_parser/Cargo.toml b/compiler/erg_parser/Cargo.toml index fd5617f9..2da1c44e 100644 --- a/compiler/erg_parser/Cargo.toml +++ b/compiler/erg_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_parser" -version = "0.5.4" +version = "0.5.5-nightly.0" description = "The Erg parser" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4", path = "../erg_common" } +erg_common = { version = "0.5.5-nightly.0", path = "../erg_common" } [lib] path = "lib.rs" diff --git a/compiler/erg_type/Cargo.toml b/compiler/erg_type/Cargo.toml index 05f13acc..4bedd78e 100644 --- a/compiler/erg_type/Cargo.toml +++ b/compiler/erg_type/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_type" -version = "0.5.4" +version = "0.5.5-nightly.0" description = "APIs for Erg types" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -18,8 +18,8 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.4", path = "../erg_common" } -erg_parser = { version = "0.5.4", path = "../erg_parser" } +erg_common = { version = "0.5.5-nightly.0", path = "../erg_common" } +erg_parser = { version = "0.5.5-nightly.0", path = "../erg_parser" } [lib] path = "lib.rs" From 3fd8b177d249eee6299f5b30984433c9995b7e70 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Tue, 27 Sep 2022 10:02:33 +0900 Subject: [PATCH 37/38] Update config.rs --- compiler/erg_common/config.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/compiler/erg_common/config.rs b/compiler/erg_common/config.rs index 02f7b5af..5c254174 100644 --- a/compiler/erg_common/config.rs +++ b/compiler/erg_common/config.rs @@ -148,14 +148,6 @@ pub struct ErgConfig { impl Default for ErgConfig { #[inline] fn default() -> Self { - let is_stdin_piped: bool = atty::isnt(atty::Stream::Stdin); - let input = if is_stdin_piped { - let mut buffer = String::new(); - stdin().read_to_string(&mut buffer).unwrap(); - Input::Pipe(buffer) - } else { - Input::REPL - }; Self { mode: "exec", opt_level: 1, @@ -163,7 +155,7 @@ impl Default for ErgConfig { python_ver: None, py_server_timeout: 10, quiet_startup: false, - input, + input: Input::REPL, module: "", verbose: 2, ps1: ">>> ", @@ -261,6 +253,17 @@ impl ErgConfig { } } } + if cfg.input == Input::REPL { + let is_stdin_piped = atty::isnt(atty::Stream::Stdin); + let input = if is_stdin_piped { + let mut buffer = String::new(); + stdin().read_to_string(&mut buffer).unwrap(); + Input::Pipe(buffer) + } else { + Input::REPL + }; + cfg.input = input; + } cfg } } From 1c7ec91a0285ac59bb8f40f04a6fb27261573e52 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Tue, 27 Sep 2022 10:04:14 +0900 Subject: [PATCH 38/38] Update version (nightly) --- Cargo.lock | 10 +++++----- Cargo.toml | 10 +++++----- compiler/erg_common/Cargo.toml | 2 +- compiler/erg_compiler/Cargo.toml | 8 ++++---- compiler/erg_parser/Cargo.toml | 4 ++-- compiler/erg_type/Cargo.toml | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6adb64fd..fe8c8609 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "erg" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" dependencies = [ "erg_common", "erg_compiler", @@ -25,14 +25,14 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" dependencies = [ "atty", ] [[package]] name = "erg_compiler" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" dependencies = [ "erg_common", "erg_parser", @@ -41,14 +41,14 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" dependencies = [ "erg_common", ] [[package]] name = "erg_type" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" dependencies = [ "erg_common", "erg_parser", diff --git a/Cargo.toml b/Cargo.toml index 5853e05a..80759fa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" description = "The Erg programming language" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -46,10 +46,10 @@ traditional_chinese = [ ] [dependencies] -erg_common = { version = "0.5.5-nightly.0", path = "./compiler/erg_common" } -erg_parser = { version = "0.5.5-nightly.0", path = "./compiler/erg_parser" } -erg_compiler = { version = "0.5.5-nightly.0", path = "./compiler/erg_compiler" } -erg_type = { version = "0.5.5-nightly.0", path = "./compiler/erg_type" } +erg_common = { version = "0.5.5-nightly.1", path = "./compiler/erg_common" } +erg_parser = { version = "0.5.5-nightly.1", path = "./compiler/erg_parser" } +erg_compiler = { version = "0.5.5-nightly.1", path = "./compiler/erg_compiler" } +erg_type = { version = "0.5.5-nightly.1", path = "./compiler/erg_type" } # [workspace] # member = ["cm", "dyne"] diff --git a/compiler/erg_common/Cargo.toml b/compiler/erg_common/Cargo.toml index fb3240ca..6ba2d60f 100644 --- a/compiler/erg_common/Cargo.toml +++ b/compiler/erg_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_common" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" description = "A common components library of Erg" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" diff --git a/compiler/erg_compiler/Cargo.toml b/compiler/erg_compiler/Cargo.toml index cb5fcb27..2f994ce6 100644 --- a/compiler/erg_compiler/Cargo.toml +++ b/compiler/erg_compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_compiler" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" description = "Centimetre: the Erg compiler" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -17,9 +17,9 @@ simplified_chinese = [ "erg_common/simplified_chinese", "erg_parser/simplified_c traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditional_chinese", "erg_type/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.5-nightly.0", path = "../erg_common" } -erg_parser = { version = "0.5.5-nightly.0", path = "../erg_parser" } -erg_type = { version = "0.5.5-nightly.0", path = "../erg_type" } +erg_common = { version = "0.5.5-nightly.1", path = "../erg_common" } +erg_parser = { version = "0.5.5-nightly.1", path = "../erg_parser" } +erg_type = { version = "0.5.5-nightly.1", path = "../erg_type" } [lib] path = "lib.rs" diff --git a/compiler/erg_parser/Cargo.toml b/compiler/erg_parser/Cargo.toml index 2da1c44e..454b381b 100644 --- a/compiler/erg_parser/Cargo.toml +++ b/compiler/erg_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_parser" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" description = "The Erg parser" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -16,7 +16,7 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.5-nightly.0", path = "../erg_common" } +erg_common = { version = "0.5.5-nightly.1", path = "../erg_common" } [lib] path = "lib.rs" diff --git a/compiler/erg_type/Cargo.toml b/compiler/erg_type/Cargo.toml index 4bedd78e..9f0c065f 100644 --- a/compiler/erg_type/Cargo.toml +++ b/compiler/erg_type/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "erg_type" -version = "0.5.5-nightly.0" +version = "0.5.5-nightly.1" description = "APIs for Erg types" authors = ["erg-lang team "] license = "MIT OR Apache-2.0" @@ -18,8 +18,8 @@ simplified_chinese = [ "erg_common/simplified_chinese" ] traditional_chinese = [ "erg_common/traditional_chinese" ] [dependencies] -erg_common = { version = "0.5.5-nightly.0", path = "../erg_common" } -erg_parser = { version = "0.5.5-nightly.0", path = "../erg_parser" } +erg_common = { version = "0.5.5-nightly.1", path = "../erg_common" } +erg_parser = { version = "0.5.5-nightly.1", path = "../erg_parser" } [lib] path = "lib.rs"