From 23a6f630c99ad4d529d16f6c528785787d06a7ff Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Thu, 29 Sep 2022 11:48:38 +0900 Subject: [PATCH] Fix `import` to be called from anywhere --- compiler/erg_common/config.rs | 21 +- compiler/erg_compiler/context/compare.rs | 21 +- compiler/erg_compiler/context/eval.rs | 24 +- .../context/initialize/const_func.rs | 19 +- .../erg_compiler/context/initialize/mod.rs | 315 ++++++++++-------- .../context/initialize/py_mods/importlib.rs | 9 +- .../context/initialize/py_mods/random.rs | 7 +- compiler/erg_compiler/context/inquire.rs | 271 ++++++++++----- compiler/erg_compiler/context/instantiate.rs | 42 ++- compiler/erg_compiler/context/mod.rs | 19 +- compiler/erg_compiler/context/register.rs | 166 ++++----- compiler/erg_compiler/context/test.rs | 6 +- compiler/erg_compiler/context/tyvar.rs | 230 ++++++++++--- compiler/erg_compiler/hir.rs | 4 + compiler/erg_compiler/link.rs | 14 +- compiler/erg_compiler/lower.rs | 77 ++--- compiler/erg_compiler/mod_cache.rs | 88 ++--- compiler/erg_parser/parse.rs | 23 +- compiler/erg_type/constructors.rs | 55 ++- compiler/erg_type/lib.rs | 113 +++++-- compiler/erg_type/value.rs | 4 +- 21 files changed, 979 insertions(+), 549 deletions(-) diff --git a/compiler/erg_common/config.rs b/compiler/erg_common/config.rs index 5c254174..500764ee 100644 --- a/compiler/erg_common/config.rs +++ b/compiler/erg_common/config.rs @@ -4,7 +4,7 @@ use std::env; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process; use std::str::FromStr; @@ -35,7 +35,7 @@ impl Input { pub fn enclosed_name(&self) -> &str { match self { - Self::File(filename) => filename.as_os_str().to_str().unwrap_or("???"), + Self::File(filename) => filename.to_str().unwrap_or("???"), Self::REPL | Self::Pipe(_) => "", Self::Str(_) => "", Self::Dummy => "", @@ -45,7 +45,7 @@ impl Input { /// ファイルに書き出すとき使う pub fn filename(&self) -> &str { match self { - Self::File(filename) => filename.as_os_str().to_str().unwrap_or("???"), + Self::File(filename) => filename.to_str().unwrap_or("???"), Self::REPL | Self::Pipe(_) => "stdin", Self::Str(_) => "string", Self::Dummy => "dummy", @@ -116,6 +116,21 @@ impl Input { Self::Dummy => panic!("cannot read from a dummy file"), } } + + pub fn resolve(&self, path: &Path) -> Result { + let mut dir = if let Self::File(mut path) = self.clone() { + path.pop(); + path + } else { + PathBuf::new() + }; + dir.push(path); + dir.set_extension("er"); + dir.canonicalize().or_else(|_| { + dir.set_extension("d.er"); + dir.canonicalize() + }) + } } #[derive(Debug, Clone)] diff --git a/compiler/erg_compiler/context/compare.rs b/compiler/erg_compiler/context/compare.rs index 9956e0b3..693b6a19 100644 --- a/compiler/erg_compiler/context/compare.rs +++ b/compiler/erg_compiler/context/compare.rs @@ -594,11 +594,11 @@ impl Context { (Ref(l), r) => self.supertype_of(l, r), (RefMut { before: l, .. }, r) => self.supertype_of(l, r), ( - Poly { + BuiltinPoly { name: ln, params: lparams, }, - Poly { + BuiltinPoly { name: rn, params: rparams, }, @@ -608,6 +608,23 @@ impl Context { } self.poly_supertype_of(lhs, lparams, rparams) } + ( + Poly { + path: lp, + name: ln, + params: lparams, + }, + Poly { + path: rp, + name: rn, + params: rparams, + }, + ) => { + if lp != rp || ln != rn || lparams.len() != rparams.len() { + return false; + } + self.poly_supertype_of(lhs, lparams, rparams) + } (MonoQVar(name), r) | (PolyQVar { name, .. }, r) => { panic!("internal error: not instantiated type variable: '{name}, r: {r}") } diff --git a/compiler/erg_compiler/context/eval.rs b/compiler/erg_compiler/context/eval.rs index 73818358..9bcb9b04 100644 --- a/compiler/erg_compiler/context/eval.rs +++ b/compiler/erg_compiler/context/eval.rs @@ -14,7 +14,7 @@ use erg_parser::ast::*; use erg_parser::token::{Token, TokenKind}; use erg_type::constructors::{ - builtin_mono, enum_t, mono_proj, poly, ref_, ref_mut, refinement, subr_t, + builtin_mono, builtin_poly, mono_proj, poly, ref_, ref_mut, refinement, subr_t, v_enum, }; use erg_type::typaram::{OpKind, TyParam}; use erg_type::value::ValueObj; @@ -305,7 +305,7 @@ impl Context { match subr { ConstSubr::User(_user) => todo!(), ConstSubr::Builtin(builtin) => builtin - .call(args, self.mod_name().clone(), __name__) + .call(args, self.path().to_path_buf(), __name__) .map_err(|mut e| { e.loc = loc; EvalErrors::from(EvalError::new(e, self.cfg.input.clone(), self.caused_by())) @@ -445,7 +445,7 @@ impl Context { non_default_params.clone(), var_params.clone(), default_params.clone(), - enum_t(set![return_t.clone()]), + v_enum(set![return_t.clone()]), ); let sig_t = self.generalize_t(sig_t); let as_type = subr_t( @@ -791,11 +791,21 @@ impl Context { }; Ok(ref_mut(before, after)) } - Type::Poly { name, mut params } => { + Type::BuiltinPoly { name, mut params } => { for p in params.iter_mut() { *p = self.eval_tp(&mem::take(p))?; } - Ok(poly(name, params)) + Ok(builtin_poly(name, params)) + } + Type::Poly { + path, + name, + mut params, + } => { + for p in params.iter_mut() { + *p = self.eval_tp(&mem::take(p))?; + } + Ok(poly(path, name, params)) } other if other.is_monomorphic() => Ok(other), other => todo!("{other}"), @@ -839,7 +849,7 @@ impl Context { let p = self.eval_tp(p)?; match p { TyParam::Value(ValueObj::Mut(v)) => Ok(v.borrow().class().mutate()), - TyParam::Value(v) => Ok(enum_t(set![v])), + TyParam::Value(v) => Ok(v_enum(set![v])), TyParam::Erased(t) => Ok((*t).clone()), TyParam::FreeVar(fv) => { if let Some(t) = fv.get_type() { @@ -852,7 +862,7 @@ impl Context { TyParam::Type(_) => Ok(Type::Type), TyParam::Mono(name) => self .rec_get_const_obj(&name) - .map(|v| enum_t(set![v.clone()])) + .map(|v| v_enum(set![v.clone()])) .ok_or_else(|| { EvalErrors::from(EvalError::unreachable( self.cfg.input.clone(), diff --git a/compiler/erg_compiler/context/initialize/const_func.rs b/compiler/erg_compiler/context/initialize/const_func.rs index aa5aed54..35efb3ad 100644 --- a/compiler/erg_compiler/context/initialize/const_func.rs +++ b/compiler/erg_compiler/context/initialize/const_func.rs @@ -1,4 +1,5 @@ use std::mem; +use std::path::PathBuf; use erg_common::Str; @@ -12,7 +13,7 @@ use erg_type::ValueArgs; /// Requirement: Type, Impl := Type -> ClassType pub fn class_func( mut args: ValueArgs, - mod_name: Str, + path: PathBuf, __name__: Option, ) -> EvalValueResult { let require = args.remove_left_or_key("Requirement").ok_or_else(|| { @@ -39,14 +40,14 @@ pub fn class_func( }; 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(""))); + let t = mono(path, __name__.unwrap_or(Str::ever(""))); Ok(ValueObj::gen_t(TypeKind::Class, t, require, impls, None)) } /// Super: ClassType, Impl := Type, Additional := Type -> ClassType pub fn inherit_func( mut args: ValueArgs, - mod_name: Str, + path: PathBuf, __name__: Option, ) -> EvalValueResult { let sup = args.remove_left_or_key("Super").ok_or_else(|| { @@ -75,7 +76,7 @@ pub fn inherit_func( let impls = impls.map(|v| v.as_type().unwrap()); let additional = args.remove_left_or_key("Additional"); let additional = additional.map(|v| v.as_type().unwrap()); - let t = mono(mod_name, __name__.unwrap_or(Str::ever(""))); + let t = mono(path, __name__.unwrap_or(Str::ever(""))); Ok(ValueObj::gen_t( TypeKind::Subclass, t, @@ -89,7 +90,7 @@ pub fn inherit_func( /// This function is used by the compiler to mark a class as inheritable and does nothing in terms of actual operation. pub fn inheritable_func( mut args: ValueArgs, - _mod_name: Str, + _path: PathBuf, __name__: Option, ) -> EvalValueResult { let class = args.remove_left_or_key("Class").ok_or_else(|| { @@ -124,7 +125,7 @@ pub fn inheritable_func( /// Requirement: Type, Impl := Type -> TraitType pub fn trait_func( mut args: ValueArgs, - mod_name: Str, + path: PathBuf, __name__: Option, ) -> EvalValueResult { let require = args.remove_left_or_key("Requirement").ok_or_else(|| { @@ -151,14 +152,14 @@ pub fn trait_func( }; 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(""))); + let t = mono(path, __name__.unwrap_or(Str::ever(""))); Ok(ValueObj::gen_t(TypeKind::Trait, t, require, impls, None)) } /// Super: TraitType, Impl := Type, Additional := Type -> TraitType pub fn subsume_func( mut args: ValueArgs, - mod_name: Str, + path: PathBuf, __name__: Option, ) -> EvalValueResult { let sup = args.remove_left_or_key("Super").ok_or_else(|| { @@ -187,7 +188,7 @@ pub fn subsume_func( let impls = impls.map(|v| v.as_type().unwrap()); let additional = args.remove_left_or_key("Additional"); let additional = additional.map(|v| v.as_type().unwrap()); - let t = mono(mod_name, __name__.unwrap_or(Str::ever(""))); + let t = mono(path, __name__.unwrap_or(Str::ever(""))); Ok(ValueObj::gen_t( TypeKind::Subtrait, t, diff --git a/compiler/erg_compiler/context/initialize/mod.rs b/compiler/erg_compiler/context/initialize/mod.rs index f39fcf25..8aed6b91 100644 --- a/compiler/erg_compiler/context/initialize/mod.rs +++ b/compiler/erg_compiler/context/initialize/mod.rs @@ -4,6 +4,8 @@ pub mod const_func; pub mod py_mods; +use std::path::PathBuf; + use erg_common::config::ErgConfig; use erg_common::error::Location; use erg_common::vis::Visibility; @@ -61,7 +63,7 @@ impl Context { panic!("already registered: {name}"); } else { // TODO: not all value objects are comparable - let vi = VarInfo::new(enum_t(set! {obj.clone()}), Const, Private, Builtin, None); + let vi = VarInfo::new(v_enum(set! {obj.clone()}), Const, Private, Builtin, None); self.consts.insert(VarName::from_str(Str::rc(name)), obj); self.locals.insert(VarName::from_str(Str::rc(name)), vi); } @@ -206,31 +208,31 @@ impl Context { let params = vec![PS::t("T", NonDefault)]; let input = Self::builtin_poly_trait("Input", params.clone(), 2); let output = Self::builtin_poly_trait("Output", params, 2); - in_.register_superclass(poly("Input", vec![ty_tp(mono_q("T"))]), &input); + in_.register_superclass(builtin_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( op_t, - set! { static_instance("T", Type), subtypeof(mono_q("I"), poly("In", vec![ty_tp(mono_q("T"))])) }, + set! { static_instance("T", Type), subtypeof(mono_q("I"), builtin_poly("In", vec![ty_tp(mono_q("T"))])) }, ); in_.register_builtin_decl("__in__", op_t, Public); // 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::builtin_poly_trait("Eq", vec![PS::t("R", WithDefault)], 2); - eq.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); + eq.register_superclass(builtin_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); let op_t = quant( op_t, set! { - subtypeof(mono_q("Self"), poly("Eq", vec![ty_tp(mono_q("R"))])), + subtypeof(mono_q("Self"), builtin_poly("Eq", vec![ty_tp(mono_q("R"))])), static_instance("R", Type) }, ); eq.register_builtin_decl("__eq__", op_t, Public); let mut partial_ord = Self::builtin_poly_trait("PartialOrd", vec![PS::t("R", WithDefault)], 2); - partial_ord.register_superclass(poly("Eq", vec![ty_tp(mono_q("R"))]), &eq); + partial_ord.register_superclass(builtin_poly("Eq", vec![ty_tp(mono_q("R"))]), &eq); let op_t = fn1_met( mono_q("Self"), mono_q("R"), @@ -239,15 +241,15 @@ impl Context { let op_t = quant( op_t, set! { - subtypeof(mono_q("Self"), poly("PartialOrd", vec![ty_tp(mono_q("R"))])), + subtypeof(mono_q("Self"), builtin_poly("PartialOrd", vec![ty_tp(mono_q("R"))])), static_instance("R", Type) }, ); partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public); let mut ord = Self::builtin_mono_trait("Ord", 2); - ord.register_superclass(poly("Eq", vec![ty_tp(builtin_mono("Self"))]), &eq); + ord.register_superclass(builtin_poly("Eq", vec![ty_tp(builtin_mono("Self"))]), &eq); ord.register_superclass( - poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]), + builtin_poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]), &partial_ord, ); // FIXME: poly trait @@ -258,18 +260,18 @@ impl Context { poly("Mul", vec![]), ], */ let mut seq = Self::builtin_poly_trait("Seq", vec![PS::t("T", NonDefault)], 2); - seq.register_superclass(poly("Output", vec![ty_tp(mono_q("T"))]), &output); + seq.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("T"))]), &output); let self_t = mono_q("Self"); let t = fn0_met(self_t.clone(), Nat); let t = quant( t, - set! {subtypeof(self_t.clone(), poly("Seq", vec![TyParam::erased(Type)]))}, + set! {subtypeof(self_t.clone(), builtin_poly("Seq", vec![TyParam::erased(Type)]))}, ); seq.register_builtin_decl("len", t, Public); let t = fn1_met(self_t.clone(), Nat, mono_q("T")); let t = quant( t, - set! {subtypeof(self_t, poly("Seq", vec![ty_tp(mono_q("T"))])), static_instance("T", Type)}, + set! {subtypeof(self_t, builtin_poly("Seq", vec![ty_tp(mono_q("T"))])), static_instance("T", Type)}, ); // Seq.get: |Self <: Seq(T)| Self.(Nat) -> T seq.register_builtin_decl("get", t, Public); @@ -279,8 +281,8 @@ impl Context { let ty_params = vec![ty_tp(mono_q("R"))]; let mut add = Self::builtin_poly_trait("Add", params.clone(), 2); // 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())); + add.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output); + let self_bound = subtypeof(mono_q("Self"), builtin_poly("Add", ty_params.clone())); let op_t = fn1_met( mono_q("Self"), r.clone(), @@ -290,31 +292,31 @@ impl Context { add.register_builtin_decl("__add__", op_t, Public); add.register_builtin_decl("Output", Type, Public); let mut sub = Self::builtin_poly_trait("Sub", params.clone(), 2); - sub.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); + sub.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output); let op_t = fn1_met( mono_q("Self"), r.clone(), mono_proj(mono_q("Self"), "Output"), ); - let self_bound = subtypeof(mono_q("Self"), poly("Sub", ty_params.clone())); + let self_bound = subtypeof(mono_q("Self"), builtin_poly("Sub", ty_params.clone())); 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::builtin_poly_trait("Mul", params.clone(), 2); - mul.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); + mul.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output); let op_t = fn1_met( mono_q("Self"), r.clone(), mono_proj(mono_q("Self"), "Output"), ); - let self_bound = subtypeof(mono_q("Self"), poly("Mul", ty_params.clone())); + let self_bound = subtypeof(mono_q("Self"), builtin_poly("Mul", ty_params.clone())); 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::builtin_poly_trait("Div", params, 2); - div.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); + div.register_superclass(builtin_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())); + let self_bound = subtypeof(mono_q("Self"), builtin_poly("Div", ty_params.clone())); let op_t = quant(op_t, set! {r_bound, self_bound}); div.register_builtin_decl("__div__", op_t, Public); div.register_builtin_decl("Output", Type, Public); @@ -324,22 +326,30 @@ impl Context { self.register_builtin_type(builtin_mono("Mutable"), mutable, Const); self.register_builtin_type(builtin_mono("Immutizable"), immutizable, Const); self.register_builtin_type(builtin_mono("Mutizable"), mutizable, Const); - self.register_builtin_type(poly("Input", vec![ty_tp(mono_q("T"))]), input, Const); - self.register_builtin_type(poly("Output", vec![ty_tp(mono_q("T"))]), output, Const); - self.register_builtin_type(poly("In", vec![ty_tp(mono_q("T"))]), in_, Const); - self.register_builtin_type(poly("Eq", vec![ty_tp(mono_q("R"))]), eq, Const); self.register_builtin_type( - poly("PartialOrd", vec![ty_tp(mono_q("R"))]), + builtin_poly("Input", vec![ty_tp(mono_q("T"))]), + input, + Const, + ); + self.register_builtin_type( + builtin_poly("Output", vec![ty_tp(mono_q("T"))]), + output, + Const, + ); + self.register_builtin_type(builtin_poly("In", vec![ty_tp(mono_q("T"))]), in_, Const); + self.register_builtin_type(builtin_poly("Eq", vec![ty_tp(mono_q("R"))]), eq, Const); + self.register_builtin_type( + builtin_poly("PartialOrd", vec![ty_tp(mono_q("R"))]), partial_ord, Const, ); self.register_builtin_type(builtin_mono("Ord"), ord, Const); self.register_builtin_type(builtin_mono("Num"), num, Const); - self.register_builtin_type(poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Const); - self.register_builtin_type(poly("Add", ty_params.clone()), add, Const); - self.register_builtin_type(poly("Sub", ty_params.clone()), sub, Const); - self.register_builtin_type(poly("Mul", ty_params.clone()), mul, Const); - self.register_builtin_type(poly("Div", ty_params), div, Const); + self.register_builtin_type(builtin_poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Const); + self.register_builtin_type(builtin_poly("Add", ty_params.clone()), add, Const); + self.register_builtin_type(builtin_poly("Sub", ty_params.clone()), sub, Const); + self.register_builtin_type(builtin_poly("Mul", ty_params.clone()), mul, Const); + self.register_builtin_type(builtin_poly("Div", ty_params), div, Const); self.register_const_param_defaults( "Eq", vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))], @@ -384,7 +394,7 @@ impl Context { ); let mut obj_in = Self::builtin_methods("In", 2); 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); + obj.register_trait(Obj, builtin_poly("Eq", vec![ty_tp(Type)]), obj_in); let mut obj_mutizable = Self::builtin_methods("Mutizable", 1); obj_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Obj!"))); obj.register_trait(Obj, builtin_mono("Mutizable"), obj_mutizable); @@ -405,7 +415,7 @@ impl Context { ); float.register_trait( Float, - poly("PartialOrd", vec![ty_tp(Float)]), + builtin_poly("PartialOrd", vec![ty_tp(Float)]), float_partial_ord, ); // Float doesn't have an `Eq` implementation @@ -413,21 +423,21 @@ impl Context { let mut float_add = Self::builtin_methods("Add", 2); 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); + float.register_trait(Float, builtin_poly("Add", vec![ty_tp(Float)]), float_add); let mut float_sub = Self::builtin_methods("Sub", 2); 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); + float.register_trait(Float, builtin_poly("Sub", vec![ty_tp(Float)]), float_sub); let mut float_mul = Self::builtin_methods("Mul", 2); 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); + float.register_trait(Float, builtin_poly("Mul", vec![ty_tp(Float)]), float_mul); let mut float_div = Self::builtin_methods("Div", 2); 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); + float.register_trait(Float, builtin_poly("Div", vec![ty_tp(Float)]), float_div); let mut float_mutizable = Self::builtin_methods("Mutizable", 2); float_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Float!"))); @@ -448,31 +458,31 @@ impl Context { ); ratio.register_trait( Ratio, - poly("PartialOrd", vec![ty_tp(Ratio)]), + builtin_poly("PartialOrd", vec![ty_tp(Ratio)]), ratio_partial_ord, ); let mut ratio_eq = Self::builtin_methods("Eq", 2); 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); + ratio.register_trait(Ratio, builtin_poly("Eq", vec![ty_tp(Ratio)]), ratio_eq); let op_t = fn1_met(Ratio, Ratio, Ratio); let mut ratio_add = Self::builtin_methods("Add", 2); 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); + ratio.register_trait(Ratio, builtin_poly("Add", vec![ty_tp(Ratio)]), ratio_add); let mut ratio_sub = Self::builtin_methods("Sub", 2); 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); + ratio.register_trait(Ratio, builtin_poly("Sub", vec![ty_tp(Ratio)]), ratio_sub); let mut ratio_mul = Self::builtin_methods("Mul", 2); 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); + ratio.register_trait(Ratio, builtin_poly("Mul", vec![ty_tp(Ratio)]), ratio_mul); let mut ratio_div = Self::builtin_methods("Div", 2); 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); + ratio.register_trait(Ratio, builtin_poly("Div", vec![ty_tp(Ratio)]), ratio_div); let mut ratio_mutizable = Self::builtin_methods("Mutizable", 2); ratio_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Ratio!"))); @@ -482,7 +492,7 @@ impl Context { int.register_superclass(Obj, &obj); int.register_marker_trait(builtin_mono("Num")); int.register_marker_trait(builtin_mono("Ord")); - int.register_marker_trait(poly("Eq", vec![ty_tp(Int)])); + int.register_marker_trait(builtin_poly("Eq", vec![ty_tp(Int)])); // class("Rational"), // class("Integral"), int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public); @@ -493,25 +503,29 @@ impl Context { Const, Public, ); - int.register_trait(Int, poly("PartialOrd", vec![ty_tp(Int)]), int_partial_ord); + int.register_trait( + Int, + builtin_poly("PartialOrd", vec![ty_tp(Int)]), + int_partial_ord, + ); let mut int_eq = Self::builtin_methods("Eq", 2); 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); + int.register_trait(Int, builtin_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::builtin_methods("Add", 2); 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); + int.register_trait(Int, builtin_poly("Add", vec![ty_tp(Int)]), int_add); let mut int_sub = Self::builtin_methods("Sub", 2); 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); + int.register_trait(Int, builtin_poly("Sub", vec![ty_tp(Int)]), int_sub); let mut int_mul = Self::builtin_methods("Mul", 2); 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); + int.register_trait(Int, builtin_poly("Mul", vec![ty_tp(Int)]), int_mul); let mut int_mutizable = Self::builtin_methods("Mutizable", 2); int_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Int!"))); int.register_trait(Int, builtin_mono("Mutizable"), int_mutizable); @@ -539,7 +553,7 @@ impl Context { nat.register_marker_trait(builtin_mono("Ord")); let mut nat_eq = Self::builtin_methods("Eq", 2); 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); + nat.register_trait(Nat, builtin_poly("Eq", vec![ty_tp(Nat)]), nat_eq); let mut nat_partial_ord = Self::builtin_methods("PartialOrd", 2); nat_partial_ord.register_builtin_impl( "__cmp__", @@ -547,17 +561,21 @@ impl Context { Const, Public, ); - nat.register_trait(Nat, poly("PartialOrd", vec![ty_tp(Nat)]), nat_partial_ord); + nat.register_trait( + Nat, + builtin_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::builtin_methods("Add", 2); 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); + nat.register_trait(Nat, builtin_poly("Add", vec![ty_tp(Nat)]), nat_add); let mut nat_mul = Self::builtin_methods("Mul", 2); 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); + nat.register_trait(Nat, builtin_poly("Mul", vec![ty_tp(Nat)]), nat_mul); let mut nat_mutizable = Self::builtin_methods("Mutizable", 2); nat_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Nat!"))); nat.register_trait(Nat, builtin_mono("Mutizable"), nat_mutizable); @@ -584,16 +602,16 @@ impl Context { ); bool_.register_trait( Bool, - poly("PartialOrd", vec![ty_tp(Bool)]), + builtin_poly("PartialOrd", vec![ty_tp(Bool)]), bool_partial_ord, ); let mut bool_eq = Self::builtin_methods("Eq", 2); 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); + bool_.register_trait(Bool, builtin_poly("Eq", vec![ty_tp(Bool)]), bool_eq); let mut bool_add = Self::builtin_methods("Add", 2); 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); + bool_.register_trait(Bool, builtin_poly("Add", vec![ty_tp(Bool)]), bool_add); let mut bool_mutizable = Self::builtin_methods("Mutizable", 2); bool_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Bool!"))); @@ -627,19 +645,19 @@ impl Context { ); let mut str_eq = Self::builtin_methods("Eq", 2); 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); + str_.register_trait(Str, builtin_poly("Eq", vec![ty_tp(Str)]), str_eq); let mut str_seq = Self::builtin_methods("Seq", 2); 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); + str_.register_trait(Str, builtin_poly("Seq", vec![ty_tp(Str)]), str_seq); let mut str_add = Self::builtin_methods("Add", 2); 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); + str_.register_trait(Str, builtin_poly("Add", vec![ty_tp(Str)]), str_add); let mut str_mul = Self::builtin_methods("Mul", 2); 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); + str_.register_trait(Str, builtin_poly("Mul", vec![ty_tp(Nat)]), str_mul); let mut str_mutizable = Self::builtin_methods("Mutizable", 2); str_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Str!"))); str_.register_trait(Str, builtin_mono("Mutizable"), str_mutizable); @@ -649,24 +667,37 @@ impl Context { type_.register_marker_trait(builtin_mono("Named")); let mut type_eq = Self::builtin_methods("Eq", 2); 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); + type_.register_trait(Type, builtin_poly("Eq", vec![ty_tp(Type)]), type_eq); let mut class_type = Self::builtin_mono_class("ClassType", 2); 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::builtin_methods("Eq", 2); 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::builtin_mono_class("Module", 2); - module.register_superclass(Obj, &obj); - module.register_marker_trait(builtin_mono("Named")); - let mut module_eq = Self::builtin_methods("Eq", 2); - 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); + class_type.register_trait(Class, builtin_poly("Eq", vec![ty_tp(Class)]), class_eq); + let g_module_t = builtin_mono("GenericModule"); + let mut generic_module = Self::builtin_mono_class("GenericModule", 2); + generic_module.register_superclass(Obj, &obj); + generic_module.register_marker_trait(builtin_mono("Named")); + let mut generic_module_eq = Self::builtin_methods("Eq", 2); + generic_module_eq.register_builtin_impl( + "__eq__", + fn1_met(g_module_t.clone(), g_module_t.clone(), Bool), + Const, + Public, + ); + generic_module.register_trait( + g_module_t.clone(), + builtin_poly("Eq", vec![ty_tp(g_module_t.clone())]), + generic_module_eq, + ); + let module_t = module(mono_q_tp("Path")); + let mut module = Self::builtin_poly_class("Module", vec![PS::named_nd("Path", Str)], 2); + module.register_superclass(g_module_t.clone(), &generic_module); let mut array_ = Self::builtin_poly_class("Array", vec![PS::t_nd("T"), PS::named_nd("N", Nat)], 10); array_.register_superclass(Obj, &obj); - array_.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))])); + array_.register_marker_trait(builtin_poly("Output", vec![ty_tp(mono_q("T"))])); let n = mono_q_tp("N"); let m = mono_q_tp("M"); let array_t = array(mono_q("T"), n.clone()); @@ -682,7 +713,7 @@ impl Context { set! {static_instance("N", Nat), static_instance("M", Nat)}, ); array_.register_builtin_impl("concat", t, Immutable, Public); - let mut_type = ValueObj::builtin_t(poly( + let mut_type = ValueObj::builtin_t(builtin_poly( "Array!", vec![TyParam::t(mono_q("T")), TyParam::mono_q("N").mutate()], )); @@ -695,9 +726,13 @@ impl Context { Const, Public, ); - array_.register_trait(array_t.clone(), poly("Eq", vec![ty_tp(array_t)]), array_eq); + array_.register_trait( + array_t.clone(), + builtin_poly("Eq", vec![ty_tp(array_t)]), + array_eq, + ); array_.register_marker_trait(builtin_mono("Mutizable")); - array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))])); + array_.register_marker_trait(builtin_poly("Seq", vec![ty_tp(mono_q("T"))])); // TODO: make Tuple6, Tuple7, ... etc. let mut tuple_ = Self::builtin_mono_class("Tuple", 2); tuple_.register_superclass(Obj, &obj); @@ -710,7 +745,7 @@ impl Context { ); tuple_.register_trait( builtin_mono("Tuple"), - poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]), + builtin_poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]), tuple_eq, ); let mut tuple1 = Self::builtin_poly_class("Tuple1", vec![PS::t_nd("A")], 2); @@ -720,16 +755,19 @@ impl Context { tuple1_eq.register_builtin_impl( "__eq__", fn1_met( - poly("Tuple1", vec![ty_tp(mono_q("A"))]), - poly("Tuple1", vec![ty_tp(mono_q("A"))]), + builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]), + builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]), Bool, ), Const, Public, ); tuple1.register_trait( - poly("Tuple1", vec![ty_tp(mono_q("A"))]), - poly("Eq", vec![ty_tp(poly("Tuple1", vec![ty_tp(mono_q("A"))]))]), + builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]), + builtin_poly( + "Eq", + vec![ty_tp(builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]))], + ), tuple1_eq, ); let mut tuple2 = Self::builtin_poly_class("Tuple2", vec![PS::t_nd("A"), PS::t_nd("B")], 2); @@ -739,18 +777,18 @@ impl Context { tuple2_eq.register_builtin_impl( "__eq__", fn1_met( - poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), - poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), + builtin_poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), + builtin_poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), Bool, ), Const, Public, ); tuple2.register_trait( - poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), - poly( + builtin_poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), + builtin_poly( "Eq", - vec![ty_tp(poly( + vec![ty_tp(builtin_poly( "Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))], ))], @@ -768,11 +806,11 @@ impl Context { tuple3_eq.register_builtin_impl( "__eq__", fn1_met( - poly( + builtin_poly( "Tuple3", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))], ), - poly( + builtin_poly( "Tuple3", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))], ), @@ -782,13 +820,13 @@ impl Context { Public, ); tuple3.register_trait( - poly( + builtin_poly( "Tuple3", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))], ), - poly( + builtin_poly( "Eq", - vec![ty_tp(poly( + vec![ty_tp(builtin_poly( "Tuple3", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))], ))], @@ -806,7 +844,7 @@ impl Context { tuple4_eq.register_builtin_impl( "__eq__", fn1_met( - poly( + builtin_poly( "Tuple4", vec![ ty_tp(mono_q("A")), @@ -815,7 +853,7 @@ impl Context { ty_tp(mono_q("D")), ], ), - poly( + builtin_poly( "Tuple4", vec![ ty_tp(mono_q("A")), @@ -830,7 +868,7 @@ impl Context { Public, ); tuple4.register_trait( - poly( + builtin_poly( "Tuple4", vec![ ty_tp(mono_q("A")), @@ -839,9 +877,9 @@ impl Context { ty_tp(mono_q("D")), ], ), - poly( + builtin_poly( "Eq", - vec![ty_tp(poly( + vec![ty_tp(builtin_poly( "Tuple4", vec![ ty_tp(mono_q("A")), @@ -870,7 +908,7 @@ impl Context { tuple5_eq.register_builtin_impl( "__eq__", fn1_met( - poly( + builtin_poly( "Tuple5", vec![ ty_tp(mono_q("A")), @@ -880,7 +918,7 @@ impl Context { ty_tp(mono_q("E")), ], ), - poly( + builtin_poly( "Tuple5", vec![ ty_tp(mono_q("A")), @@ -896,7 +934,7 @@ impl Context { Public, ); tuple5.register_trait( - poly( + builtin_poly( "Tuple5", vec![ ty_tp(mono_q("A")), @@ -906,9 +944,9 @@ impl Context { ty_tp(mono_q("E")), ], ), - poly( + builtin_poly( "Eq", - vec![ty_tp(poly( + vec![ty_tp(builtin_poly( "Tuple5", vec![ ty_tp(mono_q("A")), @@ -939,7 +977,7 @@ impl Context { tuple6_eq.register_builtin_impl( "__eq__", fn1_met( - poly( + builtin_poly( "Tuple6", vec![ ty_tp(mono_q("A")), @@ -950,7 +988,7 @@ impl Context { ty_tp(mono_q("F")), ], ), - poly( + builtin_poly( "Tuple6", vec![ ty_tp(mono_q("A")), @@ -967,7 +1005,7 @@ impl Context { Public, ); tuple6.register_trait( - poly( + builtin_poly( "Tuple6", vec![ ty_tp(mono_q("A")), @@ -978,9 +1016,9 @@ impl Context { ty_tp(mono_q("F")), ], ), - poly( + builtin_poly( "Eq", - vec![ty_tp(poly( + vec![ty_tp(builtin_poly( "Tuple6", vec![ ty_tp(mono_q("A")), @@ -1013,7 +1051,7 @@ impl Context { tuple7_eq.register_builtin_impl( "__eq__", fn1_met( - poly( + builtin_poly( "Tuple7", vec![ ty_tp(mono_q("A")), @@ -1025,7 +1063,7 @@ impl Context { ty_tp(mono_q("G")), ], ), - poly( + builtin_poly( "Tuple7", vec![ ty_tp(mono_q("A")), @@ -1043,7 +1081,7 @@ impl Context { Public, ); tuple7.register_trait( - poly( + builtin_poly( "Tuple7", vec![ ty_tp(mono_q("A")), @@ -1055,9 +1093,9 @@ impl Context { ty_tp(mono_q("G")), ], ), - poly( + builtin_poly( "Eq", - vec![ty_tp(poly( + vec![ty_tp(builtin_poly( "Tuple7", vec![ ty_tp(mono_q("A")), @@ -1092,7 +1130,7 @@ impl Context { tuple8_eq.register_builtin_impl( "__eq__", fn1_met( - poly( + builtin_poly( "Tuple8", vec![ ty_tp(mono_q("A")), @@ -1105,7 +1143,7 @@ impl Context { ty_tp(mono_q("H")), ], ), - poly( + builtin_poly( "Tuple8", vec![ ty_tp(mono_q("A")), @@ -1124,7 +1162,7 @@ impl Context { Public, ); tuple8.register_trait( - poly( + builtin_poly( "Tuple8", vec![ ty_tp(mono_q("A")), @@ -1137,9 +1175,9 @@ impl Context { ty_tp(mono_q("H")), ], ), - poly( + builtin_poly( "Eq", - vec![ty_tp(poly( + vec![ty_tp(builtin_poly( "Tuple8", vec![ ty_tp(mono_q("A")), @@ -1289,8 +1327,8 @@ impl Context { builtin_mono("Mutable"), str_mut_mutable, ); - let array_t = poly("Array", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); - let array_mut_t = poly("Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); + let array_t = builtin_poly("Array", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); + let array_mut_t = builtin_poly("Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); let mut array_mut_ = Self::builtin_poly_class( "Array!", vec![PS::t_nd("T"), PS::named_nd("N", builtin_mono("Nat!"))], @@ -1301,7 +1339,7 @@ impl Context { let t = pr_met( ref_mut( array_mut_t.clone(), - Some(poly( + Some(builtin_poly( "Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N") + value(1)], )), @@ -1354,10 +1392,10 @@ impl Context { builtin_mono("Mutable"), array_mut_mutable, ); - let range_t = poly("Range", vec![TyParam::t(mono_q("T"))]); + let range_t = builtin_poly("Range", vec![TyParam::t(mono_q("T"))]); let mut range = Self::builtin_poly_class("Range", vec![PS::t_nd("T")], 2); range.register_superclass(Obj, &obj); - range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))])); + range.register_marker_trait(builtin_poly("Output", vec![ty_tp(mono_q("T"))])); let mut range_eq = Self::builtin_methods("Eq", 2); range_eq.register_builtin_impl( "__eq__", @@ -1367,7 +1405,7 @@ impl Context { ); range.register_trait( range_t.clone(), - poly("Eq", vec![ty_tp(range_t.clone())]), + builtin_poly("Eq", vec![ty_tp(range_t.clone())]), range_eq, ); let mut proc = Self::builtin_mono_class("Proc", 2); @@ -1392,7 +1430,8 @@ impl Context { self.register_builtin_type(Str, str_, Const); self.register_builtin_type(Type, type_, Const); self.register_builtin_type(Class, class_type, Const); - self.register_builtin_type(Module, module, Const); + self.register_builtin_type(g_module_t, generic_module, Const); + self.register_builtin_type(module_t, module, Const); self.register_builtin_type(array_t, array_, Const); self.register_builtin_type(tuple(vec![mono_q("A")]), tuple1, Const); self.register_builtin_type(tuple(vec![mono_q("A"), mono_q("B")]), tuple2, Const); @@ -1504,7 +1543,12 @@ impl Context { option(mono_q("T")), ); let t_if = quant(t_if, set! {static_instance("T", Type)}); - let t_import = nd_func(vec![param_t("path", Str)], None, Module); + let t_import = nd_func( + vec![anon(tp_enum(Str, set! {mono_q_tp("Path")}))], + None, + module(mono_q_tp("Path")), + ); + let t_import = quant(t_import, set! {static_instance("Path", Str)}); let t_log = func( vec![], Some(param_t("objects", ref_(Obj))), @@ -1516,7 +1560,12 @@ impl Context { ], NoneType, ); - let t_pyimport = nd_func(vec![param_t("path", Str)], None, Module); + let t_pyimport = nd_func( + vec![anon(tp_enum(Str, set! {mono_q_tp("Path")}))], + None, + module(mono_q_tp("Path")), + ); + let t_pyimport = quant(t_pyimport, set! {static_instance("Path", Str)}); let t_quit = func(vec![], None, vec![param_t("code", Int)], NoneType); self.register_builtin_impl("abs", t_abs, Immutable, Private); self.register_builtin_impl("assert", t_assert, Const, Private); // assert casting に悪影響が出る可能性があるため、Constとしておく @@ -1658,7 +1707,7 @@ impl Context { op_t, set! { static_instance("R", Type), - subtypeof(l.clone(), poly("Add", params.clone())) + subtypeof(l.clone(), builtin_poly("Add", params.clone())) }, ); self.register_builtin_impl("__add__", op_t, Const, Private); @@ -1667,7 +1716,7 @@ impl Context { op_t, set! { static_instance("R", Type), - subtypeof(l.clone(), poly("Sub", params.clone())) + subtypeof(l.clone(), builtin_poly("Sub", params.clone())) }, ); self.register_builtin_impl("__sub__", op_t, Const, Private); @@ -1676,7 +1725,7 @@ impl Context { op_t, set! { static_instance("R", Type), - subtypeof(l.clone(), poly("Mul", params.clone())) + subtypeof(l.clone(), builtin_poly("Mul", params.clone())) }, ); self.register_builtin_impl("__mul__", op_t, Const, Private); @@ -1685,22 +1734,22 @@ impl Context { op_t, set! { static_instance("R", Type), - subtypeof(l.clone(), poly("Div", params.clone())) + subtypeof(l.clone(), builtin_poly("Div", params.clone())) }, ); self.register_builtin_impl("__div__", op_t, Const, Private); let m = mono_q("M"); let op_t = bin_op(m.clone(), m.clone(), mono_proj(m.clone(), "PowOutput")); - let op_t = quant(op_t, set! {subtypeof(m, poly("Mul", vec![]))}); + let op_t = quant(op_t, set! {subtypeof(m, builtin_poly("Mul", vec![]))}); // TODO: add bound: M == M.Output self.register_builtin_impl("__pow__", op_t, Const, Private); let d = mono_q("D"); let op_t = bin_op(d.clone(), d.clone(), mono_proj(d.clone(), "ModOutput")); - let op_t = quant(op_t, set! {subtypeof(d, poly("Div", vec![]))}); + let op_t = quant(op_t, set! {subtypeof(d, builtin_poly("Div", vec![]))}); self.register_builtin_impl("__mod__", op_t, Const, Private); let e = mono_q("E"); let op_t = bin_op(e.clone(), e.clone(), Bool); - let op_t = quant(op_t, set! {subtypeof(e, poly("Eq", vec![]))}); + let op_t = quant(op_t, set! {subtypeof(e, builtin_poly("Eq", vec![]))}); self.register_builtin_impl("__eq__", op_t.clone(), Const, Private); self.register_builtin_impl("__ne__", op_t, Const, Private); let op_t = bin_op(l.clone(), r, Bool); @@ -1708,7 +1757,7 @@ impl Context { op_t, set! { static_instance("R", Type), - subtypeof(l, poly("PartialOrd", params)) + subtypeof(l, builtin_poly("PartialOrd", params)) }, ); self.register_builtin_impl("__lt__", op_t.clone(), Const, Private); @@ -1728,7 +1777,7 @@ impl Context { let op_t = bin_op(mono_q("T"), mono_q("I"), Bool); let op_t = quant( op_t, - set! { static_instance("T", Type), subtypeof(mono_q("I"), poly("In", vec![ty_tp(mono_q("T"))])) }, + set! { static_instance("T", Type), subtypeof(mono_q("I"), builtin_poly("In", vec![ty_tp(mono_q("T"))])) }, ); self.register_builtin_impl("__in__", op_t, Const, Private); /* unary */ @@ -1772,7 +1821,7 @@ impl Context { ); interval.register_trait( Type::from(&m..=&n), - poly("Add", vec![TyParam::from(&o..=&p)]), + builtin_poly("Add", vec![TyParam::from(&o..=&p)]), interval_add, ); let mut interval_sub = Self::builtin_methods("Sub", 2); @@ -1788,7 +1837,7 @@ impl Context { ); interval.register_trait( Type::from(&m..=&n), - poly("Sub", vec![TyParam::from(&o..=&p)]), + builtin_poly("Sub", vec![TyParam::from(&o..=&p)]), interval_sub, ); self.register_builtin_patch("Interval", interval, Const); @@ -1800,7 +1849,7 @@ impl Context { pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) { // TODO: capacityを正確に把握する - let mut ctx = Context::module("".into(), ErgConfig::default(), None, None, 40); + let mut ctx = Context::builtin_module("", 40); ctx.init_builtin_funcs(); ctx.init_builtin_const_funcs(); ctx.init_builtin_procs(); @@ -1808,7 +1857,7 @@ impl Context { ctx.init_builtin_traits(); ctx.init_builtin_classes(); ctx.init_builtin_patches(); - mod_cache.register(VarName::from_static(""), None, ctx); + mod_cache.register(PathBuf::from(""), None, ctx); } pub fn new_module>( diff --git a/compiler/erg_compiler/context/initialize/py_mods/importlib.rs b/compiler/erg_compiler/context/initialize/py_mods/importlib.rs index c69636a3..e7636339 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/importlib.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/importlib.rs @@ -1,6 +1,6 @@ use erg_common::vis::Visibility; -use erg_type::constructors::proc1; +use erg_type::constructors::{builtin_mono, proc1}; use erg_type::Type; use Type::*; @@ -12,7 +12,12 @@ use Visibility::*; impl Context { pub(crate) fn init_py_importlib_mod() -> Self { let mut importlib = Context::builtin_module("importlib", 15); - importlib.register_builtin_impl("reload!", proc1(Module, NoneType), Immutable, Public); + importlib.register_builtin_impl( + "reload!", + proc1(builtin_mono("GenericModule"), NoneType), + Immutable, + Public, + ); importlib } } diff --git a/compiler/erg_compiler/context/initialize/py_mods/random.rs b/compiler/erg_compiler/context/initialize/py_mods/random.rs index d7419f31..2c2c1914 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/random.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/random.rs @@ -2,7 +2,7 @@ use erg_common::set; use erg_common::vis::Visibility; use erg_type::constructors::{ - builtin_mono, mono_q, nd_proc, param_t, poly, proc, quant, static_instance, ty_tp, + builtin_mono, builtin_poly, mono_q, nd_proc, param_t, proc, quant, static_instance, ty_tp, }; use erg_type::Type; use Type::*; @@ -36,7 +36,10 @@ impl Context { Public, ); let t = nd_proc( - vec![param_t("seq", poly("Seq", vec![ty_tp(mono_q("T"))]))], + vec![param_t( + "seq", + builtin_poly("Seq", vec![ty_tp(mono_q("T"))]), + )], None, mono_q("T"), ); diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index 5352fc9f..8e99d550 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -1,20 +1,23 @@ // (type) getters & validators use std::option::Option; // conflicting to Type::Option +use std::path::{Path, PathBuf}; +use erg_common::config::Input; use erg_common::error::{ErrorCore, ErrorKind, Location}; use erg_common::levenshtein::get_similar_name; use erg_common::set::Set; use erg_common::traits::{Locational, Stream}; use erg_common::vis::{Field, Visibility}; -use erg_common::Str; use erg_common::{enum_unwrap, fmt_option, fmt_slice, log, set}; +use erg_common::{option_enum_unwrap, Str}; use Type::*; use ast::VarName; use erg_parser::ast::{self, Identifier}; use erg_parser::token::Token; -use erg_type::constructors::{builtin_mono, func, mono, mono_proj}; +use erg_type::constructors::{builtin_mono, func, module, mono, mono_proj, v_enum}; +use erg_type::typaram::TyParam; use erg_type::value::{GenTypeObj, TypeObj, ValueObj}; use erg_type::{HasType, ParamTy, SubrKind, SubrType, TyBound, Type}; @@ -86,21 +89,15 @@ impl Context { self.locals.get_key_value(name) } - fn get_singular_ctx(&self, obj: &hir::Expr, namespace: &Str) -> SingleTyCheckResult<&Context> { + pub fn get_singular_ctx( + &self, + obj: &hir::Expr, + namespace: &Str, + ) -> SingleTyCheckResult<&Context> { match obj { - hir::Expr::Accessor(hir::Accessor::Ident(ident)) => self - .get_mod(ident.inspect()) - .or_else(|| self.rec_get_type(ident.inspect()).map(|(_, ctx)| ctx)) - .ok_or_else(|| { - TyCheckError::no_var_error( - self.cfg.input.clone(), - line!() as usize, - obj.loc(), - namespace.into(), - ident.inspect(), - self.get_similar_name(ident.inspect()), - ) - }), + hir::Expr::Accessor(hir::Accessor::Ident(ident)) => { + self.get_singular_ctx_from_ident(&ident.clone().downcast(), namespace) + } hir::Expr::Accessor(hir::Accessor::Attr(attr)) => { // REVIEW: 両方singularとは限らない? let ctx = self.get_singular_ctx(&attr.obj, namespace)?; @@ -111,6 +108,25 @@ impl Context { } } + pub fn get_singular_ctx_from_ident( + &self, + ident: &ast::Identifier, + namespace: &Str, + ) -> SingleTyCheckResult<&Context> { + self.get_mod(ident) + .or_else(|| self.rec_get_type(ident.inspect()).map(|(_, ctx)| ctx)) + .ok_or_else(|| { + TyCheckError::no_var_error( + self.cfg.input.clone(), + line!() as usize, + ident.loc(), + namespace.into(), + ident.inspect(), + self.get_similar_name(ident.inspect()), + ) + }) + } + fn get_match_call_t( &self, pos_args: &[hir::PosArg], @@ -197,31 +213,74 @@ impl Context { Ok(t) } - pub(crate) fn get_local_uniq_obj_name(&self, name: &VarName) -> Option { - // TODO: types, functions, patches - if let Some(ctx) = self.get_mod(name.inspect()) { - return Some(ctx.name.clone()); - } - if let Some((_, ctx)) = self.rec_get_type(name.inspect()) { - return Some(ctx.name.clone()); - } - None + fn get_import_call_t( + &self, + pos_args: &[hir::PosArg], + kw_args: &[hir::KwArg], + ) -> TyCheckResult { + let mod_name = pos_args + .get(0) + .map(|a| &a.expr) + .or_else(|| { + kw_args + .iter() + .find(|k| &k.keyword.inspect()[..] == "Path") + .map(|a| &a.expr) + }) + .unwrap(); + let path = match mod_name { + hir::Expr::Lit(lit) => { + if self.subtype_of(&lit.value.class(), &Str) { + enum_unwrap!(&lit.value, ValueObj::Str) + } else { + return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error( + self.cfg.input.clone(), + line!() as usize, + mod_name.loc(), + self.caused_by(), + "import::name", + &Str, + mod_name.ref_t(), + self.get_candidates(mod_name.ref_t()), + self.get_type_mismatch_hint(&Str, mod_name.ref_t()), + ))); + } + } + _other => { + return Err(TyCheckErrors::from(TyCheckError::feature_error( + self.cfg.input.clone(), + mod_name.loc(), + "non-literal importing", + self.caused_by(), + ))) + } + }; + let path = PathBuf::from(&path[..]); + let s = ValueObj::Str(Str::rc(path.to_str().unwrap())); + let import_t = func( + vec![ParamTy::anonymous(v_enum(set! {s.clone()}))], + None, + vec![], + module(TyParam::Value(s)), + ); + Ok(import_t) } pub(crate) fn rec_get_var_t( &self, ident: &Identifier, + input: &Input, namespace: &Str, ) -> SingleTyCheckResult { if let Some(vi) = self.get_current_scope_var(&ident.inspect()[..]) { - self.validate_visibility(ident, vi, namespace)?; + self.validate_visibility(ident, vi, input, namespace)?; Ok(vi.t()) } else { if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { - return parent.rec_get_var_t(ident, namespace); + return parent.rec_get_var_t(ident, input, namespace); } Err(TyCheckError::no_var_error( - self.cfg.input.clone(), + input.clone(), line!() as usize, ident.loc(), namespace.into(), @@ -235,11 +294,12 @@ impl Context { &self, obj: &hir::Expr, ident: &Identifier, + input: &Input, namespace: &Str, ) -> SingleTyCheckResult { let self_t = obj.t(); let name = ident.name.token(); - match self.get_attr_t_from_attributive_t(obj, &self_t, ident, namespace) { + match self.get_attr_t_from_attributive(obj, &self_t, ident, namespace) { Ok(t) => { return Ok(t); } @@ -249,7 +309,7 @@ impl Context { } } if let Ok(singular_ctx) = self.get_singular_ctx(obj, namespace) { - match singular_ctx.rec_get_var_t(ident, namespace) { + match singular_ctx.rec_get_var_t(ident, input, namespace) { Ok(t) => { return Ok(t); } @@ -269,7 +329,7 @@ impl Context { None, // TODO: ) })? { - match ctx.rec_get_var_t(ident, namespace) { + match ctx.rec_get_var_t(ident, input, namespace) { Ok(t) => { return Ok(t); } @@ -281,10 +341,10 @@ impl Context { } // TODO: dependent type widening if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { - parent.rec_get_attr_t(obj, ident, namespace) + parent.rec_get_attr_t(obj, ident, input, namespace) } else { Err(TyCheckError::no_attr_error( - self.cfg.input.clone(), + input.clone(), line!() as usize, name.loc(), namespace.into(), @@ -295,7 +355,9 @@ impl Context { } } - fn get_attr_t_from_attributive_t( + /// get type from given attributive type (Record). + /// not ModuleType or ClassType etc. + fn get_attr_t_from_attributive( &self, obj: &hir::Expr, t: &Type, @@ -304,18 +366,18 @@ impl Context { ) -> SingleTyCheckResult { match t { Type::FreeVar(fv) if fv.is_linked() => { - self.get_attr_t_from_attributive_t(obj, &fv.crack(), ident, namespace) + self.get_attr_t_from_attributive(obj, &fv.crack(), ident, namespace) } Type::FreeVar(fv) => { let sup = fv.get_sup().unwrap(); - self.get_attr_t_from_attributive_t(obj, &sup, ident, namespace) + self.get_attr_t_from_attributive(obj, &sup, ident, namespace) } - Type::Ref(t) => self.get_attr_t_from_attributive_t(obj, t, ident, namespace), + Type::Ref(t) => self.get_attr_t_from_attributive(obj, t, ident, namespace), Type::RefMut { before, .. } => { - self.get_attr_t_from_attributive_t(obj, before, ident, namespace) + self.get_attr_t_from_attributive(obj, before, ident, namespace) } Type::Refinement(refine) => { - self.get_attr_t_from_attributive_t(obj, &refine.t, ident, namespace) + self.get_attr_t_from_attributive(obj, &refine.t, ident, namespace) } Type::Record(record) => { // REVIEW: `rec.get(name.inspect())` returns None (Borrow is implemented for Field). Why? @@ -334,11 +396,6 @@ impl Context { )) } } - Module => { - let mod_ctx = self.get_singular_ctx(obj, namespace)?; - let t = mod_ctx.rec_get_var_t(ident, namespace)?; - Ok(t) - } other => { if let Some(v) = self.rec_get_const_obj(&other.name()) { match v { @@ -372,6 +429,7 @@ impl Context { &self, obj: &hir::Expr, method_name: &Option, + input: &Input, namespace: &Str, ) -> SingleTyCheckResult { if let Some(method_name) = method_name.as_ref() { @@ -393,7 +451,7 @@ impl Context { .get(method_name.inspect()) .or_else(|| ctx.decls.get(method_name.inspect())) { - self.validate_visibility(method_name, vi, namespace)?; + self.validate_visibility(method_name, vi, input, namespace)?; return Ok(vi.t()); } for (_, methods_ctx) in ctx.methods_list.iter() { @@ -402,7 +460,7 @@ impl Context { .get(method_name.inspect()) .or_else(|| methods_ctx.decls.get(method_name.inspect())) { - self.validate_visibility(method_name, vi, namespace)?; + self.validate_visibility(method_name, vi, input, namespace)?; return Ok(vi.t()); } } @@ -413,7 +471,7 @@ impl Context { .get(method_name.inspect()) .or_else(|| singular_ctx.decls.get(method_name.inspect())) { - self.validate_visibility(method_name, vi, namespace)?; + self.validate_visibility(method_name, vi, input, namespace)?; return Ok(vi.t()); } for (_, method_ctx) in singular_ctx.methods_list.iter() { @@ -422,7 +480,7 @@ impl Context { .get(method_name.inspect()) .or_else(|| method_ctx.decls.get(method_name.inspect())) { - self.validate_visibility(method_name, vi, namespace)?; + self.validate_visibility(method_name, vi, input, namespace)?; return Ok(vi.t()); } } @@ -456,11 +514,12 @@ impl Context { &self, ident: &Identifier, vi: &VarInfo, + input: &Input, namespace: &str, ) -> SingleTyCheckResult<()> { if ident.vis() != vi.vis { Err(TyCheckError::visibility_error( - self.cfg.input.clone(), + input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -474,7 +533,7 @@ impl Context { && !namespace.contains(&self.name[..]) { Err(TyCheckError::visibility_error( - self.cfg.input.clone(), + input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -490,6 +549,7 @@ impl Context { &self, op: &Token, args: &[hir::PosArg], + input: &Input, namespace: &Str, ) -> TyCheckResult { erg_common::debug_power_assert!(args.len() == 2); @@ -497,10 +557,11 @@ impl Context { let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin); let t = self.rec_get_var_t( &Identifier::new(None, VarName::new(symbol.clone())), + input, namespace, )?; let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); - self.get_call_t(&op, &None, args, &[], namespace) + self.get_call_t(&op, &None, args, &[], input, namespace) .map_err(|errs| { let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); let lhs = args[0].expr.clone(); @@ -528,6 +589,7 @@ impl Context { &self, op: &Token, args: &[hir::PosArg], + input: &Input, namespace: &Str, ) -> TyCheckResult { erg_common::debug_power_assert!(args.len() == 1); @@ -535,10 +597,11 @@ impl Context { let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin); let t = self.rec_get_var_t( &Identifier::new(None, VarName::new(symbol.clone())), + input, namespace, )?; let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); - self.get_call_t(&op, &None, args, &[], namespace) + self.get_call_t(&op, &None, args, &[], input, namespace) .map_err(|errs| { let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); let expr = args[0].expr.clone(); @@ -880,17 +943,34 @@ impl Context { method_name: &Option, pos_args: &[hir::PosArg], kw_args: &[hir::KwArg], + input: &Input, namespace: &Str, ) -> TyCheckResult { - match obj { - hir::Expr::Accessor(hir::Accessor::Ident(local)) - if local.vis().is_private() && &local.inspect()[..] == "match" => - { - return self.get_match_call_t(pos_args, kw_args); + if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj { + if local.vis().is_private() { + match &local.inspect()[..] { + "match" => { + return self.get_match_call_t(pos_args, kw_args); + } + "import" | "pyimport" | "py" => { + return self.get_import_call_t(pos_args, kw_args); + } + // handle assert casting + /*"assert" => { + if let Some(arg) = pos_args.first() { + match &arg.expr { + hir::Expr::BinOp(bin) if bin.op.is(TokenKind::InOp) && bin.rhs.ref_t() == &Type => { + let t = self.eval_const_expr(bin.lhs.as_ref(), None)?.as_type().unwrap(); + } + _ => {} + } + } + },*/ + _ => {} + } } - _ => {} } - let found = self.search_callee_t(obj, method_name, namespace)?; + let found = self.search_callee_t(obj, method_name, input, namespace)?; log!( "Found:\ncallee: {obj}{}\nfound: {found}", fmt_option!(pre ".", method_name.as_ref().map(|ident| &ident.name)) @@ -1192,9 +1272,31 @@ impl Context { } } }, - Type::Poly { name, params: _ } => { - if let Some((t, ctx)) = self.rec_get_poly_type(name) { - return Some((t, ctx)); + Type::BuiltinPoly { name, .. } => { + if let Some(res) = self.get_builtins().unwrap_or(self).rec_get_poly_type(name) { + return Some(res); + } + } + Type::Poly { path, name, .. } => { + if self.path() == path { + if let Some((t, ctx)) = self.rec_get_mono_type(name) { + return Some((t, ctx)); + } + } + let path = self.cfg.input.resolve(path.as_path()).ok()?; + if let Some(ctx) = self + .mod_cache + .as_ref() + .and_then(|cache| cache.ref_ctx(path.as_path())) + .or_else(|| { + self.py_mod_cache + .as_ref() + .and_then(|cache| cache.ref_ctx(path.as_path())) + }) + { + if let Some((t, ctx)) = ctx.rec_get_mono_type(name) { + return Some((t, ctx)); + } } } Type::Record(rec) if rec.values().all(|attr| self.supertype_of(&Type, attr)) => { @@ -1210,14 +1312,21 @@ impl Context { .rec_get_mono_type("Record"); } Type::Mono { path, name } => { - if self.mod_name() == path { + if self.path() == path { if let Some((t, ctx)) = self.rec_get_mono_type(name) { return Some((t, ctx)); } - } else if let Some(ctx) = self + } + let path = self.cfg.input.resolve(path.as_path()).ok()?; + if let Some(ctx) = self .mod_cache .as_ref() - .and_then(|cache| cache.ref_ctx(path)) + .and_then(|cache| cache.ref_ctx(path.as_path())) + .or_else(|| { + self.py_mod_cache + .as_ref() + .and_then(|cache| cache.ref_ctx(path.as_path())) + }) { if let Some((t, ctx)) = ctx.rec_get_mono_type(name) { return Some((t, ctx)); @@ -1274,7 +1383,7 @@ impl Context { return Some(res); } } - Type::Poly { name, params: _ } => { + Type::BuiltinPoly { name, params: _ } => { if let Some((t, ctx)) = self.rec_get_mut_poly_type(name) { return Some((t, ctx)); } @@ -1327,15 +1436,27 @@ impl Context { } // FIXME: 現在の実装だとimportしたモジュールはどこからでも見れる - fn get_mod(&self, name: &Str) -> Option<&Context> { - self.mod_cache - .as_ref() - .and_then(|cache| cache.ref_ctx(name)) - .or_else(|| { - self.py_mod_cache + fn get_mod(&self, ident: &ast::Identifier) -> Option<&Context> { + let t = self + .rec_get_var_t(ident, &self.cfg.input, &self.name) + .ok()?; + match t { + Type::BuiltinPoly { name, mut params } if &name[..] == "Module" => { + let path = + option_enum_unwrap!(params.remove(0), TyParam::Value:(ValueObj::Str:(_)))?; + let path = Path::new(&path[..]); + let path = self.cfg.input.resolve(path).ok()?; + self.mod_cache .as_ref() - .and_then(|cache| cache.ref_ctx(name)) - }) + .and_then(|cache| cache.ref_ctx(&path)) + .or_else(|| { + self.py_mod_cache + .as_ref() + .and_then(|cache| cache.ref_ctx(&path)) + }) + } + _ => None, + } } // rec_get_const_localとは違い、位置情報を持たないしエラーとならない @@ -1370,7 +1491,7 @@ impl Context { if self.kind.is_method_def() || self.kind.is_type() { // TODO: poly type let name = self.name.split(&[':', '.']).last().unwrap(); - let mono_t = mono(self.mod_name(), Str::rc(name)); + let mono_t = mono(self.path(), Str::rc(name)); if let Some((t, _)) = self.get_nominal_type_ctx(&mono_t) { Some(t.clone()) } else { diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 5132226e..f48443b2 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -106,7 +106,7 @@ impl TyVarContext { ) -> Type { if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(name) { let (_, ctx) = ctx - .get_nominal_type_ctx(&poly(name.clone(), params.clone())) + .get_nominal_type_ctx(&builtin_poly(name.clone(), params.clone())) .unwrap_or_else(|| panic!("{} not found", name)); let defined_params_len = ctx.params.len(); let given_params_len = params.len(); @@ -123,9 +123,9 @@ impl TyVarContext { self.push_or_init_typaram(&tp.tvar_name().unwrap(), &tp); inst_defaults.push(tp); } - poly(name, [inst_non_defaults, inst_defaults].concat()) + builtin_poly(name, [inst_non_defaults, inst_defaults].concat()) } else { - poly(name, self.instantiate_params(params)) + builtin_poly(name, self.instantiate_params(params)) } } @@ -146,7 +146,10 @@ impl TyVarContext { 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::Poly { .. } => todo!(), + Type::BuiltinPoly { name, params } => { + self.instantiate_poly(mid.name(), &name, params, ctx) + } Type::MonoProj { lhs, rhs } => { let lhs = if lhs.has_qvar() { self.instantiate_qvar(*lhs) @@ -174,9 +177,10 @@ impl TyVarContext { } TyBound::Instance { name, t } => { let t = match t { - Type::Poly { name, params } => { + Type::BuiltinPoly { name, params } => { self.instantiate_poly(name.clone(), &name, params, ctx) } + Type::Poly { .. } => todo!(), t => t, }; let constraint = Constraint::new_type_of(t.clone()); @@ -385,7 +389,7 @@ impl Context { mode: RegistrationMode, ) -> TyCheckResult { let opt_decl_sig_t = self - .rec_get_var_t(&sig.ident, &self.name) + .rec_get_var_t(&sig.ident, &self.cfg.input, &self.name) .ok() .map(|t| enum_unwrap!(t, Type::Subr)); let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?; @@ -453,7 +457,7 @@ impl Context { self.instantiate_typespec(&spec_with_op.t_spec, opt_decl_t, tv_ctx, mode)? } else { match &sig.pat { - ast::ParamPattern::Lit(lit) => enum_t(set![eval_lit(lit)]), + ast::ParamPattern::Lit(lit) => v_enum(set![eval_lit(lit)]), // TODO: Array _ => { let level = if mode == PreRegister { @@ -528,7 +532,7 @@ impl Context { } else if let Some(decl_t) = opt_decl_t { Ok(decl_t.typ().clone()) } else { - let typ = mono(self.mod_name(), Str::rc(other)); + let typ = mono(self.path(), Str::rc(other)); if let Some((defined_t, _)) = self.get_nominal_type_ctx(&typ) { Ok(defined_t.clone()) } else { @@ -551,8 +555,8 @@ impl Context { todo!() } }); - // FIXME: if type is a trait - Ok(poly(Str::rc(other), params.collect())) + // FIXME: non-builtin + Ok(builtin_poly(Str::rc(other), params.collect())) } } } @@ -573,7 +577,7 @@ impl Context { ) -> SingleTyCheckResult { match expr { ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => { - Ok(mono(self.mod_name(), name.inspect())) + Ok(mono(self.path(), name.inspect())) } _ => todo!(), } @@ -632,7 +636,7 @@ impl Context { .collect(), )), // TODO: エラー処理(リテラルでない、ダブりがある)はパーサーにやらせる - TypeSpec::Enum(set) => Ok(enum_t( + TypeSpec::Enum(set) => Ok(v_enum( set.pos_args() .map(|arg| { if let ast::ConstExpr::Lit(lit) = &arg.expr { @@ -861,11 +865,21 @@ impl Context { let lhs = self.instantiate_t(*lhs, tv_ctx, loc)?; Ok(mono_proj(lhs, rhs)) } - Poly { name, mut params } => { + BuiltinPoly { name, mut params } => { for param in params.iter_mut() { *param = self.instantiate_tp(mem::take(param), tv_ctx, loc)?; } - Ok(poly(name, params)) + Ok(builtin_poly(name, params)) + } + Poly { + path, + name, + mut params, + } => { + for param in params.iter_mut() { + *param = self.instantiate_tp(mem::take(param), tv_ctx, loc)?; + } + Ok(poly(path, name, params)) } Quantified(_) => { panic!("a quantified type should not be instantiated, instantiate the inner type") diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index 5adff82e..4ef22c46 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -16,6 +16,7 @@ pub mod tyvar; use std::fmt; use std::mem; use std::option::Option; // conflicting to Type::Option +use std::path::Path; use erg_common::astr::AtomicStr; use erg_common::config::ErgConfig; @@ -288,6 +289,11 @@ impl ImportKind { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct ContextInfo { + mod_id: usize, +} + /// Represents the context of the current scope /// /// Recursive functions/methods are highlighted with the prefix `rec_`, as performance may be significantly degraded. @@ -773,13 +779,13 @@ impl Context { self.outer.as_ref().map(|x| x.as_ref()) } - pub(crate) fn mod_name(&self) -> &Str { + pub(crate) fn path(&self) -> &Path { if let Some(outer) = self.get_outer() { - outer.mod_name() + outer.path() } else if self.kind == ContextKind::Module { - &self.name + Path::new(&self.name[..]) } else { - BUILTINS + Path::new(&BUILTINS[..]) } } @@ -787,10 +793,10 @@ impl Context { /// This avoids infinite loops. pub(crate) fn get_builtins(&self) -> Option<&Context> { // builtins中で定義した型等はmod_cacheがNoneになっている - if &self.mod_name()[..] != "" { + if self.path().to_string_lossy() != "" { self.mod_cache .as_ref() - .map(|cache| cache.ref_ctx("").unwrap()) + .map(|cache| cache.ref_ctx(Path::new("")).unwrap()) } else { None } @@ -809,6 +815,7 @@ impl Context { }; log!(info "{}: current namespace: {name}", fn_name!()); self.outer = Some(Box::new(mem::take(self))); + self.cfg = self.get_outer().unwrap().cfg.clone(); 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(); diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index 8471d95a..f00d2aeb 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -1,5 +1,5 @@ use std::option::Option; -use std::path::PathBuf; // conflicting to Type::Option +use std::path::PathBuf; use erg_common::config::{ErgConfig, Input}; use erg_common::levenshtein::get_similar_name; @@ -12,10 +12,9 @@ use erg_type::free::HasLevel; use ast::{DefId, Identifier, VarName}; use erg_parser::ast; -use erg_type::constructors::{enum_t, func, func1, proc, ref_, ref_mut}; +use erg_type::constructors::{func, func1, proc, ref_, ref_mut, v_enum}; use erg_type::value::{GenTypeObj, TypeKind, TypeObj, ValueObj}; -use erg_type::{HasType, ParamTy, SubrType, TyBound, Type}; -use Type::*; +use erg_type::{ParamTy, SubrType, TyBound, Type}; use crate::build_hir::HIRBuilder; use crate::context::{ClassDefType, Context, DefaultInfo, RegistrationMode, TraitInstance}; @@ -23,7 +22,7 @@ use crate::error::readable_name; use crate::error::{ CompileResult, SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult, }; -use crate::hir::{self, Literal}; +use crate::hir::Literal; use crate::mod_cache::SharedModuleCache; use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind}; use Mutability::*; @@ -484,7 +483,7 @@ impl Context { let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?; let mut tv_ctx = TyVarContext::new(self.level, bounds, self); let (obj, const_t) = match self.eval_const_block(&def.body.block, __name__) { - Ok(obj) => (obj.clone(), enum_t(set! {obj})), + Ok(obj) => (obj.clone(), v_enum(set! {obj})), Err(e) => { return Err(e); } @@ -505,7 +504,7 @@ impl Context { } ast::Signature::Var(sig) if sig.is_const() => { let (obj, const_t) = match self.eval_const_block(&def.body.block, __name__) { - Ok(obj) => (obj.clone(), enum_t(set! {obj})), + Ok(obj) => (obj.clone(), v_enum(set! {obj})), Err(e) => { return Err(e); } @@ -609,7 +608,7 @@ impl Context { other => { let id = DefId(get_hash(ident)); let vi = VarInfo::new( - enum_t(set! {other.clone()}), + v_enum(set! {other.clone()}), Const, ident.vis(), VarKind::Defined(id), @@ -818,67 +817,33 @@ impl Context { pub(crate) fn import_mod( &mut self, kind: ImportKind, - var_name: &VarName, - mod_name: &hir::Expr, - ) -> CompileResult<()> { - match mod_name { - hir::Expr::Lit(lit) => { - if self.subtype_of(&lit.value.class(), &Str) { - if kind.is_erg_import() { - self.import_erg_mod(var_name, lit)?; - } else { - self.import_py_mod(var_name, lit)?; - } - } else { - return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error( - self.cfg.input.clone(), - line!() as usize, - mod_name.loc(), - self.caused_by(), - "import::name", - &Str, - mod_name.ref_t(), - self.get_candidates(mod_name.ref_t()), - self.get_type_mismatch_hint(&Str, mod_name.ref_t()), - ))); - } - } - _other => { - return Err(TyCheckErrors::from(TyCheckError::feature_error( - self.cfg.input.clone(), - mod_name.loc(), - "non-literal importing", - self.caused_by(), - ))) - } + mod_name: &Literal, + ) -> CompileResult { + if kind.is_erg_import() { + self.import_erg_mod(mod_name) + } else { + self.import_py_mod(mod_name) } - Ok(()) } - fn import_erg_mod(&mut self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { - let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); + fn import_erg_mod(&mut self, mod_name: &Literal) -> CompileResult { + let __name__ = enum_unwrap!(mod_name.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__[..] { // TODO: erg builtin modules - _ => self.import_user_erg_mod(var_name, __name__, lit, mod_cache, py_mod_cache)?, + _ => self.import_user_erg_mod(__name__, mod_name, mod_cache, py_mod_cache), } - Ok(()) } fn import_user_erg_mod( &self, - var_name: &VarName, __name__: Str, - name_lit: &Literal, + mod_name: &Literal, mod_cache: &SharedModuleCache, py_mod_cache: &SharedModuleCache, - ) -> CompileResult<()> { - if let Some((_, entry)) = mod_cache.get_by_name(&__name__) { - mod_cache.register_alias(var_name.clone(), entry); - return Ok(()); - } + ) -> CompileResult { let mut dir = if let Input::File(mut path) = self.cfg.input.clone() { path.pop(); path @@ -893,7 +858,7 @@ impl Context { self.cfg.input.clone(), line!() as usize, err.to_string(), - name_lit.loc(), + mod_name.loc(), self.caused_by(), self.mod_cache.as_ref().unwrap().get_similar_name(&__name__), self.similar_builtin_py_mod_name(&__name__).or_else(|| { @@ -906,56 +871,68 @@ impl Context { return Err(err); } }; - let cfg = ErgConfig::with_path(path); + if mod_cache.get(&path).is_some() { + return Ok(path); + } + let cfg = ErgConfig::with_path(path.clone()); let src = cfg.input.read(); - let mut builder = HIRBuilder::new_with_cache( - cfg, - var_name.inspect(), - mod_cache.clone(), - py_mod_cache.clone(), - ); + let mut builder = + HIRBuilder::new_with_cache(cfg, __name__, 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()); + mod_cache.register(path.clone(), Some(hir), builder.pop_ctx()); } Err((maybe_hir, errs)) => { if let Some(hir) = maybe_hir { - mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); + mod_cache.register(path, Some(hir), builder.pop_ctx()); } return Err(errs); } } - Ok(()) + Ok(path) } - fn import_py_mod(&mut self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { - let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); - let mod_cache = self.mod_cache.as_ref().unwrap(); + fn import_py_mod(&mut self, mod_name: &Literal) -> CompileResult { + let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str); + let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); match &__name__[..] { "importlib" => { - mod_cache.register(var_name.clone(), None, Self::init_py_importlib_mod()); + let path = PathBuf::from(".importlib"); + py_mod_cache.register(path.clone(), None, Self::init_py_importlib_mod()); + Ok(path) } "io" => { - mod_cache.register(var_name.clone(), None, Self::init_py_io_mod()); + let path = PathBuf::from(".io"); + py_mod_cache.register(path.clone(), None, Self::init_py_io_mod()); + Ok(path) } "math" => { - mod_cache.register(var_name.clone(), None, Self::init_py_math_mod()); + let path = PathBuf::from(".math"); + py_mod_cache.register(path.clone(), None, Self::init_py_math_mod()); + Ok(path) } "random" => { - mod_cache.register(var_name.clone(), None, Self::init_py_random_mod()); + let path = PathBuf::from(".random"); + py_mod_cache.register(path.clone(), None, Self::init_py_random_mod()); + Ok(path) } "socket" => { - mod_cache.register(var_name.clone(), None, Self::init_py_socket_mod()); + let path = PathBuf::from(".socket"); + py_mod_cache.register(path.clone(), None, Self::init_py_socket_mod()); + Ok(path) } "sys" => { - mod_cache.register(var_name.clone(), None, Self::init_py_sys_mod()); + let path = PathBuf::from(".sys"); + py_mod_cache.register(path.clone(), None, Self::init_py_sys_mod()); + Ok(path) } "time" => { - mod_cache.register(var_name.clone(), None, Self::init_py_time_mod()); + let path = PathBuf::from(".time"); + py_mod_cache.register(path.clone(), None, Self::init_py_time_mod()); + Ok(path) } - _ => self.import_user_py_mod(var_name, lit)?, + _ => self.import_user_py_mod(mod_name), } - Ok(()) } fn similar_builtin_py_mod_name(&self, name: &Str) -> Option { @@ -966,13 +943,9 @@ impl Context { .map(Str::rc) } - fn import_user_py_mod(&self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { - let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); + fn import_user_py_mod(&self, mod_name: &Literal) -> CompileResult { + let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str); 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) = self.cfg.input.clone() { path.pop(); path @@ -987,39 +960,34 @@ impl Context { self.cfg.input.clone(), line!() as usize, err.to_string(), - lit.loc(), + mod_name.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__) - }), + self.similar_builtin_py_mod_name(&__name__) + .or_else(|| py_mod_cache.get_similar_name(&__name__)), ); return Err(TyCheckErrors::from(err)); } }; - let cfg = ErgConfig::with_path(path); + if py_mod_cache.get(&path).is_some() { + return Ok(path); + } + let cfg = ErgConfig::with_path(path.clone()); let src = cfg.input.read(); - let mut builder = HIRBuilder::new_with_cache( - cfg, - var_name.inspect(), - py_mod_cache.clone(), - py_mod_cache.clone(), - ); + let mut builder = + HIRBuilder::new_with_cache(cfg, __name__, 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()); + py_mod_cache.register(path.clone(), Some(hir), builder.pop_ctx()); } Err((maybe_hir, errs)) => { if let Some(hir) = maybe_hir { - py_mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); + py_mod_cache.register(path, Some(hir), builder.pop_ctx()); } return Err(errs); } } - Ok(()) + Ok(path) } pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) { diff --git a/compiler/erg_compiler/context/test.rs b/compiler/erg_compiler/context/test.rs index 07b528e7..225cad55 100644 --- a/compiler/erg_compiler/context/test.rs +++ b/compiler/erg_compiler/context/test.rs @@ -4,7 +4,7 @@ use erg_common::Str; // use erg_common::error::Location; use erg_common::{enum_unwrap, set}; -use erg_type::constructors::{func1, mono_q, poly, quant, refinement}; +use erg_type::constructors::{builtin_poly, func1, mono_q, quant, refinement}; use erg_type::typaram::TyParam; use erg_type::{Predicate, TyBound, Type}; use Type::*; @@ -32,7 +32,7 @@ impl Context { pub fn test_resolve_trait_inner1(&self) -> Result<(), ()> { let name = Str::ever("Add"); let params = vec![TyParam::t(Nat)]; - let maybe_trait = poly(name.clone(), params); + let maybe_trait = builtin_poly(name.clone(), params); let mut min = Type::Obj; for pair in self.rec_get_trait_impls(&name) { if self.supertype_of(&pair.sup_trait, &maybe_trait) { @@ -48,7 +48,7 @@ impl Context { pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> { let t = mono_q("T"); - let eq = poly("Eq", vec![TyParam::t(t.clone())]); + let eq = builtin_poly("Eq", vec![TyParam::t(t.clone())]); let bound = TyBound::subtype_of(t.clone(), eq); let bounds = set! {bound}; let unbound_t = func1(t.clone(), t); diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index 606913c1..201fc3f9 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -22,6 +22,7 @@ use crate::hir; use Predicate as Pred; use Type::*; use ValueObj::{Inf, NegInf}; +use Variance::*; impl Context { pub const TOP_LEVEL: usize = 1; @@ -159,12 +160,23 @@ impl Context { let after = after.map(|aft| self.generalize_t_inner(*aft, bounds, lazy_inits)); ref_mut(self.generalize_t_inner(*before, bounds, lazy_inits), after) } - Poly { name, mut params } => { + BuiltinPoly { name, mut params } => { let params = params .iter_mut() .map(|p| self.generalize_tp(mem::take(p), bounds, lazy_inits)) .collect::>(); - poly(name, params) + builtin_poly(name, params) + } + Poly { + path, + name, + mut params, + } => { + let params = params + .iter_mut() + .map(|p| self.generalize_tp(mem::take(p), bounds, lazy_inits)) + .collect::>(); + poly(path, name, params) } MonoProj { lhs, rhs } => { let lhs = self.generalize_t_inner(*lhs, bounds, lazy_inits); @@ -203,21 +215,26 @@ impl Context { } } - fn deref_tp(&self, tp: TyParam, loc: Location) -> SingleTyCheckResult { + fn deref_tp( + &self, + tp: TyParam, + variance: Variance, + loc: Location, + ) -> SingleTyCheckResult { match tp { TyParam::FreeVar(fv) if fv.is_linked() => { let inner = fv.unwrap_linked(); - self.deref_tp(inner, loc) + self.deref_tp(inner, variance, loc) } TyParam::FreeVar(_fv) if self.level == 0 => Err(TyCheckError::dummy_infer_error( self.cfg.input.clone(), fn_name!(), line!(), )), - TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t, loc)?)), + TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t, variance, loc)?)), TyParam::App { name, mut args } => { for param in args.iter_mut() { - *param = self.deref_tp(mem::take(param), loc)?; + *param = self.deref_tp(mem::take(param), variance, loc)?; } Ok(TyParam::App { name, args }) } @@ -243,6 +260,7 @@ impl Context { fn deref_constraint( &self, constraint: Constraint, + variance: Variance, loc: Location, ) -> SingleTyCheckResult { match constraint { @@ -259,12 +277,14 @@ impl Context { )); } Ok(Constraint::new_sandwiched( - self.deref_tyvar(sub, loc)?, - self.deref_tyvar(sup, loc)?, + self.deref_tyvar(sub, variance, loc)?, + self.deref_tyvar(sup, variance, loc)?, cyclic, )) } - Constraint::TypeOf(t) => Ok(Constraint::new_type_of(self.deref_tyvar(t, loc)?)), + Constraint::TypeOf(t) => { + Ok(Constraint::new_type_of(self.deref_tyvar(t, variance, loc)?)) + } _ => unreachable!(), } } @@ -273,10 +293,16 @@ impl Context { /// ```python // ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n) // ?T(:> Nat, <: Sub(?U(:> {1}))) ==> Nat + // ?T(:> Nat, <: Sub(?U(:> {1}))) -> ?U ==> |U: Type, T <: Sub(U)| T -> U // ?T(:> Nat, <: Sub(Str)) ==> Error! // ?T(:> {1, "a"}, <: Eq(?T(:> {1, "a"}, ...)) ==> Error! // ``` - pub(crate) fn deref_tyvar(&self, t: Type, loc: Location) -> SingleTyCheckResult { + pub(crate) fn deref_tyvar( + &self, + t: Type, + variance: Variance, + loc: Location, + ) -> SingleTyCheckResult { match t { // ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n) // ?T(:> Nat, <: Sub ?U(:> {1}))[n] ==> Nat @@ -288,13 +314,31 @@ impl Context { if self.level <= fv.level().unwrap() { // REVIEW: Even if type constraints can be satisfied, implementation may not exist if self.subtype_of(sub_t, super_t) { - Ok(sub_t.clone()) + match variance { + Variance::Covariant => Ok(sub_t.clone()), + Variance::Contravariant => Ok(super_t.clone()), + Variance::Invariant => { + if self.supertype_of(sub_t, super_t) { + Ok(sub_t.clone()) + } else { + Err(TyCheckError::subtyping_error( + self.cfg.input.clone(), + line!() as usize, + &self.deref_tyvar(sub_t.clone(), variance, loc)?, + &self.deref_tyvar(super_t.clone(), variance, loc)?, + None, + Some(loc), + self.caused_by(), + )) + } + } + } } else { Err(TyCheckError::subtyping_error( self.cfg.input.clone(), line!() as usize, - &self.deref_tyvar(sub_t.clone(), loc)?, - &self.deref_tyvar(super_t.clone(), loc)?, + &self.deref_tyvar(sub_t.clone(), variance, loc)?, + &self.deref_tyvar(super_t.clone(), variance, loc)?, None, Some(loc), self.caused_by(), @@ -318,42 +362,62 @@ impl Context { } } else { let new_constraint = fv.crack_constraint().clone(); - let new_constraint = self.deref_constraint(new_constraint, loc)?; + let new_constraint = self.deref_constraint(new_constraint, variance, loc)?; fv.update_constraint(new_constraint); Ok(Type::FreeVar(fv)) } } Type::FreeVar(fv) if fv.is_linked() => { let t = fv.unwrap_linked(); - self.deref_tyvar(t, loc) + self.deref_tyvar(t, variance, loc) } - Type::Poly { name, mut params } => { - for param in params.iter_mut() { - *param = self.deref_tp(mem::take(param), loc)?; + Type::BuiltinPoly { name, mut params } => { + let typ = builtin_poly(&name, params.clone()); + let (_, ctx) = self.get_nominal_type_ctx(&typ).unwrap(); + let variances = ctx.type_params_variance(); + for (param, variance) in params.iter_mut().zip(variances.into_iter()) { + *param = self.deref_tp(mem::take(param), variance, loc)?; } - Ok(Type::Poly { name, params }) + Ok(Type::BuiltinPoly { name, params }) + } + Type::Poly { + path, + name, + mut params, + } => { + let typ = poly(path.clone(), &name, params.clone()); + let (_, ctx) = self.get_nominal_type_ctx(&typ).unwrap(); + let variances = ctx.type_params_variance(); + for (param, variance) in params.iter_mut().zip(variances.into_iter()) { + *param = self.deref_tp(mem::take(param), variance, loc)?; + } + Ok(Type::Poly { path, name, params }) } Type::Subr(mut subr) => { for param in subr.non_default_params.iter_mut() { - *param.typ_mut() = self.deref_tyvar(mem::take(param.typ_mut()), loc)?; + *param.typ_mut() = + self.deref_tyvar(mem::take(param.typ_mut()), Contravariant, loc)?; } if let Some(var_args) = &mut subr.var_params { - *var_args.typ_mut() = self.deref_tyvar(mem::take(var_args.typ_mut()), loc)?; + *var_args.typ_mut() = + self.deref_tyvar(mem::take(var_args.typ_mut()), Contravariant, loc)?; } for d_param in subr.default_params.iter_mut() { - *d_param.typ_mut() = self.deref_tyvar(mem::take(d_param.typ_mut()), loc)?; + *d_param.typ_mut() = + self.deref_tyvar(mem::take(d_param.typ_mut()), Contravariant, loc)?; } - subr.return_t = Box::new(self.deref_tyvar(mem::take(&mut subr.return_t), loc)?); + subr.return_t = + Box::new(self.deref_tyvar(mem::take(&mut subr.return_t), Covariant, loc)?); Ok(Type::Subr(subr)) } Type::Ref(t) => { - let t = self.deref_tyvar(*t, loc)?; + let t = self.deref_tyvar(*t, variance, loc)?; Ok(ref_(t)) } Type::RefMut { before, after } => { - let before = self.deref_tyvar(*before, loc)?; + let before = self.deref_tyvar(*before, variance, loc)?; let after = if let Some(after) = after { - Some(self.deref_tyvar(*after, loc)?) + Some(self.deref_tyvar(*after, variance, loc)?) } else { None }; @@ -362,12 +426,29 @@ impl Context { Type::Callable { .. } => todo!(), Type::Record(mut rec) => { for (_, field) in rec.iter_mut() { - *field = self.deref_tyvar(mem::take(field), loc)?; + *field = self.deref_tyvar(mem::take(field), variance, loc)?; } Ok(Type::Record(rec)) } + // |X <: T <: X| X -> X ==> T -> T + /*Type::Quantified(quant) => { + let mut replace_list = vec![]; + let mut new_bounds = set!{}; + for bound in quant.bounds.into_iter() { + if let Some((sub, mid, sup)) = bound.get_types() { + if self.subtype_of(sub, sup) && self.supertype_of(sub, sup) { + replace_list.push((mid, sub)); + } else { + new_bounds.insert(bound); + } + } else { + new_bounds.insert(bound); + } + } + Ok(()) + }*/ Type::Refinement(refine) => { - let t = self.deref_tyvar(*refine.t, loc)?; + let t = self.deref_tyvar(*refine.t, variance, loc)?; // TODO: deref_predicate Ok(refinement(refine.var, t, refine.preds)) } @@ -401,7 +482,7 @@ impl Context { hir::Expr::Accessor(acc) => { let loc = acc.loc(); let t = acc.ref_mut_t(); - *t = self.deref_tyvar(mem::take(t), loc)?; + *t = self.deref_tyvar(mem::take(t), Covariant, loc)?; match acc { hir::Accessor::Attr(attr) => { self.resolve_expr_t(&mut attr.obj)?; @@ -420,7 +501,7 @@ impl Context { hir::Expr::Array(array) => match array { hir::Array::Normal(arr) => { let loc = arr.loc(); - arr.t = self.deref_tyvar(mem::take(&mut arr.t), loc)?; + arr.t = self.deref_tyvar(mem::take(&mut arr.t), Covariant, loc)?; for elem in arr.elems.pos_args.iter_mut() { self.resolve_expr_t(&mut elem.expr)?; } @@ -443,10 +524,12 @@ impl Context { for attr in record.attrs.iter_mut() { match &mut attr.sig { hir::Signature::Var(var) => { - var.t = self.deref_tyvar(mem::take(&mut var.t), var.loc())?; + var.t = + self.deref_tyvar(mem::take(&mut var.t), Covariant, var.loc())?; } hir::Signature::Subr(subr) => { - subr.t = self.deref_tyvar(mem::take(&mut subr.t), subr.loc())?; + subr.t = + self.deref_tyvar(mem::take(&mut subr.t), Covariant, subr.loc())?; } } for chunk in attr.body.block.iter_mut() { @@ -458,7 +541,7 @@ impl Context { hir::Expr::BinOp(binop) => { let loc = binop.loc(); let t = binop.signature_mut_t().unwrap(); - *t = self.deref_tyvar(mem::take(t), loc)?; + *t = self.deref_tyvar(mem::take(t), Covariant, loc)?; self.resolve_expr_t(&mut binop.lhs)?; self.resolve_expr_t(&mut binop.rhs)?; Ok(()) @@ -466,14 +549,14 @@ impl Context { hir::Expr::UnaryOp(unaryop) => { let loc = unaryop.loc(); let t = unaryop.signature_mut_t().unwrap(); - *t = self.deref_tyvar(mem::take(t), loc)?; + *t = self.deref_tyvar(mem::take(t), Covariant, loc)?; self.resolve_expr_t(&mut unaryop.expr)?; Ok(()) } hir::Expr::Call(call) => { let loc = call.loc(); let t = call.signature_mut_t().unwrap(); - *t = self.deref_tyvar(mem::take(t), loc)?; + *t = self.deref_tyvar(mem::take(t), Covariant, loc)?; for arg in call.args.pos_args.iter_mut() { self.resolve_expr_t(&mut arg.expr)?; } @@ -483,16 +566,16 @@ impl Context { Ok(()) } hir::Expr::Decl(decl) => { - decl.t = self.deref_tyvar(mem::take(&mut decl.t), decl.loc())?; + decl.t = self.deref_tyvar(mem::take(&mut decl.t), Covariant, decl.loc())?; Ok(()) } hir::Expr::Def(def) => { match &mut def.sig { hir::Signature::Var(var) => { - var.t = self.deref_tyvar(mem::take(&mut var.t), var.loc())?; + var.t = self.deref_tyvar(mem::take(&mut var.t), Covariant, var.loc())?; } hir::Signature::Subr(subr) => { - subr.t = self.deref_tyvar(mem::take(&mut subr.t), subr.loc())?; + subr.t = self.deref_tyvar(mem::take(&mut subr.t), Covariant, subr.loc())?; } } for chunk in def.body.block.iter_mut() { @@ -501,7 +584,7 @@ impl Context { Ok(()) } hir::Expr::Lambda(lambda) => { - lambda.t = self.deref_tyvar(mem::take(&mut lambda.t), lambda.loc())?; + lambda.t = self.deref_tyvar(mem::take(&mut lambda.t), Covariant, lambda.loc())?; for chunk in lambda.body.iter_mut() { self.resolve_expr_t(chunk)?; } @@ -780,17 +863,46 @@ impl Context { (l, Type::Ref(r)) => self.reunify(l, r, bef_loc, aft_loc), (l, Type::RefMut { before, .. }) => self.reunify(l, before, bef_loc, aft_loc), ( - Type::Poly { + Type::BuiltinPoly { name: ln, params: lps, }, - Type::Poly { + Type::BuiltinPoly { name: rn, params: rps, }, ) => { if ln != rn { - let before_t = poly(ln.clone(), lps.clone()); + let before_t = builtin_poly(ln.clone(), lps.clone()); + return Err(TyCheckError::re_unification_error( + self.cfg.input.clone(), + line!() as usize, + &before_t, + after_t, + bef_loc, + aft_loc, + self.caused_by(), + )); + } + for (l, r) in lps.iter().zip(rps.iter()) { + self.reunify_tp(l, r)?; + } + Ok(()) + } + ( + Type::Poly { + path: lp, + name: ln, + params: lps, + }, + Type::Poly { + path: rp, + name: rn, + params: rps, + }, + ) => { + if lp != rp || ln != rn { + let before_t = poly(lp.clone(), ln.clone(), lps.clone()); return Err(TyCheckError::re_unification_error( self.cfg.input.clone(), line!() as usize, @@ -1047,11 +1159,11 @@ impl Context { Ok(()) } ( - Type::Poly { + Type::BuiltinPoly { name: ln, params: lps, }, - Type::Poly { + Type::BuiltinPoly { name: rn, params: rps, }, @@ -1072,6 +1184,34 @@ impl Context { } Ok(()) } + ( + Type::Poly { + path: lp, + name: ln, + params: lps, + }, + Type::Poly { + path: rp, + name: rn, + params: rps, + }, + ) => { + if lp != rp || ln != rn { + return Err(TyCheckErrors::from(TyCheckError::unification_error( + self.cfg.input.clone(), + line!() as usize, + maybe_sub, + maybe_sup, + sub_loc, + sup_loc, + self.caused_by(), + ))); + } + for (l, r) in lps.iter().zip(rps.iter()) { + self.sub_unify_tp(l, r, None, false)?; + } + Ok(()) + } (_, Type::Ref(t)) => { self.sub_unify(maybe_sub, t, sub_loc, sup_loc, param_name)?; Ok(()) @@ -1085,7 +1225,7 @@ impl Context { (Refinement(_), Refinement(_)) => todo!(), (Type::Subr(_) | Type::Record(_), Type) => Ok(()), // TODO Tuple2, ... - (Type::Poly{ name, .. }, Type) if &name[..] == "Array" || &name[..] == "Tuple" => Ok(()), + (Type::BuiltinPoly{ name, .. }, Type) if &name[..] == "Array" || &name[..] == "Tuple" => Ok(()), _ => todo!("{maybe_sub} can be a subtype of {maybe_sup}, but failed to semi-unify (or existential types are not supported)"), } } diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index f9e8e2e3..56041e4b 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -385,6 +385,10 @@ impl Identifier { pub fn is_procedural(&self) -> bool { self.name.is_procedural() } + + pub fn downcast(self) -> erg_parser::ast::Identifier { + erg_parser::ast::Identifier::new(self.dot, self.name) + } } #[derive(Debug, Clone)] diff --git a/compiler/erg_compiler/link.rs b/compiler/erg_compiler/link.rs index 7a4d2d69..037a3834 100644 --- a/compiler/erg_compiler/link.rs +++ b/compiler/erg_compiler/link.rs @@ -1,5 +1,5 @@ use std::mem; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use erg_common::config::{ErgConfig, Input}; use erg_common::traits::{Locational, Stream}; @@ -9,8 +9,9 @@ use erg_common::{enum_unwrap, log}; use erg_parser::ast::DefId; use erg_parser::token::{Token, TokenKind}; +use erg_type::typaram::TyParam; use erg_type::value::ValueObj; -use erg_type::Type; +use erg_type::{HasType, Type}; use crate::hir::{ Accessor, Args, Block, Call, Def, DefBody, Expr, Identifier, Literal, PosArg, HIR, @@ -30,15 +31,16 @@ impl Linker { // x = ModuleType("mod") // exec(code, x.__dict__) # `code` is the mod's content Expr::Def(ref def) if def.def_kind().is_erg_import() => { + let path = enum_unwrap!(def.sig.ref_t().typarams().remove(0), TyParam::Value:(ValueObj::Str:(_))); + let path = Path::new(&path[..]); + let path = cfg.input.resolve(path).unwrap(); // In the case of REPL, entries cannot be used up let hir = if cfg.input.is_repl() { mod_cache - .get(&def.sig.ident().inspect()[..]) + .get(path.as_path()) .and_then(|entry| entry.hir.clone()) } else { - mod_cache - .remove(&def.sig.ident().inspect()[..]) - .and_then(|entry| entry.hir) + mod_cache.remove(path.as_path()).and_then(|entry| entry.hir) }; let mod_name = enum_unwrap!(def.body.block.first().unwrap(), Expr::Call) .args diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 2bac0d2c..790c2a79 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -16,7 +16,7 @@ use erg_parser::build_ast::ASTBuilder; use erg_parser::token::{Token, TokenKind}; use erg_type::constructors::{ - array, array_mut, builtin_mono, free_var, func, mono, poly, proc, quant, + array, array_mut, builtin_mono, builtin_poly, free_var, func, mono, proc, quant, }; use erg_type::free::Constraint; use erg_type::typaram::TyParam; @@ -85,11 +85,8 @@ impl Runnable for ASTLowerer { fn exec(&mut self) -> Result<(), Self::Errs> { let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let ast = ast_builder.build(self.input().read())?; - let (hir, warns) = self - .lower(ast, "exec") - .map_err(|(_, errs)| self.convert(errs))?; + let (hir, warns) = self.lower(ast, "exec").map_err(|(_, errs)| errs)?; if self.cfg.verbose >= 2 { - let warns = self.convert(warns); warns.fmt_all_stderr(); } println!("{hir}"); @@ -99,9 +96,7 @@ impl Runnable for ASTLowerer { 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))?; + let (hir, ..) = self.lower(ast, "eval").map_err(|(_, errs)| errs)?; Ok(format!("{hir}")) } } @@ -121,13 +116,6 @@ impl ASTLowerer { } } - fn convert(&self, errs: LowerErrors) -> CompileErrors { - errs.into_iter() - .map(|e| CompileError::new(e.core, self.input().clone(), e.caused_by)) - .collect::>() - .into() - } - fn return_t_check( &self, loc: Location, @@ -160,7 +148,7 @@ impl ASTLowerer { if mode != "eval" && !expr.ref_t().is_nonelike() && !expr.is_type_asc() { Err(LowerError::syntax_error( self.cfg.input.clone(), - 0, + line!() as usize, expr.loc(), AtomicStr::arc(&self.ctx.name[..]), switch_lang!( @@ -264,7 +252,7 @@ impl ASTLowerer { match maybe_len { Ok(v @ ValueObj::Nat(_)) => { if elem.ref_t().is_mut() { - poly( + builtin_poly( "ArrayWithMutType!", vec![TyParam::t(elem.t()), TyParam::Value(v)], ) @@ -274,7 +262,7 @@ impl ASTLowerer { } Ok(v @ ValueObj::Mut(_)) if v.class() == builtin_mono("Nat!") => { if elem.ref_t().is_mut() { - poly( + builtin_poly( "ArrayWithMutTypeAndLength!", vec![TyParam::t(elem.t()), TyParam::Value(v)], ) @@ -286,7 +274,7 @@ impl ASTLowerer { // REVIEW: is it ok to ignore the error? Err(_e) => { if elem.ref_t().is_mut() { - poly( + builtin_poly( "ArrayWithMutType!", vec![TyParam::t(elem.t()), TyParam::erased(Type::Nat)], ) @@ -349,7 +337,9 @@ impl ASTLowerer { } ast::Accessor::Attr(attr) => { let obj = self.lower_expr(*attr.obj)?; - let t = self.ctx.rec_get_attr_t(&obj, &attr.ident, &self.ctx.name)?; + let t = + self.ctx + .rec_get_attr_t(&obj, &attr.ident, &self.cfg.input, &self.ctx.name)?; let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name); let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident, t)); Ok(acc) @@ -389,8 +379,12 @@ impl ASTLowerer { (Type::Failure, None) } else { ( - self.ctx.rec_get_var_t(&ident, &self.ctx.name)?, - self.ctx.get_local_uniq_obj_name(&ident.name), + self.ctx + .rec_get_var_t(&ident, &self.cfg.input, &self.ctx.name)?, + self.ctx + .get_singular_ctx_from_ident(&ident, &self.ctx.name) + .ok() + .map(|ctx| ctx.name.clone()), ) }; let ident = hir::Identifier::new(ident.dot, ident.name, __name__, t); @@ -403,7 +397,9 @@ impl ASTLowerer { let lhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?); let rhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?); let args = [lhs, rhs]; - let t = self.ctx.get_binop_t(&bin.op, &args, &self.ctx.name)?; + let t = self + .ctx + .get_binop_t(&bin.op, &args, &self.cfg.input, &self.ctx.name)?; let mut args = args.into_iter(); let lhs = args.next().unwrap().expr; let rhs = args.next().unwrap().expr; @@ -415,7 +411,9 @@ impl ASTLowerer { let mut args = unary.args.into_iter(); let arg = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?); let args = [arg]; - let t = self.ctx.get_unaryop_t(&unary.op, &args, &self.ctx.name)?; + let t = self + .ctx + .get_unaryop_t(&unary.op, &args, &self.cfg.input, &self.ctx.name)?; let mut args = args.into_iter(); let expr = args.next().unwrap().expr; Ok(hir::UnaryOp::new(unary.op, expr, t)) @@ -443,6 +441,7 @@ impl ASTLowerer { &call.method_name, &hir_args.pos_args, &hir_args.kw_args, + &self.cfg.input, &self.ctx.name, )?; let method_name = if let Some(method_name) = call.method_name { @@ -455,7 +454,14 @@ impl ASTLowerer { } else { None }; - Ok(hir::Call::new(obj, method_name, hir_args, sig_t)) + let call = hir::Call::new(obj, method_name, hir_args, sig_t); + if let Some(kind) = call.import_kind() { + let mod_name = enum_unwrap!(call.args.get_left_or_key("Path").unwrap(), hir::Expr::Lit); + if let Err(errs) = self.ctx.import_mod(kind, mod_name) { + self.errs.extend(errs.into_iter()); + }; + } + Ok(call) } fn lower_pack(&mut self, pack: ast::DataPack) -> LowerResult { @@ -482,6 +488,7 @@ impl ASTLowerer { &Some(method_name.clone()), &args, &[], + &self.cfg.input, &self.ctx.name, )?; let args = hir::Args::new(args, None, vec![], None); @@ -630,20 +637,6 @@ impl ASTLowerer { .as_mut() .unwrap() .assign_var_sig(&sig, found_body_t, id)?; - match block.first().unwrap() { - hir::Expr::Call(call) => { - if let Some(kind) = call.import_kind() { - if let Err(errs) = self.ctx.outer.as_mut().unwrap().import_mod( - kind, - &ident.name, - &call.args.pos_args.first().unwrap().expr, - ) { - self.errs.extend(errs.into_iter()); - }; - } - } - _other => {} - } 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); @@ -785,7 +778,7 @@ impl ASTLowerer { } let (_, ctx) = self .ctx - .get_nominal_type_ctx(&mono(self.ctx.mod_name(), hir_def.sig.ident().inspect())) + .get_nominal_type_ctx(&mono(self.ctx.path(), hir_def.sig.ident().inspect())) .unwrap(); let type_obj = enum_unwrap!(self.ctx.rec_get_const_obj(hir_def.sig.ident().inspect()).unwrap(), ValueObj::Type:(TypeObj::Generated:(_))); let sup_type = enum_unwrap!(&hir_def.body.block.first().unwrap(), hir::Expr::Call) @@ -1224,7 +1217,7 @@ impl ASTLowerer { Ok(hir) => hir, Err((hir, errs)) => { self.errs.extend(errs.into_iter()); - log!(err "the AST lowering process has failed."); + log!(err "the resolving process has failed. errs: {}", self.errs.len()); return Err((Some(hir), LowerErrors::from(self.errs.take_all()))); } }; @@ -1239,7 +1232,7 @@ impl ASTLowerer { log!(info "the AST lowering process has completed."); Ok((hir, LowerWarnings::from(self.warns.take_all()))) } else { - log!(err "the AST lowering process has failed."); + log!(err "the AST lowering process has failed. errs: {}", self.errs.len()); Err((Some(hir), LowerErrors::from(self.errs.take_all()))) } } diff --git a/compiler/erg_compiler/mod_cache.rs b/compiler/erg_compiler/mod_cache.rs index 676bb6c5..a5cd873b 100644 --- a/compiler/erg_compiler/mod_cache.rs +++ b/compiler/erg_compiler/mod_cache.rs @@ -1,6 +1,7 @@ use std::borrow::Borrow; use std::fmt; use std::hash::Hash; +use std::path::PathBuf; use std::rc::Rc; use erg_common::dict::Dict; @@ -8,8 +9,6 @@ use erg_common::levenshtein::get_similar_name; use erg_common::shared::Shared; use erg_common::Str; -use erg_parser::ast::VarName; - use crate::context::Context; use crate::hir::HIR; @@ -65,13 +64,17 @@ impl ModuleEntry { #[derive(Debug, Default)] pub struct ModuleCache { - cache: Dict, + cache: Dict, last_id: usize, } impl fmt::Display for ModuleCache { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ModuleCache {}", self.cache) + write!(f, "ModuleCache {{")?; + for (path, entry) in self.cache.iter() { + writeln!(f, "{}: {}, ", path.display(), entry)?; + } + write!(f, "}}") } } @@ -83,42 +86,32 @@ impl ModuleCache { } } - pub fn get(&self, name: &Q) -> Option<&ModuleEntry> + pub fn get(&self, path: &P) -> Option<&ModuleEntry> where - VarName: Borrow, + PathBuf: Borrow

, { - self.cache.get(name) + self.cache.get(path) } - 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> + pub fn get_mut(&mut self, path: &Q) -> Option<&mut ModuleEntry> where - VarName: Borrow, + PathBuf: Borrow, { - self.cache.get_mut(name) + self.cache.get_mut(path) } - pub fn register(&mut self, name: VarName, hir: Option, ctx: Context) { + pub fn register(&mut self, path: PathBuf, hir: Option, ctx: Context) { self.last_id += 1; let id = ModId::new(self.last_id); let entry = ModuleEntry::new(id, hir, ctx); - self.cache.insert(name, entry); + self.cache.insert(path, 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 + pub fn remove(&mut self, path: &Q) -> Option where - VarName: Borrow, + PathBuf: Borrow, { - self.cache.remove(name) + self.cache.remove(path) } pub fn remove_by_id(&mut self, id: ModId) -> Option { @@ -136,7 +129,7 @@ impl ModuleCache { } pub fn get_similar_name(&self, name: &str) -> Option { - get_similar_name(self.cache.iter().map(|(v, _)| &v.inspect()[..]), name).map(Str::rc) + get_similar_name(self.cache.iter().map(|(v, _)| v.to_str().unwrap()), name).map(Str::rc) } } @@ -156,55 +149,46 @@ impl SharedModuleCache { self_ } - pub fn get(&self, name: &Q) -> Option<&ModuleEntry> + pub fn get(&self, path: &Q) -> Option<&ModuleEntry> where - VarName: Borrow, + PathBuf: Borrow, { let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() }; - ref_.get(name) + ref_.get(path) } - 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> + pub fn get_mut(&self, path: &Q) -> Option<&mut ModuleEntry> where - VarName: Borrow, + PathBuf: Borrow, { let ref_ = unsafe { self.0.as_ptr().as_mut().unwrap() }; - ref_.get_mut(name) + ref_.get_mut(path) } - pub fn get_ctx(&self, name: &Q) -> Option> + pub fn get_ctx(&self, path: &Q) -> Option> where - VarName: Borrow, + PathBuf: Borrow, { - self.0.borrow().get(name).map(|entry| entry.ctx.clone()) + self.0.borrow().get(path).map(|entry| entry.ctx.clone()) } - pub fn ref_ctx(&self, name: &Q) -> Option<&Context> + pub fn ref_ctx(&self, path: &Q) -> Option<&Context> where - VarName: Borrow, + PathBuf: Borrow, { let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() }; - ref_.get(name).map(|entry| entry.ctx.as_ref()) + ref_.get(path).map(|entry| entry.ctx.as_ref()) } - pub fn register(&self, name: VarName, hir: Option, ctx: Context) { - self.0.borrow_mut().register(name, hir, ctx); + pub fn register(&self, path: PathBuf, hir: Option, ctx: Context) { + self.0.borrow_mut().register(path, 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 + pub fn remove(&self, path: &Q) -> Option where - VarName: Borrow, + PathBuf: Borrow, { - self.0.borrow_mut().remove(name) + self.0.borrow_mut().remove(path) } pub fn remove_by_id(&self, id: ModId) -> Option { diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index 09f25917..c0ad5b5f 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -509,7 +509,28 @@ impl Parser { let local = ConstLocal::new(local.name.into_token()); Ok(ConstExpr::Accessor(ConstAccessor::Local(local))) } - // TODO: App, Array, Record, BinOp, UnaryOp, + Expr::Array(array) => match array { + Array::Normal(arr) => { + let (elems, _, _) = arr.elems.deconstruct(); + let mut const_elems = vec![]; + for elem in elems.into_iter() { + let const_expr = self.validate_const_expr(elem.expr)?; + const_elems.push(ConstPosArg::new(const_expr)); + } + let elems = ConstArgs::new(const_elems, vec![], None); + let const_arr = ConstArray::new(arr.l_sqbr, arr.r_sqbr, elems, None); + Ok(ConstExpr::Array(const_arr)) + } + other => { + self.errs.push(ParseError::feature_error( + line!() as usize, + other.loc(), + "???", + )); + Err(()) + } + }, + // TODO: App, Record, BinOp, UnaryOp, other => { self.errs.push(ParseError::syntax_error( 0, diff --git a/compiler/erg_type/constructors.rs b/compiler/erg_type/constructors.rs index b23dd1be..8a7edd93 100644 --- a/compiler/erg_type/constructors.rs +++ b/compiler/erg_type/constructors.rs @@ -23,35 +23,51 @@ pub fn named_free_var(name: Str, level: usize, constraint: Constraint) -> Type { } pub fn array(elem_t: Type, len: TyParam) -> Type { - poly("Array", vec![TyParam::t(elem_t), len]) + builtin_poly("Array", vec![TyParam::t(elem_t), len]) } pub fn array_mut(elem_t: Type, len: TyParam) -> Type { - poly("Array!", vec![TyParam::t(elem_t), len]) + builtin_poly("Array!", vec![TyParam::t(elem_t), len]) } pub fn dict(k_t: Type, v_t: Type) -> Type { - poly("Dict", vec![TyParam::t(k_t), TyParam::t(v_t)]) + builtin_poly("Dict", vec![TyParam::t(k_t), TyParam::t(v_t)]) } pub fn tuple(args: Vec) -> Type { let name = format!("Tuple{}", args.len()); - poly(name, args.into_iter().map(TyParam::t).collect()) + builtin_poly(name, args.into_iter().map(TyParam::t).collect()) } #[inline] pub fn range(t: Type) -> Type { - poly("Range", vec![TyParam::t(t)]) + builtin_poly("Range", vec![TyParam::t(t)]) } -pub fn enum_t(s: Set) -> Type { +#[inline] +pub fn module(path: TyParam) -> Type { + builtin_poly("Module", vec![path]) +} + +pub fn v_enum(s: Set) -> Type { assert!(is_homogeneous(&s)); let name = Str::from(fresh_varname()); + let t = inner_class(&s); let preds = s - .iter() - .map(|o| Predicate::eq(name.clone(), TyParam::value(o.clone()))) + .into_iter() + .map(|o| Predicate::eq(name.clone(), TyParam::value(o))) .collect(); - let refine = RefinementType::new(name, inner_class(&s), preds); + let refine = RefinementType::new(name, t, preds); + Type::Refinement(refine) +} + +pub fn tp_enum(ty: Type, s: Set) -> Type { + let name = Str::from(fresh_varname()); + let preds = s + .into_iter() + .map(|tp| Predicate::eq(name.clone(), tp)) + .collect(); + let refine = RefinementType::new(name, ty, preds); Type::Refinement(refine) } @@ -97,7 +113,7 @@ where } pub fn iter(t: Type) -> Type { - poly("Iter", vec![TyParam::t(t)]) + builtin_poly("Iter", vec![TyParam::t(t)]) } pub fn ref_(t: Type) -> Type { @@ -112,11 +128,11 @@ pub fn ref_mut(before: Type, after: Option) -> Type { } pub fn option(t: Type) -> Type { - poly("Option", vec![TyParam::t(t)]) + builtin_poly("Option", vec![TyParam::t(t)]) } pub fn option_mut(t: Type) -> Type { - poly("Option!", vec![TyParam::t(t)]) + builtin_poly("Option!", vec![TyParam::t(t)]) } pub fn subr_t( @@ -305,7 +321,7 @@ pub fn mono_q>(name: S) -> Type { } #[inline] -pub fn mono, T: Into>(path: S, name: T) -> Type { +pub fn mono, S: Into>(path: P, name: S) -> Type { Type::Mono { path: path.into(), name: name.into(), @@ -313,8 +329,8 @@ pub fn mono, T: Into>(path: S, name: T) -> Type { } #[inline] -pub fn poly>(name: S, params: Vec) -> Type { - Type::Poly { +pub fn builtin_poly>(name: S, params: Vec) -> Type { + Type::BuiltinPoly { name: name.into(), params, } @@ -328,6 +344,15 @@ pub fn poly_q>(name: S, params: Vec) -> Type { } } +#[inline] +pub fn poly, T: Into>(path: P, name: T, params: Vec) -> Type { + Type::Poly { + path: path.into(), + name: name.into(), + params, + } +} + #[inline] pub fn mono_proj>(lhs: Type, rhs: S) -> Type { Type::MonoProj { diff --git a/compiler/erg_type/lib.rs b/compiler/erg_type/lib.rs index 20c2538c..0f725cd2 100644 --- a/compiler/erg_type/lib.rs +++ b/compiler/erg_type/lib.rs @@ -12,6 +12,7 @@ pub mod value; use std::fmt; use std::ops::{Range, RangeInclusive}; +use std::path::PathBuf; use erg_common::dict::Dict; use erg_common::set::Set; @@ -181,7 +182,7 @@ impl ValueArgs { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct BuiltinConstSubr { name: &'static str, - subr: fn(ValueArgs, Str, Option) -> EvalValueResult, + subr: fn(ValueArgs, PathBuf, Option) -> EvalValueResult, sig_t: Type, as_type: Option, } @@ -195,7 +196,7 @@ impl fmt::Display for BuiltinConstSubr { impl BuiltinConstSubr { pub const fn new( name: &'static str, - subr: fn(ValueArgs, Str, Option) -> EvalValueResult, + subr: fn(ValueArgs, PathBuf, Option) -> EvalValueResult, sig_t: Type, as_type: Option, ) -> Self { @@ -210,10 +211,10 @@ impl BuiltinConstSubr { pub fn call( &self, args: ValueArgs, - mod_name: Str, + path: PathBuf, __name__: Option, ) -> EvalValueResult { - (self.subr)(args, mod_name, __name__) + (self.subr)(args, path, __name__) } } @@ -416,6 +417,13 @@ impl TyBound { } } + pub fn get_types(&self) -> Option<(&Type, &Type, &Type)> { + match self { + Self::Sandwiched { sub, mid, sup } => Some((sub, mid, sup)), + Self::Instance { .. } => None, + } + } + pub fn get_lhs(&self) -> Str { match self { Self::Sandwiched { mid, .. } => mid.name(), @@ -1095,7 +1103,6 @@ pub enum Type { Str, NoneType, Code, - Module, Frame, Error, Inf, // {∞} @@ -1110,7 +1117,7 @@ pub enum Type { Never, // {} BuiltinMono(Str), Mono { - path: Str, + path: PathBuf, name: Str, }, /* Polymorphic types */ @@ -1138,7 +1145,12 @@ pub enum Type { And(Box, Box), Not(Box, Box), Or(Box, Box), + BuiltinPoly { + name: Str, + params: Vec, + }, Poly { + path: PathBuf, name: Str, params: Vec, }, @@ -1170,7 +1182,6 @@ impl PartialEq for Type { | (Self::Str, Self::Str) | (Self::NoneType, Self::NoneType) | (Self::Code, Self::Code) - | (Self::Module, Self::Module) | (Self::Frame, Self::Frame) | (Self::Error, Self::Error) | (Self::Inf, Self::Inf) @@ -1182,11 +1193,11 @@ impl PartialEq for Type { | (Self::NotImplemented, Self::NotImplemented) | (Self::Ellipsis, Self::Ellipsis) | (Self::Never, Self::Never) => true, - (Self::BuiltinMono(l), Self::BuiltinMono(r)) => l == r, + (Self::BuiltinMono(l), Self::BuiltinMono(r)) + | (Self::MonoQVar(l), Self::MonoQVar(r)) => l == r, (Self::Mono { path: lp, name: ln }, Self::Mono { path: rp, name: rn }) => { lp == rp && ln == rn } - (Self::MonoQVar(l), Self::MonoQVar(r)) => l == r, (Self::Ref(l), Self::Ref(r)) => l == r, ( Self::RefMut { @@ -1228,6 +1239,18 @@ impl PartialEq for Type { | (Self::Or(ll, lr), Self::Or(rl, rr)) => ll == rl && lr == rr, ( Self::Poly { + path: lp, + name: ln, + params: lps, + }, + Self::Poly { + path: rp, + name: rn, + params: rps, + }, + ) => lp == rp && ln == rn && lps == rps, + ( + Self::BuiltinPoly { name: ln, params: lps, } @@ -1235,7 +1258,7 @@ impl PartialEq for Type { name: ln, params: lps, }, - Self::Poly { + Self::BuiltinPoly { name: rn, params: rps, } @@ -1281,7 +1304,7 @@ impl LimitedDisplay for Type { } match self { Self::BuiltinMono(name) => write!(f, "{name}"), - Self::Mono { path, name } => write!(f, "{name}(of {path})"), + Self::Mono { path, name } => write!(f, "{}.{name}", path.display()), Self::Ref(t) => { write!(f, "{}(", self.name())?; t.limited_fmt(f, limit - 1)?; @@ -1338,7 +1361,17 @@ impl LimitedDisplay for Type { write!(f, " or ")?; rhs.limited_fmt(f, limit - 1) } - Self::Poly { name, params } => { + Self::Poly { path, name, params } => { + write!(f, "{}.{name}(", path.display())?; + for (i, tp) in params.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + tp.limited_fmt(f, limit - 1)?; + } + write!(f, ")") + } + Self::BuiltinPoly { name, params } => { write!(f, "{name}(")?; for (i, tp) in params.iter().enumerate() { if i > 0 { @@ -1430,7 +1463,9 @@ impl HasType for Type { // Self::And(ts) | Self::Or(ts) => , Self::Subr(_sub) => todo!(), Self::Callable { param_ts, .. } => param_ts.clone(), - Self::Poly { params, .. } => params.iter().filter_map(get_t_from_tp).collect(), + Self::BuiltinPoly { params, .. } + | Self::Poly { params, .. } + | Self::PolyQVar { params, .. } => params.iter().filter_map(get_t_from_tp).collect(), _ => vec![], } } @@ -1488,7 +1523,9 @@ impl HasLevel for Type { t.update_level(level); } } - Self::Poly { params, .. } => { + Self::Poly { params, .. } + | Self::BuiltinPoly { params, .. } + | Self::PolyQVar { params, .. } => { for p in params.iter() { p.update_level(level); } @@ -1549,7 +1586,9 @@ impl HasLevel for Type { t.lift(); } } - Self::Poly { params, .. } => { + Self::Poly { params, .. } + | Self::BuiltinPoly { params, .. } + | Self::PolyQVar { params, .. } => { for p in params.iter() { p.lift(); } @@ -1622,7 +1661,6 @@ impl Type { | Self::Str | Self::NoneType | Self::Code - | Self::Module | Self::Frame | Self::Error | Self::Inf @@ -1648,8 +1686,10 @@ impl Type { } } Self::BuiltinMono(name) + | Self::Mono { name, .. } | Self::MonoQVar(name) | Self::Poly { name, .. } + | Self::BuiltinPoly { name, .. } | Self::PolyQVar { name, .. } | Self::MonoProj { rhs: name, .. } => name.ends_with('!'), Self::Refinement(refine) => refine.t.is_mut(), @@ -1661,11 +1701,13 @@ impl Type { match self { Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_nonelike(), Self::NoneType => true, - Self::Poly { name, params } if &name[..] == "Option" || &name[..] == "Option!" => { + Self::BuiltinPoly { name, params, .. } + if &name[..] == "Option" || &name[..] == "Option!" => + { let inner_t = enum_unwrap!(params.first().unwrap(), TyParam::Type); inner_t.is_nonelike() } - Self::Poly { name, params } if &name[..] == "Tuple" => params.is_empty(), + Self::BuiltinPoly { name, params, .. } if &name[..] == "Tuple" => params.is_empty(), Self::Refinement(refine) => refine.t.is_nonelike(), _ => false, } @@ -1693,7 +1735,9 @@ impl Type { .map(|(sub, sup)| sub.contains_tvar(name) || sup.contains_tvar(name)) .unwrap_or(false) } - Self::Poly { params, .. } => { + Self::Poly { params, .. } + | Self::BuiltinPoly { params, .. } + | Self::PolyQVar { params, .. } => { for param in params.iter() { match param { TyParam::Type(t) if t.contains_tvar(name) => { @@ -1766,7 +1810,6 @@ impl Type { Self::Trait => Str::ever("TraitType"), Self::Patch => Str::ever("Patch"), Self::Code => Str::ever("Code"), - Self::Module => Str::ever("Module"), Self::Frame => Str::ever("Frame"), Self::Error => Str::ever("Error"), Self::Inf => Str::ever("Inf"), @@ -1789,7 +1832,9 @@ impl Type { }) => Str::ever("Proc"), Self::Callable { .. } => Str::ever("Callable"), Self::Record(_) => Str::ever("Record"), - Self::Poly { name, .. } | Self::PolyQVar { name, .. } => name.clone(), + Self::Poly { name, .. } + | Self::BuiltinPoly { name, .. } + | Self::PolyQVar { name, .. } => name.clone(), // NOTE: compiler/codegen/convert_to_python_methodでクラス名を使うため、こうすると都合が良い Self::Refinement(refine) => refine.t.name(), Self::Quantified(_) => Str::ever("Quantified"), @@ -1819,7 +1864,7 @@ impl Type { 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()), + Self::MonoQVar(name) | Self::PolyQVar { name, .. } => Some(name.clone()), _ => None, } } @@ -1869,7 +1914,9 @@ impl Type { quant.unbound_callable.has_unbound_var() || quant.bounds.iter().any(|tb| tb.has_qvar()) } - Self::Poly { params, .. } => params.iter().any(|tp| tp.has_qvar()), + Self::Poly { params, .. } | Self::BuiltinPoly { params, .. } => { + params.iter().any(|tp| tp.has_qvar()) + } Self::MonoProj { lhs, .. } => lhs.has_qvar(), _ => false, } @@ -1907,9 +1954,9 @@ impl Type { Self::Quantified(quant) => { quant.unbound_callable.is_cachable() || quant.bounds.iter().all(|b| b.is_cachable()) } - Self::Poly { params, .. } | Self::PolyQVar { params, .. } => { - params.iter().all(|p| p.is_cachable()) - } + Self::Poly { params, .. } + | Self::BuiltinPoly { params, .. } + | Self::PolyQVar { params, .. } => params.iter().all(|p| p.is_cachable()), Self::MonoProj { lhs, .. } => lhs.is_cachable(), _ => true, } @@ -1958,9 +2005,9 @@ impl Type { quant.unbound_callable.has_unbound_var() || quant.bounds.iter().any(|b| b.has_unbound_var()) } - Self::Poly { params, .. } | Self::PolyQVar { params, .. } => { - params.iter().any(|p| p.has_unbound_var()) - } + Self::Poly { params, .. } + | Self::BuiltinPoly { params, .. } + | Self::PolyQVar { params, .. } => params.iter().any(|p| p.has_unbound_var()), Self::MonoProj { lhs, .. } => lhs.has_no_unbound_var(), _ => false, } @@ -1984,7 +2031,9 @@ impl Type { + 1, ), Self::Callable { param_ts, .. } => Some(param_ts.len() + 1), - Self::Poly { params, .. } | Self::PolyQVar { params, .. } => Some(params.len()), + Self::Poly { params, .. } + | Self::BuiltinPoly { params, .. } + | Self::PolyQVar { params, .. } => Some(params.len()), _ => None, } } @@ -2000,7 +2049,9 @@ impl Type { } Self::Subr(subr) => subr.typarams(), Self::Callable { param_ts: _, .. } => todo!(), - Self::Poly { params, .. } | Self::PolyQVar { params, .. } => params.clone(), + Self::Poly { params, .. } + | Self::BuiltinPoly { params, .. } + | Self::PolyQVar { params, .. } => params.clone(), _ => vec![], } } diff --git a/compiler/erg_type/value.rs b/compiler/erg_type/value.rs index 58997796..e296991b 100644 --- a/compiler/erg_type/value.rs +++ b/compiler/erg_type/value.rs @@ -18,7 +18,7 @@ use erg_common::{dict, fmt_iter, impl_display_from_debug, switch_lang}; use erg_common::{RcArray, Str}; use crate::codeobj::CodeObj; -use crate::constructors::{array, builtin_mono, poly, refinement, tuple}; +use crate::constructors::{array, builtin_mono, builtin_poly, refinement, tuple}; use crate::free::fresh_varname; use crate::typaram::TyParam; use crate::{ConstSubr, HasType, Predicate, Type}; @@ -506,7 +506,7 @@ impl ValueObj { Self::Float(_) => builtin_mono("Float!"), Self::Str(_) => builtin_mono("Str!"), Self::Bool(_) => builtin_mono("Bool!"), - Self::Array(arr) => poly( + Self::Array(arr) => builtin_poly( "Array!", vec![ TyParam::t(arr.iter().next().unwrap().class()),