WIP: Impl Context::monomorphise

Impled: TyVarContext::sort_bounds
This commit is contained in:
Shunsuke Shibayama 2022-08-15 03:39:45 +09:00
parent 4a4b346199
commit 6d3dda8129
6 changed files with 462 additions and 325 deletions

View file

@ -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(),

View file

@ -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,
}
}

View file

@ -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);

View file

@ -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!(&params);
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() {

View file

@ -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)?))
}
}
}

View file

@ -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)],