mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 12:51:10 +00:00
Change Eq(R)
to Eq
This commit is contained in:
parent
9f85c88e7e
commit
d56549f528
15 changed files with 231 additions and 196 deletions
|
@ -21,7 +21,7 @@ use Type::*;
|
||||||
use crate::context::cache::{SubtypePair, GLOBAL_TYPE_CACHE};
|
use crate::context::cache::{SubtypePair, GLOBAL_TYPE_CACHE};
|
||||||
use crate::context::eval::SubstContext;
|
use crate::context::eval::SubstContext;
|
||||||
use crate::context::instantiate::TyVarInstContext;
|
use crate::context::instantiate::TyVarInstContext;
|
||||||
use crate::context::{Context, TraitInstance, Variance};
|
use crate::context::{Context, TypeRelationInstance, Variance};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum Credibility {
|
pub enum Credibility {
|
||||||
|
@ -258,25 +258,10 @@ impl Context {
|
||||||
self.register_cache(lhs, rhs, judge);
|
self.register_cache(lhs, rhs, judge);
|
||||||
return judge;
|
return judge;
|
||||||
}
|
}
|
||||||
// FIXME: rec_get_patch
|
/*if self._find_compatible_patch(lhs, rhs).is_some() {
|
||||||
for patch in self.patches.values() {
|
self.register_cache(lhs, rhs, true);
|
||||||
if let ContextKind::GluePatch(tr_inst) = &patch.kind {
|
return true;
|
||||||
if tr_inst.sub_type.has_qvar() || tr_inst.sup_trait.has_qvar() {
|
}*/
|
||||||
todo!("{tr_inst}");
|
|
||||||
} else {
|
|
||||||
// e.g.
|
|
||||||
// P = Patch X, Impl: Ord
|
|
||||||
// Rhs <: X => Rhs <: Ord
|
|
||||||
// Ord <: Lhs => Rhs <: Ord <: Lhs
|
|
||||||
if self.supertype_of(&tr_inst.sub_type, rhs)
|
|
||||||
&& self.subtype_of(&tr_inst.sup_trait, lhs)
|
|
||||||
{
|
|
||||||
self.register_cache(lhs, rhs, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.register_cache(lhs, rhs, false);
|
self.register_cache(lhs, rhs, false);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -285,6 +270,41 @@ impl Context {
|
||||||
self.nominal_supertype_of(rhs, lhs)
|
self.nominal_supertype_of(rhs, lhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _find_compatible_patch(&self, sup: &Type, sub: &Type) -> Option<Str> {
|
||||||
|
let subst_ctx = SubstContext::try_new(sub, self, Location::Unknown)?;
|
||||||
|
for patch in self._all_patches().into_iter() {
|
||||||
|
if let ContextKind::GluePatch(tr_inst) = &patch.kind {
|
||||||
|
if tr_inst.sub_type.has_qvar() || tr_inst.sup_trait.has_qvar() {
|
||||||
|
if let (Ok(sub_type), Ok(sup_trait)) = (
|
||||||
|
subst_ctx.substitute(tr_inst.sub_type.clone()),
|
||||||
|
subst_ctx.substitute(tr_inst.sup_trait.clone()),
|
||||||
|
) {
|
||||||
|
let l1 = self.subtype_of(sub, &sub_type);
|
||||||
|
let l2 = self.subtype_of(&sup_trait, sup);
|
||||||
|
if l1 && l2 {
|
||||||
|
return Some(patch.name.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// e.g.
|
||||||
|
// P = Patch X, Impl: Y
|
||||||
|
// # => TypeRelationInstance { X <: Y }
|
||||||
|
// X <: Y => Sub <: Y (if Sub <: X)
|
||||||
|
// X <: Y => X <: Sup (if Y <: Sup)
|
||||||
|
// # => OK if Sub <: X and Y <: Sup
|
||||||
|
// Rhs <: X => Rhs <: Ord
|
||||||
|
// Ord <: Lhs => Rhs <: Ord <: Lhs
|
||||||
|
if self.subtype_of(sub, &tr_inst.sub_type)
|
||||||
|
&& self.subtype_of(&tr_inst.sup_trait, sup)
|
||||||
|
{
|
||||||
|
return Some(patch.name.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn classes_supertype_of(&self, lhs: &Type, rhs: &Type) -> (Credibility, bool) {
|
fn classes_supertype_of(&self, lhs: &Type, rhs: &Type) -> (Credibility, bool) {
|
||||||
if !self.is_class(lhs) || !self.is_class(rhs) {
|
if !self.is_class(lhs) || !self.is_class(rhs) {
|
||||||
return (Maybe, false);
|
return (Maybe, false);
|
||||||
|
@ -321,6 +341,7 @@ impl Context {
|
||||||
|
|
||||||
// e.g. Eq(Nat) :> Nat
|
// e.g. Eq(Nat) :> Nat
|
||||||
// Nat.super_traits = [Add(Nat), Eq(Nat), Sub(Float), ...]
|
// Nat.super_traits = [Add(Nat), Eq(Nat), Sub(Float), ...]
|
||||||
|
// e.g. Eq :> ?L or ?R (if ?L <: Eq and ?R <: Eq)
|
||||||
fn traits_supertype_of(&self, lhs: &Type, rhs: &Type) -> (Credibility, bool) {
|
fn traits_supertype_of(&self, lhs: &Type, rhs: &Type) -> (Credibility, bool) {
|
||||||
if !self.is_trait(lhs) {
|
if !self.is_trait(lhs) {
|
||||||
return (Maybe, false);
|
return (Maybe, false);
|
||||||
|
@ -369,7 +390,7 @@ impl Context {
|
||||||
|
|
||||||
/// assert!(sup_conforms(?E(<: Eq(?E)), {Nat, Eq(Nat)}))
|
/// assert!(sup_conforms(?E(<: Eq(?E)), {Nat, Eq(Nat)}))
|
||||||
/// assert!(sup_conforms(?E(<: Eq(?R)), {Nat, Eq(T)}))
|
/// assert!(sup_conforms(?E(<: Eq(?R)), {Nat, Eq(T)}))
|
||||||
fn _sub_conforms(&self, free: &FreeTyVar, inst_pair: &TraitInstance) -> bool {
|
fn _sub_conforms(&self, free: &FreeTyVar, inst_pair: &TypeRelationInstance) -> bool {
|
||||||
let (_sub, sup) = free.get_bound_types().unwrap();
|
let (_sub, sup) = free.get_bound_types().unwrap();
|
||||||
log!(info "{free}");
|
log!(info "{free}");
|
||||||
free.forced_undoable_link(&inst_pair.sub_type);
|
free.forced_undoable_link(&inst_pair.sub_type);
|
||||||
|
@ -648,11 +669,20 @@ impl Context {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.structural_supertype_of(l, &q_callable)
|
self.structural_supertype_of(l, &q_callable)
|
||||||
}
|
}
|
||||||
|
// Int or Str :> Str or Int == (Int :> Str && Str :> Int) || (Int :> Int && Str :> Str) == true
|
||||||
|
(Or(l_1, l_2), Or(r_1, r_2)) => {
|
||||||
|
(self.supertype_of(l_1, r_1) && self.supertype_of(l_2, r_2))
|
||||||
|
|| (self.supertype_of(l_1, r_2) && self.supertype_of(l_2, r_1))
|
||||||
|
}
|
||||||
// (Int or Str) :> Nat == Int :> Nat || Str :> Nat == true
|
// (Int or Str) :> Nat == Int :> Nat || Str :> Nat == true
|
||||||
// (Num or Show) :> Show == Num :> Show || Show :> Num == true
|
// (Num or Show) :> Show == Num :> Show || Show :> Num == true
|
||||||
(Or(l_or, r_or), rhs) => self.supertype_of(l_or, rhs) || self.supertype_of(r_or, rhs),
|
(Or(l_or, r_or), rhs) => self.supertype_of(l_or, rhs) || self.supertype_of(r_or, rhs),
|
||||||
// Int :> (Nat or Str) == Int :> Nat && Int :> Str == false
|
// Int :> (Nat or Str) == Int :> Nat && Int :> Str == false
|
||||||
(lhs, Or(l_or, r_or)) => self.supertype_of(lhs, l_or) && self.supertype_of(lhs, r_or),
|
(lhs, Or(l_or, r_or)) => self.supertype_of(lhs, l_or) && self.supertype_of(lhs, r_or),
|
||||||
|
(And(l_1, l_2), And(r_1, r_2)) => {
|
||||||
|
(self.supertype_of(l_1, r_1) && self.supertype_of(l_2, r_2))
|
||||||
|
|| (self.supertype_of(l_1, r_2) && self.supertype_of(l_2, r_1))
|
||||||
|
}
|
||||||
// (Num and Show) :> Show == false
|
// (Num and Show) :> Show == false
|
||||||
(And(l_and, r_and), rhs) => {
|
(And(l_and, r_and), rhs) => {
|
||||||
self.supertype_of(l_and, rhs) && self.supertype_of(r_and, rhs)
|
self.supertype_of(l_and, rhs) && self.supertype_of(r_and, rhs)
|
||||||
|
|
|
@ -136,9 +136,11 @@ impl<'c> SubstContext<'c> {
|
||||||
///
|
///
|
||||||
/// `ctx` is used to obtain information on the names and variance of the parameters.
|
/// `ctx` is used to obtain information on the names and variance of the parameters.
|
||||||
pub fn new(substituted: &Type, ctx: &'c Context, loc: Location) -> Self {
|
pub fn new(substituted: &Type, ctx: &'c Context, loc: Location) -> Self {
|
||||||
let ty_ctx = ctx
|
Self::try_new(substituted, ctx, loc).unwrap()
|
||||||
.get_nominal_type_ctx(substituted)
|
}
|
||||||
.unwrap_or_else(|| todo!("{substituted} not found"));
|
|
||||||
|
pub fn try_new(substituted: &Type, ctx: &'c Context, loc: Location) -> Option<Self> {
|
||||||
|
let ty_ctx = ctx.get_nominal_type_ctx(substituted)?;
|
||||||
let bounds = ty_ctx.type_params_bounds();
|
let bounds = ty_ctx.type_params_bounds();
|
||||||
let param_names = ty_ctx.params.iter().map(|(opt_name, _)| {
|
let param_names = ty_ctx.params.iter().map(|(opt_name, _)| {
|
||||||
opt_name
|
opt_name
|
||||||
|
@ -146,13 +148,14 @@ impl<'c> SubstContext<'c> {
|
||||||
.map_or_else(|| Str::ever("_"), |n| n.inspect().clone())
|
.map_or_else(|| Str::ever("_"), |n| n.inspect().clone())
|
||||||
});
|
});
|
||||||
if param_names.len() != substituted.typarams().len() {
|
if param_names.len() != substituted.typarams().len() {
|
||||||
let param_names = param_names.collect::<Vec<_>>();
|
/*let param_names = param_names.collect::<Vec<_>>();
|
||||||
panic!(
|
panic!(
|
||||||
"{} param_names: {param_names:?} != {} substituted_params: [{}]",
|
"{} param_names: {param_names:?} != {} substituted_params: [{}]",
|
||||||
ty_ctx.name,
|
ty_ctx.name,
|
||||||
substituted.qual_name(),
|
substituted.qual_name(),
|
||||||
erg_common::fmt_vec(&substituted.typarams())
|
erg_common::fmt_vec(&substituted.typarams())
|
||||||
);
|
);*/
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
let params = param_names
|
let params = param_names
|
||||||
.zip(substituted.typarams().into_iter())
|
.zip(substituted.typarams().into_iter())
|
||||||
|
@ -165,12 +168,12 @@ impl<'c> SubstContext<'c> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// REVIEW: 順番は保証されるか? 引数がunnamed_paramsに入る可能性は?
|
// REVIEW: 順番は保証されるか? 引数がunnamed_paramsに入る可能性は?
|
||||||
SubstContext {
|
Some(SubstContext {
|
||||||
ctx,
|
ctx,
|
||||||
bounds,
|
bounds,
|
||||||
params,
|
params,
|
||||||
loc,
|
loc,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn substitute(&self, quant_t: Type) -> TyCheckResult<Type> {
|
pub fn substitute(&self, quant_t: Type) -> TyCheckResult<Type> {
|
||||||
|
@ -229,7 +232,7 @@ impl<'c> SubstContext<'c> {
|
||||||
self.ctx.sub_unify(param_t, &t, Location::Unknown, None)?;
|
self.ctx.sub_unify(param_t, &t, Location::Unknown, None)?;
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
todo!("")
|
todo!("{tp}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,7 +279,7 @@ impl<'c> SubstContext<'c> {
|
||||||
self.substitute_tp(param)?;
|
self.substitute_tp(param)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t => todo!("{t:?}"),
|
_t => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ use std::path::PathBuf;
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
use erg_common::dict;
|
use erg_common::dict;
|
||||||
// use erg_common::error::Location;
|
// use erg_common::error::Location;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use erg_common::log;
|
||||||
use erg_common::vis::Visibility;
|
use erg_common::vis::Visibility;
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
use erg_common::{set, unique_in_place};
|
use erg_common::{set, unique_in_place};
|
||||||
|
@ -25,7 +27,7 @@ use erg_parser::ast::VarName;
|
||||||
use crate::context::initialize::const_func::*;
|
use crate::context::initialize::const_func::*;
|
||||||
use crate::context::instantiate::ConstTemplate;
|
use crate::context::instantiate::ConstTemplate;
|
||||||
use crate::context::{
|
use crate::context::{
|
||||||
ClassDefType, Context, ContextKind, DefaultInfo, MethodInfo, ParamSpec, TraitInstance,
|
ClassDefType, Context, ContextKind, DefaultInfo, MethodInfo, ParamSpec, TypeRelationInstance,
|
||||||
};
|
};
|
||||||
use crate::mod_cache::SharedModuleCache;
|
use crate::mod_cache::SharedModuleCache;
|
||||||
use crate::varinfo::{Mutability, VarInfo, VarKind};
|
use crate::varinfo::{Mutability, VarInfo, VarKind};
|
||||||
|
@ -236,11 +238,11 @@ impl Context {
|
||||||
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
|
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
|
||||||
for impl_trait in ctx.super_traits.iter() {
|
for impl_trait in ctx.super_traits.iter() {
|
||||||
if let Some(impls) = self.trait_impls.get_mut(&impl_trait.qual_name()) {
|
if let Some(impls) = self.trait_impls.get_mut(&impl_trait.qual_name()) {
|
||||||
impls.insert(TraitInstance::new(t.clone(), impl_trait.clone()));
|
impls.insert(TypeRelationInstance::new(t.clone(), impl_trait.clone()));
|
||||||
} else {
|
} else {
|
||||||
self.trait_impls.insert(
|
self.trait_impls.insert(
|
||||||
impl_trait.qual_name(),
|
impl_trait.qual_name(),
|
||||||
set![TraitInstance::new(t.clone(), impl_trait.clone())],
|
set![TypeRelationInstance::new(t.clone(), impl_trait.clone())],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,11 +305,11 @@ impl Context {
|
||||||
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
|
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
|
||||||
for impl_trait in ctx.super_traits.iter() {
|
for impl_trait in ctx.super_traits.iter() {
|
||||||
if let Some(impls) = self.trait_impls.get_mut(&impl_trait.qual_name()) {
|
if let Some(impls) = self.trait_impls.get_mut(&impl_trait.qual_name()) {
|
||||||
impls.insert(TraitInstance::new(t.clone(), impl_trait.clone()));
|
impls.insert(TypeRelationInstance::new(t.clone(), impl_trait.clone()));
|
||||||
} else {
|
} else {
|
||||||
self.trait_impls.insert(
|
self.trait_impls.insert(
|
||||||
impl_trait.qual_name(),
|
impl_trait.qual_name(),
|
||||||
set![TraitInstance::new(t.clone(), impl_trait.clone())],
|
set![TypeRelationInstance::new(t.clone(), impl_trait.clone())],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,6 +360,14 @@ impl Context {
|
||||||
.insert(method_name.clone(), vec![name.clone()]);
|
.insert(method_name.clone(), vec![name.clone()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let ContextKind::GluePatch(tr_inst) = &ctx.kind {
|
||||||
|
if let Some(impls) = self.trait_impls.get_mut(&tr_inst.sup_trait.qual_name()) {
|
||||||
|
impls.insert(tr_inst.clone());
|
||||||
|
} else {
|
||||||
|
self.trait_impls
|
||||||
|
.insert(tr_inst.sup_trait.qual_name(), set![tr_inst.clone()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
self.patches.insert(name, ctx);
|
self.patches.insert(name, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -459,35 +469,21 @@ 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::builtin_poly_trait("Eq", vec![PS::t("R", WithDefault)], 2);
|
let mut eq = Self::builtin_mono_trait("Eq", 2);
|
||||||
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("Self"), Bool);
|
||||||
let op_t = fn1_met(mono_q("Self"), mono_q("R"), Bool);
|
let op_t = quant(op_t, set! { subtypeof(mono_q("Self"), mono("Eq")) });
|
||||||
let op_t = quant(
|
|
||||||
op_t,
|
|
||||||
set! {
|
|
||||||
subtypeof(mono_q("Self"), poly("Eq", vec![ty_tp(mono_q("R"))])),
|
|
||||||
static_instance("R", Type)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
eq.register_builtin_decl("__eq__", op_t, Public);
|
eq.register_builtin_decl("__eq__", op_t, Public);
|
||||||
/* Partial_ord */
|
|
||||||
let mut partial_ord =
|
|
||||||
Self::builtin_poly_trait("PartialOrd", vec![PS::t("R", WithDefault)], 2);
|
|
||||||
partial_ord.register_superclass(poly("Eq", vec![ty_tp(mono_q("R"))]), &eq);
|
|
||||||
let op_t = fn1_met(mono_q("Self"), mono_q("R"), or(mono("Ordering"), NoneType));
|
|
||||||
let op_t = quant(
|
|
||||||
op_t,
|
|
||||||
set! {
|
|
||||||
subtypeof(mono_q("Self"), poly("PartialOrd", vec![ty_tp(mono_q("R"))])),
|
|
||||||
static_instance("R", Type)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public);
|
|
||||||
/* Ord */
|
/* Ord */
|
||||||
let mut ord = Self::builtin_mono_trait("Ord", 2);
|
let mut ord = Self::builtin_mono_trait("Ord", 2);
|
||||||
ord.register_superclass(poly("Eq", vec![ty_tp(mono("Self"))]), &eq);
|
ord.register_superclass(mono("Eq"), &eq);
|
||||||
ord.register_superclass(poly("PartialOrd", vec![ty_tp(mono("Self"))]), &partial_ord);
|
let op_t = fn1_met(
|
||||||
|
mono_q("Self"),
|
||||||
|
mono_q("Self"),
|
||||||
|
or(mono("Ordering"), NoneType),
|
||||||
|
);
|
||||||
|
let op_t = quant(op_t, set! { subtypeof(mono_q("Self"), mono("Ord")) });
|
||||||
|
ord.register_builtin_decl("__cmp__", op_t, Public);
|
||||||
// FIXME: poly trait
|
// FIXME: poly trait
|
||||||
/* Num */
|
/* Num */
|
||||||
let num = Self::builtin_mono_trait("Num", 2);
|
let num = Self::builtin_mono_trait("Num", 2);
|
||||||
|
@ -620,20 +616,7 @@ impl Context {
|
||||||
Const,
|
Const,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
self.register_builtin_type(
|
self.register_builtin_type(mono("Eq"), eq, Private, Const, None);
|
||||||
poly("Eq", vec![ty_tp(mono_q("R"))]),
|
|
||||||
eq,
|
|
||||||
Private,
|
|
||||||
Const,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
self.register_builtin_type(
|
|
||||||
poly("PartialOrd", vec![ty_tp(mono_q("R"))]),
|
|
||||||
partial_ord,
|
|
||||||
Private,
|
|
||||||
Const,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
self.register_builtin_type(mono("Ord"), ord, Private, Const, None);
|
self.register_builtin_type(mono("Ord"), ord, Private, Const, None);
|
||||||
self.register_builtin_type(mono("Num"), num, Private, Const, None);
|
self.register_builtin_type(mono("Num"), num, Private, Const, None);
|
||||||
self.register_builtin_type(
|
self.register_builtin_type(
|
||||||
|
@ -655,14 +638,6 @@ impl Context {
|
||||||
self.register_builtin_type(poly("Mul", ty_params.clone()), mul, Private, Const, None);
|
self.register_builtin_type(poly("Mul", ty_params.clone()), mul, Private, Const, None);
|
||||||
self.register_builtin_type(poly("Div", ty_params.clone()), div, Private, Const, None);
|
self.register_builtin_type(poly("Div", ty_params.clone()), div, Private, Const, None);
|
||||||
self.register_builtin_type(poly("FloorDiv", ty_params), floor_div, Private, Const, None);
|
self.register_builtin_type(poly("FloorDiv", ty_params), floor_div, Private, Const, None);
|
||||||
self.register_const_param_defaults(
|
|
||||||
"Eq",
|
|
||||||
vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))],
|
|
||||||
);
|
|
||||||
self.register_const_param_defaults(
|
|
||||||
"PartialOrd",
|
|
||||||
vec![ConstTemplate::app("Self", vec![], vec![])],
|
|
||||||
);
|
|
||||||
self.register_const_param_defaults(
|
self.register_const_param_defaults(
|
||||||
"Add",
|
"Add",
|
||||||
vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))],
|
vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))],
|
||||||
|
@ -719,15 +694,14 @@ impl Context {
|
||||||
float.register_builtin_py_impl("Imag", Float, Const, Public, Some("imag"));
|
float.register_builtin_py_impl("Imag", Float, Const, Public, Some("imag"));
|
||||||
float.register_marker_trait(mono("Num"));
|
float.register_marker_trait(mono("Num"));
|
||||||
float.register_marker_trait(mono("Ord"));
|
float.register_marker_trait(mono("Ord"));
|
||||||
let mut float_partial_ord =
|
let mut float_ord = Self::builtin_methods(Some(mono("Ord")), 2);
|
||||||
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Float)])), 2);
|
float_ord.register_builtin_impl(
|
||||||
float_partial_ord.register_builtin_impl(
|
|
||||||
"__cmp__",
|
"__cmp__",
|
||||||
fn1_met(Float, Float, mono("Ordering")),
|
fn1_met(Float, Float, mono("Ordering")),
|
||||||
Const,
|
Const,
|
||||||
Public,
|
Public,
|
||||||
);
|
);
|
||||||
float.register_trait(Float, float_partial_ord);
|
float.register_trait(Float, float_ord);
|
||||||
// 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::builtin_methods(Some(poly("Add", vec![ty_tp(Float)])), 2);
|
let mut float_add = Self::builtin_methods(Some(poly("Add", vec![ty_tp(Float)])), 2);
|
||||||
|
@ -773,16 +747,15 @@ impl Context {
|
||||||
ratio.register_builtin_py_impl("Imag", Ratio, Const, Public, Some("imag"));
|
ratio.register_builtin_py_impl("Imag", Ratio, Const, Public, Some("imag"));
|
||||||
ratio.register_marker_trait(mono("Num"));
|
ratio.register_marker_trait(mono("Num"));
|
||||||
ratio.register_marker_trait(mono("Ord"));
|
ratio.register_marker_trait(mono("Ord"));
|
||||||
let mut ratio_partial_ord =
|
let mut ratio_ord = Self::builtin_methods(Some(mono("Ord")), 2);
|
||||||
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Ratio)])), 2);
|
ratio_ord.register_builtin_impl(
|
||||||
ratio_partial_ord.register_builtin_impl(
|
|
||||||
"__cmp__",
|
"__cmp__",
|
||||||
fn1_met(Ratio, Ratio, mono("Ordering")),
|
fn1_met(Ratio, Ratio, mono("Ordering")),
|
||||||
Const,
|
Const,
|
||||||
Public,
|
Public,
|
||||||
);
|
);
|
||||||
ratio.register_trait(Ratio, ratio_partial_ord);
|
ratio.register_trait(Ratio, ratio_ord);
|
||||||
let mut ratio_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Ratio)])), 2);
|
let mut ratio_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
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, ratio_eq);
|
ratio.register_trait(Ratio, ratio_eq);
|
||||||
let op_t = fn1_met(Ratio, Ratio, Ratio);
|
let op_t = fn1_met(Ratio, Ratio, Ratio);
|
||||||
|
@ -825,21 +798,18 @@ impl Context {
|
||||||
let mut int = Self::builtin_mono_class("Int", 2);
|
let mut int = Self::builtin_mono_class("Int", 2);
|
||||||
int.register_superclass(Float, &float); // TODO: Float -> Ratio
|
int.register_superclass(Float, &float); // TODO: Float -> Ratio
|
||||||
int.register_marker_trait(mono("Num"));
|
int.register_marker_trait(mono("Num"));
|
||||||
int.register_marker_trait(mono("Ord"));
|
|
||||||
int.register_marker_trait(poly("Eq", vec![ty_tp(Int)]));
|
|
||||||
// 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 =
|
let mut int_ord = Self::builtin_methods(Some(mono("Ord")), 2);
|
||||||
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Int)])), 2);
|
int_ord.register_builtin_impl(
|
||||||
int_partial_ord.register_builtin_impl(
|
|
||||||
"__partial_cmp__",
|
"__partial_cmp__",
|
||||||
fn1_met(Int, Int, or(mono("Ordering"), NoneType)),
|
fn1_met(Int, Int, or(mono("Ordering"), NoneType)),
|
||||||
Const,
|
Const,
|
||||||
Public,
|
Public,
|
||||||
);
|
);
|
||||||
int.register_trait(Int, int_partial_ord);
|
int.register_trait(Int, int_ord);
|
||||||
let mut int_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Int)])), 2);
|
let mut int_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
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, int_eq);
|
int.register_trait(Int, int_eq);
|
||||||
// __div__ is not included in Int (cast to Ratio)
|
// __div__ is not included in Int (cast to Ratio)
|
||||||
|
@ -890,19 +860,17 @@ impl Context {
|
||||||
Some("times"),
|
Some("times"),
|
||||||
);
|
);
|
||||||
nat.register_marker_trait(mono("Num"));
|
nat.register_marker_trait(mono("Num"));
|
||||||
nat.register_marker_trait(mono("Ord"));
|
let mut nat_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
let mut nat_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Nat)])), 2);
|
|
||||||
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, nat_eq);
|
nat.register_trait(Nat, nat_eq);
|
||||||
let mut nat_partial_ord =
|
let mut nat_ord = Self::builtin_methods(Some(mono("Ord")), 2);
|
||||||
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Nat)])), 2);
|
nat_ord.register_builtin_impl(
|
||||||
nat_partial_ord.register_builtin_impl(
|
|
||||||
"__cmp__",
|
"__cmp__",
|
||||||
fn1_met(Nat, Nat, mono("Ordering")),
|
fn1_met(Nat, Nat, mono("Ordering")),
|
||||||
Const,
|
Const,
|
||||||
Public,
|
Public,
|
||||||
);
|
);
|
||||||
nat.register_trait(Nat, nat_partial_ord);
|
nat.register_trait(Nat, nat_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::builtin_methods(Some(poly("Add", vec![ty_tp(Nat)])), 2);
|
let mut nat_add = Self::builtin_methods(Some(poly("Add", vec![ty_tp(Nat)])), 2);
|
||||||
|
@ -931,17 +899,15 @@ impl Context {
|
||||||
bool_.register_builtin_impl("__and__", fn1_met(Bool, Bool, Bool), Const, Public);
|
bool_.register_builtin_impl("__and__", fn1_met(Bool, Bool, Bool), Const, Public);
|
||||||
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(mono("Num"));
|
bool_.register_marker_trait(mono("Num"));
|
||||||
bool_.register_marker_trait(mono("Ord"));
|
let mut bool_ord = Self::builtin_methods(Some(mono("Ord")), 2);
|
||||||
let mut bool_partial_ord =
|
bool_ord.register_builtin_impl(
|
||||||
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Bool)])), 2);
|
|
||||||
bool_partial_ord.register_builtin_impl(
|
|
||||||
"__cmp__",
|
"__cmp__",
|
||||||
fn1_met(Bool, Bool, mono("Ordering")),
|
fn1_met(Bool, Bool, mono("Ordering")),
|
||||||
Const,
|
Const,
|
||||||
Public,
|
Public,
|
||||||
);
|
);
|
||||||
bool_.register_trait(Bool, bool_partial_ord);
|
bool_.register_trait(Bool, bool_ord);
|
||||||
let mut bool_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Bool)])), 2);
|
let mut bool_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
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, bool_eq);
|
bool_.register_trait(Bool, bool_eq);
|
||||||
let mut bool_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 2);
|
let mut bool_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 2);
|
||||||
|
@ -983,7 +949,7 @@ impl Context {
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
);
|
);
|
||||||
let mut str_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Str)])), 2);
|
let mut str_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
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, str_eq);
|
str_.register_trait(Str, str_eq);
|
||||||
let mut str_seq = Self::builtin_methods(Some(poly("Seq", vec![ty_tp(Str)])), 2);
|
let mut str_seq = Self::builtin_methods(Some(poly("Seq", vec![ty_tp(Str)])), 2);
|
||||||
|
@ -1015,7 +981,7 @@ impl Context {
|
||||||
/* NoneType */
|
/* NoneType */
|
||||||
let mut nonetype = Self::builtin_mono_class("NoneType", 10);
|
let mut nonetype = Self::builtin_mono_class("NoneType", 10);
|
||||||
nonetype.register_superclass(Obj, &obj);
|
nonetype.register_superclass(Obj, &obj);
|
||||||
let mut nonetype_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(NoneType)])), 2);
|
let mut nonetype_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
nonetype_eq.register_builtin_impl(
|
nonetype_eq.register_builtin_impl(
|
||||||
"__eq__",
|
"__eq__",
|
||||||
fn1_met(NoneType, NoneType, Bool),
|
fn1_met(NoneType, NoneType, Bool),
|
||||||
|
@ -1036,13 +1002,13 @@ impl Context {
|
||||||
Public,
|
Public,
|
||||||
);
|
);
|
||||||
type_.register_marker_trait(mono("Named"));
|
type_.register_marker_trait(mono("Named"));
|
||||||
let mut type_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Type)])), 2);
|
let mut type_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
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, type_eq);
|
type_.register_trait(Type, type_eq);
|
||||||
let mut class_type = Self::builtin_mono_class("ClassType", 2);
|
let mut class_type = Self::builtin_mono_class("ClassType", 2);
|
||||||
class_type.register_superclass(Type, &type_);
|
class_type.register_superclass(Type, &type_);
|
||||||
class_type.register_marker_trait(mono("Named"));
|
class_type.register_marker_trait(mono("Named"));
|
||||||
let mut class_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(ClassType)])), 2);
|
let mut class_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
class_eq.register_builtin_impl(
|
class_eq.register_builtin_impl(
|
||||||
"__eq__",
|
"__eq__",
|
||||||
fn1_met(ClassType, ClassType, Bool),
|
fn1_met(ClassType, ClassType, Bool),
|
||||||
|
@ -1053,7 +1019,7 @@ impl Context {
|
||||||
let mut trait_type = Self::builtin_mono_class("TraitType", 2);
|
let mut trait_type = Self::builtin_mono_class("TraitType", 2);
|
||||||
trait_type.register_superclass(Type, &type_);
|
trait_type.register_superclass(Type, &type_);
|
||||||
trait_type.register_marker_trait(mono("Named"));
|
trait_type.register_marker_trait(mono("Named"));
|
||||||
let mut trait_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(TraitType)])), 2);
|
let mut trait_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
trait_eq.register_builtin_impl(
|
trait_eq.register_builtin_impl(
|
||||||
"__eq__",
|
"__eq__",
|
||||||
fn1_met(TraitType, TraitType, Bool),
|
fn1_met(TraitType, TraitType, Bool),
|
||||||
|
@ -1065,8 +1031,7 @@ impl Context {
|
||||||
let mut generic_module = Self::builtin_mono_class("GenericModule", 2);
|
let mut generic_module = Self::builtin_mono_class("GenericModule", 2);
|
||||||
generic_module.register_superclass(Obj, &obj);
|
generic_module.register_superclass(Obj, &obj);
|
||||||
generic_module.register_marker_trait(mono("Named"));
|
generic_module.register_marker_trait(mono("Named"));
|
||||||
let mut generic_module_eq =
|
let mut generic_module_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
Self::builtin_methods(Some(poly("Eq", vec![ty_tp(g_module_t.clone())])), 2);
|
|
||||||
generic_module_eq.register_builtin_impl(
|
generic_module_eq.register_builtin_impl(
|
||||||
"__eq__",
|
"__eq__",
|
||||||
fn1_met(g_module_t.clone(), g_module_t.clone(), Bool),
|
fn1_met(g_module_t.clone(), g_module_t.clone(), Bool),
|
||||||
|
@ -1152,7 +1117,7 @@ impl Context {
|
||||||
None,
|
None,
|
||||||
)));
|
)));
|
||||||
array_.register_builtin_const("__getitem__", Public, get_item);
|
array_.register_builtin_const("__getitem__", Public, get_item);
|
||||||
let mut array_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(arr_t.clone())])), 2);
|
let mut array_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
array_eq.register_builtin_impl(
|
array_eq.register_builtin_impl(
|
||||||
"__eq__",
|
"__eq__",
|
||||||
fn1_met(arr_t.clone(), arr_t.clone(), Bool),
|
fn1_met(arr_t.clone(), arr_t.clone(), Bool),
|
||||||
|
@ -1205,7 +1170,7 @@ impl Context {
|
||||||
vec![TyParam::t(mono_q("T")), TyParam::mono_q("N").mutate()],
|
vec![TyParam::t(mono_q("T")), TyParam::mono_q("N").mutate()],
|
||||||
));
|
));
|
||||||
set_.register_builtin_const("MutType!", Public, mut_type);
|
set_.register_builtin_const("MutType!", Public, mut_type);
|
||||||
let mut set_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(set_t.clone())])), 2);
|
let mut set_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
set_eq.register_builtin_impl(
|
set_eq.register_builtin_impl(
|
||||||
"__eq__",
|
"__eq__",
|
||||||
fn1_met(set_t.clone(), set_t.clone(), Bool),
|
fn1_met(set_t.clone(), set_t.clone(), Bool),
|
||||||
|
@ -1221,8 +1186,7 @@ impl Context {
|
||||||
let g_dict_t = mono("GenericDict");
|
let g_dict_t = mono("GenericDict");
|
||||||
let mut generic_dict = Self::builtin_mono_class("GenericDict", 2);
|
let mut generic_dict = Self::builtin_mono_class("GenericDict", 2);
|
||||||
generic_dict.register_superclass(Obj, &obj);
|
generic_dict.register_superclass(Obj, &obj);
|
||||||
let mut generic_dict_eq =
|
let mut generic_dict_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
Self::builtin_methods(Some(poly("Eq", vec![ty_tp(g_dict_t.clone())])), 2);
|
|
||||||
generic_dict_eq.register_builtin_impl(
|
generic_dict_eq.register_builtin_impl(
|
||||||
"__eq__",
|
"__eq__",
|
||||||
fn1_met(g_dict_t.clone(), g_dict_t.clone(), Bool),
|
fn1_met(g_dict_t.clone(), g_dict_t.clone(), Bool),
|
||||||
|
@ -1271,8 +1235,7 @@ impl Context {
|
||||||
/* GenericTuple */
|
/* GenericTuple */
|
||||||
let mut generic_tuple = Self::builtin_mono_class("GenericTuple", 1);
|
let mut generic_tuple = Self::builtin_mono_class("GenericTuple", 1);
|
||||||
generic_tuple.register_superclass(Obj, &obj);
|
generic_tuple.register_superclass(Obj, &obj);
|
||||||
let mut tuple_eq =
|
let mut tuple_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
Self::builtin_methods(Some(poly("Eq", vec![ty_tp(mono("GenericTuple"))])), 2);
|
|
||||||
tuple_eq.register_builtin_impl(
|
tuple_eq.register_builtin_impl(
|
||||||
"__eq__",
|
"__eq__",
|
||||||
fn1_met(mono("GenericTuple"), mono("GenericTuple"), Bool),
|
fn1_met(mono("GenericTuple"), mono("GenericTuple"), Bool),
|
||||||
|
@ -1551,7 +1514,7 @@ impl Context {
|
||||||
range.register_superclass(Type, &type_);
|
range.register_superclass(Type, &type_);
|
||||||
range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))]));
|
range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))]));
|
||||||
range.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))]));
|
range.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))]));
|
||||||
let mut range_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(range_t.clone())])), 2);
|
let mut range_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
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),
|
||||||
|
@ -2059,12 +2022,12 @@ impl Context {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.register_builtin_impl("__div__", op_t, Const, Private);
|
self.register_builtin_impl("__div__", op_t, Const, Private);
|
||||||
let op_t = bin_op(l.clone(), r.clone(), proj(mono_q("L"), "Output"));
|
let op_t = bin_op(l.clone(), r, proj(mono_q("L"), "Output"));
|
||||||
let op_t = quant(
|
let op_t = quant(
|
||||||
op_t,
|
op_t,
|
||||||
set! {
|
set! {
|
||||||
static_instance("R", Type),
|
static_instance("R", Type),
|
||||||
subtypeof(l.clone(), poly("FloorDiv", params.clone()))
|
subtypeof(l.clone(), poly("FloorDiv", params))
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.register_builtin_impl("__floordiv__", op_t, Const, Private);
|
self.register_builtin_impl("__floordiv__", op_t, Const, Private);
|
||||||
|
@ -2079,17 +2042,11 @@ impl Context {
|
||||||
self.register_builtin_impl("__mod__", op_t, Const, Private);
|
self.register_builtin_impl("__mod__", op_t, Const, Private);
|
||||||
let e = mono_q("E");
|
let e = mono_q("E");
|
||||||
let op_t = bin_op(e.clone(), e.clone(), Bool);
|
let op_t = bin_op(e.clone(), e.clone(), Bool);
|
||||||
let op_t = quant(op_t, set! {subtypeof(e, poly("Eq", vec![]))});
|
let op_t = quant(op_t, set! {subtypeof(e, mono("Eq"))});
|
||||||
self.register_builtin_impl("__eq__", op_t.clone(), Const, Private);
|
self.register_builtin_impl("__eq__", op_t.clone(), Const, Private);
|
||||||
self.register_builtin_impl("__ne__", op_t, Const, Private);
|
self.register_builtin_impl("__ne__", op_t, Const, Private);
|
||||||
let op_t = bin_op(l.clone(), r, Bool);
|
let op_t = bin_op(l.clone(), l.clone(), Bool);
|
||||||
let op_t = quant(
|
let op_t = quant(op_t, set! { subtypeof(l, mono("Ord")) });
|
||||||
op_t,
|
|
||||||
set! {
|
|
||||||
static_instance("R", Type),
|
|
||||||
subtypeof(l, poly("PartialOrd", params))
|
|
||||||
},
|
|
||||||
);
|
|
||||||
self.register_builtin_impl("__lt__", op_t.clone(), Const, Private);
|
self.register_builtin_impl("__lt__", op_t.clone(), Const, Private);
|
||||||
self.register_builtin_impl("__le__", op_t.clone(), Const, Private);
|
self.register_builtin_impl("__le__", op_t.clone(), Const, Private);
|
||||||
self.register_builtin_impl("__gt__", op_t.clone(), Const, Private);
|
self.register_builtin_impl("__gt__", op_t.clone(), Const, Private);
|
||||||
|
@ -2172,22 +2129,18 @@ impl Context {
|
||||||
// ord.register_impl("__le__", op_t.clone(), Const, Public);
|
// ord.register_impl("__le__", op_t.clone(), Const, Public);
|
||||||
// ord.register_impl("__gt__", op_t.clone(), Const, Public);
|
// ord.register_impl("__gt__", op_t.clone(), Const, Public);
|
||||||
// ord.register_impl("__ge__", op_t, Const, Public);
|
// ord.register_impl("__ge__", op_t, Const, Public);
|
||||||
let t = mono_q("T");
|
let t = mono_q("L");
|
||||||
let u = mono_q("U");
|
let base = or(t.clone(), NoneType);
|
||||||
let base = or(t.clone(), u.clone());
|
let impls = mono("Eq");
|
||||||
let impls = poly("Eq", vec![ty_tp(base.clone())]);
|
let params = vec![PS::named_nd("L", Type)];
|
||||||
let params = vec![PS::named_nd("T", Type), PS::named_nd("U", Type)];
|
let mut option_eq =
|
||||||
let mut union_eq =
|
Self::builtin_poly_glue_patch("OptionEq", base.clone(), impls.clone(), params, 1);
|
||||||
Self::builtin_poly_glue_patch("UnionEq", base.clone(), impls.clone(), params, 1);
|
let mut option_eq_impl = Self::builtin_methods(Some(impls), 1);
|
||||||
let mut union_eq_impl = Self::builtin_methods(Some(impls), 1);
|
|
||||||
let op_t = fn1_met(base.clone(), base.clone(), Bool);
|
let op_t = fn1_met(base.clone(), base.clone(), Bool);
|
||||||
let op_t = quant(
|
let op_t = quant(op_t, set! {subtypeof(t, mono("Eq"))});
|
||||||
op_t,
|
option_eq_impl.register_builtin_impl("__eq__", op_t, Const, Public);
|
||||||
set! {subtypeof(t.clone(), poly("Eq", vec![ty_tp(t)])), subtypeof(u.clone(), poly("Eq", vec![ty_tp(u)]))},
|
option_eq.register_trait(base, option_eq_impl);
|
||||||
);
|
self.register_builtin_patch("OptionEq", option_eq, Private, Const);
|
||||||
union_eq_impl.register_builtin_impl("__eq__", op_t, Const, Public);
|
|
||||||
union_eq.register_trait(base, union_eq_impl);
|
|
||||||
self.register_builtin_patch("UnionEq", union_eq, Private, Const);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) {
|
pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||||
use crate::ty::{HasType, ParamTy, SubrKind, SubrType, TyBound, Type};
|
use crate::ty::{HasType, ParamTy, SubrKind, SubrType, TyBound, Type};
|
||||||
|
|
||||||
use crate::context::instantiate::ConstTemplate;
|
use crate::context::instantiate::ConstTemplate;
|
||||||
use crate::context::{Context, RegistrationMode, TraitInstance, Variance};
|
use crate::context::{Context, RegistrationMode, TypeRelationInstance, Variance};
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
binop_to_dname, readable_name, unaryop_to_dname, SingleTyCheckResult, TyCheckError,
|
binop_to_dname, readable_name, unaryop_to_dname, SingleTyCheckResult, TyCheckError,
|
||||||
TyCheckErrors, TyCheckResult,
|
TyCheckErrors, TyCheckResult,
|
||||||
|
@ -1695,7 +1695,7 @@ impl Context {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_trait_impls(&self, t: &Type) -> Set<TraitInstance> {
|
pub(crate) fn get_trait_impls(&self, t: &Type) -> Set<TypeRelationInstance> {
|
||||||
match t {
|
match t {
|
||||||
// And(Add, Sub) == intersection({Int <: Add(Int), Bool <: Add(Bool) ...}, {Int <: Sub(Int), ...})
|
// And(Add, Sub) == intersection({Int <: Add(Int), Bool <: Add(Bool) ...}, {Int <: Sub(Int), ...})
|
||||||
// == {Int <: Add(Int) and Sub(Int), ...}
|
// == {Int <: Add(Int) and Sub(Int), ...}
|
||||||
|
@ -1710,7 +1710,7 @@ impl Context {
|
||||||
let lti = l_impls.iter().find(|ti| &ti.sub_type == base).unwrap();
|
let lti = l_impls.iter().find(|ti| &ti.sub_type == base).unwrap();
|
||||||
let rti = r_impls.iter().find(|ti| &ti.sub_type == base).unwrap();
|
let rti = r_impls.iter().find(|ti| &ti.sub_type == base).unwrap();
|
||||||
let sup_trait = self.intersection(<i.sup_trait, &rti.sup_trait);
|
let sup_trait = self.intersection(<i.sup_trait, &rti.sup_trait);
|
||||||
isec.insert(TraitInstance::new(lti.sub_type.clone(), sup_trait));
|
isec.insert(TypeRelationInstance::new(lti.sub_type.clone(), sup_trait));
|
||||||
}
|
}
|
||||||
isec
|
isec
|
||||||
}
|
}
|
||||||
|
@ -1724,7 +1724,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_simple_trait_impls(&self, t: &Type) -> Set<TraitInstance> {
|
pub(crate) fn get_simple_trait_impls(&self, t: &Type) -> Set<TypeRelationInstance> {
|
||||||
let current = if let Some(impls) = self.trait_impls.get(&t.qual_name()) {
|
let current = if let Some(impls) = self.trait_impls.get(&t.qual_name()) {
|
||||||
impls.clone()
|
impls.clone()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1747,6 +1747,14 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn _all_patches(&self) -> Vec<&Context> {
|
||||||
|
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
|
[outer._all_patches(), self.patches.values().collect()].concat()
|
||||||
|
} else {
|
||||||
|
self.patches.values().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: erg std
|
// TODO: erg std
|
||||||
pub(crate) fn resolve_path(&self, path: &Path) -> PathBuf {
|
pub(crate) fn resolve_path(&self, path: &Path) -> PathBuf {
|
||||||
if let Ok(path) = self.cfg.input.local_resolve(path) {
|
if let Ok(path) = self.cfg.input.local_resolve(path) {
|
||||||
|
|
|
@ -48,24 +48,24 @@ use Visibility::*;
|
||||||
const BUILTINS: &Str = &Str::ever("<builtins>");
|
const BUILTINS: &Str = &Str::ever("<builtins>");
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct TraitInstance {
|
pub struct TypeRelationInstance {
|
||||||
pub sub_type: Type,
|
pub sub_type: Type,
|
||||||
pub sup_trait: Type,
|
pub sup_trait: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for TraitInstance {
|
impl std::fmt::Display for TypeRelationInstance {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"TraitInstancePair{{{} <: {}}}",
|
"TypeRelationInstance{{{} <: {}}}",
|
||||||
self.sub_type, self.sup_trait
|
self.sub_type, self.sup_trait
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TraitInstance {
|
impl TypeRelationInstance {
|
||||||
pub const fn new(sub_type: Type, sup_trait: Type) -> Self {
|
pub const fn new(sub_type: Type, sup_trait: Type) -> Self {
|
||||||
TraitInstance {
|
Self {
|
||||||
sub_type,
|
sub_type,
|
||||||
sup_trait,
|
sup_trait,
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ pub enum ContextKind {
|
||||||
StructuralTrait,
|
StructuralTrait,
|
||||||
Patch(Type),
|
Patch(Type),
|
||||||
StructuralPatch(Type),
|
StructuralPatch(Type),
|
||||||
GluePatch(TraitInstance),
|
GluePatch(TypeRelationInstance), // TODO: deprecate (integrate into Patch)
|
||||||
Module,
|
Module,
|
||||||
Instant,
|
Instant,
|
||||||
Dummy,
|
Dummy,
|
||||||
|
@ -338,7 +338,7 @@ pub struct Context {
|
||||||
/// K: name of a trait, V: (type, monomorphised trait that the type implements)
|
/// K: name of a trait, V: (type, monomorphised trait that the type implements)
|
||||||
/// K: トレイトの名前, V: (型, その型が実装する単相化トレイト)
|
/// K: トレイトの名前, V: (型, その型が実装する単相化トレイト)
|
||||||
/// e.g. { "Named": [(Type, Named), (Func, Named), ...], "Add": [(Nat, Add(Nat)), (Int, Add(Int)), ...], ... }
|
/// e.g. { "Named": [(Type, Named), (Func, Named), ...], "Add": [(Nat, Add(Nat)), (Int, Add(Int)), ...], ... }
|
||||||
pub(crate) trait_impls: Dict<Str, Set<TraitInstance>>,
|
pub(crate) trait_impls: Dict<Str, Set<TypeRelationInstance>>,
|
||||||
/// stores declared names (not initialized)
|
/// stores declared names (not initialized)
|
||||||
pub(crate) decls: Dict<VarName, VarInfo>,
|
pub(crate) decls: Dict<VarName, VarInfo>,
|
||||||
// stores defined names
|
// stores defined names
|
||||||
|
@ -714,7 +714,7 @@ impl Context {
|
||||||
Self::poly(
|
Self::poly(
|
||||||
name.into(),
|
name.into(),
|
||||||
cfg,
|
cfg,
|
||||||
ContextKind::GluePatch(TraitInstance::new(base, impls)),
|
ContextKind::GluePatch(TypeRelationInstance::new(base, impls)),
|
||||||
params,
|
params,
|
||||||
None,
|
None,
|
||||||
mod_cache,
|
mod_cache,
|
||||||
|
|
|
@ -21,7 +21,8 @@ use crate::ty::{HasType, ParamTy, SubrType, Type};
|
||||||
|
|
||||||
use crate::build_hir::HIRBuilder;
|
use crate::build_hir::HIRBuilder;
|
||||||
use crate::context::{
|
use crate::context::{
|
||||||
ClassDefType, Context, ContextKind, DefaultInfo, MethodInfo, RegistrationMode, TraitInstance,
|
ClassDefType, Context, ContextKind, DefaultInfo, MethodInfo, RegistrationMode,
|
||||||
|
TypeRelationInstance,
|
||||||
};
|
};
|
||||||
use crate::error::readable_name;
|
use crate::error::readable_name;
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
|
@ -988,11 +989,11 @@ impl Context {
|
||||||
.insert(name.clone(), ValueObj::Type(TypeObj::Generated(gen)));
|
.insert(name.clone(), ValueObj::Type(TypeObj::Generated(gen)));
|
||||||
for impl_trait in ctx.super_traits.iter() {
|
for impl_trait in ctx.super_traits.iter() {
|
||||||
if let Some(impls) = self.trait_impls.get_mut(&impl_trait.qual_name()) {
|
if let Some(impls) = self.trait_impls.get_mut(&impl_trait.qual_name()) {
|
||||||
impls.insert(TraitInstance::new(t.clone(), impl_trait.clone()));
|
impls.insert(TypeRelationInstance::new(t.clone(), impl_trait.clone()));
|
||||||
} else {
|
} else {
|
||||||
self.trait_impls.insert(
|
self.trait_impls.insert(
|
||||||
impl_trait.qual_name(),
|
impl_trait.qual_name(),
|
||||||
set![TraitInstance::new(t.clone(), impl_trait.clone())],
|
set![TypeRelationInstance::new(t.clone(), impl_trait.clone())],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use erg_common::Str;
|
||||||
// use erg_common::error::Location;
|
// use erg_common::error::Location;
|
||||||
use erg_common::{enum_unwrap, set};
|
use erg_common::{enum_unwrap, set};
|
||||||
|
|
||||||
use crate::ty::constructors::{func1, mono_q, poly, quant, refinement};
|
use crate::ty::constructors::{func1, mono, mono_q, poly, quant, refinement};
|
||||||
use crate::ty::typaram::TyParam;
|
use crate::ty::typaram::TyParam;
|
||||||
use crate::ty::{Predicate, TyBound, Type};
|
use crate::ty::{Predicate, TyBound, Type};
|
||||||
use Type::*;
|
use Type::*;
|
||||||
|
@ -48,7 +48,7 @@ impl Context {
|
||||||
|
|
||||||
pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> {
|
pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> {
|
||||||
let t = mono_q("T");
|
let t = mono_q("T");
|
||||||
let eq = poly("Eq", vec![TyParam::t(t.clone())]);
|
let eq = mono("Eq");
|
||||||
let bound = TyBound::subtype_of(t.clone(), eq);
|
let bound = TyBound::subtype_of(t.clone(), eq);
|
||||||
let bounds = set! {bound};
|
let bounds = set! {bound};
|
||||||
let unbound_t = func1(t.clone(), t);
|
let unbound_t = func1(t.clone(), t);
|
||||||
|
|
|
@ -637,8 +637,13 @@ impl Context {
|
||||||
let sub_type = if inst.sub_type.has_qvar() {
|
let sub_type = if inst.sub_type.has_qvar() {
|
||||||
let sub_ctx = self.get_nominal_type_ctx(&inst.sub_type).unwrap();
|
let sub_ctx = self.get_nominal_type_ctx(&inst.sub_type).unwrap();
|
||||||
let tv_ctx = TyVarInstContext::new(self.level, sub_ctx.bounds(), self);
|
let tv_ctx = TyVarInstContext::new(self.level, sub_ctx.bounds(), self);
|
||||||
self.instantiate_t_inner(inst.sub_type, &tv_ctx, Location::Unknown)
|
if let Ok(t) =
|
||||||
.unwrap()
|
self.instantiate_t_inner(inst.sub_type.clone(), &tv_ctx, Location::Unknown)
|
||||||
|
{
|
||||||
|
t
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
inst.sub_type
|
inst.sub_type
|
||||||
};
|
};
|
||||||
|
@ -1414,10 +1419,6 @@ impl Context {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
match (maybe_sub, maybe_sup) {
|
match (maybe_sub, maybe_sup) {
|
||||||
(Type::FreeVar(lfv), _) if lfv.is_linked() =>
|
|
||||||
self.sub_unify(&lfv.crack(), maybe_sup, loc, param_name),
|
|
||||||
(_, Type::FreeVar(rfv)) if rfv.is_linked() =>
|
|
||||||
self.sub_unify(maybe_sub, &rfv.crack(), loc, param_name),
|
|
||||||
// lfv's sup can be shrunk (take min), rfv's sub can be expanded (take union)
|
// lfv's sup can be shrunk (take min), rfv's sub can be expanded (take union)
|
||||||
// lfvのsupは縮小可能(minを取る)、rfvのsubは拡大可能(unionを取る)
|
// lfvのsupは縮小可能(minを取る)、rfvのsubは拡大可能(unionを取る)
|
||||||
// sub_unify(?T[0](:> Never, <: Int), ?U[1](:> Never, <: Nat)): (/* ?U[1] --> ?T[0](:> Never, <: Nat))
|
// sub_unify(?T[0](:> Never, <: Int), ?U[1](:> Never, <: Nat)): (/* ?U[1] --> ?T[0](:> Never, <: Nat))
|
||||||
|
@ -1455,6 +1456,10 @@ impl Context {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
(Type::FreeVar(lfv), _) if lfv.is_linked() =>
|
||||||
|
self.sub_unify(&lfv.crack(), maybe_sup, loc, param_name),
|
||||||
|
(_, Type::FreeVar(rfv)) if rfv.is_linked() =>
|
||||||
|
self.sub_unify(maybe_sub, &rfv.crack(), loc, param_name),
|
||||||
(_, Type::FreeVar(rfv)) if rfv.is_unbound() => {
|
(_, Type::FreeVar(rfv)) if rfv.is_unbound() => {
|
||||||
// NOTE: cannot `borrow_mut` because of cycle reference
|
// NOTE: cannot `borrow_mut` because of cycle reference
|
||||||
let rfv_ref = unsafe { rfv.as_ptr().as_mut().unwrap() };
|
let rfv_ref = unsafe { rfv.as_ptr().as_mut().unwrap() };
|
||||||
|
@ -1473,13 +1478,18 @@ impl Context {
|
||||||
// sub = union(l, sub) if max does not exist
|
// sub = union(l, sub) if max does not exist
|
||||||
// * sub_unify(Str, ?T(:> Int, <: Obj)): (?T(:> Str or Int, <: Obj))
|
// * sub_unify(Str, ?T(:> Int, <: Obj)): (?T(:> Str or Int, <: Obj))
|
||||||
// * sub_unify({0}, ?T(:> {1}, <: Nat)): (?T(:> {0, 1}, <: Nat))
|
// * sub_unify({0}, ?T(:> {1}, <: Nat)): (?T(:> {0, 1}, <: Nat))
|
||||||
|
// * sub_unify(Bool, ?T(<: Bool or Y)): (?T == Bool)
|
||||||
Constraint::Sandwiched { sub, sup, cyclicity } => {
|
Constraint::Sandwiched { sub, sup, cyclicity } => {
|
||||||
/*if let Some(new_sub) = self.max(maybe_sub, sub) {
|
/*if let Some(new_sub) = self.max(maybe_sub, sub) {
|
||||||
*constraint =
|
*constraint =
|
||||||
Constraint::new_sandwiched(new_sub.clone(), mem::take(sup), *cyclicity);
|
Constraint::new_sandwiched(new_sub.clone(), mem::take(sup), *cyclicity);
|
||||||
} else {*/
|
} else {*/
|
||||||
let new_sub = self.union(maybe_sub, sub);
|
let new_sub = self.union(maybe_sub, sub);
|
||||||
*constraint = Constraint::new_sandwiched(new_sub, mem::take(sup), *cyclicity);
|
if sup.contains_union(&new_sub) {
|
||||||
|
rfv.link(&new_sub); // Bool <: ?T <: Bool or Y ==> ?T == Bool
|
||||||
|
} else {
|
||||||
|
*constraint = Constraint::new_sandwiched(new_sub, mem::take(sup), *cyclicity);
|
||||||
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
// sub_unify(Nat, ?T(: Type)): (/* ?T(:> Nat) */)
|
// sub_unify(Nat, ?T(: Type)): (/* ?T(:> Nat) */)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# e.g. `nightly.0`
|
# e.g. `nightly.0`
|
||||||
.Identifier = Class { .name = Str; .num = Nat }
|
.Identifier = Class { .name = Str; .num = Nat }
|
||||||
.Identifier|.Identifier <: Eq(.Identifier)|.
|
.Identifier|.Identifier <: Eq|.
|
||||||
__eq__ self, other: .Identifier =
|
__eq__ self, other: .Identifier =
|
||||||
self.name == other.name and self.num == other.num
|
self.name == other.name and self.num == other.num
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
[_, True, _, True, True] -> True
|
[_, True, _, True, True] -> True
|
||||||
_ -> False
|
_ -> False
|
||||||
]#
|
]#
|
||||||
.Version|.Version <: Eq(.Version)|.
|
.Version|.Version <: Eq|.
|
||||||
__eq__ self, other: .Version =
|
__eq__ self, other: .Version =
|
||||||
self.major == other.major and self.minor == other.minor and self.patch == other.patch # and self.pre == other.pre
|
self.major == other.major and self.minor == other.minor and self.patch == other.patch and self.pre == "" # other.pre
|
||||||
|
|
||||||
if! __name__ == "__main__", do!:
|
if! __name__ == "__main__", do!:
|
||||||
v = .Version.new(0, 0, 1)
|
v = .Version.new(0, 0, 1)
|
||||||
|
|
|
@ -27,7 +27,7 @@ use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||||
use crate::ty::{HasType, ParamTy, Type};
|
use crate::ty::{HasType, ParamTy, Type};
|
||||||
|
|
||||||
use crate::context::instantiate::TyVarInstContext;
|
use crate::context::instantiate::TyVarInstContext;
|
||||||
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode, TraitInstance};
|
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode, TypeRelationInstance};
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CompileError, CompileErrors, LowerError, LowerErrors, LowerResult, LowerWarnings,
|
CompileError, CompileErrors, LowerError, LowerErrors, LowerResult, LowerWarnings,
|
||||||
SingleLowerResult,
|
SingleLowerResult,
|
||||||
|
@ -411,9 +411,8 @@ impl ASTLowerer {
|
||||||
Ok(normal_set)
|
Ok(normal_set)
|
||||||
*/
|
*/
|
||||||
let elems = hir::Args::from(new_set);
|
let elems = hir::Args::from(new_set);
|
||||||
let sup = poly("Eq", vec![TyParam::t(elem_t.clone())]);
|
|
||||||
// check if elem_t is Eq
|
// check if elem_t is Eq
|
||||||
if let Err(errs) = self.ctx.sub_unify(&elem_t, &sup, elems.loc(), None) {
|
if let Err(errs) = self.ctx.sub_unify(&elem_t, &mono("Eq"), elems.loc(), None) {
|
||||||
self.errs.extend(errs.into_iter());
|
self.errs.extend(errs.into_iter());
|
||||||
}
|
}
|
||||||
Ok(hir::NormalSet::new(set.l_brace, set.r_brace, elem_t, elems))
|
Ok(hir::NormalSet::new(set.l_brace, set.r_brace, elem_t, elems))
|
||||||
|
@ -514,10 +513,9 @@ impl ASTLowerer {
|
||||||
new_kvs.push(hir::KeyValue::new(key, value));
|
new_kvs.push(hir::KeyValue::new(key, value));
|
||||||
}
|
}
|
||||||
for key_t in union.keys() {
|
for key_t in union.keys() {
|
||||||
let sup = poly("Eq", vec![TyParam::t(key_t.clone())]);
|
|
||||||
let loc = Location::concat(&dict.l_brace, &dict.r_brace);
|
let loc = Location::concat(&dict.l_brace, &dict.r_brace);
|
||||||
// check if key_t is Eq
|
// check if key_t is Eq
|
||||||
if let Err(errs) = self.ctx.sub_unify(key_t, &sup, loc, None) {
|
if let Err(errs) = self.ctx.sub_unify(key_t, &mono("Eq"), loc, None) {
|
||||||
self.errs.extend(errs.into_iter());
|
self.errs.extend(errs.into_iter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1239,8 +1237,23 @@ impl ASTLowerer {
|
||||||
) -> SingleLowerResult<()> {
|
) -> SingleLowerResult<()> {
|
||||||
if let Some((impl_trait, loc)) = impl_trait {
|
if let Some((impl_trait, loc)) = impl_trait {
|
||||||
// assume the class has implemented the trait, regardless of whether the implementation is correct
|
// assume the class has implemented the trait, regardless of whether the implementation is correct
|
||||||
let trait_ctx = self.ctx.get_nominal_type_ctx(&impl_trait).unwrap().clone();
|
let trait_ctx = if let Some(trait_ctx) = self.ctx.get_nominal_type_ctx(&impl_trait) {
|
||||||
let (_, class_ctx) = self.ctx.get_mut_nominal_type_ctx(class).unwrap();
|
trait_ctx.clone()
|
||||||
|
} else {
|
||||||
|
// TODO: maybe parameters are wrong
|
||||||
|
return Err(LowerError::no_var_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
loc,
|
||||||
|
self.ctx.caused_by(),
|
||||||
|
&impl_trait.local_name(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
};
|
||||||
|
let (_, class_ctx) = self
|
||||||
|
.ctx
|
||||||
|
.get_mut_nominal_type_ctx(class)
|
||||||
|
.unwrap_or_else(|| todo!("{class} not found"));
|
||||||
class_ctx.register_supertrait(impl_trait.clone(), &trait_ctx);
|
class_ctx.register_supertrait(impl_trait.clone(), &trait_ctx);
|
||||||
let mut unverified_names = self.ctx.locals.keys().collect::<Set<_>>();
|
let mut unverified_names = self.ctx.locals.keys().collect::<Set<_>>();
|
||||||
if let Some(trait_obj) = self.ctx.rec_get_const_obj(&impl_trait.local_name()) {
|
if let Some(trait_obj) = self.ctx.rec_get_const_obj(&impl_trait.local_name()) {
|
||||||
|
@ -1354,11 +1367,11 @@ impl ASTLowerer {
|
||||||
let trait_impls = &mut self.ctx.outer.as_mut().unwrap().trait_impls;
|
let trait_impls = &mut self.ctx.outer.as_mut().unwrap().trait_impls;
|
||||||
// TODO: polymorphic trait
|
// TODO: polymorphic trait
|
||||||
if let Some(impls) = trait_impls.get_mut(&trait_.qual_name()) {
|
if let Some(impls) = trait_impls.get_mut(&trait_.qual_name()) {
|
||||||
impls.insert(TraitInstance::new(class.clone(), trait_.clone()));
|
impls.insert(TypeRelationInstance::new(class.clone(), trait_.clone()));
|
||||||
} else {
|
} else {
|
||||||
trait_impls.insert(
|
trait_impls.insert(
|
||||||
trait_.qual_name(),
|
trait_.qual_name(),
|
||||||
set! {TraitInstance::new(class.clone(), trait_.clone())},
|
set! {TypeRelationInstance::new(class.clone(), trait_.clone())},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1384,9 +1384,11 @@ impl LimitedDisplay for Type {
|
||||||
rhs.limited_fmt(f, limit - 1)
|
rhs.limited_fmt(f, limit - 1)
|
||||||
}
|
}
|
||||||
Self::Or(lhs, rhs) => {
|
Self::Or(lhs, rhs) => {
|
||||||
|
write!(f, "(")?;
|
||||||
lhs.limited_fmt(f, limit - 1)?;
|
lhs.limited_fmt(f, limit - 1)?;
|
||||||
write!(f, " or ")?;
|
write!(f, " or ")?;
|
||||||
rhs.limited_fmt(f, limit - 1)
|
rhs.limited_fmt(f, limit - 1)?;
|
||||||
|
write!(f, ")")
|
||||||
}
|
}
|
||||||
Self::Poly { name, params } => {
|
Self::Poly { name, params } => {
|
||||||
write!(f, "{name}(")?;
|
write!(f, "{name}(")?;
|
||||||
|
@ -1977,6 +1979,14 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// assert!((A or B).contains_union(B))
|
||||||
|
pub fn contains_union(&self, typ: &Type) -> bool {
|
||||||
|
match self {
|
||||||
|
Type::Or(t1, t2) => t1.contains_union(typ) || t2.contains_union(typ),
|
||||||
|
_ => self == typ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tvar_name(&self) -> Option<Str> {
|
pub fn tvar_name(&self) -> Option<Str> {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(),
|
Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(),
|
||||||
|
|
|
@ -13,10 +13,12 @@ A typical Union is the `Option` type. The `Option` type is a `T or NoneType` pat
|
||||||
IntOrStr = Int or Str
|
IntOrStr = Int or Str
|
||||||
assert dict.get("some key") in (Int or NoneType)
|
assert dict.get("some key") in (Int or NoneType)
|
||||||
|
|
||||||
# Implicitly become `T != NoneType`
|
|
||||||
Option T = T or NoneType
|
Option T = T or NoneType
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that Union types are commutative but not associative. That is, `X or Y or Z` is `(X or Y) or Z`, not `X or (Y or Z)`.
|
||||||
|
Allowing this would result in, for example, `Int or Option(Str)`, `Option(Int) or Str` and `Option(Int or Str)` being of the same type.
|
||||||
|
|
||||||
## Intersection
|
## Intersection
|
||||||
|
|
||||||
Intersection types are got by combining types with the `and` operation.
|
Intersection types are got by combining types with the `and` operation.
|
||||||
|
|
|
@ -15,10 +15,12 @@ Union型では型について複数の可能性を与える事ができる。名
|
||||||
IntOrStr = Int or Str
|
IntOrStr = Int or Str
|
||||||
assert dict.get("some key") in (Int or NoneType)
|
assert dict.get("some key") in (Int or NoneType)
|
||||||
|
|
||||||
# 暗黙に`T != NoneType`となる
|
|
||||||
Option T = T or NoneType
|
Option T = T or NoneType
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Union型は可換ですが結合的ではないことに注意してください。すなわち、`X or Y or Z`は`(X or Y) or Z`であって`X or (Y or Z)`とはなりません。
|
||||||
|
これを認めると、例えば`Int or Option(Str)`と`Option(Int) or Str`と`Option(Int or Str)`が同じ型になってしまいます。
|
||||||
|
|
||||||
## 交差型
|
## 交差型
|
||||||
|
|
||||||
Intersection型は型同士を`and`演算で結合して得られます。
|
Intersection型は型同士を`and`演算で結合して得られます。
|
||||||
|
|
|
@ -10,7 +10,7 @@ Point|Point <: Mul(Point)|.
|
||||||
Output = Nat
|
Output = Nat
|
||||||
__mul__ self, other: Point =
|
__mul__ self, other: Point =
|
||||||
self::x * other::x + self::y * other::y
|
self::x * other::x + self::y * other::y
|
||||||
Point|Point <: Eq(Point)|.
|
Point|Point <: Eq|.
|
||||||
__eq__ self, other: Point =
|
__eq__ self, other: Point =
|
||||||
self::x == other::x and self::y == other::y
|
self::x == other::x and self::y == other::y
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
stop_or_call n, f: (Nat -> Nat), g: (Nat -> Nat) =
|
stop_or_call n, f: (Nat -> Nat), g: (Nat -> Nat) =
|
||||||
cond n <= 0:
|
if n <= 0:
|
||||||
1
|
do 1
|
||||||
g (f (n - 1))
|
do:
|
||||||
|
m = n - 1
|
||||||
|
assert m in Nat
|
||||||
|
g (f m)
|
||||||
|
|
||||||
fact(n: Nat): Nat =
|
fact(n: Nat): Nat =
|
||||||
stop_or_call n, fact, (r, ) -> r * n
|
stop_or_call n, fact, (r, ) -> r * n
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue