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() } }