Unify poly_classes and poly_traits of Context

This commit is contained in:
Shunsuke Shibayama 2022-09-03 12:07:27 +09:00
parent e1eebb252f
commit 618f73f0c0
4 changed files with 10 additions and 48 deletions

View file

@ -71,13 +71,7 @@ impl Context {
if t.typarams_len().is_none() {
self.register_mono_type(t, ctx, muty);
} else {
if t.is_class() {
self.register_poly_class(t, ctx, muty);
} else if t.is_trait() {
self.register_poly_trait(t, ctx, muty);
} else {
todo!()
}
self.register_poly_type(t, ctx, muty);
}
}
@ -103,10 +97,10 @@ impl Context {
}
}
fn register_poly_class(&mut self, t: Type, ctx: Self, muty: Mutability) {
fn register_poly_type(&mut self, t: Type, ctx: Self, muty: Mutability) {
let mut tv_ctx = TyVarContext::new(self.level, ctx.type_params_bounds(), self);
let t = Self::instantiate_t(t, &mut tv_ctx);
if let Some((_, root_ctx)) = self.poly_classes.get_mut(&t.name()) {
if let Some((_, root_ctx)) = self.poly_types.get_mut(&t.name()) {
root_ctx.specializations.push((t, ctx));
} else {
let name = VarName::from_str(t.name());
@ -123,31 +117,7 @@ impl Context {
);
}
}
self.poly_classes.insert(name, (t, ctx));
}
}
fn register_poly_trait(&mut self, t: Type, ctx: Self, muty: Mutability) {
if self.poly_traits.contains_key(&t.name()) {
panic!("{} has already been registered", t.name());
} else {
let mut tv_ctx = TyVarContext::new(self.level, ctx.type_params_bounds(), self);
let t = Self::instantiate_t(t, &mut tv_ctx);
let name = VarName::from_str(t.name());
self.locals
.insert(name.clone(), VarInfo::new(Type, muty, Private, Builtin));
self.consts.insert(name.clone(), ValueObj::t(t.clone()));
for impl_trait in ctx.super_traits.iter() {
if let Some(impls) = self.trait_impls.get_mut(&impl_trait.name()) {
impls.push(TraitInstance::new(t.clone(), impl_trait.clone()));
} else {
self.trait_impls.insert(
impl_trait.name(),
vec![TraitInstance::new(t.clone(), impl_trait.clone())],
);
}
}
self.poly_traits.insert(name, (t, ctx));
self.poly_types.insert(name, (t, ctx));
}
}

View file

@ -1000,13 +1000,8 @@ impl Context {
Type::Quantified(_) => {
return self.rec_get_nominal_type_ctx(&class("QuantifiedFunction"));
}
Type::PolyClass { name, params: _ } => {
if let Some((t, ctx)) = self.poly_classes.get(name) {
return Some((t, ctx));
}
}
Type::PolyTrait { name, params: _ } => {
if let Some((t, ctx)) = self.poly_traits.get(name) {
Type::PolyClass { name, params: _ } | Type::PolyTrait { name, params: _ } => {
if let Some((t, ctx)) = self.poly_types.get(name) {
return Some((t, ctx));
}
}

View file

@ -258,9 +258,7 @@ pub struct Context {
// Implementation Contexts for Polymorphic Types
// Vec<TyParam> are specialization parameters
// e.g. {"Array": [(Array(Nat), ctx), (Array(Int), ctx), (Array(Str), ctx), (Array(Obj), ctx), (Array('T), ctx)], ...}
pub(crate) poly_classes: Dict<VarName, (Type, Context)>,
// Traits cannot be specialized
pub(crate) poly_traits: Dict<VarName, (Type, Context)>,
pub(crate) poly_types: Dict<VarName, (Type, Context)>,
// patches can be accessed like normal records
// but when used as a fallback to a type, values are traversed instead of accessing by keys
pub(crate) patches: Dict<VarName, Context>,
@ -295,7 +293,7 @@ impl fmt::Display for Context {
.field("locals", &self.params)
.field("consts", &self.consts)
.field("mono_types", &self.mono_types)
.field("poly_types", &self.poly_classes)
.field("poly_types", &self.poly_types)
.field("patches", &self.patches)
.field("mods", &self.mods)
.finish()
@ -368,8 +366,7 @@ impl Context {
locals: Dict::with_capacity(capacity),
consts: Dict::default(),
mono_types: Dict::default(),
poly_classes: Dict::default(),
poly_traits: Dict::default(),
poly_types: Dict::default(),
mods: Dict::default(),
patches: Dict::default(),
_nlocals: 0,

View file

@ -535,7 +535,7 @@ impl ASTLowerer {
ast::Expr::UnaryOp(unary) => Ok(hir::Expr::UnaryOp(self.lower_unary(unary)?)),
ast::Expr::Call(call) => Ok(hir::Expr::Call(self.lower_call(call)?)),
ast::Expr::Lambda(lambda) => Ok(hir::Expr::Lambda(self.lower_lambda(lambda)?)),
// ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)),
ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)),
other => todo!("{other}"),
}
}