Split cache between Python and Erg modules

This commit is contained in:
Shunsuke Shibayama 2022-09-26 14:03:06 +09:00
parent 5916096cc4
commit 5aae4a69a5
22 changed files with 521 additions and 258 deletions

View file

@ -33,3 +33,19 @@ pub fn levenshtein(lhs: &str, rhs: &str) -> usize {
} }
table[l_len][r_len] table[l_len][r_len]
} }
pub fn get_similar_name<'a, I: Iterator<Item = &'a str>>(
candidates: I,
name: &str,
) -> Option<&'a str> {
if name.len() <= 1 {
return None;
}
let most_similar_name = candidates.min_by_key(|v| levenshtein(v, name))?;
let len = most_similar_name.len();
if levenshtein(most_similar_name, name) >= len / 2 {
None
} else {
Some(most_similar_name)
}
}

View file

@ -27,7 +27,12 @@ impl Runnable for HIRBuilder {
const NAME: &'static str = "Erg HIR builder"; const NAME: &'static str = "Erg HIR builder";
fn new(cfg: ErgConfig) -> Self { fn new(cfg: ErgConfig) -> Self {
HIRBuilder::new_with_cache(cfg, Str::ever("<module>"), SharedModuleCache::new()) HIRBuilder::new_with_cache(
cfg,
Str::ever("<module>"),
SharedModuleCache::new(),
SharedModuleCache::new(),
)
} }
#[inline] #[inline]
@ -61,9 +66,10 @@ impl HIRBuilder {
cfg: ErgConfig, cfg: ErgConfig,
mod_name: S, mod_name: S,
mod_cache: SharedModuleCache, mod_cache: SharedModuleCache,
py_mod_cache: SharedModuleCache,
) -> Self { ) -> Self {
Self { Self {
lowerer: ASTLowerer::new_with_cache(cfg, mod_name, mod_cache), lowerer: ASTLowerer::new_with_cache(cfg, mod_name, mod_cache, py_mod_cache),
ownership_checker: OwnershipChecker::new(), ownership_checker: OwnershipChecker::new(),
} }
} }

View file

@ -103,8 +103,14 @@ impl Runnable for Compiler {
fn new(cfg: ErgConfig) -> Self { fn new(cfg: ErgConfig) -> Self {
let mod_cache = SharedModuleCache::new(); let mod_cache = SharedModuleCache::new();
let py_mod_cache = SharedModuleCache::new();
Self { Self {
builder: HIRBuilder::new_with_cache(cfg.copy(), "<module>", mod_cache.clone()), builder: HIRBuilder::new_with_cache(
cfg.copy(),
"<module>",
mod_cache.clone(),
py_mod_cache,
),
code_generator: CodeGenerator::new(cfg.copy()), code_generator: CodeGenerator::new(cfg.copy()),
mod_cache, mod_cache,
cfg, cfg,

View file

@ -353,6 +353,7 @@ impl Context {
Str::ever("<unnamed record>"), Str::ever("<unnamed record>"),
2, 2,
self.mod_cache.clone(), self.mod_cache.clone(),
self.py_mod_cache.clone(),
self.clone(), self.clone(),
); );
for attr in record.attrs.iter() { for attr in record.attrs.iter() {
@ -424,6 +425,7 @@ impl Context {
Str::ever("<lambda>"), Str::ever("<lambda>"),
0, 0,
self.mod_cache.clone(), self.mod_cache.clone(),
self.py_mod_cache.clone(),
self.clone(), self.clone(),
); );
let return_t = lambda_ctx.eval_const_block(&lambda.body, None)?; let return_t = lambda_ctx.eval_const_block(&lambda.body, None)?;

View file

@ -180,10 +180,10 @@ impl Context {
// 型境界はすべて各サブルーチンで定義する // 型境界はすべて各サブルーチンで定義する
// push_subtype_boundなどはユーザー定義APIの型境界決定のために使用する // push_subtype_boundなどはユーザー定義APIの型境界決定のために使用する
fn init_builtin_traits(&mut self) { fn init_builtin_traits(&mut self) {
let unpack = Self::mono_trait("Unpack", None, Self::TOP_LEVEL); let unpack = Self::mono_trait("Unpack", None, None, Self::TOP_LEVEL);
let inheritable_type = Self::mono_trait("InheritableType", None, Self::TOP_LEVEL); let inheritable_type = Self::mono_trait("InheritableType", None, None, Self::TOP_LEVEL);
let named = Self::mono_trait("Named", None, Self::TOP_LEVEL); let named = Self::mono_trait("Named", None, None, Self::TOP_LEVEL);
let mut mutable = Self::mono_trait("Mutable", None, Self::TOP_LEVEL); let mut mutable = Self::mono_trait("Mutable", None, None, Self::TOP_LEVEL);
let proj = mono_proj(mono_q("Self"), "ImmutType"); let proj = mono_proj(mono_q("Self"), "ImmutType");
let f_t = func(vec![param_t("old", proj.clone())], None, vec![], proj); let f_t = func(vec![param_t("old", proj.clone())], None, vec![], proj);
let t = pr1_met(ref_mut(mono_q("Self"), None), f_t, NoneType); let t = pr1_met(ref_mut(mono_q("Self"), None), f_t, NoneType);
@ -193,16 +193,22 @@ impl Context {
); );
mutable.register_builtin_decl("update!", t, Public); mutable.register_builtin_decl("update!", t, Public);
// REVIEW: Immutatable? // REVIEW: Immutatable?
let mut immutizable = Self::mono_trait("Immutizable", None, Self::TOP_LEVEL); let mut immutizable = Self::mono_trait("Immutizable", None, None, Self::TOP_LEVEL);
immutizable.register_superclass(builtin_mono("Mutable"), &mutable); immutizable.register_superclass(builtin_mono("Mutable"), &mutable);
immutizable.register_builtin_decl("ImmutType", Type, Public); immutizable.register_builtin_decl("ImmutType", Type, Public);
// REVIEW: Mutatable? // REVIEW: Mutatable?
let mut mutizable = Self::mono_trait("Mutizable", None, Self::TOP_LEVEL); let mut mutizable = Self::mono_trait("Mutizable", None, None, Self::TOP_LEVEL);
mutizable.register_builtin_decl("MutType!", Type, Public); mutizable.register_builtin_decl("MutType!", Type, Public);
let mut in_ = Self::poly_trait("In", vec![PS::t("T", NonDefault)], None, Self::TOP_LEVEL); let mut in_ = Self::poly_trait(
"In",
vec![PS::t("T", NonDefault)],
None,
None,
Self::TOP_LEVEL,
);
let params = vec![PS::t("T", NonDefault)]; let params = vec![PS::t("T", NonDefault)];
let input = Self::poly_trait("Input", params.clone(), None, Self::TOP_LEVEL); let input = Self::poly_trait("Input", params.clone(), None, None, Self::TOP_LEVEL);
let output = Self::poly_trait("Output", params, None, Self::TOP_LEVEL); let output = Self::poly_trait("Output", params, None, None, Self::TOP_LEVEL);
in_.register_superclass(poly("Input", vec![ty_tp(mono_q("T"))]), &input); in_.register_superclass(poly("Input", vec![ty_tp(mono_q("T"))]), &input);
let op_t = fn1_met(mono_q("T"), mono_q("I"), Bool); let op_t = fn1_met(mono_q("T"), mono_q("I"), Bool);
let op_t = quant( let op_t = quant(
@ -213,7 +219,13 @@ impl Context {
// Erg does not have a trait equivalent to `PartialEq` in Rust // Erg does not have a trait equivalent to `PartialEq` in Rust
// This means, Erg's `Float` cannot be compared with other `Float` // This means, Erg's `Float` cannot be compared with other `Float`
// use `l - r < EPSILON` to check if two floats are almost equal // use `l - r < EPSILON` to check if two floats are almost equal
let mut eq = Self::poly_trait("Eq", vec![PS::t("R", WithDefault)], None, Self::TOP_LEVEL); let mut eq = Self::poly_trait(
"Eq",
vec![PS::t("R", WithDefault)],
None,
None,
Self::TOP_LEVEL,
);
eq.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); eq.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output);
// __eq__: |Self <: Eq()| Self.(Self) -> Bool // __eq__: |Self <: Eq()| Self.(Self) -> Bool
let op_t = fn1_met(mono_q("Self"), mono_q("R"), Bool); let op_t = fn1_met(mono_q("Self"), mono_q("R"), Bool);
@ -229,6 +241,7 @@ impl Context {
"PartialOrd", "PartialOrd",
vec![PS::t("R", WithDefault)], vec![PS::t("R", WithDefault)],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
partial_ord.register_superclass(poly("Eq", vec![ty_tp(mono_q("R"))]), &eq); partial_ord.register_superclass(poly("Eq", vec![ty_tp(mono_q("R"))]), &eq);
@ -245,20 +258,26 @@ impl Context {
}, },
); );
partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public); partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public);
let mut ord = Self::mono_trait("Ord", None, Self::TOP_LEVEL); let mut ord = Self::mono_trait("Ord", None, None, Self::TOP_LEVEL);
ord.register_superclass(poly("Eq", vec![ty_tp(builtin_mono("Self"))]), &eq); ord.register_superclass(poly("Eq", vec![ty_tp(builtin_mono("Self"))]), &eq);
ord.register_superclass( ord.register_superclass(
poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]), poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]),
&partial_ord, &partial_ord,
); );
// FIXME: poly trait // FIXME: poly trait
let num = Self::mono_trait("Num", None, Self::TOP_LEVEL); let num = Self::mono_trait("Num", None, None, Self::TOP_LEVEL);
/* vec![ /* vec![
poly("Add", vec![]), poly("Add", vec![]),
poly("Sub", vec![]), poly("Sub", vec![]),
poly("Mul", vec![]), poly("Mul", vec![]),
], */ ], */
let mut seq = Self::poly_trait("Seq", vec![PS::t("T", NonDefault)], None, Self::TOP_LEVEL); let mut seq = Self::poly_trait(
"Seq",
vec![PS::t("T", NonDefault)],
None,
None,
Self::TOP_LEVEL,
);
seq.register_superclass(poly("Output", vec![ty_tp(mono_q("T"))]), &output); seq.register_superclass(poly("Output", vec![ty_tp(mono_q("T"))]), &output);
let self_t = mono_q("Self"); let self_t = mono_q("Self");
let t = fn0_met(self_t.clone(), Nat); let t = fn0_met(self_t.clone(), Nat);
@ -278,7 +297,7 @@ impl Context {
let r_bound = static_instance("R", Type); let r_bound = static_instance("R", Type);
let params = vec![PS::t("R", WithDefault)]; let params = vec![PS::t("R", WithDefault)];
let ty_params = vec![ty_tp(mono_q("R"))]; let ty_params = vec![ty_tp(mono_q("R"))];
let mut add = Self::poly_trait("Add", params.clone(), None, Self::TOP_LEVEL); let mut add = Self::poly_trait("Add", params.clone(), None, None, Self::TOP_LEVEL);
// Rについて共変(__add__の型とは関係ない) // Rについて共変(__add__の型とは関係ない)
add.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); add.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output);
let self_bound = subtypeof(mono_q("Self"), poly("Add", ty_params.clone())); let self_bound = subtypeof(mono_q("Self"), poly("Add", ty_params.clone()));
@ -290,7 +309,7 @@ impl Context {
let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
add.register_builtin_decl("__add__", op_t, Public); add.register_builtin_decl("__add__", op_t, Public);
add.register_builtin_decl("Output", Type, Public); add.register_builtin_decl("Output", Type, Public);
let mut sub = Self::poly_trait("Sub", params.clone(), None, Self::TOP_LEVEL); let mut sub = Self::poly_trait("Sub", params.clone(), None, None, Self::TOP_LEVEL);
sub.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); sub.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output);
let op_t = fn1_met( let op_t = fn1_met(
mono_q("Self"), mono_q("Self"),
@ -301,7 +320,7 @@ impl Context {
let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
sub.register_builtin_decl("__sub__", op_t, Public); sub.register_builtin_decl("__sub__", op_t, Public);
sub.register_builtin_decl("Output", Type, Public); sub.register_builtin_decl("Output", Type, Public);
let mut mul = Self::poly_trait("Mul", params.clone(), None, Self::TOP_LEVEL); let mut mul = Self::poly_trait("Mul", params.clone(), None, None, Self::TOP_LEVEL);
mul.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); mul.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output);
let op_t = fn1_met( let op_t = fn1_met(
mono_q("Self"), mono_q("Self"),
@ -312,7 +331,7 @@ impl Context {
let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
mul.register_builtin_decl("__mul__", op_t, Public); mul.register_builtin_decl("__mul__", op_t, Public);
mul.register_builtin_decl("Output", Type, Public); mul.register_builtin_decl("Output", Type, Public);
let mut div = Self::poly_trait("Div", params, None, Self::TOP_LEVEL); let mut div = Self::poly_trait("Div", params, None, None, Self::TOP_LEVEL);
div.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); div.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output);
let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "Output")); let 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"), poly("Div", ty_params.clone()));
@ -368,7 +387,7 @@ impl Context {
} }
fn init_builtin_classes(&mut self) { fn init_builtin_classes(&mut self) {
let mut obj = Self::mono_class("Obj", None, Self::TOP_LEVEL); let mut obj = Self::mono_class("Obj", None, None, Self::TOP_LEVEL);
let t = fn0_met(mono_q("Self"), mono_q("Self")); let t = fn0_met(mono_q("Self"), mono_q("Self"));
let t = quant(t, set! {subtypeof(mono_q("Self"), builtin_mono("Obj"))}); let t = quant(t, set! {subtypeof(mono_q("Self"), builtin_mono("Obj"))});
obj.register_builtin_impl("clone", t, Const, Public); obj.register_builtin_impl("clone", t, Const, Public);
@ -383,13 +402,13 @@ impl Context {
Immutable, Immutable,
Public, Public,
); );
let mut obj_in = Self::methods("In", None, Self::TOP_LEVEL); let mut obj_in = Self::methods("In", None, None, Self::TOP_LEVEL);
obj_in.register_builtin_impl("__in__", fn1_met(Obj, Type, Bool), Const, Public); obj_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, poly("Eq", vec![ty_tp(Type)]), obj_in);
let mut obj_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); let mut obj_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL);
obj_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Obj!"))); obj_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Obj!")));
obj.register_trait(Obj, builtin_mono("Mutizable"), obj_mutizable); obj.register_trait(Obj, builtin_mono("Mutizable"), obj_mutizable);
let mut float = Self::mono_class("Float", None, Self::TOP_LEVEL); let mut float = Self::mono_class("Float", None, None, Self::TOP_LEVEL);
float.register_superclass(Obj, &obj); float.register_superclass(Obj, &obj);
// TODO: support multi platform // TODO: support multi platform
float.register_builtin_const("EPSILON", ValueObj::Float(2.220446049250313e-16)); float.register_builtin_const("EPSILON", ValueObj::Float(2.220446049250313e-16));
@ -397,7 +416,7 @@ impl Context {
float.register_builtin_impl("Imag", Float, Const, Public); float.register_builtin_impl("Imag", Float, Const, Public);
float.register_marker_trait(builtin_mono("Num")); float.register_marker_trait(builtin_mono("Num"));
float.register_marker_trait(builtin_mono("Ord")); float.register_marker_trait(builtin_mono("Ord"));
let mut float_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); let mut float_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL);
float_partial_ord.register_builtin_impl( float_partial_ord.register_builtin_impl(
"__cmp__", "__cmp__",
fn1_met(Float, Float, builtin_mono("Ordering")), fn1_met(Float, Float, builtin_mono("Ordering")),
@ -411,36 +430,36 @@ impl Context {
); );
// Float doesn't have an `Eq` implementation // Float doesn't have an `Eq` implementation
let op_t = fn1_met(Float, Float, Float); let op_t = fn1_met(Float, Float, Float);
let mut float_add = Self::methods("Add", None, Self::TOP_LEVEL); let mut float_add = Self::methods("Add", None, None, Self::TOP_LEVEL);
float_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); float_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
float_add.register_builtin_const("Output", ValueObj::builtin_t(Float)); 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, poly("Add", vec![ty_tp(Float)]), float_add);
let mut float_sub = Self::methods("Sub", None, Self::TOP_LEVEL); let mut float_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL);
float_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); float_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
float_sub.register_builtin_const("Output", ValueObj::builtin_t(Float)); 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, poly("Sub", vec![ty_tp(Float)]), float_sub);
let mut float_mul = Self::methods("Mul", None, Self::TOP_LEVEL); let mut float_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL);
float_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public); float_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public);
float_mul.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_mul.register_builtin_const("Output", ValueObj::builtin_t(Float));
float_mul.register_builtin_const("PowOutput", 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, poly("Mul", vec![ty_tp(Float)]), float_mul);
let mut float_div = Self::methods("Div", None, Self::TOP_LEVEL); let mut float_div = Self::methods("Div", None, None, Self::TOP_LEVEL);
float_div.register_builtin_impl("__div__", op_t, Const, Public); float_div.register_builtin_impl("__div__", op_t, Const, Public);
float_div.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_div.register_builtin_const("Output", ValueObj::builtin_t(Float));
float_div.register_builtin_const("ModOutput", 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, poly("Div", vec![ty_tp(Float)]), float_div);
let mut float_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); let mut float_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL);
float_mutizable float_mutizable
.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Float!"))); .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Float!")));
float.register_trait(Float, builtin_mono("Mutizable"), float_mutizable); float.register_trait(Float, builtin_mono("Mutizable"), float_mutizable);
// TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat) // TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat)
let mut ratio = Self::mono_class("Ratio", None, Self::TOP_LEVEL); let mut ratio = Self::mono_class("Ratio", None, None, Self::TOP_LEVEL);
ratio.register_superclass(Obj, &obj); ratio.register_superclass(Obj, &obj);
ratio.register_builtin_impl("Real", Ratio, Const, Public); ratio.register_builtin_impl("Real", Ratio, Const, Public);
ratio.register_builtin_impl("Imag", Ratio, Const, Public); ratio.register_builtin_impl("Imag", Ratio, Const, Public);
ratio.register_marker_trait(builtin_mono("Num")); ratio.register_marker_trait(builtin_mono("Num"));
ratio.register_marker_trait(builtin_mono("Ord")); ratio.register_marker_trait(builtin_mono("Ord"));
let mut ratio_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); let mut ratio_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL);
ratio_partial_ord.register_builtin_impl( ratio_partial_ord.register_builtin_impl(
"__cmp__", "__cmp__",
fn1_met(Ratio, Ratio, builtin_mono("Ordering")), fn1_met(Ratio, Ratio, builtin_mono("Ordering")),
@ -452,33 +471,33 @@ impl Context {
poly("PartialOrd", vec![ty_tp(Ratio)]), poly("PartialOrd", vec![ty_tp(Ratio)]),
ratio_partial_ord, ratio_partial_ord,
); );
let mut ratio_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut ratio_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
ratio_eq.register_builtin_impl("__eq__", fn1_met(Ratio, Ratio, Bool), Const, Public); ratio_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, poly("Eq", vec![ty_tp(Ratio)]), ratio_eq);
let op_t = fn1_met(Ratio, Ratio, Ratio); let op_t = fn1_met(Ratio, Ratio, Ratio);
let mut ratio_add = Self::methods("Add", None, Self::TOP_LEVEL); let mut ratio_add = Self::methods("Add", None, None, Self::TOP_LEVEL);
ratio_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); ratio_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
ratio_add.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); 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, poly("Add", vec![ty_tp(Ratio)]), ratio_add);
let mut ratio_sub = Self::methods("Sub", None, Self::TOP_LEVEL); let mut ratio_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL);
ratio_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); ratio_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
ratio_sub.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); 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, poly("Sub", vec![ty_tp(Ratio)]), ratio_sub);
let mut ratio_mul = Self::methods("Mul", None, Self::TOP_LEVEL); let mut ratio_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL);
ratio_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public); ratio_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public);
ratio_mul.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_mul.register_builtin_const("Output", ValueObj::builtin_t(Ratio));
ratio_mul.register_builtin_const("PowOutput", 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, poly("Mul", vec![ty_tp(Ratio)]), ratio_mul);
let mut ratio_div = Self::methods("Div", None, Self::TOP_LEVEL); let mut ratio_div = Self::methods("Div", None, None, Self::TOP_LEVEL);
ratio_div.register_builtin_impl("__div__", op_t, Const, Public); ratio_div.register_builtin_impl("__div__", op_t, Const, Public);
ratio_div.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_div.register_builtin_const("Output", ValueObj::builtin_t(Ratio));
ratio_div.register_builtin_const("ModOutput", 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, poly("Div", vec![ty_tp(Ratio)]), ratio_div);
let mut ratio_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); let mut ratio_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL);
ratio_mutizable ratio_mutizable
.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Ratio!"))); .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Ratio!")));
ratio.register_trait(Ratio, builtin_mono("Mutizable"), ratio_mutizable); ratio.register_trait(Ratio, builtin_mono("Mutizable"), ratio_mutizable);
let mut int = Self::mono_class("Int", None, Self::TOP_LEVEL); let mut int = Self::mono_class("Int", None, None, Self::TOP_LEVEL);
int.register_superclass(Float, &float); // TODO: Float -> Ratio int.register_superclass(Float, &float); // TODO: Float -> Ratio
int.register_superclass(Obj, &obj); int.register_superclass(Obj, &obj);
int.register_marker_trait(builtin_mono("Num")); int.register_marker_trait(builtin_mono("Num"));
@ -487,7 +506,7 @@ impl Context {
// class("Rational"), // class("Rational"),
// class("Integral"), // class("Integral"),
int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public); int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public);
let mut int_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); let mut int_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL);
int_partial_ord.register_builtin_impl( int_partial_ord.register_builtin_impl(
"__partial_cmp__", "__partial_cmp__",
fn1_met(Int, Int, option(builtin_mono("Ordering"))), fn1_met(Int, Int, option(builtin_mono("Ordering"))),
@ -495,30 +514,30 @@ impl Context {
Public, Public,
); );
int.register_trait(Int, poly("PartialOrd", vec![ty_tp(Int)]), int_partial_ord); int.register_trait(Int, poly("PartialOrd", vec![ty_tp(Int)]), int_partial_ord);
let mut int_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut int_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
int_eq.register_builtin_impl("__eq__", fn1_met(Int, Int, Bool), Const, Public); int_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, poly("Eq", vec![ty_tp(Int)]), int_eq);
// __div__ is not included in Int (cast to Ratio) // __div__ is not included in Int (cast to Ratio)
let op_t = fn1_met(Int, Int, Int); let op_t = fn1_met(Int, Int, Int);
let mut int_add = Self::methods("Add", None, Self::TOP_LEVEL); let mut int_add = Self::methods("Add", None, None, Self::TOP_LEVEL);
int_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); int_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
int_add.register_builtin_const("Output", ValueObj::builtin_t(Int)); 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, poly("Add", vec![ty_tp(Int)]), int_add);
let mut int_sub = Self::methods("Sub", None, Self::TOP_LEVEL); let mut int_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL);
int_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); int_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
int_sub.register_builtin_const("Output", ValueObj::builtin_t(Int)); 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, poly("Sub", vec![ty_tp(Int)]), int_sub);
let mut int_mul = Self::methods("Mul", None, Self::TOP_LEVEL); let mut int_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL);
int_mul.register_builtin_impl("__mul__", op_t, Const, Public); int_mul.register_builtin_impl("__mul__", op_t, Const, Public);
int_mul.register_builtin_const("Output", ValueObj::builtin_t(Int)); int_mul.register_builtin_const("Output", ValueObj::builtin_t(Int));
int_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Nat)); 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, poly("Mul", vec![ty_tp(Int)]), int_mul);
let mut int_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); let mut int_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL);
int_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Int!"))); int_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Int!")));
int.register_trait(Int, builtin_mono("Mutizable"), int_mutizable); int.register_trait(Int, builtin_mono("Mutizable"), int_mutizable);
int.register_builtin_impl("Real", Int, Const, Public); int.register_builtin_impl("Real", Int, Const, Public);
int.register_builtin_impl("Imag", Int, Const, Public); int.register_builtin_impl("Imag", Int, Const, Public);
let mut nat = Self::mono_class("Nat", None, Self::TOP_LEVEL); let mut nat = Self::mono_class("Nat", None, None, Self::TOP_LEVEL);
nat.register_superclass(Int, &int); nat.register_superclass(Int, &int);
nat.register_superclass(Float, &float); // TODO: Float -> Ratio nat.register_superclass(Float, &float); // TODO: Float -> Ratio
nat.register_superclass(Obj, &obj); nat.register_superclass(Obj, &obj);
@ -538,10 +557,10 @@ impl Context {
); );
nat.register_marker_trait(builtin_mono("Num")); nat.register_marker_trait(builtin_mono("Num"));
nat.register_marker_trait(builtin_mono("Ord")); nat.register_marker_trait(builtin_mono("Ord"));
let mut nat_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut nat_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
nat_eq.register_builtin_impl("__eq__", fn1_met(Nat, Nat, Bool), Const, Public); nat_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, poly("Eq", vec![ty_tp(Nat)]), nat_eq);
let mut nat_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); let mut nat_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL);
nat_partial_ord.register_builtin_impl( nat_partial_ord.register_builtin_impl(
"__cmp__", "__cmp__",
fn1_met(Nat, Nat, builtin_mono("Ordering")), fn1_met(Nat, Nat, builtin_mono("Ordering")),
@ -551,20 +570,20 @@ impl Context {
nat.register_trait(Nat, poly("PartialOrd", vec![ty_tp(Nat)]), nat_partial_ord); nat.register_trait(Nat, poly("PartialOrd", vec![ty_tp(Nat)]), nat_partial_ord);
// __sub__, __div__ is not included in Nat (cast to Int/ Ratio) // __sub__, __div__ is not included in Nat (cast to Int/ Ratio)
let op_t = fn1_met(Nat, Nat, Nat); let op_t = fn1_met(Nat, Nat, Nat);
let mut nat_add = Self::methods("Add", None, Self::TOP_LEVEL); let mut nat_add = Self::methods("Add", None, None, Self::TOP_LEVEL);
nat_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); nat_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
nat_add.register_builtin_const("Output", ValueObj::builtin_t(Nat)); 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, poly("Add", vec![ty_tp(Nat)]), nat_add);
let mut nat_mul = Self::methods("Mul", None, Self::TOP_LEVEL); let mut nat_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL);
nat_mul.register_builtin_impl("__mul__", op_t, Const, Public); nat_mul.register_builtin_impl("__mul__", op_t, Const, Public);
nat_mul.register_builtin_const("Output", ValueObj::builtin_t(Nat)); 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, poly("Mul", vec![ty_tp(Nat)]), nat_mul);
let mut nat_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); let mut nat_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL);
nat_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Nat!"))); nat_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Nat!")));
nat.register_trait(Nat, builtin_mono("Mutizable"), nat_mutizable); nat.register_trait(Nat, builtin_mono("Mutizable"), nat_mutizable);
nat.register_builtin_impl("Real", Nat, Const, Public); nat.register_builtin_impl("Real", Nat, Const, Public);
nat.register_builtin_impl("Imag", Nat, Const, Public); nat.register_builtin_impl("Imag", Nat, Const, Public);
let mut bool_ = Self::mono_class("Bool", None, Self::TOP_LEVEL); let mut bool_ = Self::mono_class("Bool", None, None, Self::TOP_LEVEL);
bool_.register_superclass(Nat, &nat); bool_.register_superclass(Nat, &nat);
bool_.register_superclass(Int, &int); bool_.register_superclass(Int, &int);
bool_.register_superclass(Float, &float); // TODO: Float -> Ratio bool_.register_superclass(Float, &float); // TODO: Float -> Ratio
@ -576,7 +595,7 @@ impl Context {
bool_.register_builtin_impl("__or__", fn1_met(Bool, Bool, Bool), Const, Public); bool_.register_builtin_impl("__or__", fn1_met(Bool, Bool, Bool), Const, Public);
bool_.register_marker_trait(builtin_mono("Num")); bool_.register_marker_trait(builtin_mono("Num"));
bool_.register_marker_trait(builtin_mono("Ord")); bool_.register_marker_trait(builtin_mono("Ord"));
let mut bool_partial_ord = Self::methods("PartialOrd", None, Self::TOP_LEVEL); let mut bool_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL);
bool_partial_ord.register_builtin_impl( bool_partial_ord.register_builtin_impl(
"__cmp__", "__cmp__",
fn1_met(Bool, Bool, builtin_mono("Ordering")), fn1_met(Bool, Bool, builtin_mono("Ordering")),
@ -588,18 +607,18 @@ impl Context {
poly("PartialOrd", vec![ty_tp(Bool)]), poly("PartialOrd", vec![ty_tp(Bool)]),
bool_partial_ord, bool_partial_ord,
); );
let mut bool_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut bool_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
bool_eq.register_builtin_impl("__eq__", fn1_met(Bool, Bool, Bool), Const, Public); bool_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, poly("Eq", vec![ty_tp(Bool)]), bool_eq);
let mut bool_add = Self::methods("Add", None, Self::TOP_LEVEL); let mut bool_add = Self::methods("Add", None, None, Self::TOP_LEVEL);
bool_add.register_builtin_impl("__add__", fn1_met(Bool, Bool, Int), Const, Public); bool_add.register_builtin_impl("__add__", fn1_met(Bool, Bool, Int), Const, Public);
bool_add.register_builtin_const("Output", ValueObj::builtin_t(Nat)); 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, poly("Add", vec![ty_tp(Bool)]), bool_add);
let mut bool_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); let mut bool_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL);
bool_mutizable bool_mutizable
.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Bool!"))); .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Bool!")));
bool_.register_trait(Bool, builtin_mono("Mutizable"), bool_mutizable); bool_.register_trait(Bool, builtin_mono("Mutizable"), bool_mutizable);
let mut str_ = Self::mono_class("Str", None, Self::TOP_LEVEL); let mut str_ = Self::mono_class("Str", None, None, Self::TOP_LEVEL);
str_.register_superclass(Obj, &obj); str_.register_superclass(Obj, &obj);
str_.register_marker_trait(builtin_mono("Ord")); str_.register_marker_trait(builtin_mono("Ord"));
str_.register_builtin_impl( str_.register_builtin_impl(
@ -626,48 +645,49 @@ impl Context {
Immutable, Immutable,
Public, Public,
); );
let mut str_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut str_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
str_eq.register_builtin_impl("__eq__", fn1_met(Str, Str, Bool), Const, Public); str_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, poly("Eq", vec![ty_tp(Str)]), str_eq);
let mut str_seq = Self::methods("Seq", None, Self::TOP_LEVEL); let mut str_seq = Self::methods("Seq", None, None, Self::TOP_LEVEL);
str_seq.register_builtin_impl("len", fn0_met(Str, Nat), Const, Public); str_seq.register_builtin_impl("len", fn0_met(Str, Nat), Const, Public);
str_seq.register_builtin_impl("get", fn1_met(Str, Nat, Str), 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, poly("Seq", vec![ty_tp(Str)]), str_seq);
let mut str_add = Self::methods("Add", None, Self::TOP_LEVEL); let mut str_add = Self::methods("Add", None, None, Self::TOP_LEVEL);
str_add.register_builtin_impl("__add__", fn1_met(Str, Str, Str), Const, Public); str_add.register_builtin_impl("__add__", fn1_met(Str, Str, Str), Const, Public);
str_add.register_builtin_const("Output", ValueObj::builtin_t(Str)); 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, poly("Add", vec![ty_tp(Str)]), str_add);
let mut str_mul = Self::methods("Mul", None, Self::TOP_LEVEL); let mut str_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL);
str_mul.register_builtin_impl("__mul__", fn1_met(Str, Nat, Str), Const, Public); str_mul.register_builtin_impl("__mul__", fn1_met(Str, Nat, Str), Const, Public);
str_mul.register_builtin_const("Output", ValueObj::builtin_t(Str)); 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, poly("Mul", vec![ty_tp(Nat)]), str_mul);
let mut str_mutizable = Self::methods("Mutizable", None, Self::TOP_LEVEL); let mut str_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL);
str_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Str!"))); str_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Str!")));
str_.register_trait(Str, builtin_mono("Mutizable"), str_mutizable); str_.register_trait(Str, builtin_mono("Mutizable"), str_mutizable);
let mut type_ = Self::mono_class("Type", None, Self::TOP_LEVEL); let mut type_ = Self::mono_class("Type", None, None, Self::TOP_LEVEL);
type_.register_superclass(Obj, &obj); type_.register_superclass(Obj, &obj);
type_.register_builtin_impl("mro", array(Type, TyParam::erased(Nat)), Immutable, Public); type_.register_builtin_impl("mro", array(Type, TyParam::erased(Nat)), Immutable, Public);
type_.register_marker_trait(builtin_mono("Named")); type_.register_marker_trait(builtin_mono("Named"));
let mut type_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut type_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
type_eq.register_builtin_impl("__eq__", fn1_met(Type, Type, Bool), Const, Public); type_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, poly("Eq", vec![ty_tp(Type)]), type_eq);
let mut class_type = Self::mono_class("ClassType", None, Self::TOP_LEVEL); let mut class_type = Self::mono_class("ClassType", None, None, Self::TOP_LEVEL);
class_type.register_superclass(Type, &type_); class_type.register_superclass(Type, &type_);
class_type.register_superclass(Obj, &obj); class_type.register_superclass(Obj, &obj);
class_type.register_marker_trait(builtin_mono("Named")); class_type.register_marker_trait(builtin_mono("Named"));
let mut class_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut class_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
class_eq.register_builtin_impl("__eq__", fn1_met(Class, Class, Bool), Const, Public); class_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); class_type.register_trait(Class, poly("Eq", vec![ty_tp(Class)]), class_eq);
let mut module = Self::mono_class("Module", None, Self::TOP_LEVEL); let mut module = Self::mono_class("Module", None, None, Self::TOP_LEVEL);
module.register_superclass(Obj, &obj); module.register_superclass(Obj, &obj);
module.register_marker_trait(builtin_mono("Named")); module.register_marker_trait(builtin_mono("Named"));
let mut module_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut module_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
module_eq.register_builtin_impl("__eq__", fn1_met(Module, Module, Bool), Const, Public); module_eq.register_builtin_impl("__eq__", fn1_met(Module, Module, Bool), Const, Public);
module.register_trait(Module, poly("Eq", vec![ty_tp(Module)]), module_eq); module.register_trait(Module, poly("Eq", vec![ty_tp(Module)]), module_eq);
let mut array_ = Self::poly_class( let mut array_ = Self::poly_class(
"Array", "Array",
vec![PS::t_nd("T"), PS::named_nd("N", Nat)], vec![PS::t_nd("T"), PS::named_nd("N", Nat)],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
array_.register_superclass(Obj, &obj); array_.register_superclass(Obj, &obj);
@ -693,7 +713,7 @@ impl Context {
)); ));
// [T; N].MutType! = [T; !N] (neither [T!; N] nor [T; N]!) // [T; N].MutType! = [T; !N] (neither [T!; N] nor [T; N]!)
array_.register_builtin_const("MutType!", mut_type); array_.register_builtin_const("MutType!", mut_type);
let mut array_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut array_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
array_eq.register_builtin_impl( array_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met(array_t.clone(), array_t.clone(), Bool), fn1_met(array_t.clone(), array_t.clone(), Bool),
@ -704,9 +724,9 @@ impl Context {
array_.register_marker_trait(builtin_mono("Mutizable")); array_.register_marker_trait(builtin_mono("Mutizable"));
array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))])); array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))]));
// TODO: make Tuple6, Tuple7, ... etc. // TODO: make Tuple6, Tuple7, ... etc.
let mut tuple_ = Self::mono_class("Tuple", None, Self::TOP_LEVEL); let mut tuple_ = Self::mono_class("Tuple", None, None, Self::TOP_LEVEL);
tuple_.register_superclass(Obj, &obj); tuple_.register_superclass(Obj, &obj);
let mut tuple_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple_eq.register_builtin_impl( tuple_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met(builtin_mono("Tuple"), builtin_mono("Tuple"), Bool), fn1_met(builtin_mono("Tuple"), builtin_mono("Tuple"), Bool),
@ -718,10 +738,11 @@ impl Context {
poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]), poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]),
tuple_eq, tuple_eq,
); );
let mut tuple1 = Self::poly_class("Tuple1", vec![PS::t_nd("A")], None, Self::TOP_LEVEL); let mut tuple1 =
Self::poly_class("Tuple1", vec![PS::t_nd("A")], None, None, Self::TOP_LEVEL);
tuple1.register_superclass(builtin_mono("Tuple"), &tuple_); tuple1.register_superclass(builtin_mono("Tuple"), &tuple_);
tuple1.register_superclass(Obj, &obj); tuple1.register_superclass(Obj, &obj);
let mut tuple1_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple1_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple1_eq.register_builtin_impl( tuple1_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
@ -741,11 +762,12 @@ impl Context {
"Tuple2", "Tuple2",
vec![PS::t_nd("A"), PS::t_nd("B")], vec![PS::t_nd("A"), PS::t_nd("B")],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
tuple2.register_superclass(builtin_mono("Tuple"), &tuple_); tuple2.register_superclass(builtin_mono("Tuple"), &tuple_);
tuple2.register_superclass(Obj, &obj); tuple2.register_superclass(Obj, &obj);
let mut tuple2_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple2_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple2_eq.register_builtin_impl( tuple2_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
@ -771,11 +793,12 @@ impl Context {
"Tuple3", "Tuple3",
vec![PS::t_nd("A"), PS::t_nd("B"), PS::t_nd("C")], vec![PS::t_nd("A"), PS::t_nd("B"), PS::t_nd("C")],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
tuple3.register_superclass(builtin_mono("Tuple"), &tuple_); tuple3.register_superclass(builtin_mono("Tuple"), &tuple_);
tuple3.register_superclass(Obj, &obj); tuple3.register_superclass(Obj, &obj);
let mut tuple3_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple3_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple3_eq.register_builtin_impl( tuple3_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
@ -810,11 +833,12 @@ impl Context {
"Tuple4", "Tuple4",
vec![PS::t_nd("A"), PS::t_nd("B"), PS::t_nd("C"), PS::t_nd("D")], vec![PS::t_nd("A"), PS::t_nd("B"), PS::t_nd("C"), PS::t_nd("D")],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
tuple4.register_superclass(builtin_mono("Tuple"), &tuple_); tuple4.register_superclass(builtin_mono("Tuple"), &tuple_);
tuple4.register_superclass(Obj, &obj); tuple4.register_superclass(Obj, &obj);
let mut tuple4_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple4_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple4_eq.register_builtin_impl( tuple4_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
@ -875,11 +899,12 @@ impl Context {
PS::t_nd("E"), PS::t_nd("E"),
], ],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
tuple5.register_superclass(builtin_mono("Tuple"), &tuple_); tuple5.register_superclass(builtin_mono("Tuple"), &tuple_);
tuple5.register_superclass(Obj, &obj); tuple5.register_superclass(Obj, &obj);
let mut tuple5_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple5_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple5_eq.register_builtin_impl( tuple5_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
@ -945,11 +970,12 @@ impl Context {
PS::t_nd("F"), PS::t_nd("F"),
], ],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
tuple6.register_superclass(builtin_mono("Tuple"), &tuple_); tuple6.register_superclass(builtin_mono("Tuple"), &tuple_);
tuple6.register_superclass(Obj, &obj); tuple6.register_superclass(Obj, &obj);
let mut tuple6_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple6_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple6_eq.register_builtin_impl( tuple6_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
@ -1020,11 +1046,12 @@ impl Context {
PS::t_nd("G"), PS::t_nd("G"),
], ],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
tuple7.register_superclass(builtin_mono("Tuple"), &tuple_); tuple7.register_superclass(builtin_mono("Tuple"), &tuple_);
tuple7.register_superclass(Obj, &obj); tuple7.register_superclass(Obj, &obj);
let mut tuple7_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple7_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple7_eq.register_builtin_impl( tuple7_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
@ -1100,11 +1127,12 @@ impl Context {
PS::t_nd("H"), PS::t_nd("H"),
], ],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
tuple8.register_superclass(builtin_mono("Tuple"), &tuple_); tuple8.register_superclass(builtin_mono("Tuple"), &tuple_);
tuple8.register_superclass(Obj, &obj); tuple8.register_superclass(Obj, &obj);
let mut tuple8_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut tuple8_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
tuple8_eq.register_builtin_impl( tuple8_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
@ -1171,16 +1199,16 @@ impl Context {
), ),
tuple8_eq, tuple8_eq,
); );
let mut record = Self::mono_class("Record", None, Self::TOP_LEVEL); let mut record = Self::mono_class("Record", None, None, Self::TOP_LEVEL);
record.register_superclass(Obj, &obj); record.register_superclass(Obj, &obj);
let mut record_type = Self::mono_class("RecordType", None, Self::TOP_LEVEL); let mut record_type = Self::mono_class("RecordType", None, None, Self::TOP_LEVEL);
record_type.register_superclass(builtin_mono("Record"), &record); record_type.register_superclass(builtin_mono("Record"), &record);
record_type.register_superclass(builtin_mono("Type"), &type_); record_type.register_superclass(builtin_mono("Type"), &type_);
record_type.register_superclass(Obj, &obj); record_type.register_superclass(Obj, &obj);
let mut float_mut = Self::mono_class("Float!", None, Self::TOP_LEVEL); let mut float_mut = Self::mono_class("Float!", None, None, Self::TOP_LEVEL);
float_mut.register_superclass(Float, &float); float_mut.register_superclass(Float, &float);
float_mut.register_superclass(Obj, &obj); float_mut.register_superclass(Obj, &obj);
let mut float_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); let mut float_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL);
float_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Float)); float_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Float));
let f_t = param_t("f", func(vec![param_t("old", Float)], None, vec![], Float)); let f_t = param_t("f", func(vec![param_t("old", Float)], None, vec![], Float));
let t = pr_met( let t = pr_met(
@ -1196,10 +1224,10 @@ impl Context {
builtin_mono("Mutable"), builtin_mono("Mutable"),
float_mut_mutable, float_mut_mutable,
); );
let mut ratio_mut = Self::mono_class("Ratio!", None, Self::TOP_LEVEL); let mut ratio_mut = Self::mono_class("Ratio!", None, None, Self::TOP_LEVEL);
ratio_mut.register_superclass(Ratio, &ratio); ratio_mut.register_superclass(Ratio, &ratio);
ratio_mut.register_superclass(Obj, &obj); ratio_mut.register_superclass(Obj, &obj);
let mut ratio_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); let mut ratio_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL);
ratio_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Ratio)); ratio_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Ratio));
let f_t = param_t( let f_t = param_t(
"f", "f",
@ -1223,11 +1251,11 @@ impl Context {
builtin_mono("Mutable"), builtin_mono("Mutable"),
ratio_mut_mutable, ratio_mut_mutable,
); );
let mut int_mut = Self::mono_class("Int!", None, Self::TOP_LEVEL); let mut int_mut = Self::mono_class("Int!", None, None, Self::TOP_LEVEL);
int_mut.register_superclass(Int, &int); int_mut.register_superclass(Int, &int);
int_mut.register_superclass(builtin_mono("Float!"), &float_mut); int_mut.register_superclass(builtin_mono("Float!"), &float_mut);
int_mut.register_superclass(Obj, &obj); int_mut.register_superclass(Obj, &obj);
let mut int_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); let mut int_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL);
int_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Int)); int_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Int));
let f_t = param_t("f", func(vec![param_t("old", Int)], None, vec![], Int)); let f_t = param_t("f", func(vec![param_t("old", Int)], None, vec![], Int));
let t = pr_met( let t = pr_met(
@ -1243,12 +1271,12 @@ impl Context {
builtin_mono("Mutable"), builtin_mono("Mutable"),
int_mut_mutable, int_mut_mutable,
); );
let mut nat_mut = Self::mono_class("Nat!", None, Self::TOP_LEVEL); let mut nat_mut = Self::mono_class("Nat!", None, None, Self::TOP_LEVEL);
nat_mut.register_superclass(Nat, &nat); nat_mut.register_superclass(Nat, &nat);
nat_mut.register_superclass(builtin_mono("Int!"), &int_mut); nat_mut.register_superclass(builtin_mono("Int!"), &int_mut);
nat_mut.register_superclass(builtin_mono("Float!"), &float_mut); nat_mut.register_superclass(builtin_mono("Float!"), &float_mut);
nat_mut.register_superclass(Obj, &obj); nat_mut.register_superclass(Obj, &obj);
let mut nat_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); let mut nat_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL);
nat_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Nat)); nat_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Nat));
let f_t = param_t("f", func(vec![param_t("old", Nat)], None, vec![], Nat)); let f_t = param_t("f", func(vec![param_t("old", Nat)], None, vec![], Nat));
let t = pr_met( let t = pr_met(
@ -1264,13 +1292,13 @@ impl Context {
builtin_mono("Mutable"), builtin_mono("Mutable"),
nat_mut_mutable, nat_mut_mutable,
); );
let mut bool_mut = Self::mono_class("Bool!", None, Self::TOP_LEVEL); let mut bool_mut = Self::mono_class("Bool!", None, None, Self::TOP_LEVEL);
bool_mut.register_superclass(Bool, &bool_); bool_mut.register_superclass(Bool, &bool_);
bool_mut.register_superclass(builtin_mono("Nat!"), &nat_mut); bool_mut.register_superclass(builtin_mono("Nat!"), &nat_mut);
bool_mut.register_superclass(builtin_mono("Int!"), &int_mut); bool_mut.register_superclass(builtin_mono("Int!"), &int_mut);
bool_mut.register_superclass(builtin_mono("Float!"), &float_mut); bool_mut.register_superclass(builtin_mono("Float!"), &float_mut);
bool_mut.register_superclass(Obj, &obj); bool_mut.register_superclass(Obj, &obj);
let mut bool_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); let mut bool_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL);
bool_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Bool)); bool_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Bool));
let f_t = param_t("f", func(vec![param_t("old", Bool)], None, vec![], Bool)); let f_t = param_t("f", func(vec![param_t("old", Bool)], None, vec![], Bool));
let t = pr_met( let t = pr_met(
@ -1286,10 +1314,10 @@ impl Context {
builtin_mono("Mutable"), builtin_mono("Mutable"),
bool_mut_mutable, bool_mut_mutable,
); );
let mut str_mut = Self::mono_class("Str!", None, Self::TOP_LEVEL); let mut str_mut = Self::mono_class("Str!", None, None, Self::TOP_LEVEL);
str_mut.register_superclass(Str, &str_); str_mut.register_superclass(Str, &str_);
str_mut.register_superclass(Obj, &obj); str_mut.register_superclass(Obj, &obj);
let mut str_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); let mut str_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL);
str_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Str)); str_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Str));
let f_t = param_t("f", func(vec![param_t("old", Str)], None, vec![], Str)); let f_t = param_t("f", func(vec![param_t("old", Str)], None, vec![], Str));
let t = pr_met( let t = pr_met(
@ -1311,6 +1339,7 @@ impl Context {
"Array!", "Array!",
vec![PS::t_nd("T"), PS::named_nd("N", builtin_mono("Nat!"))], vec![PS::t_nd("T"), PS::named_nd("N", builtin_mono("Nat!"))],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
array_mut_.register_superclass(array_t.clone(), &array_); array_mut_.register_superclass(array_t.clone(), &array_);
@ -1364,7 +1393,7 @@ impl Context {
vec![], vec![],
NoneType, NoneType,
); );
let mut array_mut_mutable = Self::methods("Mutable", None, Self::TOP_LEVEL); let mut array_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL);
array_mut_mutable.register_builtin_impl("update!", t, Immutable, Public); array_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
array_mut_.register_trait( array_mut_.register_trait(
array_mut_t.clone(), array_mut_t.clone(),
@ -1372,10 +1401,10 @@ impl Context {
array_mut_mutable, array_mut_mutable,
); );
let range_t = poly("Range", vec![TyParam::t(mono_q("T"))]); let range_t = poly("Range", vec![TyParam::t(mono_q("T"))]);
let mut range = Self::poly_class("Range", vec![PS::t_nd("T")], None, Self::TOP_LEVEL); let mut range = Self::poly_class("Range", vec![PS::t_nd("T")], None, None, Self::TOP_LEVEL);
range.register_superclass(Obj, &obj); range.register_superclass(Obj, &obj);
range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))])); range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))]));
let mut range_eq = Self::methods("Eq", None, Self::TOP_LEVEL); let mut range_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL);
range_eq.register_builtin_impl( range_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met(range_t.clone(), range_t.clone(), Bool), fn1_met(range_t.clone(), range_t.clone(), Bool),
@ -1387,16 +1416,16 @@ impl Context {
poly("Eq", vec![ty_tp(range_t.clone())]), poly("Eq", vec![ty_tp(range_t.clone())]),
range_eq, range_eq,
); );
let mut proc = Self::mono_class("Proc", None, Self::TOP_LEVEL); let mut proc = Self::mono_class("Proc", None, None, Self::TOP_LEVEL);
proc.register_superclass(Obj, &obj); proc.register_superclass(Obj, &obj);
// TODO: lambda // TODO: lambda
proc.register_marker_trait(builtin_mono("Named")); proc.register_marker_trait(builtin_mono("Named"));
let mut func = Self::mono_class("Func", None, Self::TOP_LEVEL); let mut func = Self::mono_class("Func", None, None, Self::TOP_LEVEL);
func.register_superclass(builtin_mono("Proc"), &proc); func.register_superclass(builtin_mono("Proc"), &proc);
func.register_superclass(Obj, &obj); func.register_superclass(Obj, &obj);
// TODO: lambda // TODO: lambda
func.register_marker_trait(builtin_mono("Named")); func.register_marker_trait(builtin_mono("Named"));
let mut qfunc = Self::mono_class("QuantifiedFunc", None, Self::TOP_LEVEL); let mut qfunc = Self::mono_class("QuantifiedFunc", None, None, Self::TOP_LEVEL);
qfunc.register_superclass(builtin_mono("Func"), &func); qfunc.register_superclass(builtin_mono("Func"), &func);
qfunc.register_superclass(Obj, &obj); qfunc.register_superclass(Obj, &obj);
self.register_builtin_type(Obj, obj, Const); self.register_builtin_type(Obj, obj, Const);
@ -1780,6 +1809,7 @@ impl Context {
params, params,
// super: vec![Type::from(&m..=&n)], // super: vec![Type::from(&m..=&n)],
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
let op_t = fn1_met( let op_t = fn1_met(
@ -1787,7 +1817,7 @@ impl Context {
Type::from(&o..=&p), Type::from(&o..=&p),
Type::from(m.clone() + o.clone()..=n.clone() + p.clone()), Type::from(m.clone() + o.clone()..=n.clone() + p.clone()),
); );
let mut interval_add = Self::methods("Add", None, Self::TOP_LEVEL); let mut interval_add = Self::methods("Add", None, None, Self::TOP_LEVEL);
interval_add.register_builtin_impl("__add__", op_t, Const, Public); interval_add.register_builtin_impl("__add__", op_t, Const, Public);
interval_add.register_builtin_const( interval_add.register_builtin_const(
"Output", "Output",
@ -1798,7 +1828,7 @@ impl Context {
poly("Add", vec![TyParam::from(&o..=&p)]), poly("Add", vec![TyParam::from(&o..=&p)]),
interval_add, interval_add,
); );
let mut interval_sub = Self::methods("Sub", None, Self::TOP_LEVEL); let mut interval_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL);
let op_t = fn1_met( let op_t = fn1_met(
Type::from(&m..=&n), Type::from(&m..=&n),
Type::from(&o..=&p), Type::from(&o..=&p),
@ -1823,7 +1853,7 @@ impl Context {
pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) { pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) {
// TODO: capacityを正確に把握する // TODO: capacityを正確に把握する
let mut ctx = Context::module("<builtins>".into(), None, 40); let mut ctx = Context::module("<builtins>".into(), None, None, 40);
ctx.init_builtin_funcs(); ctx.init_builtin_funcs();
ctx.init_builtin_const_funcs(); ctx.init_builtin_const_funcs();
ctx.init_builtin_procs(); ctx.init_builtin_procs();
@ -1834,13 +1864,18 @@ impl Context {
mod_cache.register(VarName::from_static("<builtins>"), None, ctx); mod_cache.register(VarName::from_static("<builtins>"), None, ctx);
} }
pub fn new_module<S: Into<Str>>(name: S, mod_cache: SharedModuleCache) -> Self { pub fn new_module<S: Into<Str>>(
name: S,
mod_cache: SharedModuleCache,
py_mod_cache: SharedModuleCache,
) -> Self {
Context::new( Context::new(
name.into(), name.into(),
ContextKind::Module, ContextKind::Module,
vec![], vec![],
None, None,
Some(mod_cache), Some(mod_cache),
Some(py_mod_cache),
Context::TOP_LEVEL, Context::TOP_LEVEL,
) )
} }

View file

@ -11,7 +11,7 @@ use Visibility::*;
impl Context { impl Context {
pub(crate) fn init_py_importlib_mod() -> Self { pub(crate) fn init_py_importlib_mod() -> Self {
let mut importlib = Context::module("importlib".into(), None, 15); let mut importlib = Context::module("importlib".into(), None, None, 15);
importlib.register_builtin_impl("reload!", proc1(Module, NoneType), Immutable, Public); importlib.register_builtin_impl("reload!", proc1(Module, NoneType), Immutable, Public);
importlib importlib
} }

View file

@ -12,8 +12,8 @@ use Visibility::*;
impl Context { impl Context {
pub(crate) fn init_py_io_mod() -> Self { pub(crate) fn init_py_io_mod() -> Self {
let mut io = Context::module("io".into(), None, 15); let mut io = Context::module("io".into(), None, None, 15);
let mut string_io = Context::mono_class(Str::ever("StringIO!"), None, 0); let mut string_io = Context::mono_class(Str::ever("StringIO!"), None, None, 0);
// FIXME: include Obj (pass main_ctx as a param) // FIXME: include Obj (pass main_ctx as a param)
// string_io.register_superclass(Obj, obj); // string_io.register_superclass(Obj, obj);
string_io.register_builtin_impl( string_io.register_builtin_impl(

View file

@ -11,7 +11,7 @@ use Visibility::*;
impl Context { impl Context {
pub(crate) fn init_py_math_mod() -> Self { pub(crate) fn init_py_math_mod() -> Self {
let mut math = Context::module("math".into(), None, 10); let mut math = Context::module("math".into(), None, None, 10);
math.register_builtin_impl("pi", Float, Immutable, Public); math.register_builtin_impl("pi", Float, Immutable, Public);
math.register_builtin_impl("tau", Float, Immutable, Public); math.register_builtin_impl("tau", Float, Immutable, Public);
math.register_builtin_impl("e", Float, Immutable, Public); math.register_builtin_impl("e", Float, Immutable, Public);

View file

@ -14,7 +14,7 @@ use Visibility::*;
impl Context { impl Context {
pub(crate) fn init_py_random_mod() -> Self { pub(crate) fn init_py_random_mod() -> Self {
let mut random = Context::module("random".into(), None, 10); let mut random = Context::module("random".into(), None, None, 10);
random.register_builtin_impl( random.register_builtin_impl(
"seed!", "seed!",
proc( proc(

View file

@ -12,8 +12,8 @@ use Visibility::*;
impl Context { impl Context {
pub(crate) fn init_py_socket_mod() -> Self { pub(crate) fn init_py_socket_mod() -> Self {
let mut socket = Context::module("socket".into(), None, 15); let mut socket = Context::module("socket".into(), None, None, 15);
let mut sock = Context::mono_class(Str::ever("Socket!"), None, 0); let mut sock = Context::mono_class(Str::ever("Socket!"), None, None, 0);
// FIXME: include Obj (pass main_ctx as a param) // FIXME: include Obj (pass main_ctx as a param)
// sock.register_superclass(Obj, obj); // sock.register_superclass(Obj, obj);
sock.register_builtin_impl( sock.register_builtin_impl(

View file

@ -12,7 +12,7 @@ use Visibility::*;
impl Context { impl Context {
pub(crate) fn init_py_sys_mod() -> Self { pub(crate) fn init_py_sys_mod() -> Self {
let mut sys = Context::module("sys".into(), None, 15); let mut sys = Context::module("sys".into(), None, None, 15);
sys.register_builtin_impl("argv", array(Str, TyParam::erased(Nat)), Immutable, Public); sys.register_builtin_impl("argv", array(Str, TyParam::erased(Nat)), Immutable, Public);
sys.register_builtin_impl("byteorder", Str, Immutable, Public); sys.register_builtin_impl("byteorder", Str, Immutable, Public);
sys.register_builtin_impl( sys.register_builtin_impl(

View file

@ -11,7 +11,7 @@ use Visibility::*;
impl Context { impl Context {
pub(crate) fn init_py_time_mod() -> Self { pub(crate) fn init_py_time_mod() -> Self {
let mut time = Context::module("time".into(), None, 15); let mut time = Context::module("time".into(), None, None, 15);
time.register_builtin_impl("sleep!", proc1(Float, NoneType), Immutable, Public); time.register_builtin_impl("sleep!", proc1(Float, NoneType), Immutable, Public);
time.register_builtin_impl("time!", proc0(Float), Immutable, Public); time.register_builtin_impl("time!", proc0(Float), Immutable, Public);
time time

View file

@ -2,7 +2,7 @@
use std::option::Option; // conflicting to Type::Option use std::option::Option; // conflicting to Type::Option
use erg_common::error::{ErrorCore, ErrorKind, Location}; use erg_common::error::{ErrorCore, ErrorKind, Location};
use erg_common::levenshtein::levenshtein; use erg_common::levenshtein::get_similar_name;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::traits::Locational; use erg_common::traits::Locational;
use erg_common::vis::{Field, Visibility}; use erg_common::vis::{Field, Visibility};
@ -897,33 +897,23 @@ impl Context {
} }
} }
pub(crate) fn get_similar_name(&self, name: &str) -> Option<&Str> { pub(crate) fn get_similar_name(&self, name: &str) -> Option<&str> {
let name = readable_name(name); let name = readable_name(name);
if name.len() <= 1 { // TODO: add decls
return None; get_similar_name(
} self.params
// TODO: add `.decls` .iter()
let most_similar_name = self .filter_map(|(opt_name, _)| opt_name.as_ref().map(|n| &n.inspect()[..]))
.params .chain(self.locals.keys().map(|name| &name.inspect()[..])),
.iter() name,
.filter_map(|(opt_name, _)| opt_name.as_ref()) )
.chain(self.locals.keys())
.min_by_key(|v| levenshtein(readable_name(v.inspect()), name))?
.inspect();
let len = most_similar_name.len();
if levenshtein(most_similar_name, name) >= len / 2 {
let outer = self.get_outer().or_else(|| self.get_builtins())?;
outer.get_similar_name(name)
} else {
Some(most_similar_name)
}
} }
pub(crate) fn get_similar_attr_from_singular<'a>( pub(crate) fn get_similar_attr_from_singular<'a>(
&'a self, &'a self,
obj: &hir::Expr, obj: &hir::Expr,
name: &str, name: &str,
) -> Option<&'a Str> { ) -> Option<&'a str> {
if let Ok(ctx) = self.get_singular_ctx(obj, &self.name) { if let Ok(ctx) = self.get_singular_ctx(obj, &self.name) {
if let Some(name) = ctx.get_similar_name(name) { if let Some(name) = ctx.get_similar_name(name) {
return Some(name); return Some(name);
@ -932,7 +922,7 @@ impl Context {
None None
} }
pub(crate) fn get_similar_attr<'a>(&'a self, self_t: &'a Type, name: &str) -> Option<&'a Str> { pub(crate) fn get_similar_attr<'a>(&'a self, self_t: &'a Type, name: &str) -> Option<&'a str> {
for (_, ctx) in self.get_nominal_super_type_ctxs(self_t)? { for (_, ctx) in self.get_nominal_super_type_ctxs(self_t)? {
if let Some(name) = ctx.get_similar_name(name) { if let Some(name) = ctx.get_similar_name(name) {
return Some(name); return Some(name);

View file

@ -239,7 +239,7 @@ impl From<DefKind> for ContextKind {
DefKind::Class | DefKind::Inherit => Self::Class, DefKind::Class | DefKind::Inherit => Self::Class,
DefKind::Trait | DefKind::Subsume => Self::Trait, DefKind::Trait | DefKind::Subsume => Self::Trait,
DefKind::StructuralTrait => Self::StructuralTrait, DefKind::StructuralTrait => Self::StructuralTrait,
DefKind::Module => Self::Module, DefKind::Import | DefKind::PyImport => Self::Module,
DefKind::Other => Self::Instant, DefKind::Other => Self::Instant,
} }
} }
@ -272,6 +272,21 @@ pub enum RegistrationMode {
Normal, Normal,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ImportKind {
ErgImport,
PyImport,
}
impl ImportKind {
pub const fn is_erg_import(&self) -> bool {
matches!(self, Self::ErgImport)
}
pub const fn is_py_import(&self) -> bool {
matches!(self, Self::PyImport)
}
}
/// Represents the context of the current scope /// Represents the context of the current scope
/// ///
/// Recursive functions/methods are highlighted with the prefix `rec_`, as performance may be significantly degraded. /// Recursive functions/methods are highlighted with the prefix `rec_`, as performance may be significantly degraded.
@ -326,6 +341,7 @@ pub struct Context {
// but when used as a fallback to a type, values are traversed instead of accessing by keys // but when used as a fallback to a type, values are traversed instead of accessing by keys
pub(crate) patches: Dict<VarName, Context>, pub(crate) patches: Dict<VarName, Context>,
pub(crate) mod_cache: Option<SharedModuleCache>, pub(crate) mod_cache: Option<SharedModuleCache>,
pub(crate) py_mod_cache: Option<SharedModuleCache>,
pub(crate) level: usize, pub(crate) level: usize,
} }
@ -338,6 +354,7 @@ impl Default for Context {
vec![], vec![],
None, None,
None, None,
None,
Self::TOP_LEVEL, Self::TOP_LEVEL,
) )
} }
@ -369,9 +386,10 @@ impl Context {
params: Vec<ParamSpec>, params: Vec<ParamSpec>,
outer: Option<Context>, outer: Option<Context>,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
Self::with_capacity(name, kind, params, outer, 0, mod_cache, level) Self::with_capacity(name, kind, params, outer, 0, mod_cache, py_mod_cache, level)
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@ -382,6 +400,7 @@ impl Context {
outer: Option<Context>, outer: Option<Context>,
capacity: usize, capacity: usize,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
let mut params_ = Vec::new(); let mut params_ = Vec::new();
@ -420,6 +439,7 @@ impl Context {
mono_types: Dict::default(), mono_types: Dict::default(),
poly_types: Dict::default(), poly_types: Dict::default(),
mod_cache, mod_cache,
py_mod_cache,
patches: Dict::default(), patches: Dict::default(),
level, level,
} }
@ -431,9 +451,10 @@ impl Context {
kind: ContextKind, kind: ContextKind,
outer: Option<Context>, outer: Option<Context>,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
Self::with_capacity(name, kind, vec![], outer, 0, mod_cache, level) Self::with_capacity(name, kind, vec![], outer, 0, mod_cache, py_mod_cache, level)
} }
#[inline] #[inline]
@ -443,53 +464,75 @@ impl Context {
params: Vec<ParamSpec>, params: Vec<ParamSpec>,
outer: Option<Context>, outer: Option<Context>,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
Self::with_capacity(name, kind, params, outer, 0, mod_cache, level) Self::with_capacity(name, kind, params, outer, 0, mod_cache, py_mod_cache, level)
} }
pub fn poly_trait<S: Into<Str>>( pub fn poly_trait<S: Into<Str>>(
name: S, name: S,
params: Vec<ParamSpec>, params: Vec<ParamSpec>,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
let name = name.into(); let name = name.into();
Self::poly(name, ContextKind::Trait, params, None, mod_cache, level) Self::poly(
name,
ContextKind::Trait,
params,
None,
mod_cache,
py_mod_cache,
level,
)
} }
pub fn poly_class<S: Into<Str>>( pub fn poly_class<S: Into<Str>>(
name: S, name: S,
params: Vec<ParamSpec>, params: Vec<ParamSpec>,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
let name = name.into(); let name = name.into();
Self::poly(name, ContextKind::Class, params, None, mod_cache, level) Self::poly(
name,
ContextKind::Class,
params,
None,
mod_cache,
py_mod_cache,
level,
)
} }
#[inline] #[inline]
pub fn mono_trait<S: Into<Str>>( pub fn mono_trait<S: Into<Str>>(
name: S, name: S,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
Self::poly_trait(name, vec![], mod_cache, level) Self::poly_trait(name, vec![], mod_cache, py_mod_cache, level)
} }
#[inline] #[inline]
pub fn mono_class<S: Into<Str>>( pub fn mono_class<S: Into<Str>>(
name: S, name: S,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
Self::poly_class(name, vec![], mod_cache, level) Self::poly_class(name, vec![], mod_cache, py_mod_cache, level)
} }
#[inline] #[inline]
pub fn methods<S: Into<Str>>( pub fn methods<S: Into<Str>>(
name: S, name: S,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
Self::with_capacity( Self::with_capacity(
@ -499,6 +542,7 @@ impl Context {
None, None,
2, 2,
mod_cache, mod_cache,
py_mod_cache,
level, level,
) )
} }
@ -508,6 +552,7 @@ impl Context {
name: S, name: S,
params: Vec<ParamSpec>, params: Vec<ParamSpec>,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
level: usize, level: usize,
) -> Self { ) -> Self {
Self::poly( Self::poly(
@ -516,12 +561,18 @@ impl Context {
params, params,
None, None,
mod_cache, mod_cache,
py_mod_cache,
level, level,
) )
} }
#[inline] #[inline]
pub fn module(name: Str, mod_cache: Option<SharedModuleCache>, capacity: usize) -> Self { pub fn module(
name: Str,
mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
capacity: usize,
) -> Self {
Self::with_capacity( Self::with_capacity(
name, name,
ContextKind::Module, ContextKind::Module,
@ -529,6 +580,7 @@ impl Context {
None, None,
capacity, capacity,
mod_cache, mod_cache,
py_mod_cache,
Self::TOP_LEVEL, Self::TOP_LEVEL,
) )
} }
@ -538,6 +590,7 @@ impl Context {
name: Str, name: Str,
capacity: usize, capacity: usize,
mod_cache: Option<SharedModuleCache>, mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
outer: Context, outer: Context,
) -> Self { ) -> Self {
Self::with_capacity( Self::with_capacity(
@ -547,6 +600,7 @@ impl Context {
Some(outer), Some(outer),
capacity, capacity,
mod_cache, mod_cache,
py_mod_cache,
Self::TOP_LEVEL, Self::TOP_LEVEL,
) )
} }
@ -597,6 +651,7 @@ impl Context {
log!(info "{}: current namespace: {name}", fn_name!()); log!(info "{}: current namespace: {name}", fn_name!());
self.outer = Some(Box::new(mem::take(self))); self.outer = Some(Box::new(mem::take(self)));
self.mod_cache = self.get_outer().unwrap().mod_cache.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(); self.name = name.into();
self.kind = kind; self.kind = kind;
Ok(()) Ok(())

View file

@ -3,6 +3,7 @@ use std::path::PathBuf; // conflicting to Type::Option
use erg_common::config::{ErgConfig, Input}; use erg_common::config::{ErgConfig, Input};
use erg_common::error::MultiErrorDisplay; use erg_common::error::MultiErrorDisplay;
use erg_common::levenshtein::get_similar_name;
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
use erg_common::vis::Visibility; use erg_common::vis::Visibility;
use erg_common::Str; use erg_common::Str;
@ -29,6 +30,7 @@ use RegistrationMode::*;
use Visibility::*; use Visibility::*;
use super::instantiate::TyVarContext; use super::instantiate::TyVarContext;
use super::ImportKind;
impl Context { impl Context {
/// If it is a constant that is defined, there must be no variable of the same name defined across all scopes /// If it is a constant that is defined, there must be no variable of the same name defined across all scopes
@ -611,10 +613,18 @@ impl Context {
TypeKind::Class => { TypeKind::Class => {
if gen.t.is_monomorphic() { if gen.t.is_monomorphic() {
// let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect();
let mut ctx = let mut ctx = Self::mono_class(
Self::mono_class(gen.t.name(), self.mod_cache.clone(), self.level); gen.t.name(),
let mut methods = self.mod_cache.clone(),
Self::methods(gen.t.name(), self.mod_cache.clone(), self.level); self.py_mod_cache.clone(),
self.level,
);
let mut methods = Self::methods(
gen.t.name(),
self.mod_cache.clone(),
self.py_mod_cache.clone(),
self.level,
);
let require = gen.require_or_sup.typ().clone(); let require = gen.require_or_sup.typ().clone();
let new_t = func1(require, gen.t.clone()); let new_t = func1(require, gen.t.clone());
methods.register_fixed_auto_impl("__new__", new_t.clone(), Immutable, Private); methods.register_fixed_auto_impl("__new__", new_t.clone(), Immutable, Private);
@ -631,14 +641,22 @@ impl Context {
if gen.t.is_monomorphic() { if gen.t.is_monomorphic() {
let super_classes = vec![gen.require_or_sup.typ().clone()]; let super_classes = vec![gen.require_or_sup.typ().clone()];
// let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect();
let mut ctx = let mut ctx = Self::mono_class(
Self::mono_class(gen.t.name(), self.mod_cache.clone(), self.level); gen.t.name(),
self.mod_cache.clone(),
self.py_mod_cache.clone(),
self.level,
);
for sup in super_classes.into_iter() { for sup in super_classes.into_iter() {
let (_, sup_ctx) = self.get_nominal_type_ctx(&sup).unwrap(); let (_, sup_ctx) = self.get_nominal_type_ctx(&sup).unwrap();
ctx.register_superclass(sup, sup_ctx); ctx.register_superclass(sup, sup_ctx);
} }
let mut methods = let mut methods = Self::methods(
Self::methods(gen.t.name(), self.mod_cache.clone(), self.level); gen.t.name(),
self.mod_cache.clone(),
self.py_mod_cache.clone(),
self.level,
);
if let Some(sup) = self.rec_get_const_obj(&gen.require_or_sup.typ().name()) { if let Some(sup) = self.rec_get_const_obj(&gen.require_or_sup.typ().name()) {
let sup = enum_unwrap!(sup, ValueObj::Type); let sup = enum_unwrap!(sup, ValueObj::Type);
let param_t = match sup { let param_t = match sup {
@ -673,8 +691,12 @@ impl Context {
} }
TypeKind::Trait => { TypeKind::Trait => {
if gen.t.is_monomorphic() { if gen.t.is_monomorphic() {
let mut ctx = let mut ctx = Self::mono_trait(
Self::mono_trait(gen.t.name(), self.mod_cache.clone(), self.level); gen.t.name(),
self.mod_cache.clone(),
self.py_mod_cache.clone(),
self.level,
);
let require = enum_unwrap!(gen.require_or_sup.as_ref(), TypeObj::Builtin:(Type::Record:(_))); let require = enum_unwrap!(gen.require_or_sup.as_ref(), TypeObj::Builtin:(Type::Record:(_)));
for (field, t) in require.iter() { for (field, t) in require.iter() {
let muty = if field.is_const() { let muty = if field.is_const() {
@ -695,8 +717,12 @@ impl Context {
if gen.t.is_monomorphic() { if gen.t.is_monomorphic() {
let super_classes = vec![gen.require_or_sup.typ().clone()]; let super_classes = vec![gen.require_or_sup.typ().clone()];
// let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect();
let mut ctx = let mut ctx = Self::mono_trait(
Self::mono_trait(gen.t.name(), self.mod_cache.clone(), self.level); gen.t.name(),
self.mod_cache.clone(),
self.py_mod_cache.clone(),
self.level,
);
let additional = gen.additional.as_ref().map(|additional| enum_unwrap!(additional.as_ref(), TypeObj::Builtin:(Type::Record:(_)))); let additional = gen.additional.as_ref().map(|additional| enum_unwrap!(additional.as_ref(), TypeObj::Builtin:(Type::Record:(_))));
if let Some(additional) = additional { if let Some(additional) = additional {
for (field, t) in additional.iter() { for (field, t) in additional.iter() {
@ -764,6 +790,7 @@ impl Context {
pub(crate) fn import_mod( pub(crate) fn import_mod(
&mut self, &mut self,
kind: ImportKind,
current_input: Input, current_input: Input,
var_name: &VarName, var_name: &VarName,
mod_name: &hir::Expr, mod_name: &hir::Expr,
@ -771,61 +798,10 @@ impl Context {
match mod_name { match mod_name {
hir::Expr::Lit(lit) => { hir::Expr::Lit(lit) => {
if self.subtype_of(&lit.value.class(), &Str) { if self.subtype_of(&lit.value.class(), &Str) {
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); if kind.is_erg_import() {
if let Some(mod_cache) = self.mod_cache.as_ref() { self.import_erg_mod(current_input, var_name, lit)?;
match &__name__[..] {
"importlib" => {
mod_cache.register(
var_name.clone(),
None,
Self::init_py_importlib_mod(),
);
}
"io" => {
mod_cache.register(var_name.clone(), None, Self::init_py_io_mod());
}
"math" => {
mod_cache.register(
var_name.clone(),
None,
Self::init_py_math_mod(),
);
}
"random" => {
mod_cache.register(
var_name.clone(),
None,
Self::init_py_random_mod(),
);
}
"socket" => {
mod_cache.register(
var_name.clone(),
None,
Self::init_py_socket_mod(),
);
}
"sys" => {
mod_cache.register(var_name.clone(), None, Self::init_py_sys_mod());
}
"time" => {
mod_cache.register(
var_name.clone(),
None,
Self::init_py_time_mod(),
);
}
_ => self.import_user_module(
current_input,
var_name,
__name__,
lit,
mod_cache,
)?,
}
} else { } else {
// maybe unreachable self.import_py_mod(current_input, var_name, lit)?;
todo!("importing {__name__} in the builtin module")
} }
} else { } else {
return Err(TyCheckError::type_mismatch_error( return Err(TyCheckError::type_mismatch_error(
@ -852,14 +828,42 @@ impl Context {
Ok(()) Ok(())
} }
fn import_user_module( fn import_erg_mod(
&mut self,
current_input: Input,
var_name: &VarName,
lit: &Literal,
) -> TyCheckResult<()> {
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str);
let mod_cache = self.mod_cache.as_ref().unwrap();
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
#[allow(clippy::match_single_binding)]
match &__name__[..] {
_ => self.import_user_erg_mod(
current_input,
var_name,
__name__,
lit,
mod_cache,
py_mod_cache,
)?,
}
Ok(())
}
fn import_user_erg_mod(
&self, &self,
current_input: Input, current_input: Input,
var_name: &VarName, var_name: &VarName,
__name__: Str, __name__: Str,
name_lit: &Literal, name_lit: &Literal,
mod_cache: &SharedModuleCache, mod_cache: &SharedModuleCache,
py_mod_cache: &SharedModuleCache,
) -> TyCheckResult<()> { ) -> TyCheckResult<()> {
if let Some((_, entry)) = mod_cache.get_by_name(&__name__) {
mod_cache.register_alias(var_name.clone(), entry);
return Ok(());
}
let mut dir = if let Input::File(mut path) = current_input { let mut dir = if let Input::File(mut path) = current_input {
path.pop(); path.pop();
path path
@ -871,11 +875,18 @@ impl Context {
let path = match dir.canonicalize() { let path = match dir.canonicalize() {
Ok(path) => path, Ok(path) => path,
Err(err) => { Err(err) => {
return Err(TyCheckError::file_error( return Err(TyCheckError::import_error(
line!() as usize, line!() as usize,
err.to_string(), err.to_string(),
name_lit.loc(), name_lit.loc(),
self.caused_by(), self.caused_by(),
self.mod_cache.as_ref().unwrap().get_similar_name(&__name__),
self.similar_builtin_py_mod_name(&__name__).or_else(|| {
self.py_mod_cache
.as_ref()
.unwrap()
.get_similar_name(&__name__)
}),
)); ));
} }
}; };
@ -884,7 +895,12 @@ impl Context {
..ErgConfig::default() ..ErgConfig::default()
}; };
let src = cfg.input.read(); let src = cfg.input.read();
let mut builder = HIRBuilder::new_with_cache(cfg, var_name.inspect(), mod_cache.clone()); let mut builder = HIRBuilder::new_with_cache(
cfg,
var_name.inspect(),
mod_cache.clone(),
py_mod_cache.clone(),
);
match builder.build(src, "exec") { match builder.build(src, "exec") {
Ok(hir) => { Ok(hir) => {
mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx());
@ -896,6 +912,60 @@ impl Context {
Ok(()) Ok(())
} }
fn import_py_mod(
&mut self,
current_input: Input,
var_name: &VarName,
lit: &Literal,
) -> TyCheckResult<()> {
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str);
let mod_cache = self.mod_cache.as_ref().unwrap();
match &__name__[..] {
"importlib" => {
mod_cache.register(var_name.clone(), None, Self::init_py_importlib_mod());
}
"io" => {
mod_cache.register(var_name.clone(), None, Self::init_py_io_mod());
}
"math" => {
mod_cache.register(var_name.clone(), None, Self::init_py_math_mod());
}
"random" => {
mod_cache.register(var_name.clone(), None, Self::init_py_random_mod());
}
"socket" => {
mod_cache.register(var_name.clone(), None, Self::init_py_socket_mod());
}
"sys" => {
mod_cache.register(var_name.clone(), None, Self::init_py_sys_mod());
}
"time" => {
mod_cache.register(var_name.clone(), None, Self::init_py_time_mod());
}
_ => self.import_user_py_mod(current_input, var_name, lit)?,
}
Ok(())
}
fn similar_builtin_py_mod_name(&self, name: &Str) -> Option<Str> {
get_similar_name(
["importlib", "io", "math", "random", "socket", "sys", "time"].into_iter(),
name,
)
.map(Str::rc)
}
fn import_user_py_mod(
&self,
_current_input: Input,
_var_name: &VarName,
lit: &Literal,
) -> TyCheckResult<()> {
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str);
let _mod_cache = self.mod_cache.as_ref().unwrap();
todo!()
}
pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) { pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) {
self.bounds.push(TyBound::subtype_of(sub, sup)); self.bounds.push(TyBound::subtype_of(sub, sup));
} }

View file

@ -416,7 +416,7 @@ impl TyCheckError {
loc: Location, loc: Location,
caused_by: AtomicStr, caused_by: AtomicStr,
name: &str, name: &str,
similar_name: Option<&Str>, similar_name: Option<&str>,
) -> Self { ) -> Self {
let name = readable_name(name); let name = readable_name(name);
let hint = similar_name.map(|n| { let hint = similar_name.map(|n| {
@ -452,7 +452,7 @@ impl TyCheckError {
caused_by: AtomicStr, caused_by: AtomicStr,
obj_t: &Type, obj_t: &Type,
name: &str, name: &str,
similar_name: Option<&Str>, similar_name: Option<&str>,
) -> Self { ) -> Self {
let hint = similar_name.map(|n| { let hint = similar_name.map(|n| {
let n = readable_name(n); let n = readable_name(n);
@ -488,7 +488,7 @@ impl TyCheckError {
obj_name: &str, obj_name: &str,
obj_t: &Type, obj_t: &Type,
name: &str, name: &str,
similar_name: Option<&Str>, similar_name: Option<&str>,
) -> Self { ) -> Self {
let hint = similar_name.map(|n| { let hint = similar_name.map(|n| {
let n = readable_name(n); let n = readable_name(n);
@ -1298,8 +1298,34 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
) )
} }
pub fn file_error(errno: usize, desc: String, loc: Location, caused_by: AtomicStr) -> Self { pub fn file_error(
Self::new(ErrorCore::new(errno, IoError, loc, desc, None), caused_by) errno: usize,
desc: String,
loc: Location,
caused_by: AtomicStr,
hint: Option<AtomicStr>,
) -> Self {
Self::new(ErrorCore::new(errno, IoError, loc, desc, hint), caused_by)
}
pub fn import_error(
errno: usize,
desc: String,
loc: Location,
caused_by: AtomicStr,
similar_erg_mod: Option<Str>,
similar_py_mod: Option<Str>,
) -> Self {
let hint = match (similar_erg_mod, similar_py_mod) {
(Some(erg), Some(py)) => Some(format!(
"similar name erg module {YELLOW}{erg}{RESET} and python module {YELLOW}{py}{RESET} exists (to import python modules, use `pyimport`)",
)),
(Some(erg), None) => Some(format!("similar name erg module exists: {YELLOW}{erg}{RESET}")),
(None, Some(py)) => Some(format!("similar name python module exists: {YELLOW}{py}{RESET} (to import python modules, use `pyimport`)")),
(None, None) => None,
};
let hint = hint.map(AtomicStr::from);
Self::file_error(errno, desc, loc, caused_by, hint)
} }
pub fn inner_typedef_error(errno: usize, loc: Location, caused_by: AtomicStr) -> Self { pub fn inner_typedef_error(errno: usize, loc: Location, caused_by: AtomicStr) -> Self {

View file

@ -20,6 +20,7 @@ use erg_type::value::{TypeKind, ValueObj};
use erg_type::{impl_t, impl_t_for_enum, HasType, Type}; use erg_type::{impl_t, impl_t_for_enum, HasType, Type};
use crate::context::eval::type_from_token_kind; use crate::context::eval::type_from_token_kind;
use crate::context::ImportKind;
use crate::error::readable_name; use crate::error::readable_name;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -1006,11 +1007,12 @@ impl Call {
} }
} }
pub fn is_import_call(&self) -> bool { pub fn import_kind(&self) -> Option<ImportKind> {
self.obj self.obj.show_acc().and_then(|s| match &s[..] {
.show_acc() "import" => Some(ImportKind::ErgImport),
.map(|s| &s[..] == "import" || &s[..] == "pyimport" || &s[..] == "py") "pyimport" | "py" => Some(ImportKind::PyImport),
.unwrap_or(false) _ => None,
})
} }
} }
@ -1332,7 +1334,7 @@ impl Def {
DefKind::Other DefKind::Other
} }
} }
Some("import") => DefKind::Module, Some("import") => DefKind::Import,
_ => DefKind::Other, _ => DefKind::Other,
}, },
_ => DefKind::Other, _ => DefKind::Other,

View file

@ -22,7 +22,7 @@ impl Linker {
// ↓ // ↓
// x = ModuleType("mod") // x = ModuleType("mod")
// exec(code, x.__dict__) # `code` is the mod's content // exec(code, x.__dict__) # `code` is the mod's content
Expr::Def(ref def) if def.def_kind().is_module() => { Expr::Def(ref def) if def.def_kind().is_erg_import() => {
// In the case of REPL, entries cannot be used up // In the case of REPL, entries cannot be used up
let hir = if cfg.input.is_repl() { let hir = if cfg.input.is_repl() {
mod_cache mod_cache

View file

@ -49,6 +49,7 @@ impl Default for ASTLowerer {
ErgConfig::default(), ErgConfig::default(),
Str::ever("<module>"), Str::ever("<module>"),
SharedModuleCache::new(), SharedModuleCache::new(),
SharedModuleCache::new(),
) )
} }
} }
@ -64,7 +65,12 @@ impl Runnable for ASTLowerer {
} }
fn new(cfg: ErgConfig) -> Self { fn new(cfg: ErgConfig) -> Self {
Self::new_with_cache(cfg, Str::ever("<module>"), SharedModuleCache::new()) Self::new_with_cache(
cfg,
Str::ever("<module>"),
SharedModuleCache::new(),
SharedModuleCache::new(),
)
} }
#[inline] #[inline]
@ -87,7 +93,7 @@ impl Runnable for ASTLowerer {
Ok(()) Ok(())
} }
fn eval(&mut self, src: String) -> Result<String, CompileErrors> { fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let mut ast_builder = ASTBuilder::new(self.cfg.copy());
let ast = ast_builder.build(src)?; 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| self.convert(errs))?;
@ -100,10 +106,11 @@ impl ASTLowerer {
cfg: ErgConfig, cfg: ErgConfig,
mod_name: S, mod_name: S,
mod_cache: SharedModuleCache, mod_cache: SharedModuleCache,
py_mod_cache: SharedModuleCache,
) -> Self { ) -> Self {
Self { Self {
cfg, cfg,
ctx: Context::new_module(mod_name, mod_cache), ctx: Context::new_module(mod_name, mod_cache, py_mod_cache),
errs: LowerErrors::empty(), errs: LowerErrors::empty(),
warns: LowerWarnings::empty(), warns: LowerWarnings::empty(),
} }
@ -611,9 +618,10 @@ impl ASTLowerer {
.assign_var_sig(&sig, found_body_t, id)?; .assign_var_sig(&sig, found_body_t, id)?;
match block.first().unwrap() { match block.first().unwrap() {
hir::Expr::Call(call) => { hir::Expr::Call(call) => {
if call.is_import_call() { if let Some(kind) = call.import_kind() {
let current_input = self.input().clone(); let current_input = self.input().clone();
self.ctx.outer.as_mut().unwrap().import_mod( self.ctx.outer.as_mut().unwrap().import_mod(
kind,
current_input, current_input,
&ident.name, &ident.name,
&call.args.pos_args.first().unwrap().expr, &call.args.pos_args.first().unwrap().expr,

View file

@ -4,7 +4,9 @@ use std::hash::Hash;
use std::rc::Rc; use std::rc::Rc;
use erg_common::dict::Dict; use erg_common::dict::Dict;
use erg_common::levenshtein::get_similar_name;
use erg_common::shared::Shared; use erg_common::shared::Shared;
use erg_common::Str;
use erg_parser::ast::VarName; use erg_parser::ast::VarName;
@ -26,7 +28,7 @@ impl ModId {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct ModuleEntry { pub struct ModuleEntry {
id: ModId, // builtin == 0, __main__ == 1 id: ModId, // builtin == 0, __main__ == 1
pub hir: Option<HIR>, pub hir: Option<HIR>,
@ -88,6 +90,12 @@ impl ModuleCache {
self.cache.get(name) self.cache.get(name)
} }
pub fn get_by_name(&self, __name__: &str) -> Option<(&VarName, &ModuleEntry)> {
self.cache
.iter()
.find(|(_, ent)| &ent.ctx.name[..] == __name__)
}
pub fn get_mut<Q: Eq + Hash + ?Sized>(&mut self, name: &Q) -> Option<&mut ModuleEntry> pub fn get_mut<Q: Eq + Hash + ?Sized>(&mut self, name: &Q) -> Option<&mut ModuleEntry>
where where
VarName: Borrow<Q>, VarName: Borrow<Q>,
@ -102,6 +110,10 @@ impl ModuleCache {
self.cache.insert(name, entry); self.cache.insert(name, entry);
} }
pub fn register_alias(&mut self, name: VarName, entry: &ModuleEntry) {
self.cache.insert(name, entry.clone());
}
pub fn remove<Q: Eq + Hash + ?Sized>(&mut self, name: &Q) -> Option<ModuleEntry> pub fn remove<Q: Eq + Hash + ?Sized>(&mut self, name: &Q) -> Option<ModuleEntry>
where where
VarName: Borrow<Q>, VarName: Borrow<Q>,
@ -122,6 +134,10 @@ impl ModuleCache {
None None
} }
} }
pub fn get_similar_name(&self, name: &str) -> Option<Str> {
get_similar_name(self.cache.iter().map(|(v, _)| &v.inspect()[..]), name).map(Str::rc)
}
} }
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
@ -148,6 +164,11 @@ impl SharedModuleCache {
ref_.get(name) ref_.get(name)
} }
pub fn get_by_name(&self, __name__: &str) -> Option<(&VarName, &ModuleEntry)> {
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
ref_.get_by_name(__name__)
}
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<&mut ModuleEntry> pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<&mut ModuleEntry>
where where
VarName: Borrow<Q>, VarName: Borrow<Q>,
@ -175,6 +196,10 @@ impl SharedModuleCache {
self.0.borrow_mut().register(name, hir, ctx); self.0.borrow_mut().register(name, hir, ctx);
} }
pub fn register_alias(&self, name: VarName, entry: &ModuleEntry) {
self.0.borrow_mut().register_alias(name, entry);
}
pub fn remove<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<ModuleEntry> pub fn remove<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<ModuleEntry>
where where
VarName: Borrow<Q>, VarName: Borrow<Q>,
@ -185,4 +210,8 @@ impl SharedModuleCache {
pub fn remove_by_id(&self, id: ModId) -> Option<ModuleEntry> { pub fn remove_by_id(&self, id: ModId) -> Option<ModuleEntry> {
self.0.borrow_mut().remove_by_id(id) self.0.borrow_mut().remove_by_id(id)
} }
pub fn get_similar_name(&self, name: &str) -> Option<Str> {
self.0.borrow().get_similar_name(name)
}
} }

View file

@ -3,14 +3,22 @@ use erg_compiler::mod_cache::SharedModuleCache;
#[test] #[test]
fn test_subtyping() -> Result<(), ()> { fn test_subtyping() -> Result<(), ()> {
let context = Context::new_module("<module>", SharedModuleCache::new()); let context = Context::new_module(
"<module>",
SharedModuleCache::new(),
SharedModuleCache::new(),
);
context.test_refinement_subtyping()?; context.test_refinement_subtyping()?;
Ok(()) Ok(())
} }
#[test] #[test]
fn test_instantiation_and_generalization() -> Result<(), ()> { fn test_instantiation_and_generalization() -> Result<(), ()> {
let context = Context::new_module("<module>", SharedModuleCache::new()); let context = Context::new_module(
"<module>",
SharedModuleCache::new(),
SharedModuleCache::new(),
);
context.test_instantiation_and_generalization()?; context.test_instantiation_and_generalization()?;
Ok(()) Ok(())
} }
@ -33,7 +41,11 @@ fn test_resolve_trait_inner1() -> Result<(), ()> {
#[test] #[test]
fn test_dir() -> Result<(), ()> { fn test_dir() -> Result<(), ()> {
let context = Context::new_module("<module>", SharedModuleCache::new()); let context = Context::new_module(
"<module>",
SharedModuleCache::new(),
SharedModuleCache::new(),
);
let vars = context.dir(); let vars = context.dir();
for (name, vi) in vars.into_iter() { for (name, vi) in vars.into_iter() {
println!("{name}: {vi}"); println!("{name}: {vi}");

View file

@ -2841,7 +2841,8 @@ pub enum DefKind {
Trait, Trait,
Subsume, Subsume,
StructuralTrait, StructuralTrait,
Module, Import,
PyImport,
/// type alias included /// type alias included
Other, Other,
} }
@ -2859,8 +2860,8 @@ impl DefKind {
self.is_class() || self.is_trait() self.is_class() || self.is_trait()
} }
pub fn is_module(&self) -> bool { pub fn is_erg_import(&self) -> bool {
matches!(self, Self::Module) matches!(self, Self::Import)
} }
} }
@ -2877,6 +2878,32 @@ impl DefBody {
pub const fn new(op: Token, block: Block, id: DefId) -> Self { pub const fn new(op: Token, block: Block, id: DefId) -> Self {
Self { op, block, id } Self { op, block, id }
} }
pub fn def_kind(&self) -> DefKind {
match self.block.first().unwrap() {
Expr::Call(call) => match call.obj.get_name().map(|n| &n[..]) {
Some("Class") => DefKind::Class,
Some("Inherit") => DefKind::Inherit,
Some("Trait") => DefKind::Trait,
Some("Subsume") => DefKind::Subsume,
Some("Inheritable") => {
if let Some(Expr::Call(inner)) = call.args.get_left_or_key("Class") {
match inner.obj.get_name().map(|n| &n[..]) {
Some("Class") => DefKind::Class,
Some("Inherit") => DefKind::Inherit,
_ => DefKind::Other,
}
} else {
DefKind::Other
}
}
Some("import") => DefKind::Import,
Some("pyimport") | Some("py") => DefKind::PyImport,
_ => DefKind::Other,
},
_ => DefKind::Other,
}
}
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -2910,28 +2937,7 @@ impl Def {
} }
pub fn def_kind(&self) -> DefKind { pub fn def_kind(&self) -> DefKind {
match self.body.block.first().unwrap() { self.body.def_kind()
Expr::Call(call) => match call.obj.get_name().map(|n| &n[..]) {
Some("Class") => DefKind::Class,
Some("Inherit") => DefKind::Inherit,
Some("Trait") => DefKind::Trait,
Some("Subsume") => DefKind::Subsume,
Some("Inheritable") => {
if let Some(Expr::Call(inner)) = call.args.get_left_or_key("Class") {
match inner.obj.get_name().map(|n| &n[..]) {
Some("Class") => DefKind::Class,
Some("Inherit") => DefKind::Inherit,
_ => DefKind::Other,
}
} else {
DefKind::Other
}
}
Some("import") => DefKind::Module,
_ => DefKind::Other,
},
_ => DefKind::Other,
}
} }
} }