mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-03 02:13:11 +00:00
WIP: Impl Context::monomorphise
Impled: TyVarContext::sort_bounds
This commit is contained in:
parent
4a4b346199
commit
6d3dda8129
6 changed files with 462 additions and 325 deletions
|
@ -1,25 +1,28 @@
|
|||
use crate::dict::Dict;
|
||||
use crate::set::Set;
|
||||
|
||||
type NodeIdx = usize;
|
||||
use std::hash::Hash;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Node<T> {
|
||||
_id: T,
|
||||
depends_on: Vec<NodeIdx>,
|
||||
pub struct Node<T, U> {
|
||||
id: T,
|
||||
pub data: U,
|
||||
depends_on: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T> Node<T> {
|
||||
pub const fn new(id: T, depends_on: Vec<NodeIdx>) -> Self {
|
||||
impl<T, U> Node<T, U> {
|
||||
pub const fn new(id: T, data: U, depends_on: Vec<T>) -> Self {
|
||||
Node {
|
||||
_id: id,
|
||||
id,
|
||||
data,
|
||||
depends_on,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Graph<T> = Vec<Node<T>>;
|
||||
pub type Graph<T, U> = Vec<Node<T, U>>;
|
||||
|
||||
fn reorder_by_idx<T>(mut v: Vec<T>, idx: Vec<NodeIdx>) -> Vec<T> {
|
||||
fn _reorder_by_idx<T>(mut v: Vec<T>, idx: Vec<usize>) -> Vec<T> {
|
||||
let mut swap_table = Dict::new();
|
||||
for (node_id, mut sort_i) in idx.into_iter().enumerate() {
|
||||
if node_id == sort_i {
|
||||
|
@ -34,39 +37,44 @@ fn reorder_by_idx<T>(mut v: Vec<T>, idx: Vec<NodeIdx>) -> Vec<T> {
|
|||
v
|
||||
}
|
||||
|
||||
fn dfs<T>(g: &Graph<T>, v: NodeIdx, used: &mut Vec<bool>, idx: &mut Vec<NodeIdx>) {
|
||||
used[v] = true;
|
||||
for &node_id in g[v].depends_on.iter() {
|
||||
if !used[node_id] {
|
||||
dfs(g, node_id, used, idx);
|
||||
fn reorder_by_key<T: Eq, U>(mut g: Graph<T, U>, idx: Vec<T>) -> Graph<T, U> {
|
||||
g.sort_by_key(|node| idx.iter().position(|k| k == &node.id).unwrap());
|
||||
g
|
||||
}
|
||||
|
||||
fn dfs<T: Eq + Hash + Clone, U>(g: &Graph<T, U>, v: T, used: &mut Set<T>, idx: &mut Vec<T>) {
|
||||
used.insert(v.clone());
|
||||
for node_id in g.iter().find(|n| &n.id == &v).unwrap().depends_on.iter() {
|
||||
if !used.contains(node_id) {
|
||||
dfs(g, node_id.clone(), used, idx);
|
||||
}
|
||||
}
|
||||
idx.push(v);
|
||||
}
|
||||
|
||||
/// perform topological sort on a graph
|
||||
pub fn tsort<T>(g: Graph<T>) -> Graph<T> {
|
||||
pub fn tsort<T: Eq + Hash + Clone, U>(g: Graph<T, U>) -> Graph<T, U> {
|
||||
let n = g.len();
|
||||
let mut idx = Vec::with_capacity(n);
|
||||
let mut used = vec![false; n];
|
||||
for v in 0..n {
|
||||
if !used[v] {
|
||||
dfs(&g, v, &mut used, &mut idx);
|
||||
let mut used = Set::new();
|
||||
for v in g.iter() {
|
||||
if !used.contains(&v.id) {
|
||||
dfs(&g, v.id.clone(), &mut used, &mut idx);
|
||||
}
|
||||
}
|
||||
reorder_by_idx(g, idx)
|
||||
reorder_by_key(g, idx)
|
||||
}
|
||||
|
||||
fn _test() {
|
||||
let v = vec!["e", "d", "b", "a", "c"];
|
||||
let idx = vec![3, 2, 4, 1, 0];
|
||||
assert_eq!(vec!["a", "b", "c", "d", "e"], reorder_by_idx(v, idx));
|
||||
assert_eq!(vec!["a", "b", "c", "d", "e"], _reorder_by_idx(v, idx));
|
||||
|
||||
let en_0 = Node::new("even n", vec![4, 1]);
|
||||
let o0_1 = Node::new("odd 0", vec![]);
|
||||
let on_2 = Node::new("odd n", vec![3, 0]);
|
||||
let e0_3 = Node::new("even 0", vec![]);
|
||||
let ond_4 = Node::new("odd n (decl)", vec![]);
|
||||
let en_0 = Node::new("even n", (), vec!["odd n (decl)", "odd 0"]);
|
||||
let o0_1 = Node::new("odd 0", (), vec![]);
|
||||
let on_2 = Node::new("odd n", (), vec!["even 0", "even n"]);
|
||||
let e0_3 = Node::new("even 0", (), vec![]);
|
||||
let ond_4 = Node::new("odd n (decl)", (), vec![]);
|
||||
let sorted = vec![
|
||||
ond_4.clone(),
|
||||
o0_1.clone(),
|
||||
|
|
|
@ -994,6 +994,15 @@ impl TyBound {
|
|||
Self::Instance { t, .. } => t,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lhs(&self) -> &str {
|
||||
match self {
|
||||
Self::Subtype { sub, .. } => sub.name(),
|
||||
Self::Supertype { sup, .. } => sup.name(),
|
||||
Self::Sandwiched { mid, .. } => mid.name(),
|
||||
Self::Instance { name, .. } => name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -1552,6 +1561,13 @@ impl SubrKind {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn self_t_mut(&mut self) -> Option<&mut SelfType> {
|
||||
match self {
|
||||
Self::FuncMethod(t) | Self::ProcMethod { before: t, .. } => Some(t),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
@ -1632,13 +1648,6 @@ pub enum Type {
|
|||
Class,
|
||||
Trait,
|
||||
Patch,
|
||||
FuncCommon,
|
||||
ProcCommon,
|
||||
FuncMethodCommon,
|
||||
ProcMethodCommon,
|
||||
CallableCommon,
|
||||
ArrayCommon,
|
||||
DictCommon,
|
||||
NotImplemented,
|
||||
Ellipsis, // これはクラスのほうで型推論用のマーカーではない
|
||||
Never, // {}
|
||||
|
@ -1652,17 +1661,6 @@ pub enum Type {
|
|||
param_ts: Vec<Type>,
|
||||
return_t: Box<Type>,
|
||||
},
|
||||
// e.g. [Int] == Array{ t: Int, len: _ }, [Int; 3] == Array { t: Int, len: 3 }
|
||||
Array {
|
||||
t: Box<Type>,
|
||||
len: TyParam,
|
||||
},
|
||||
// TODO: heterogeneous dict
|
||||
Dict {
|
||||
k: Box<Type>,
|
||||
v: Box<Type>,
|
||||
},
|
||||
Tuple(Vec<Type>),
|
||||
Record(Dict<Str, Type>), // e.g. {x = Int}
|
||||
// e.g. {T -> T | T: Type}, {I: Int | I > 0}, {S | N: Nat; S: Str N; N > 1}
|
||||
// 区間型と列挙型は篩型に変換される
|
||||
|
@ -1706,9 +1704,6 @@ impl fmt::Display for Type {
|
|||
Self::Callable { param_ts, return_t } => {
|
||||
write!(f, "Callable(({}), {return_t})", fmt_vec(param_ts))
|
||||
}
|
||||
Self::Array { t, len } => write!(f, "[{t}; {len}]"),
|
||||
Self::Dict { k, v } => write!(f, "{{{k}: {v}}}"),
|
||||
Self::Tuple(ts) => write!(f, "({})", fmt_vec(ts)),
|
||||
Self::Record(attrs) => write!(f, "{{{attrs}}}"),
|
||||
Self::Refinement(refinement) => write!(f, "{}", refinement),
|
||||
Self::Quantified(quantified) => write!(f, "{}", quantified),
|
||||
|
@ -1809,13 +1804,12 @@ impl HasType for Type {
|
|||
}
|
||||
fn inner_ts(&self) -> Vec<Type> {
|
||||
match self {
|
||||
Self::Dict { k, v } => vec![k.as_ref().clone(), v.as_ref().clone()],
|
||||
Self::Ref(t) | Self::RefMut(t) | Self::Array { t, .. } | Self::VarArgs(t) => {
|
||||
Self::Ref(t) | Self::RefMut(t) | Self::VarArgs(t) => {
|
||||
vec![t.as_ref().clone()]
|
||||
}
|
||||
// Self::And(ts) | Self::Or(ts) => ,
|
||||
Self::Subr(_sub) => todo!(),
|
||||
Self::Callable { param_ts, .. } | Self::Tuple(param_ts) => param_ts.clone(),
|
||||
Self::Callable { param_ts, .. } => param_ts.clone(),
|
||||
Self::Poly { params, .. } => params.iter().filter_map(get_t_from_tp).collect(),
|
||||
_ => vec![],
|
||||
}
|
||||
|
@ -1837,9 +1831,7 @@ impl HasLevel for Type {
|
|||
fn update_level(&self, level: Level) {
|
||||
match self {
|
||||
Self::FreeVar(v) => v.update_level(level),
|
||||
Self::Ref(t) | Self::RefMut(t) | Self::Array { t, .. } | Self::VarArgs(t) => {
|
||||
t.update_level(level)
|
||||
}
|
||||
Self::Ref(t) | Self::RefMut(t) | Self::VarArgs(t) => t.update_level(level),
|
||||
Self::Callable { param_ts, return_t } => {
|
||||
for p in param_ts.iter() {
|
||||
p.update_level(level);
|
||||
|
@ -1857,15 +1849,11 @@ impl HasLevel for Type {
|
|||
}
|
||||
subr.return_t.update_level(level);
|
||||
}
|
||||
Self::And(ts) | Self::Or(ts) | Self::Not(ts) | Self::Tuple(ts) => {
|
||||
Self::And(ts) | Self::Or(ts) | Self::Not(ts) => {
|
||||
for t in ts.iter() {
|
||||
t.update_level(level);
|
||||
}
|
||||
}
|
||||
Self::Dict { k, v } => {
|
||||
k.update_level(level);
|
||||
v.update_level(level);
|
||||
}
|
||||
Self::Record(attrs) => {
|
||||
for t in attrs.values() {
|
||||
t.update_level(level);
|
||||
|
@ -1898,7 +1886,7 @@ impl HasLevel for Type {
|
|||
fn lift(&self) {
|
||||
match self {
|
||||
Self::FreeVar(v) => v.lift(),
|
||||
Self::Ref(t) | Self::RefMut(t) | Self::Array { t, .. } | Self::VarArgs(t) => t.lift(),
|
||||
Self::Ref(t) | Self::RefMut(t) | Self::VarArgs(t) => t.lift(),
|
||||
Self::Callable { param_ts, return_t } => {
|
||||
for p in param_ts.iter() {
|
||||
p.lift();
|
||||
|
@ -1916,15 +1904,11 @@ impl HasLevel for Type {
|
|||
}
|
||||
subr.return_t.lift();
|
||||
}
|
||||
Self::And(ts) | Self::Or(ts) | Self::Not(ts) | Self::Tuple(ts) => {
|
||||
Self::And(ts) | Self::Or(ts) | Self::Not(ts) => {
|
||||
for t in ts.iter() {
|
||||
t.lift();
|
||||
}
|
||||
}
|
||||
Self::Dict { k, v } => {
|
||||
k.lift();
|
||||
v.lift();
|
||||
}
|
||||
Self::Record(attrs) => {
|
||||
for t in attrs.values() {
|
||||
t.lift();
|
||||
|
@ -1986,20 +1970,16 @@ impl Type {
|
|||
Self::FreeVar(Free::new_named_unbound(name, level, constraint))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn array(elem_t: Type, len: TyParam) -> Self {
|
||||
Self::Array {
|
||||
t: Box::new(elem_t),
|
||||
len,
|
||||
}
|
||||
Self::poly("Array", vec![TyParam::t(elem_t), len])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dict(k_t: Type, v_t: Type) -> Self {
|
||||
Self::Dict {
|
||||
k: Box::new(k_t),
|
||||
v: Box::new(v_t),
|
||||
}
|
||||
Self::poly("Dict", vec![TyParam::t(k_t), TyParam::t(v_t)])
|
||||
}
|
||||
|
||||
pub fn tuple(args: Vec<Type>) -> Self {
|
||||
Self::poly("Tuple", args.into_iter().map(TyParam::t).collect())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -2343,7 +2323,6 @@ impl Type {
|
|||
Self::Float => Self::FloatMut,
|
||||
Self::Bool => Self::BoolMut,
|
||||
Self::Str => Self::StrMut,
|
||||
Self::Array { t, len } => Self::poly("Array!", vec![TyParam::t(*t), len.mutate()]),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
@ -2379,7 +2358,7 @@ impl Type {
|
|||
let inner_t = enum_unwrap!(params.first().unwrap(), TyParam::Type);
|
||||
inner_t.is_nonelike()
|
||||
}
|
||||
Self::Tuple(ts) => ts.len() == 0,
|
||||
Self::Poly { name, params } if &name[..] == "Tuple" => params.is_empty(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -2480,19 +2459,12 @@ impl Type {
|
|||
return_t: _rr,
|
||||
},
|
||||
) => todo!(),
|
||||
(Self::Array { t: lt, len: ll }, Self::Array { t: rt, len: rl }) => {
|
||||
lt.rec_eq(rt) && ll.rec_eq(rl)
|
||||
}
|
||||
(Self::Dict { k: lk, v: lv }, Self::Dict { k: rk, v: rv }) => {
|
||||
lk.rec_eq(rk) && lv.rec_eq(rv)
|
||||
}
|
||||
(Self::Record(_l), Self::Record(_r)) => todo!(),
|
||||
(Self::Refinement(l), Self::Refinement(r)) => l.t.rec_eq(&r.t) && &l.preds == &r.preds,
|
||||
(Self::Quantified(l), Self::Quantified(r)) => {
|
||||
l.unbound_callable.rec_eq(&r.unbound_callable) && &l.bounds == &r.bounds
|
||||
}
|
||||
(Self::Tuple(l), Self::Tuple(r))
|
||||
| (Self::And(l), Self::And(r))
|
||||
(Self::And(l), Self::And(r))
|
||||
| (Self::Not(l), Self::Not(r))
|
||||
| (Self::Or(l), Self::Or(r)) => l.iter().zip(r.iter()).all(|(l, r)| l.rec_eq(r)),
|
||||
(Self::VarArgs(l), Self::VarArgs(r)) => l.rec_eq(r),
|
||||
|
@ -2579,27 +2551,20 @@ impl Type {
|
|||
Self::Subr(SubrType {
|
||||
kind: SubrKind::Func,
|
||||
..
|
||||
})
|
||||
| Self::FuncCommon => "Func",
|
||||
}) => "Func",
|
||||
Self::Subr(SubrType {
|
||||
kind: SubrKind::Proc,
|
||||
..
|
||||
})
|
||||
| Self::ProcCommon => "Proc",
|
||||
}) => "Proc",
|
||||
Self::Subr(SubrType {
|
||||
kind: SubrKind::FuncMethod(_),
|
||||
..
|
||||
})
|
||||
| Self::FuncMethodCommon => "FuncMethod",
|
||||
}) => "FuncMethod",
|
||||
Self::Subr(SubrType {
|
||||
kind: SubrKind::ProcMethod { .. },
|
||||
..
|
||||
})
|
||||
| Self::ProcMethodCommon => "ProcMethod",
|
||||
Self::Callable { .. } | Self::CallableCommon => "Callable",
|
||||
Self::Array { .. } | Self::ArrayCommon => "Array",
|
||||
Self::Dict { .. } | Self::DictCommon => "Dict",
|
||||
Self::Tuple(..) => "Tuple",
|
||||
}) => "ProcMethod",
|
||||
Self::Callable { .. } => "Callable",
|
||||
Self::Record(_) => "Record",
|
||||
Self::VarArgs(_) => "VarArgs",
|
||||
Self::Poly { name, .. } | Self::PolyQVar { name, .. } => &*name,
|
||||
|
@ -2625,7 +2590,7 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn is_monomorphic(&self) -> bool {
|
||||
self.typaram_len() == 0
|
||||
self.typarams_len() == 0
|
||||
}
|
||||
|
||||
pub const fn is_callable(&self) -> bool {
|
||||
|
@ -2645,8 +2610,6 @@ impl Type {
|
|||
Self::And(param_ts) | Self::Not(param_ts) | Self::Or(param_ts) => {
|
||||
param_ts.iter().any(|t| t.has_unbound_var())
|
||||
}
|
||||
Self::Array { t, len } => t.has_unbound_var() || len.has_unbound_var(),
|
||||
Self::Dict { k, v } => k.has_unbound_var() || v.has_unbound_var(),
|
||||
Self::Callable { param_ts, return_t } => {
|
||||
param_ts.iter().any(|t| t.has_unbound_var()) || return_t.has_unbound_var()
|
||||
}
|
||||
|
@ -2679,12 +2642,11 @@ impl Type {
|
|||
!self.has_unbound_var()
|
||||
}
|
||||
|
||||
pub fn typaram_len(&self) -> usize {
|
||||
pub fn typarams_len(&self) -> usize {
|
||||
match self {
|
||||
// REVIEw:
|
||||
Self::Ref(_) | Self::RefMut(_) => 1,
|
||||
Self::Array { .. } | Self::Dict { .. } => 2,
|
||||
Self::And(param_ts) | Self::Or(param_ts) | Self::Tuple(param_ts) => param_ts.len() + 1,
|
||||
Self::And(param_ts) | Self::Or(param_ts) => param_ts.len(),
|
||||
Self::Subr(subr) => {
|
||||
subr.kind.inner_len()
|
||||
+ subr.non_default_params.len()
|
||||
|
@ -2702,12 +2664,9 @@ impl Type {
|
|||
Self::FreeVar(f) if f.is_linked() => f.crack().typarams(),
|
||||
Self::FreeVar(_unbound) => todo!(),
|
||||
Self::Ref(t) | Self::RefMut(t) => vec![TyParam::t(*t.clone())],
|
||||
Self::Array { t, len } => vec![TyParam::t(*t.clone()), len.clone()],
|
||||
Self::Dict { k, v } => vec![TyParam::t(*k.clone()), TyParam::t(*v.clone())],
|
||||
Self::And(param_ts)
|
||||
| Self::Or(param_ts)
|
||||
| Self::Not(param_ts)
|
||||
| Self::Tuple(param_ts) => param_ts.iter().map(|t| TyParam::t(t.clone())).collect(),
|
||||
Self::And(param_ts) | Self::Or(param_ts) | Self::Not(param_ts) => {
|
||||
param_ts.iter().map(|t| TyParam::t(t.clone())).collect()
|
||||
}
|
||||
Self::Subr(subr) => {
|
||||
if let Some(self_t) = subr.kind.self_t() {
|
||||
[
|
||||
|
@ -2920,14 +2879,17 @@ pub enum TypeCode {
|
|||
impl From<&Type> for TypeCode {
|
||||
fn from(arg: &Type) -> Self {
|
||||
match arg {
|
||||
Type::Int => Self::Int32,
|
||||
Type::Nat => Self::Nat64,
|
||||
Type::Float => Self::Float64,
|
||||
Type::Bool => Self::Bool,
|
||||
Type::Str => Self::Str,
|
||||
Type::Array { .. } => Self::Array,
|
||||
Type::FuncCommon => Self::Func,
|
||||
Type::ProcCommon => Self::Proc,
|
||||
Type::Int | Type::IntMut => Self::Int32,
|
||||
Type::Nat | Type::NatMut => Self::Nat64,
|
||||
Type::Float | Type::FloatMut => Self::Float64,
|
||||
Type::Bool | Type::BoolMut => Self::Bool,
|
||||
Type::Str | Type::StrMut => Self::Str,
|
||||
Type::Poly { name, .. } => match &name[..] {
|
||||
"Array" | "Array!" => Self::Array,
|
||||
"Func" => Self::Func,
|
||||
"Proc" => Self::Proc,
|
||||
_ => Self::Other,
|
||||
},
|
||||
_ => Self::Other,
|
||||
}
|
||||
}
|
||||
|
@ -3002,6 +2964,7 @@ pub enum TypePair {
|
|||
ProcStr,
|
||||
ProcBool,
|
||||
ProcArray,
|
||||
ProcFunc,
|
||||
ProcProc,
|
||||
Others,
|
||||
Illegals,
|
||||
|
@ -3089,65 +3052,102 @@ impl TypePair {
|
|||
(Type::Int, Type::Float) => Self::IntFloat,
|
||||
(Type::Int, Type::Str) => Self::IntStr,
|
||||
(Type::Int, Type::Bool) => Self::IntBool,
|
||||
(Type::Int, Type::Array { .. }) => Self::IntArray,
|
||||
(Type::Int, Type::FuncCommon) => Self::IntFunc,
|
||||
(Type::Int, Type::ProcCommon) => Self::IntProc,
|
||||
(Type::Int, Type::Poly { name, .. }) if &name[..] == "Array" => Self::IntArray,
|
||||
(Type::Int, Type::Poly { name, .. }) if &name[..] == "Func" => Self::IntFunc,
|
||||
(Type::Int, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::IntProc,
|
||||
(Type::Nat, Type::Int) => Self::NatInt,
|
||||
(Type::Nat, Type::Nat) => Self::NatNat,
|
||||
(Type::Nat, Type::Float) => Self::NatFloat,
|
||||
(Type::Nat, Type::Str) => Self::NatStr,
|
||||
(Type::Nat, Type::Bool) => Self::NatBool,
|
||||
(Type::Nat, Type::Array { .. }) => Self::NatArray,
|
||||
(Type::Nat, Type::FuncCommon) => Self::NatFunc,
|
||||
(Type::Nat, Type::ProcCommon) => Self::NatProc,
|
||||
(Type::Nat, Type::Poly { name, .. }) if &name[..] == "Array" => Self::NatArray,
|
||||
(Type::Nat, Type::Poly { name, .. }) if &name[..] == "Func" => Self::NatFunc,
|
||||
(Type::Nat, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::NatProc,
|
||||
(Type::Float, Type::Int) => Self::FloatInt,
|
||||
(Type::Float, Type::Nat) => Self::FloatNat,
|
||||
(Type::Float, Type::Float) => Self::FloatFloat,
|
||||
(Type::Float, Type::Str) => Self::FloatStr,
|
||||
(Type::Float, Type::Bool) => Self::FloatBool,
|
||||
(Type::Float, Type::Array { .. }) => Self::FloatArray,
|
||||
(Type::Float, Type::FuncCommon) => Self::FloatFunc,
|
||||
(Type::Float, Type::ProcCommon) => Self::FloatProc,
|
||||
(Type::Float, Type::Poly { name, .. }) if &name[..] == "Array" => Self::FloatArray,
|
||||
(Type::Float, Type::Poly { name, .. }) if &name[..] == "Func" => Self::FloatFunc,
|
||||
(Type::Float, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::FloatProc,
|
||||
(Type::Bool, Type::Int) => Self::BoolInt,
|
||||
(Type::Bool, Type::Nat) => Self::BoolNat,
|
||||
(Type::Bool, Type::Float) => Self::BoolFloat,
|
||||
(Type::Bool, Type::Str) => Self::BoolStr,
|
||||
(Type::Bool, Type::Bool) => Self::BoolBool,
|
||||
(Type::Bool, Type::Array { .. }) => Self::BoolArray,
|
||||
(Type::Bool, Type::FuncCommon) => Self::BoolFunc,
|
||||
(Type::Bool, Type::ProcCommon) => Self::BoolProc,
|
||||
(Type::Bool, Type::Poly { name, .. }) if &name[..] == "Array" => Self::BoolArray,
|
||||
(Type::Bool, Type::Poly { name, .. }) if &name[..] == "Func" => Self::BoolFunc,
|
||||
(Type::Bool, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::BoolProc,
|
||||
(Type::Str, Type::Int) => Self::StrInt,
|
||||
(Type::Str, Type::Nat) => Self::StrNat,
|
||||
(Type::Str, Type::Float) => Self::StrFloat,
|
||||
(Type::Str, Type::Bool) => Self::StrBool,
|
||||
(Type::Str, Type::Str) => Self::StrStr,
|
||||
(Type::Str, Type::Array { .. }) => Self::StrArray,
|
||||
(Type::Str, Type::FuncCommon) => Self::StrFunc,
|
||||
(Type::Str, Type::ProcCommon) => Self::StrProc,
|
||||
(Type::Str, Type::Poly { name, .. }) if &name[..] == "Array" => Self::StrArray,
|
||||
(Type::Str, Type::Poly { name, .. }) if &name[..] == "Func" => Self::StrFunc,
|
||||
(Type::Str, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::StrProc,
|
||||
// 要素数は検査済みなので、気にする必要はない
|
||||
(Type::Array { .. }, Type::Int) => Self::ArrayInt,
|
||||
(Type::Array { .. }, Type::Nat) => Self::ArrayNat,
|
||||
(Type::Array { .. }, Type::Float) => Self::ArrayFloat,
|
||||
(Type::Array { .. }, Type::Str) => Self::ArrayStr,
|
||||
(Type::Array { .. }, Type::Bool) => Self::ArrayBool,
|
||||
(Type::Array { .. }, Type::Array { .. }) => Self::ArrayArray,
|
||||
(Type::Array { .. }, Type::FuncCommon) => Self::ArrayFunc,
|
||||
(Type::Array { .. }, Type::ProcCommon) => Self::ArrayProc,
|
||||
(Type::FuncCommon, Type::Int) => Self::FuncInt,
|
||||
(Type::FuncCommon, Type::Nat) => Self::FuncNat,
|
||||
(Type::FuncCommon, Type::Float) => Self::FuncFloat,
|
||||
(Type::FuncCommon, Type::Str) => Self::FuncStr,
|
||||
(Type::FuncCommon, Type::Bool) => Self::FuncBool,
|
||||
(Type::FuncCommon, Type::Array { .. }) => Self::FuncArray,
|
||||
(Type::FuncCommon, Type::FuncCommon) => Self::FuncFunc,
|
||||
(Type::FuncCommon, Type::ProcCommon) => Self::FuncProc,
|
||||
(Type::ProcCommon, Type::Int) => Self::ProcInt,
|
||||
(Type::ProcCommon, Type::Nat) => Self::ProcNat,
|
||||
(Type::ProcCommon, Type::Float) => Self::ProcFloat,
|
||||
(Type::ProcCommon, Type::Str) => Self::ProcStr,
|
||||
(Type::ProcCommon, Type::Bool) => Self::ProcBool,
|
||||
(Type::ProcCommon, Type::Array { .. }) => Self::ProcArray,
|
||||
(Type::ProcCommon, Type::ProcCommon) => Self::ProcProc,
|
||||
(Type::Poly { name, .. }, Type::Int) if &name[..] == "Array" => Self::ArrayInt,
|
||||
(Type::Poly { name, .. }, Type::Nat) if &name[..] == "Array" => Self::ArrayNat,
|
||||
(Type::Poly { name, .. }, Type::Float) if &name[..] == "Array" => Self::ArrayFloat,
|
||||
(Type::Poly { name, .. }, Type::Str) if &name[..] == "Array" => Self::ArrayStr,
|
||||
(Type::Poly { name, .. }, Type::Bool) if &name[..] == "Array" => Self::ArrayBool,
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Array" && &rn[..] == "Array" =>
|
||||
{
|
||||
Self::ArrayArray
|
||||
}
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Array" && &rn[..] == "Func" =>
|
||||
{
|
||||
Self::ArrayFunc
|
||||
}
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Array" && &rn[..] == "Proc" =>
|
||||
{
|
||||
Self::ArrayProc
|
||||
}
|
||||
(Type::Poly { name, .. }, Type::Int) if &name[..] == "Func" => Self::FuncInt,
|
||||
(Type::Poly { name, .. }, Type::Nat) if &name[..] == "Func" => Self::FuncNat,
|
||||
(Type::Poly { name, .. }, Type::Float) if &name[..] == "Func" => Self::FuncFloat,
|
||||
(Type::Poly { name, .. }, Type::Str) if &name[..] == "Func" => Self::FuncStr,
|
||||
(Type::Poly { name, .. }, Type::Bool) if &name[..] == "Func" => Self::FuncBool,
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Func" && &rn[..] == "Array" =>
|
||||
{
|
||||
Self::FuncArray
|
||||
}
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Func" && &rn[..] == "Func" =>
|
||||
{
|
||||
Self::FuncFunc
|
||||
}
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Func" && &rn[..] == "Proc" =>
|
||||
{
|
||||
Self::FuncProc
|
||||
}
|
||||
(Type::Poly { name, .. }, Type::Int) if &name[..] == "Proc" => Self::ProcInt,
|
||||
(Type::Poly { name, .. }, Type::Nat) if &name[..] == "Proc" => Self::ProcNat,
|
||||
(Type::Poly { name, .. }, Type::Float) if &name[..] == "Proc" => Self::ProcFloat,
|
||||
(Type::Poly { name, .. }, Type::Str) if &name[..] == "Proc" => Self::ProcStr,
|
||||
(Type::Poly { name, .. }, Type::Bool) if &name[..] == "Proc" => Self::ProcBool,
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Proc" && &rn[..] == "Array" =>
|
||||
{
|
||||
Self::ProcArray
|
||||
}
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Proc" && &rn[..] == "Func" =>
|
||||
{
|
||||
Self::ProcFunc
|
||||
}
|
||||
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
|
||||
if &ln[..] == "Proc" && &rn[..] == "Proc" =>
|
||||
{
|
||||
Self::ProcProc
|
||||
}
|
||||
(_, _) => Self::Others,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1237,7 +1237,8 @@ impl CodeGenerator {
|
|||
}
|
||||
self.cancel_pop_top(); // 最後の値は戻り値として取っておく
|
||||
if self.input().is_repl() {
|
||||
if self.cur_block().stack_len == 1 { // remains `print`, nothing to be printed
|
||||
if self.cur_block().stack_len == 1 {
|
||||
// remains `print`, nothing to be printed
|
||||
self.edit_code(print_point, Opcode::NOP as usize);
|
||||
} else {
|
||||
self.write_instr(CALL_FUNCTION);
|
||||
|
|
|
@ -9,17 +9,17 @@ use erg_common::error::{ErrorCore, Location};
|
|||
use erg_common::levenshtein::levenshtein;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{HasType, Locational, Stream};
|
||||
use erg_common::tsort::tsort;
|
||||
use erg_common::tsort::{Graph, Node};
|
||||
use erg_common::ty::fresh_varname;
|
||||
use erg_common::ty::Constraint;
|
||||
use erg_common::ty::RefinementType;
|
||||
use erg_common::ty::{
|
||||
ConstObj, FreeKind, HasLevel, IntervalOp, ParamTy, Predicate, SubrKind, SubrType, TyBound,
|
||||
TyParam, TyParamOrdering, Type,
|
||||
ConstObj, Constraint, FreeKind, HasLevel, IntervalOp, ParamTy, Predicate, RefinementType,
|
||||
SubrKind, SubrType, TyBound, TyParam, TyParamOrdering, Type,
|
||||
};
|
||||
use erg_common::value::ValueObj;
|
||||
use erg_common::Str;
|
||||
use erg_common::{
|
||||
assume_unreachable, enum_unwrap, fmt_slice, fn_name, get_hash, log, set, try_map,
|
||||
assume_unreachable, enum_unwrap, fmt_slice, fmt_vec, fn_name, get_hash, log, set, try_map,
|
||||
};
|
||||
use Predicate as Pred;
|
||||
use TyParamOrdering::*;
|
||||
|
@ -52,13 +52,14 @@ impl DefaultInfo {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
|
||||
pub enum Variance {
|
||||
/// Output(T)
|
||||
Covariant,
|
||||
Covariant, // 共変
|
||||
/// Input(T)
|
||||
Contravariant,
|
||||
Invariant,
|
||||
Contravariant, // 反変
|
||||
#[default]
|
||||
Invariant, // 不変
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -121,6 +122,8 @@ pub enum RegistrationMode {
|
|||
|
||||
use RegistrationMode::*;
|
||||
|
||||
type TyBoundGraph = Graph<Str, TyBound>;
|
||||
|
||||
/// Context for instantiating a quantified type
|
||||
/// 量化型をインスタンス化するための文脈
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -137,12 +140,71 @@ impl TyVarContext {
|
|||
tyvar_instances: Dict::new(),
|
||||
typaram_instances: Dict::new(),
|
||||
};
|
||||
for bound in bounds.into_iter() {
|
||||
for bound in Self::sort_bounds(bounds) {
|
||||
self_.instantiate_bound(bound);
|
||||
}
|
||||
self_
|
||||
}
|
||||
|
||||
fn sort_bounds(_bounds: Set<TyBound>) -> impl Iterator<Item = TyBound> {
|
||||
let mut graph = TyBoundGraph::new();
|
||||
for bound in _bounds.into_iter() {
|
||||
let depends_on = Self::bound_dependencies(&bound);
|
||||
graph.push(Node::new(Str::rc(bound.lhs()), bound, depends_on));
|
||||
}
|
||||
let graph = tsort(graph);
|
||||
graph.into_iter().map(|node| node.data)
|
||||
}
|
||||
|
||||
fn bound_dependencies(_bound: &TyBound) -> Vec<Str> {
|
||||
// TODO: Polymorphic lhs
|
||||
match _bound {
|
||||
TyBound::Subtype { sup, .. } => Self::rec_t_inner_qvars(sup, vec![]),
|
||||
TyBound::Supertype { sub, .. } => Self::rec_t_inner_qvars(sub, vec![]),
|
||||
TyBound::Sandwiched { mid, .. } => Self::rec_t_inner_qvars(mid, vec![]),
|
||||
TyBound::Instance { t, .. } => Self::rec_t_inner_qvars(t, vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
fn rec_t_inner_qvars(t: &Type, dep: Vec<Str>) -> Vec<Str> {
|
||||
match t {
|
||||
Type::MonoQVar(name) | Type::PolyQVar { name, .. } => {
|
||||
[dep, vec![name.clone()]].concat()
|
||||
}
|
||||
Type::FreeVar(fv) if fv.is_linked() => Self::rec_t_inner_qvars(&fv.crack(), dep),
|
||||
Type::Ref(t) | Type::RefMut(t) => Self::rec_t_inner_qvars(t, dep),
|
||||
Type::Poly { params, .. } => params.iter().fold(dep, |acc, arg| {
|
||||
[acc, Self::rec_tp_inner_qvars(arg, vec![])].concat()
|
||||
}),
|
||||
Type::VarArgs(t) => Self::rec_t_inner_qvars(&t, dep),
|
||||
Type::Subr(_subr) => todo!(),
|
||||
Type::Callable { param_ts: _, return_t: _ } => todo!(),
|
||||
Type::And(_) | Type::Or(_) | Type::Not(_) => todo!(),
|
||||
Type::Record(_) => todo!(),
|
||||
Type::Quantified(_) => todo!(),
|
||||
Type::Refinement(_) => todo!(),
|
||||
_ => dep,
|
||||
}
|
||||
}
|
||||
|
||||
fn rec_tp_inner_qvars(tp: &TyParam, dep: Vec<Str>) -> Vec<Str> {
|
||||
match tp {
|
||||
TyParam::MonoQVar(name) | TyParam::PolyQVar { name, .. } => {
|
||||
[dep, vec![name.clone()]].concat()
|
||||
}
|
||||
TyParam::FreeVar(fv) if fv.is_linked() => Self::rec_tp_inner_qvars(&fv.crack(), dep),
|
||||
TyParam::Type(t) => Self::rec_t_inner_qvars(t, dep),
|
||||
TyParam::App { args, .. } | TyParam::Array(args) | TyParam::Tuple(args) => {
|
||||
args.iter().fold(dep, |acc, arg| {
|
||||
[acc, Self::rec_tp_inner_qvars(arg, vec![])].concat()
|
||||
})
|
||||
}
|
||||
TyParam::UnaryOp { .. } => todo!(),
|
||||
TyParam::BinOp { .. } => todo!(),
|
||||
_ => dep,
|
||||
}
|
||||
}
|
||||
|
||||
fn instantiate_bound(&mut self, bound: TyBound) {
|
||||
match bound {
|
||||
TyBound::Subtype { sub, sup } => {
|
||||
|
@ -158,7 +220,8 @@ impl TyVarContext {
|
|||
sup => sup,
|
||||
};
|
||||
let constraint = Constraint::SubtypeOf(sup);
|
||||
self.push_tyvar(Str::rc(sub.name()), Type::free_var(self.level, constraint));
|
||||
let name = Str::rc(sub.name());
|
||||
self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint));
|
||||
}
|
||||
TyBound::Supertype { sup, sub } => {
|
||||
let sub = match sub {
|
||||
|
@ -173,7 +236,8 @@ impl TyVarContext {
|
|||
sub => sub,
|
||||
};
|
||||
let constraint = Constraint::SupertypeOf(sub);
|
||||
self.push_tyvar(Str::rc(sup.name()), Type::free_var(self.level, constraint));
|
||||
let name = Str::rc(sup.name());
|
||||
self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint));
|
||||
}
|
||||
TyBound::Sandwiched { sub, mid, sup } => {
|
||||
let sub = match sub {
|
||||
|
@ -199,7 +263,8 @@ impl TyVarContext {
|
|||
sup => sup,
|
||||
};
|
||||
let constraint = Constraint::Sandwiched { sub, sup };
|
||||
self.push_tyvar(Str::rc(mid.name()), Type::free_var(self.level, constraint));
|
||||
let name = Str::rc(mid.name());
|
||||
self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint));
|
||||
}
|
||||
TyBound::Instance { name, t } => {
|
||||
let t = match t {
|
||||
|
@ -321,6 +386,9 @@ pub struct Context {
|
|||
// K: メソッド名, V: それを実装するパッチたち
|
||||
// 提供メソッドはスコープごとに実装を切り替えることができる
|
||||
pub(crate) _method_impl_patches: Dict<VarName, Vec<VarName>>,
|
||||
// K: 多相トレイトの名前, V: 実装(小さい順)
|
||||
// e.g. { "Add": [Add(Nat, Nat), Add(Int, Int), ...], ... }
|
||||
pub(crate) poly_trait_impls: Dict<Str, Vec<Type>>,
|
||||
// .0: 関係付けるパッチ(glue patch), .1: サブタイプになる型, .2: スーパータイプになるトレイト
|
||||
// 一つの型ペアを接着パッチは同時に一つまでしか存在しないが、付け替えは可能
|
||||
pub(crate) glue_patch_and_types: Vec<(VarName, Type, Type)>,
|
||||
|
@ -437,6 +505,7 @@ impl Context {
|
|||
super_classes,
|
||||
super_traits,
|
||||
_method_impl_patches: Dict::default(),
|
||||
poly_trait_impls: Dict::default(),
|
||||
glue_patch_and_types: Vec::default(),
|
||||
params: params_,
|
||||
decls: Dict::default(),
|
||||
|
@ -718,7 +787,7 @@ impl Context {
|
|||
let muty = Mutability::from(&sig.inspect().unwrap()[..]);
|
||||
let (generalized, bounds) = self.generalize_t(body_t.clone());
|
||||
let generalized = if !bounds.is_empty() {
|
||||
if self.rec_full_supertype_of(&Type::CallableCommon, &generalized) {
|
||||
if self.rec_full_supertype_of(&Type::mono("GenericCallable"), &generalized) {
|
||||
Type::quantified(generalized, bounds)
|
||||
} else {
|
||||
panic!()
|
||||
|
@ -928,7 +997,7 @@ impl Context {
|
|||
sub_t.lift();
|
||||
let (generalized, bounds) = self.generalize_t(sub_t);
|
||||
let found_t = if !bounds.is_empty() {
|
||||
if self.rec_full_supertype_of(&Type::CallableCommon, &generalized) {
|
||||
if self.rec_full_supertype_of(&Type::mono("GenericCallable"), &generalized) {
|
||||
Type::quantified(generalized, bounds)
|
||||
} else {
|
||||
panic!()
|
||||
|
@ -941,7 +1010,8 @@ impl Context {
|
|||
vi.t.lift();
|
||||
let (generalized, bounds) = self.generalize_t(vi.t.clone());
|
||||
let generalized = if !bounds.is_empty() {
|
||||
if self.rec_full_supertype_of(&Type::CallableCommon, &generalized) {
|
||||
if self.rec_full_supertype_of(&Type::mono("GenericCallable"), &generalized)
|
||||
{
|
||||
Type::quantified(generalized, bounds)
|
||||
} else {
|
||||
panic!()
|
||||
|
@ -1319,22 +1389,6 @@ impl Context {
|
|||
tv_ctx,
|
||||
)
|
||||
}
|
||||
Type::Array { t, len } => {
|
||||
let (t, tv_ctx) = Self::instantiate_t(*t, tv_ctx);
|
||||
let (len, tv_ctx) = Self::instantiate_tp(len, tv_ctx);
|
||||
(Type::array(t, len), tv_ctx)
|
||||
}
|
||||
Type::Dict { k, v } => {
|
||||
let (k, tv_ctx) = Self::instantiate_t(*k, tv_ctx);
|
||||
let (v, tv_ctx) = Self::instantiate_t(*v, tv_ctx);
|
||||
(Type::dict(k, v), tv_ctx)
|
||||
}
|
||||
Tuple(mut ts) => {
|
||||
for t in ts.iter_mut() {
|
||||
(*t, tv_ctx) = Self::instantiate_t(mem::take(t), tv_ctx);
|
||||
}
|
||||
(Type::Tuple(ts), tv_ctx)
|
||||
}
|
||||
Record(mut dict) => {
|
||||
for v in dict.values_mut() {
|
||||
(*v, tv_ctx) = Self::instantiate_t(mem::take(v), tv_ctx);
|
||||
|
@ -1488,13 +1542,13 @@ impl Context {
|
|||
}
|
||||
|
||||
// FIXME:
|
||||
fn deref_tp(tp: TyParam) -> TyCheckResult<TyParam> {
|
||||
fn deref_tp(&self, tp: TyParam) -> TyCheckResult<TyParam> {
|
||||
match tp {
|
||||
TyParam::FreeVar(fv) if fv.is_linked() => Ok(fv.unwrap()),
|
||||
TyParam::Type(t) => Ok(TyParam::t(Self::deref_tyvar(*t)?)),
|
||||
TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t)?)),
|
||||
TyParam::App { name, mut args } => {
|
||||
for param in args.iter_mut() {
|
||||
*param = Self::deref_tp(mem::take(param))?;
|
||||
*param = self.deref_tp(mem::take(param))?;
|
||||
}
|
||||
Ok(TyParam::App { name, args })
|
||||
}
|
||||
|
@ -1502,33 +1556,42 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME:
|
||||
fn deref_tyvar(t: Type) -> TyCheckResult<Type> {
|
||||
fn deref_tyvar(&self, t: Type) -> TyCheckResult<Type> {
|
||||
match t {
|
||||
// in toplevel: ?T(<: Int)[n] should replaced to Int (if n > 0)
|
||||
Type::FreeVar(fv) if fv.is_unbound() => {
|
||||
match fv.borrow().constraint().unwrap() {
|
||||
Constraint::SubtypeOf(sup)
|
||||
| Constraint::Sandwiched { sup, .. } if self.level <= fv.level().unwrap() => {
|
||||
return Ok(sup.clone());
|
||||
},
|
||||
// REVIEW: really?
|
||||
Constraint::SupertypeOf(sub) if self.level <= fv.level().unwrap() => {
|
||||
return Ok(sub.clone());
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
Ok(Type::FreeVar(fv))
|
||||
},
|
||||
Type::FreeVar(fv) if fv.is_linked() => Ok(fv.unwrap()),
|
||||
// 未連携型変数のチェックはモジュール全体の型検査が終わった後にやる
|
||||
// Type::FreeVar(_) =>
|
||||
// Err(TyCheckError::checker_bug(0, Location::Unknown, fn_name!(), line!())),
|
||||
Type::Poly { name, mut params } => {
|
||||
for param in params.iter_mut() {
|
||||
*param = Self::deref_tp(mem::take(param))?;
|
||||
*param = self.deref_tp(mem::take(param))?;
|
||||
}
|
||||
Ok(Type::poly(name, params))
|
||||
}
|
||||
Type::Array { mut t, mut len } => {
|
||||
let t = Self::deref_tyvar(mem::take(&mut t))?;
|
||||
let len = Self::deref_tp(mem::take(&mut len))?;
|
||||
Ok(Type::array(t, len))
|
||||
}
|
||||
Type::Subr(mut subr) => {
|
||||
match &mut subr.kind {
|
||||
SubrKind::FuncMethod(t) => {
|
||||
*t = Box::new(Self::deref_tyvar(mem::take(t))?);
|
||||
*t = Box::new(self.deref_tyvar(mem::take(t))?);
|
||||
}
|
||||
SubrKind::ProcMethod { before, after } => {
|
||||
*before = Box::new(Self::deref_tyvar(mem::take(before))?);
|
||||
*before = Box::new(self.deref_tyvar(mem::take(before))?);
|
||||
if let Some(after) = after {
|
||||
*after = Box::new(Self::deref_tyvar(mem::take(after))?);
|
||||
*after = Box::new(self.deref_tyvar(mem::take(after))?);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -1538,15 +1601,52 @@ impl Context {
|
|||
.iter_mut()
|
||||
.chain(subr.default_params.iter_mut());
|
||||
for param in params {
|
||||
param.ty = Self::deref_tyvar(mem::take(&mut param.ty))?;
|
||||
param.ty = self.deref_tyvar(mem::take(&mut param.ty))?;
|
||||
}
|
||||
subr.return_t = Box::new(Self::deref_tyvar(mem::take(&mut subr.return_t))?);
|
||||
subr.return_t = Box::new(self.deref_tyvar(mem::take(&mut subr.return_t))?);
|
||||
Ok(Type::Subr(subr))
|
||||
}
|
||||
t => Ok(t),
|
||||
}
|
||||
}
|
||||
|
||||
/// e.g.
|
||||
/// monomorphise_t(Add(Nat, Nat)): (Add(Nat, Nat) => Nat)
|
||||
/// monomorphise_t(Add(Nat, ?O)): (?O => Nat, Add(Nat, Nat) => Nat)
|
||||
pub(crate) fn monomorphise(&self, maybe_poly: Type) -> TyCheckResult<Type> {
|
||||
match maybe_poly {
|
||||
Type::Subr(mut subr) => {
|
||||
if let Some(self_t) = subr.kind.self_t_mut() {
|
||||
*self_t = self.monomorphise(mem::take(self_t))?;
|
||||
}
|
||||
for param_t in subr.non_default_params.iter_mut() {
|
||||
param_t.ty = self.monomorphise(mem::take(&mut param_t.ty))?;
|
||||
}
|
||||
for param_t in subr.default_params.iter_mut() {
|
||||
param_t.ty = self.monomorphise(mem::take(&mut param_t.ty))?;
|
||||
}
|
||||
subr.return_t = Box::new(self.monomorphise(mem::take(&mut subr.return_t))?);
|
||||
Ok(Type::Subr(subr))
|
||||
}
|
||||
Type::Poly{ name, params } => {
|
||||
let impls = self.rec_get_trait_impls(&name);
|
||||
if impls.is_empty() {
|
||||
panic!("{} is not implemented", name);
|
||||
}
|
||||
let min = self.smallest_t(impls.clone().into_iter()).unwrap_or_else(move || {
|
||||
panic!("cannot determine the smallest type: {}", fmt_vec(&impls))
|
||||
});
|
||||
dbg!(&min);
|
||||
for (param, min_param) in params.iter().zip(min.typarams()) {
|
||||
self.unify_tp(param, &min_param, None, None, false)?;
|
||||
}
|
||||
dbg!(¶ms);
|
||||
Ok(min)
|
||||
},
|
||||
_ => Ok(maybe_poly),
|
||||
}
|
||||
}
|
||||
|
||||
/// 可変依存型の変更を伝搬させる
|
||||
fn propagate(&self, t: &Type, callee: &hir::Expr) -> TyCheckResult<()> {
|
||||
match t {
|
||||
|
@ -2035,6 +2135,9 @@ impl Context {
|
|||
sup: mem::take(sup),
|
||||
};
|
||||
}
|
||||
Constraint::TypeOf(_t) => {
|
||||
*constraint = Constraint::SupertypeOf(l.clone());
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
|
@ -2284,7 +2387,7 @@ impl Context {
|
|||
let len = self.instantiate_const_expr(&len.expr);
|
||||
Ok(Type::array(t, len))
|
||||
} else {
|
||||
Ok(Type::ArrayCommon)
|
||||
Ok(Type::mono("GenericArray"))
|
||||
}
|
||||
}
|
||||
other if simple.args.is_empty() => Ok(Type::mono(Str::rc(other))),
|
||||
|
@ -2361,7 +2464,7 @@ impl Context {
|
|||
])),
|
||||
TypeSpec::Array { .. } => todo!(),
|
||||
// FIXME: unwrap
|
||||
TypeSpec::Tuple(tys) => Ok(Type::Tuple(
|
||||
TypeSpec::Tuple(tys) => Ok(Type::tuple(
|
||||
tys.iter()
|
||||
.map(|spec| self.instantiate_typespec(spec, mode).unwrap())
|
||||
.collect(),
|
||||
|
@ -2521,7 +2624,7 @@ impl Context {
|
|||
pos_args[i + 1].loc(),
|
||||
self.caused_by(),
|
||||
1,
|
||||
pos_args[i + 1].expr.ref_t().typaram_len(),
|
||||
pos_args[i + 1].expr.ref_t().typarams_len(),
|
||||
));
|
||||
}
|
||||
let rhs = self.instantiate_param_sig_t(&lambda.params.non_defaults[0], None, Normal)?;
|
||||
|
@ -2704,10 +2807,14 @@ impl Context {
|
|||
);
|
||||
self.substitute_call(callee, &instance, pos_args, kw_args)?;
|
||||
log!("Substituted:\ninstance: {instance}");
|
||||
let res = self.eval.eval_t(instance, &self, self.level)?;
|
||||
log!("Evaluated:\nres: {res}\n");
|
||||
let res = Self::deref_tyvar(res)?;
|
||||
let res = self.deref_tyvar(instance)?;
|
||||
log!("Eliminated:\nres: {res}\n");
|
||||
let res = self.eval.eval_t_params(res, &self, self.level)?;
|
||||
log!("Params Evaluated:\nres: {res}\n");
|
||||
let res = self.deref_tyvar(res)?;
|
||||
log!("Eliminated (2):\nres: {res}\n");
|
||||
let res = self.monomorphise(res)?;
|
||||
log!("Monomorphised:\nres: {res}\n");
|
||||
self.propagate(&res, callee)?;
|
||||
log!("Propagated:\nres: {res}\n");
|
||||
Ok(res)
|
||||
|
@ -2818,7 +2925,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
for (patch_name, sub, sup) in self.glue_patch_and_types.iter() {
|
||||
let patch = self.rec_get_patch(patch_name).unwrap();
|
||||
let patch = self.rec_get_patch(patch_name).unwrap_or_else(|| panic!("{patch_name} not found"));
|
||||
let bounds = patch.type_params_bounds();
|
||||
let variance = patch.type_params_variance();
|
||||
if self.formal_supertype_of(sub, rhs, Some(&bounds), Some(&variance))
|
||||
|
@ -2859,39 +2966,53 @@ impl Context {
|
|||
| (Float | Ratio, Ratio)
|
||||
| (Float, Float) => true,
|
||||
(
|
||||
FuncCommon,
|
||||
Type::Mono(n),
|
||||
Subr(SubrType {
|
||||
kind: SubrKind::Func,
|
||||
..
|
||||
}),
|
||||
)
|
||||
| (
|
||||
ProcCommon,
|
||||
) if &n[..] == "GenericFunc" => true,
|
||||
(
|
||||
Type::Mono(n),
|
||||
Subr(SubrType {
|
||||
kind: SubrKind::Proc,
|
||||
..
|
||||
}),
|
||||
)
|
||||
| (
|
||||
FuncMethodCommon,
|
||||
) if &n[..] == "GenericProc" => true,
|
||||
(
|
||||
Type::Mono(n),
|
||||
Subr(SubrType {
|
||||
kind: SubrKind::FuncMethod(_),
|
||||
..
|
||||
}),
|
||||
)
|
||||
| (
|
||||
ProcMethodCommon,
|
||||
) if &n[..] == "GenericFuncMethod" => true,
|
||||
(
|
||||
Type::Mono(n),
|
||||
Subr(SubrType {
|
||||
kind: SubrKind::ProcMethod { .. },
|
||||
..
|
||||
}),
|
||||
)
|
||||
| (ArrayCommon, Type::Array { .. })
|
||||
| (DictCommon, Type::Dict { .. }) => true,
|
||||
(
|
||||
CallableCommon,
|
||||
Subr(_) | FuncCommon | ProcCommon | FuncMethodCommon | ProcMethodCommon,
|
||||
) => true,
|
||||
) if &n[..] == "GenericProcMethod" => true,
|
||||
(Type::Mono(l), Type::Poly { name: r, .. })
|
||||
if &l[..] == "GenericArray" && &r[..] == "Array" =>
|
||||
{
|
||||
true
|
||||
}
|
||||
(Type::Mono(l), Type::Poly { name: r, .. })
|
||||
if &l[..] == "GenericDict" && &r[..] == "Dict" =>
|
||||
{
|
||||
true
|
||||
}
|
||||
(Type::Mono(l), Type::Mono(r))
|
||||
if &l[..] == "GenericCallable"
|
||||
&& (&r[..] == "GenericFunc"
|
||||
|| &r[..] == "GenericProc"
|
||||
|| &r[..] == "GenericFuncMethod"
|
||||
|| &r[..] == "GenericProcMethod") =>
|
||||
{
|
||||
true
|
||||
}
|
||||
(Type::Mono(n), Subr(_)) if &n[..] == "GenericCallable" => true,
|
||||
(Subr(ls), Subr(rs))
|
||||
if ls.kind.same_kind_as(&rs.kind)
|
||||
&& (ls.kind == SubrKind::Func || ls.kind == SubrKind::Proc) =>
|
||||
|
@ -2909,17 +3030,6 @@ impl Context {
|
|||
.all(|(l, r)| self.subtype_of(&l.ty, &r.ty, bounds, lhs_variance))
|
||||
// contravariant
|
||||
}
|
||||
(Type::Array { t: lhs, len: llen }, Type::Array { t: rhs, len: rlen }) => {
|
||||
self.eq_tp(llen, rlen, bounds, lhs_variance)
|
||||
&& self.formal_supertype_of(lhs, rhs, bounds, lhs_variance)
|
||||
}
|
||||
(Tuple(lhs), Tuple(rhs)) => {
|
||||
lhs.len() == rhs.len()
|
||||
&& lhs
|
||||
.iter()
|
||||
.zip(rhs.iter())
|
||||
.all(|(l, r)| self.formal_supertype_of(l, r, bounds, lhs_variance))
|
||||
}
|
||||
// RefMut, OptionMut are invariant
|
||||
(Ref(lhs), Ref(rhs)) | (VarArgs(lhs), VarArgs(rhs)) => {
|
||||
self.formal_supertype_of(lhs, rhs, bounds, lhs_variance)
|
||||
|
@ -3445,7 +3555,7 @@ impl Context {
|
|||
) {
|
||||
(true, true) | (true, false) => Some(rhs),
|
||||
(false, true) => Some(lhs),
|
||||
_ => None,
|
||||
(false, false) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3453,7 +3563,7 @@ impl Context {
|
|||
match self.min(lhs, rhs) {
|
||||
Some(l) if l == lhs => TyParamOrdering::Less,
|
||||
Some(_) => TyParamOrdering::Greater,
|
||||
None => todo!(),
|
||||
None => todo!("{lhs}, {rhs}"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3462,6 +3572,13 @@ impl Context {
|
|||
ts.min_by(|(_, lhs), (_, rhs)| self.cmp_t(lhs, rhs).try_into().unwrap())
|
||||
}
|
||||
|
||||
fn smallest_t<I: Iterator<Item = Type>>(&self, ts: I) -> Option<Type> {
|
||||
ts.min_by(|lhs, rhs| {
|
||||
let cmp = self.cmp_t(lhs, rhs);
|
||||
cmp.try_into().unwrap_or_else(|_| panic!("{cmp:?}"))
|
||||
})
|
||||
}
|
||||
|
||||
fn smallest_ref_t<'t, I: Iterator<Item = &'t Type>>(&self, ts: I) -> Option<&'t Type> {
|
||||
ts.min_by(|lhs, rhs| self.cmp_t(lhs, rhs).try_into().unwrap())
|
||||
}
|
||||
|
@ -3656,6 +3773,17 @@ impl Context {
|
|||
None
|
||||
}
|
||||
|
||||
fn rec_get_trait_impls(&self, name: &Str) -> Vec<Type> {
|
||||
let impls = if let Some(impls) = self.poly_trait_impls.get(name) {
|
||||
impls.clone()
|
||||
} else { vec![] };
|
||||
if let Some(outer) = &self.outer {
|
||||
[impls, outer.rec_get_trait_impls(name)].concat()
|
||||
} else {
|
||||
impls
|
||||
}
|
||||
}
|
||||
|
||||
// 再帰サブルーチン/型の推論を可能にするため、予め登録しておく
|
||||
pub(crate) fn preregister(&mut self, block: &Vec<ast::Expr>) -> TyCheckResult<()> {
|
||||
for expr in block.iter() {
|
||||
|
|
|
@ -307,23 +307,23 @@ impl Evaluator {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn eval_t(
|
||||
pub(crate) fn eval_t_params(
|
||||
&self,
|
||||
substituted: Type,
|
||||
ctx: &Context,
|
||||
level: usize,
|
||||
) -> EvalResult<Type> {
|
||||
match substituted {
|
||||
Type::FreeVar(fv) if fv.is_linked() => self.eval_t(fv.crack().clone(), ctx, level),
|
||||
Type::FreeVar(fv) if fv.is_linked() => self.eval_t_params(fv.crack().clone(), ctx, level),
|
||||
Type::Subr(mut subr) => {
|
||||
let kind = match subr.kind {
|
||||
SubrKind::FuncMethod(self_t) => {
|
||||
SubrKind::fn_met(self.eval_t(*self_t, ctx, level)?)
|
||||
SubrKind::fn_met(self.eval_t_params(*self_t, ctx, level)?)
|
||||
}
|
||||
SubrKind::ProcMethod { before, after } => {
|
||||
let before = self.eval_t(*before, ctx, level)?;
|
||||
let before = self.eval_t_params(*before, ctx, level)?;
|
||||
if let Some(after) = after {
|
||||
let after = self.eval_t(*after, ctx, level)?;
|
||||
let after = self.eval_t_params(*after, ctx, level)?;
|
||||
SubrKind::pr_met(before, Some(after))
|
||||
} else {
|
||||
SubrKind::pr_met(before, None)
|
||||
|
@ -332,12 +332,12 @@ impl Evaluator {
|
|||
other => other,
|
||||
};
|
||||
for p in subr.non_default_params.iter_mut() {
|
||||
p.ty = self.eval_t(mem::take(&mut p.ty), ctx, level)?;
|
||||
p.ty = self.eval_t_params(mem::take(&mut p.ty), ctx, level)?;
|
||||
}
|
||||
for p in subr.default_params.iter_mut() {
|
||||
p.ty = self.eval_t(mem::take(&mut p.ty), ctx, level)?;
|
||||
p.ty = self.eval_t_params(mem::take(&mut p.ty), ctx, level)?;
|
||||
}
|
||||
let return_t = self.eval_t(*subr.return_t, ctx, level)?;
|
||||
let return_t = self.eval_t_params(*subr.return_t, ctx, level)?;
|
||||
Ok(Type::subr(
|
||||
kind,
|
||||
subr.non_default_params,
|
||||
|
@ -345,11 +345,6 @@ impl Evaluator {
|
|||
return_t,
|
||||
))
|
||||
}
|
||||
Type::Array { t, len } => {
|
||||
let t = self.eval_t(*t, ctx, level)?;
|
||||
let len = self.eval_tp(&len, ctx)?;
|
||||
Ok(Type::array(t, len))
|
||||
}
|
||||
Type::Refinement(refine) => {
|
||||
let mut preds = Set::with_capacity(refine.preds.len());
|
||||
for pred in refine.preds.into_iter() {
|
||||
|
@ -364,7 +359,7 @@ impl Evaluator {
|
|||
if let ConstObj::Type(quant_t) = obj {
|
||||
let subst_ctx = SubstContext::new(&lhs, ty_ctx);
|
||||
let t = subst_ctx.substitute(*quant_t, ty_ctx, level)?;
|
||||
let t = self.eval_t(t, ctx, level)?;
|
||||
let t = self.eval_t_params(t, ctx, level)?;
|
||||
return Ok(t);
|
||||
} else {
|
||||
todo!()
|
||||
|
@ -373,9 +368,9 @@ impl Evaluator {
|
|||
}
|
||||
todo!()
|
||||
}
|
||||
Type::Ref(l) => Ok(Type::refer(self.eval_t(*l, ctx, level)?)),
|
||||
Type::RefMut(l) => Ok(Type::ref_mut(self.eval_t(*l, ctx, level)?)),
|
||||
Type::VarArgs(l) => Ok(Type::var_args(self.eval_t(*l, ctx, level)?)),
|
||||
Type::Ref(l) => Ok(Type::refer(self.eval_t_params(*l, ctx, level)?)),
|
||||
Type::RefMut(l) => Ok(Type::ref_mut(self.eval_t_params(*l, ctx, level)?)),
|
||||
Type::VarArgs(l) => Ok(Type::var_args(self.eval_t_params(*l, ctx, level)?)),
|
||||
Type::Poly { name, mut params } => {
|
||||
for p in params.iter_mut() {
|
||||
*p = self.eval_tp(&mem::take(p), ctx)?;
|
||||
|
@ -395,21 +390,21 @@ impl Evaluator {
|
|||
) -> EvalResult<TyBound> {
|
||||
match bound {
|
||||
TyBound::Subtype { sub, sup } => Ok(TyBound::subtype(
|
||||
self.eval_t(sub, ctx, level)?,
|
||||
self.eval_t(sup, ctx, level)?,
|
||||
self.eval_t_params(sub, ctx, level)?,
|
||||
self.eval_t_params(sup, ctx, level)?,
|
||||
)),
|
||||
TyBound::Supertype { sup, sub } => Ok(TyBound::supertype(
|
||||
self.eval_t(sup, ctx, level)?,
|
||||
self.eval_t(sub, ctx, level)?,
|
||||
self.eval_t_params(sup, ctx, level)?,
|
||||
self.eval_t_params(sub, ctx, level)?,
|
||||
)),
|
||||
TyBound::Sandwiched { sub, mid, sup } => {
|
||||
let sub = self.eval_t(sub, ctx, level)?;
|
||||
let mid = self.eval_t(mid, ctx, level)?;
|
||||
let sup = self.eval_t(sup, ctx, level)?;
|
||||
let sub = self.eval_t_params(sub, ctx, level)?;
|
||||
let mid = self.eval_t_params(mid, ctx, level)?;
|
||||
let sup = self.eval_t_params(sup, ctx, level)?;
|
||||
Ok(TyBound::sandwiched(sub, mid, sup))
|
||||
}
|
||||
TyBound::Instance { name: inst, t } => {
|
||||
Ok(TyBound::instance(inst, self.eval_t(t, ctx, level)?))
|
||||
Ok(TyBound::instance(inst, self.eval_t_params(t, ctx, level)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,18 @@ impl Context {
|
|||
let name = VarName::from_str(Str::rc(t.name()));
|
||||
self.locals
|
||||
.insert(name, VarInfo::new(Type, muty, Private, Builtin));
|
||||
for impl_trait in ctx.super_traits.iter() {
|
||||
if !impl_trait.is_monomorphic() {
|
||||
if let Some(impls) = self.poly_trait_impls.get_mut(impl_trait.name()) {
|
||||
impls.push(impl_trait.clone());
|
||||
} else {
|
||||
self.poly_trait_impls.insert(
|
||||
Str::rc(impl_trait.name()),
|
||||
vec![impl_trait.clone()],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.types.insert(t, ctx);
|
||||
}
|
||||
}
|
||||
|
@ -135,37 +147,49 @@ impl Context {
|
|||
let (r_bound, o_bound) = (static_instance("R", Type), static_instance("O", Type));
|
||||
let params = vec![PS::t("R", WithDefault), PS::t("O", WithDefault)];
|
||||
let ty_params = vec![mono_q_tp("R"), mono_q_tp("O")];
|
||||
let mut add_ro = Self::poly_trait("Add", params.clone(), vec![], Self::TOP_LEVEL);
|
||||
let mut add = Self::poly_trait("Add", params.clone(), vec![
|
||||
poly("Output", vec![ty_tp(mono_q("R"))]),
|
||||
poly("Output", vec![ty_tp(mono_q("O"))]),
|
||||
], Self::TOP_LEVEL);
|
||||
let self_bound = subtype(
|
||||
poly_q("Self", ty_params.clone()),
|
||||
poly("Add", ty_params.clone()),
|
||||
);
|
||||
let op_t = fn1_met(poly_q("Self", ty_params.clone()), r.clone(), o.clone());
|
||||
let op_t = quant(op_t, set! {r_bound.clone(), o_bound.clone(), self_bound});
|
||||
add_ro.register_decl("__add__", op_t, Public);
|
||||
let mut sub_ro = Self::poly_trait("Sub", params.clone(), vec![], Self::TOP_LEVEL);
|
||||
add.register_decl("__add__", op_t, Public);
|
||||
let mut sub = Self::poly_trait("Sub", params.clone(), vec![
|
||||
poly("Output", vec![ty_tp(mono_q("R"))]),
|
||||
poly("Output", vec![ty_tp(mono_q("O"))]),
|
||||
], Self::TOP_LEVEL);
|
||||
let self_bound = subtype(
|
||||
poly_q("Self", ty_params.clone()),
|
||||
poly("Sub", ty_params.clone()),
|
||||
);
|
||||
let op_t = fn1_met(poly_q("Self", ty_params.clone()), r.clone(), o.clone());
|
||||
let op_t = quant(op_t, set! {r_bound.clone(), o_bound.clone(), self_bound});
|
||||
sub_ro.register_decl("__sub__", op_t, Public);
|
||||
let mut mul_ro = Self::poly_trait("Mul", params.clone(), vec![], Self::TOP_LEVEL);
|
||||
sub.register_decl("__sub__", op_t, Public);
|
||||
let mut mul = Self::poly_trait("Mul", params.clone(), vec![
|
||||
poly("Output", vec![ty_tp(mono_q("R"))]),
|
||||
poly("Output", vec![ty_tp(mono_q("O"))]),
|
||||
], Self::TOP_LEVEL);
|
||||
let op_t = fn1_met(poly("Mul", ty_params.clone()), r.clone(), o.clone());
|
||||
mul_ro.register_decl("__mul__", op_t, Public);
|
||||
let mut div_ro = Self::poly_trait("Div", params.clone(), vec![], Self::TOP_LEVEL);
|
||||
mul.register_decl("__mul__", op_t, Public);
|
||||
let mut div = Self::poly_trait("Div", params.clone(), vec![
|
||||
poly("Output", vec![ty_tp(mono_q("R"))]),
|
||||
poly("Output", vec![ty_tp(mono_q("O"))]),
|
||||
], Self::TOP_LEVEL);
|
||||
let op_t = fn1_met(poly("Div", ty_params.clone()), r, o);
|
||||
div_ro.register_decl("__div__", op_t, Public);
|
||||
let sup = poly(
|
||||
div.register_decl("__div__", op_t, Public);
|
||||
/*let sup = poly(
|
||||
"Add",
|
||||
vec![
|
||||
mono_q_tp("Self"),
|
||||
TyParam::mono_proj(mono_q_tp("Self"), "AddO"),
|
||||
],
|
||||
);
|
||||
let mut add = Self::mono_trait("Add", vec![sup], Self::TOP_LEVEL);
|
||||
add.register_decl("AddO", Type, Public);
|
||||
let mut closed_add = Self::mono_trait("SelfAdd", vec![sup], Self::TOP_LEVEL);
|
||||
closed_add.register_decl("AddO", Type, Public);
|
||||
let sup = poly(
|
||||
"Sub",
|
||||
vec![
|
||||
|
@ -173,8 +197,8 @@ impl Context {
|
|||
TyParam::mono_proj(mono_q_tp("Self"), "SubO"),
|
||||
],
|
||||
);
|
||||
let mut sub = Self::mono_trait("Sub", vec![sup], Self::TOP_LEVEL);
|
||||
sub.register_decl("SubO", Type, Public);
|
||||
let mut closed_sub = Self::mono_trait("SelfSub", vec![sup], Self::TOP_LEVEL);
|
||||
closed_sub.register_decl("SubO", Type, Public);
|
||||
let sup = poly(
|
||||
"Mul",
|
||||
vec![
|
||||
|
@ -182,8 +206,8 @@ impl Context {
|
|||
TyParam::mono_proj(mono_q_tp("Self"), "MulO"),
|
||||
],
|
||||
);
|
||||
let mut mul = Self::mono_trait("Mul", vec![sup], Self::TOP_LEVEL);
|
||||
mul.register_decl("MulO", Type, Public);
|
||||
let mut closed_mul = Self::mono_trait("SelfMul", vec![sup], Self::TOP_LEVEL);
|
||||
closed_mul.register_decl("MulO", Type, Public);
|
||||
let sup = Type::poly(
|
||||
"Div",
|
||||
vec![
|
||||
|
@ -191,18 +215,19 @@ impl Context {
|
|||
TyParam::mono_proj(mono_q_tp("Self"), "DivO"),
|
||||
],
|
||||
);
|
||||
let mut div = Self::mono_trait("Div", vec![sup], Self::TOP_LEVEL);
|
||||
div.register_decl("DivO", Type, Public);
|
||||
let mut closed_div = Self::mono_trait("SelfDiv", vec![sup], Self::TOP_LEVEL);
|
||||
closed_div.register_decl("DivO", Type, Public);
|
||||
*/
|
||||
self.register_type(mono("Named"), named, Const);
|
||||
self.register_type(poly("Eq", vec![ty_tp(mono_q("R"))]), eq, Const);
|
||||
self.register_type(poly("Ord", vec![ty_tp(mono_q("R"))]), ord, Const);
|
||||
self.register_type(poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Const);
|
||||
self.register_type(poly("Input", vec![ty_tp(mono_q("T"))]), input, Const);
|
||||
self.register_type(poly("Output", vec![ty_tp(mono_q("T"))]), output, Const);
|
||||
self.register_type(poly("Add", ty_params.clone()), add_ro, Const);
|
||||
self.register_type(poly("Sub", ty_params.clone()), sub_ro, Const);
|
||||
self.register_type(poly("Mul", ty_params.clone()), mul_ro, Const);
|
||||
self.register_type(poly("Div", ty_params), div_ro, Const);
|
||||
self.register_type(poly("Add", ty_params.clone()), add, Const);
|
||||
self.register_type(poly("Sub", ty_params.clone()), sub, Const);
|
||||
self.register_type(poly("Mul", ty_params.clone()), mul, Const);
|
||||
self.register_type(poly("Div", ty_params), div, Const);
|
||||
// self.register_type(mono("Num"), num, Const);
|
||||
}
|
||||
|
||||
|
@ -277,15 +302,15 @@ impl Context {
|
|||
"Int",
|
||||
vec![Obj],
|
||||
vec![
|
||||
poly("Add", vec![ty_tp(Int), ty_tp(Int)]),
|
||||
poly("Sub", vec![ty_tp(Int), ty_tp(Int)]),
|
||||
poly("Mul", vec![ty_tp(Int), ty_tp(Int)]),
|
||||
poly("Div", vec![ty_tp(Int), ty_tp(Ratio)]),
|
||||
mono("Num"),
|
||||
mono("Rational"),
|
||||
mono("Integral"),
|
||||
mono("Ord"),
|
||||
mono("Eq"),
|
||||
mono("Add"),
|
||||
mono("Sub"),
|
||||
mono("Mul"),
|
||||
mono("Div"),
|
||||
// mono("SelfOrd"),
|
||||
// mono("SelfEq"),
|
||||
mono("Mutate"),
|
||||
],
|
||||
Self::TOP_LEVEL,
|
||||
|
@ -298,29 +323,20 @@ impl Context {
|
|||
int.register_impl("__mul__", op_t, Const, Public);
|
||||
int.register_impl("Real", Int, Const, Public);
|
||||
int.register_impl("Imag", Int, Const, Public);
|
||||
int.super_traits
|
||||
.push(poly("Add", vec![ty_tp(Int), ty_tp(Int)]));
|
||||
int.super_traits
|
||||
.push(poly("Sub", vec![ty_tp(Int), ty_tp(Int)]));
|
||||
int.super_traits
|
||||
.push(poly("Mul", vec![ty_tp(Int), ty_tp(Int)]));
|
||||
int.super_traits
|
||||
.push(poly("Div", vec![ty_tp(Int), ty_tp(Ratio)]));
|
||||
let mut nat = Self::mono_class(
|
||||
"Nat",
|
||||
vec![Int, Obj],
|
||||
vec![
|
||||
poly("Add", vec![ty_tp(Nat), ty_tp(Nat)]),
|
||||
poly("Sub", vec![ty_tp(Nat), ty_tp(Int)]),
|
||||
poly("Mul", vec![ty_tp(Nat), ty_tp(Nat)]),
|
||||
poly("Div", vec![ty_tp(Nat), ty_tp(Ratio)]),
|
||||
mono("Num"),
|
||||
mono("Rational"),
|
||||
mono("Integral"),
|
||||
mono("Ord"),
|
||||
mono("Eq"),
|
||||
mono("Add"),
|
||||
mono("Sub"),
|
||||
mono("Mul"),
|
||||
mono("Div"),
|
||||
// mono("SelfOrd"),
|
||||
// mono("SelfEq"),
|
||||
mono("Mutate"),
|
||||
Obj,
|
||||
],
|
||||
Self::TOP_LEVEL,
|
||||
);
|
||||
|
@ -342,14 +358,6 @@ impl Context {
|
|||
);
|
||||
nat.register_impl("Real", Nat, Const, Public);
|
||||
nat.register_impl("Imag", Nat, Const, Public);
|
||||
nat.super_traits
|
||||
.push(poly("Add", vec![ty_tp(Nat), ty_tp(Nat)]));
|
||||
nat.super_traits
|
||||
.push(poly("Sub", vec![ty_tp(Nat), ty_tp(Nat)]));
|
||||
nat.super_traits
|
||||
.push(poly("Mul", vec![ty_tp(Nat), ty_tp(Nat)]));
|
||||
nat.super_traits
|
||||
.push(poly("Div", vec![ty_tp(Nat), ty_tp(Ratio)]));
|
||||
let mut bool_ = Self::mono_class(
|
||||
"Bool",
|
||||
vec![Nat, Int, Obj],
|
||||
|
@ -357,14 +365,13 @@ impl Context {
|
|||
mono("Num"),
|
||||
mono("Rational"),
|
||||
mono("Integral"),
|
||||
mono("Ord"),
|
||||
mono("Eq"),
|
||||
mono("Add"),
|
||||
mono("Sub"),
|
||||
mono("Mul"),
|
||||
mono("Div"),
|
||||
// mono("SelfOrd"),
|
||||
// mono("SelfEq"),
|
||||
// mono("SelfAdd"),
|
||||
// mono("SelfSub"),
|
||||
// mono("SelfMul"),
|
||||
// mono("SelfDiv"),
|
||||
mono("Mutate"),
|
||||
Obj,
|
||||
],
|
||||
Self::TOP_LEVEL,
|
||||
);
|
||||
|
@ -373,7 +380,7 @@ impl Context {
|
|||
let mut str_ = Self::mono_class(
|
||||
"Str",
|
||||
vec![Obj],
|
||||
vec![mono("Eq"), mono("Mutate"), poly("Seq", vec![ty_tp(Str)])],
|
||||
vec![mono("Eq"), mono("Mutate"), poly("Seq", vec![ty_tp(Str)]), poly("Add", vec![ty_tp(Str), ty_tp(Str)])],
|
||||
Self::TOP_LEVEL,
|
||||
);
|
||||
str_.register_impl("__add__", fn1_met(Str, Str, Str), Const, Public);
|
||||
|
@ -388,8 +395,6 @@ impl Context {
|
|||
Immutable,
|
||||
Public,
|
||||
);
|
||||
str_.super_traits
|
||||
.push(poly("Add", vec![ty_tp(Str), ty_tp(Str)]));
|
||||
let mut array = Self::poly_class(
|
||||
"Array",
|
||||
vec![PS::t_nd("T"), PS::named_nd("N", Nat)],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue