Fix import to be called from anywhere

This commit is contained in:
Shunsuke Shibayama 2022-09-29 11:48:38 +09:00
parent f548f9e6ef
commit 23a6f630c9
21 changed files with 979 additions and 549 deletions

View file

@ -4,7 +4,7 @@
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::{stdin, BufRead, BufReader, Read}; use std::io::{stdin, BufRead, BufReader, Read};
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::process; use std::process;
use std::str::FromStr; use std::str::FromStr;
@ -35,7 +35,7 @@ impl Input {
pub fn enclosed_name(&self) -> &str { pub fn enclosed_name(&self) -> &str {
match self { match self {
Self::File(filename) => filename.as_os_str().to_str().unwrap_or("???"), Self::File(filename) => filename.to_str().unwrap_or("???"),
Self::REPL | Self::Pipe(_) => "<stdin>", Self::REPL | Self::Pipe(_) => "<stdin>",
Self::Str(_) => "<string>", Self::Str(_) => "<string>",
Self::Dummy => "<dummy>", Self::Dummy => "<dummy>",
@ -45,7 +45,7 @@ impl Input {
/// ファイルに書き出すとき使う /// ファイルに書き出すとき使う
pub fn filename(&self) -> &str { pub fn filename(&self) -> &str {
match self { match self {
Self::File(filename) => filename.as_os_str().to_str().unwrap_or("???"), Self::File(filename) => filename.to_str().unwrap_or("???"),
Self::REPL | Self::Pipe(_) => "stdin", Self::REPL | Self::Pipe(_) => "stdin",
Self::Str(_) => "string", Self::Str(_) => "string",
Self::Dummy => "dummy", Self::Dummy => "dummy",
@ -116,6 +116,21 @@ impl Input {
Self::Dummy => panic!("cannot read from a dummy file"), Self::Dummy => panic!("cannot read from a dummy file"),
} }
} }
pub fn resolve(&self, path: &Path) -> Result<PathBuf, std::io::Error> {
let mut dir = if let Self::File(mut path) = self.clone() {
path.pop();
path
} else {
PathBuf::new()
};
dir.push(path);
dir.set_extension("er");
dir.canonicalize().or_else(|_| {
dir.set_extension("d.er");
dir.canonicalize()
})
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -594,11 +594,11 @@ impl Context {
(Ref(l), r) => self.supertype_of(l, r), (Ref(l), r) => self.supertype_of(l, r),
(RefMut { before: l, .. }, r) => self.supertype_of(l, r), (RefMut { before: l, .. }, r) => self.supertype_of(l, r),
( (
Poly { BuiltinPoly {
name: ln, name: ln,
params: lparams, params: lparams,
}, },
Poly { BuiltinPoly {
name: rn, name: rn,
params: rparams, params: rparams,
}, },
@ -608,6 +608,23 @@ impl Context {
} }
self.poly_supertype_of(lhs, lparams, rparams) self.poly_supertype_of(lhs, lparams, rparams)
} }
(
Poly {
path: lp,
name: ln,
params: lparams,
},
Poly {
path: rp,
name: rn,
params: rparams,
},
) => {
if lp != rp || ln != rn || lparams.len() != rparams.len() {
return false;
}
self.poly_supertype_of(lhs, lparams, rparams)
}
(MonoQVar(name), r) | (PolyQVar { name, .. }, r) => { (MonoQVar(name), r) | (PolyQVar { name, .. }, r) => {
panic!("internal error: not instantiated type variable: '{name}, r: {r}") panic!("internal error: not instantiated type variable: '{name}, r: {r}")
} }

View file

@ -14,7 +14,7 @@ use erg_parser::ast::*;
use erg_parser::token::{Token, TokenKind}; use erg_parser::token::{Token, TokenKind};
use erg_type::constructors::{ use erg_type::constructors::{
builtin_mono, enum_t, mono_proj, poly, ref_, ref_mut, refinement, subr_t, builtin_mono, builtin_poly, mono_proj, poly, ref_, ref_mut, refinement, subr_t, v_enum,
}; };
use erg_type::typaram::{OpKind, TyParam}; use erg_type::typaram::{OpKind, TyParam};
use erg_type::value::ValueObj; use erg_type::value::ValueObj;
@ -305,7 +305,7 @@ impl Context {
match subr { match subr {
ConstSubr::User(_user) => todo!(), ConstSubr::User(_user) => todo!(),
ConstSubr::Builtin(builtin) => builtin ConstSubr::Builtin(builtin) => builtin
.call(args, self.mod_name().clone(), __name__) .call(args, self.path().to_path_buf(), __name__)
.map_err(|mut e| { .map_err(|mut e| {
e.loc = loc; e.loc = loc;
EvalErrors::from(EvalError::new(e, self.cfg.input.clone(), self.caused_by())) EvalErrors::from(EvalError::new(e, self.cfg.input.clone(), self.caused_by()))
@ -445,7 +445,7 @@ impl Context {
non_default_params.clone(), non_default_params.clone(),
var_params.clone(), var_params.clone(),
default_params.clone(), default_params.clone(),
enum_t(set![return_t.clone()]), v_enum(set![return_t.clone()]),
); );
let sig_t = self.generalize_t(sig_t); let sig_t = self.generalize_t(sig_t);
let as_type = subr_t( let as_type = subr_t(
@ -791,11 +791,21 @@ impl Context {
}; };
Ok(ref_mut(before, after)) Ok(ref_mut(before, after))
} }
Type::Poly { name, mut params } => { Type::BuiltinPoly { name, mut params } => {
for p in params.iter_mut() { for p in params.iter_mut() {
*p = self.eval_tp(&mem::take(p))?; *p = self.eval_tp(&mem::take(p))?;
} }
Ok(poly(name, params)) Ok(builtin_poly(name, params))
}
Type::Poly {
path,
name,
mut params,
} => {
for p in params.iter_mut() {
*p = self.eval_tp(&mem::take(p))?;
}
Ok(poly(path, name, params))
} }
other if other.is_monomorphic() => Ok(other), other if other.is_monomorphic() => Ok(other),
other => todo!("{other}"), other => todo!("{other}"),
@ -839,7 +849,7 @@ impl Context {
let p = self.eval_tp(p)?; let p = self.eval_tp(p)?;
match p { match p {
TyParam::Value(ValueObj::Mut(v)) => Ok(v.borrow().class().mutate()), TyParam::Value(ValueObj::Mut(v)) => Ok(v.borrow().class().mutate()),
TyParam::Value(v) => Ok(enum_t(set![v])), TyParam::Value(v) => Ok(v_enum(set![v])),
TyParam::Erased(t) => Ok((*t).clone()), TyParam::Erased(t) => Ok((*t).clone()),
TyParam::FreeVar(fv) => { TyParam::FreeVar(fv) => {
if let Some(t) = fv.get_type() { if let Some(t) = fv.get_type() {
@ -852,7 +862,7 @@ impl Context {
TyParam::Type(_) => Ok(Type::Type), TyParam::Type(_) => Ok(Type::Type),
TyParam::Mono(name) => self TyParam::Mono(name) => self
.rec_get_const_obj(&name) .rec_get_const_obj(&name)
.map(|v| enum_t(set![v.clone()])) .map(|v| v_enum(set![v.clone()]))
.ok_or_else(|| { .ok_or_else(|| {
EvalErrors::from(EvalError::unreachable( EvalErrors::from(EvalError::unreachable(
self.cfg.input.clone(), self.cfg.input.clone(),

View file

@ -1,4 +1,5 @@
use std::mem; use std::mem;
use std::path::PathBuf;
use erg_common::Str; use erg_common::Str;
@ -12,7 +13,7 @@ use erg_type::ValueArgs;
/// Requirement: Type, Impl := Type -> ClassType /// Requirement: Type, Impl := Type -> ClassType
pub fn class_func( pub fn class_func(
mut args: ValueArgs, mut args: ValueArgs,
mod_name: Str, path: PathBuf,
__name__: Option<Str>, __name__: Option<Str>,
) -> EvalValueResult<ValueObj> { ) -> EvalValueResult<ValueObj> {
let require = args.remove_left_or_key("Requirement").ok_or_else(|| { let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
@ -39,14 +40,14 @@ pub fn class_func(
}; };
let impls = args.remove_left_or_key("Impl"); let impls = args.remove_left_or_key("Impl");
let impls = impls.map(|v| v.as_type().unwrap()); let impls = impls.map(|v| v.as_type().unwrap());
let t = mono(mod_name, __name__.unwrap_or(Str::ever("<Lambda>"))); let t = mono(path, __name__.unwrap_or(Str::ever("<Lambda>")));
Ok(ValueObj::gen_t(TypeKind::Class, t, require, impls, None)) Ok(ValueObj::gen_t(TypeKind::Class, t, require, impls, None))
} }
/// Super: ClassType, Impl := Type, Additional := Type -> ClassType /// Super: ClassType, Impl := Type, Additional := Type -> ClassType
pub fn inherit_func( pub fn inherit_func(
mut args: ValueArgs, mut args: ValueArgs,
mod_name: Str, path: PathBuf,
__name__: Option<Str>, __name__: Option<Str>,
) -> EvalValueResult<ValueObj> { ) -> EvalValueResult<ValueObj> {
let sup = args.remove_left_or_key("Super").ok_or_else(|| { let sup = args.remove_left_or_key("Super").ok_or_else(|| {
@ -75,7 +76,7 @@ pub fn inherit_func(
let impls = impls.map(|v| v.as_type().unwrap()); let impls = impls.map(|v| v.as_type().unwrap());
let additional = args.remove_left_or_key("Additional"); let additional = args.remove_left_or_key("Additional");
let additional = additional.map(|v| v.as_type().unwrap()); let additional = additional.map(|v| v.as_type().unwrap());
let t = mono(mod_name, __name__.unwrap_or(Str::ever("<Lambda>"))); let t = mono(path, __name__.unwrap_or(Str::ever("<Lambda>")));
Ok(ValueObj::gen_t( Ok(ValueObj::gen_t(
TypeKind::Subclass, TypeKind::Subclass,
t, t,
@ -89,7 +90,7 @@ pub fn inherit_func(
/// This function is used by the compiler to mark a class as inheritable and does nothing in terms of actual operation. /// This function is used by the compiler to mark a class as inheritable and does nothing in terms of actual operation.
pub fn inheritable_func( pub fn inheritable_func(
mut args: ValueArgs, mut args: ValueArgs,
_mod_name: Str, _path: PathBuf,
__name__: Option<Str>, __name__: Option<Str>,
) -> EvalValueResult<ValueObj> { ) -> EvalValueResult<ValueObj> {
let class = args.remove_left_or_key("Class").ok_or_else(|| { let class = args.remove_left_or_key("Class").ok_or_else(|| {
@ -124,7 +125,7 @@ pub fn inheritable_func(
/// Requirement: Type, Impl := Type -> TraitType /// Requirement: Type, Impl := Type -> TraitType
pub fn trait_func( pub fn trait_func(
mut args: ValueArgs, mut args: ValueArgs,
mod_name: Str, path: PathBuf,
__name__: Option<Str>, __name__: Option<Str>,
) -> EvalValueResult<ValueObj> { ) -> EvalValueResult<ValueObj> {
let require = args.remove_left_or_key("Requirement").ok_or_else(|| { let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
@ -151,14 +152,14 @@ pub fn trait_func(
}; };
let impls = args.remove_left_or_key("Impl"); let impls = args.remove_left_or_key("Impl");
let impls = impls.map(|v| v.as_type().unwrap()); let impls = impls.map(|v| v.as_type().unwrap());
let t = mono(mod_name, __name__.unwrap_or(Str::ever("<Lambda>"))); let t = mono(path, __name__.unwrap_or(Str::ever("<Lambda>")));
Ok(ValueObj::gen_t(TypeKind::Trait, t, require, impls, None)) Ok(ValueObj::gen_t(TypeKind::Trait, t, require, impls, None))
} }
/// Super: TraitType, Impl := Type, Additional := Type -> TraitType /// Super: TraitType, Impl := Type, Additional := Type -> TraitType
pub fn subsume_func( pub fn subsume_func(
mut args: ValueArgs, mut args: ValueArgs,
mod_name: Str, path: PathBuf,
__name__: Option<Str>, __name__: Option<Str>,
) -> EvalValueResult<ValueObj> { ) -> EvalValueResult<ValueObj> {
let sup = args.remove_left_or_key("Super").ok_or_else(|| { let sup = args.remove_left_or_key("Super").ok_or_else(|| {
@ -187,7 +188,7 @@ pub fn subsume_func(
let impls = impls.map(|v| v.as_type().unwrap()); let impls = impls.map(|v| v.as_type().unwrap());
let additional = args.remove_left_or_key("Additional"); let additional = args.remove_left_or_key("Additional");
let additional = additional.map(|v| v.as_type().unwrap()); let additional = additional.map(|v| v.as_type().unwrap());
let t = mono(mod_name, __name__.unwrap_or(Str::ever("<Lambda>"))); let t = mono(path, __name__.unwrap_or(Str::ever("<Lambda>")));
Ok(ValueObj::gen_t( Ok(ValueObj::gen_t(
TypeKind::Subtrait, TypeKind::Subtrait,
t, t,

View file

@ -4,6 +4,8 @@
pub mod const_func; pub mod const_func;
pub mod py_mods; pub mod py_mods;
use std::path::PathBuf;
use erg_common::config::ErgConfig; use erg_common::config::ErgConfig;
use erg_common::error::Location; use erg_common::error::Location;
use erg_common::vis::Visibility; use erg_common::vis::Visibility;
@ -61,7 +63,7 @@ impl Context {
panic!("already registered: {name}"); panic!("already registered: {name}");
} else { } else {
// TODO: not all value objects are comparable // TODO: not all value objects are comparable
let vi = VarInfo::new(enum_t(set! {obj.clone()}), Const, Private, Builtin, None); let vi = VarInfo::new(v_enum(set! {obj.clone()}), Const, Private, Builtin, None);
self.consts.insert(VarName::from_str(Str::rc(name)), obj); self.consts.insert(VarName::from_str(Str::rc(name)), obj);
self.locals.insert(VarName::from_str(Str::rc(name)), vi); self.locals.insert(VarName::from_str(Str::rc(name)), vi);
} }
@ -206,31 +208,31 @@ impl Context {
let params = vec![PS::t("T", NonDefault)]; let params = vec![PS::t("T", NonDefault)];
let input = Self::builtin_poly_trait("Input", params.clone(), 2); let input = Self::builtin_poly_trait("Input", params.clone(), 2);
let output = Self::builtin_poly_trait("Output", params, 2); let output = Self::builtin_poly_trait("Output", params, 2);
in_.register_superclass(poly("Input", vec![ty_tp(mono_q("T"))]), &input); in_.register_superclass(builtin_poly("Input", vec![ty_tp(mono_q("T"))]), &input);
let op_t = fn1_met(mono_q("T"), mono_q("I"), Bool); let op_t = fn1_met(mono_q("T"), mono_q("I"), Bool);
let op_t = quant( let op_t = quant(
op_t, op_t,
set! { static_instance("T", Type), subtypeof(mono_q("I"), poly("In", vec![ty_tp(mono_q("T"))])) }, set! { static_instance("T", Type), subtypeof(mono_q("I"), builtin_poly("In", vec![ty_tp(mono_q("T"))])) },
); );
in_.register_builtin_decl("__in__", op_t, Public); in_.register_builtin_decl("__in__", op_t, Public);
// Erg does not have a trait equivalent to `PartialEq` in Rust // Erg does not have a trait equivalent to `PartialEq` in Rust
// This means, Erg's `Float` cannot be compared with other `Float` // This means, Erg's `Float` cannot be compared with other `Float`
// use `l - r < EPSILON` to check if two floats are almost equal // use `l - r < EPSILON` to check if two floats are almost equal
let mut eq = Self::builtin_poly_trait("Eq", vec![PS::t("R", WithDefault)], 2); let mut eq = Self::builtin_poly_trait("Eq", vec![PS::t("R", WithDefault)], 2);
eq.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); eq.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output);
// __eq__: |Self <: Eq()| Self.(Self) -> Bool // __eq__: |Self <: Eq()| Self.(Self) -> Bool
let op_t = fn1_met(mono_q("Self"), mono_q("R"), Bool); let op_t = fn1_met(mono_q("Self"), mono_q("R"), Bool);
let op_t = quant( let op_t = quant(
op_t, op_t,
set! { set! {
subtypeof(mono_q("Self"), poly("Eq", vec![ty_tp(mono_q("R"))])), subtypeof(mono_q("Self"), builtin_poly("Eq", vec![ty_tp(mono_q("R"))])),
static_instance("R", Type) static_instance("R", Type)
}, },
); );
eq.register_builtin_decl("__eq__", op_t, Public); eq.register_builtin_decl("__eq__", op_t, Public);
let mut partial_ord = let mut partial_ord =
Self::builtin_poly_trait("PartialOrd", vec![PS::t("R", WithDefault)], 2); Self::builtin_poly_trait("PartialOrd", vec![PS::t("R", WithDefault)], 2);
partial_ord.register_superclass(poly("Eq", vec![ty_tp(mono_q("R"))]), &eq); partial_ord.register_superclass(builtin_poly("Eq", vec![ty_tp(mono_q("R"))]), &eq);
let op_t = fn1_met( let op_t = fn1_met(
mono_q("Self"), mono_q("Self"),
mono_q("R"), mono_q("R"),
@ -239,15 +241,15 @@ impl Context {
let op_t = quant( let op_t = quant(
op_t, op_t,
set! { set! {
subtypeof(mono_q("Self"), poly("PartialOrd", vec![ty_tp(mono_q("R"))])), subtypeof(mono_q("Self"), builtin_poly("PartialOrd", vec![ty_tp(mono_q("R"))])),
static_instance("R", Type) static_instance("R", Type)
}, },
); );
partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public); partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public);
let mut ord = Self::builtin_mono_trait("Ord", 2); let mut ord = Self::builtin_mono_trait("Ord", 2);
ord.register_superclass(poly("Eq", vec![ty_tp(builtin_mono("Self"))]), &eq); ord.register_superclass(builtin_poly("Eq", vec![ty_tp(builtin_mono("Self"))]), &eq);
ord.register_superclass( ord.register_superclass(
poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]), builtin_poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]),
&partial_ord, &partial_ord,
); );
// FIXME: poly trait // FIXME: poly trait
@ -258,18 +260,18 @@ impl Context {
poly("Mul", vec![]), poly("Mul", vec![]),
], */ ], */
let mut seq = Self::builtin_poly_trait("Seq", vec![PS::t("T", NonDefault)], 2); let mut seq = Self::builtin_poly_trait("Seq", vec![PS::t("T", NonDefault)], 2);
seq.register_superclass(poly("Output", vec![ty_tp(mono_q("T"))]), &output); seq.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("T"))]), &output);
let self_t = mono_q("Self"); let self_t = mono_q("Self");
let t = fn0_met(self_t.clone(), Nat); let t = fn0_met(self_t.clone(), Nat);
let t = quant( let t = quant(
t, t,
set! {subtypeof(self_t.clone(), poly("Seq", vec![TyParam::erased(Type)]))}, set! {subtypeof(self_t.clone(), builtin_poly("Seq", vec![TyParam::erased(Type)]))},
); );
seq.register_builtin_decl("len", t, Public); seq.register_builtin_decl("len", t, Public);
let t = fn1_met(self_t.clone(), Nat, mono_q("T")); let t = fn1_met(self_t.clone(), Nat, mono_q("T"));
let t = quant( let t = quant(
t, t,
set! {subtypeof(self_t, poly("Seq", vec![ty_tp(mono_q("T"))])), static_instance("T", Type)}, set! {subtypeof(self_t, builtin_poly("Seq", vec![ty_tp(mono_q("T"))])), static_instance("T", Type)},
); );
// Seq.get: |Self <: Seq(T)| Self.(Nat) -> T // Seq.get: |Self <: Seq(T)| Self.(Nat) -> T
seq.register_builtin_decl("get", t, Public); seq.register_builtin_decl("get", t, Public);
@ -279,8 +281,8 @@ impl Context {
let ty_params = vec![ty_tp(mono_q("R"))]; let ty_params = vec![ty_tp(mono_q("R"))];
let mut add = Self::builtin_poly_trait("Add", params.clone(), 2); let mut add = Self::builtin_poly_trait("Add", params.clone(), 2);
// Rについて共変(__add__の型とは関係ない) // Rについて共変(__add__の型とは関係ない)
add.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); add.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output);
let self_bound = subtypeof(mono_q("Self"), poly("Add", ty_params.clone())); let self_bound = subtypeof(mono_q("Self"), builtin_poly("Add", ty_params.clone()));
let op_t = fn1_met( let op_t = fn1_met(
mono_q("Self"), mono_q("Self"),
r.clone(), r.clone(),
@ -290,31 +292,31 @@ impl Context {
add.register_builtin_decl("__add__", op_t, Public); add.register_builtin_decl("__add__", op_t, Public);
add.register_builtin_decl("Output", Type, Public); add.register_builtin_decl("Output", Type, Public);
let mut sub = Self::builtin_poly_trait("Sub", params.clone(), 2); let mut sub = Self::builtin_poly_trait("Sub", params.clone(), 2);
sub.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); sub.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output);
let op_t = fn1_met( let op_t = fn1_met(
mono_q("Self"), mono_q("Self"),
r.clone(), r.clone(),
mono_proj(mono_q("Self"), "Output"), mono_proj(mono_q("Self"), "Output"),
); );
let self_bound = subtypeof(mono_q("Self"), poly("Sub", ty_params.clone())); let self_bound = subtypeof(mono_q("Self"), builtin_poly("Sub", ty_params.clone()));
let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
sub.register_builtin_decl("__sub__", op_t, Public); sub.register_builtin_decl("__sub__", op_t, Public);
sub.register_builtin_decl("Output", Type, Public); sub.register_builtin_decl("Output", Type, Public);
let mut mul = Self::builtin_poly_trait("Mul", params.clone(), 2); let mut mul = Self::builtin_poly_trait("Mul", params.clone(), 2);
mul.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); mul.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output);
let op_t = fn1_met( let op_t = fn1_met(
mono_q("Self"), mono_q("Self"),
r.clone(), r.clone(),
mono_proj(mono_q("Self"), "Output"), mono_proj(mono_q("Self"), "Output"),
); );
let self_bound = subtypeof(mono_q("Self"), poly("Mul", ty_params.clone())); let self_bound = subtypeof(mono_q("Self"), builtin_poly("Mul", ty_params.clone()));
let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
mul.register_builtin_decl("__mul__", op_t, Public); mul.register_builtin_decl("__mul__", op_t, Public);
mul.register_builtin_decl("Output", Type, Public); mul.register_builtin_decl("Output", Type, Public);
let mut div = Self::builtin_poly_trait("Div", params, 2); let mut div = Self::builtin_poly_trait("Div", params, 2);
div.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); div.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output);
let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "Output")); let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "Output"));
let self_bound = subtypeof(mono_q("Self"), poly("Div", ty_params.clone())); let self_bound = subtypeof(mono_q("Self"), builtin_poly("Div", ty_params.clone()));
let op_t = quant(op_t, set! {r_bound, self_bound}); let op_t = quant(op_t, set! {r_bound, self_bound});
div.register_builtin_decl("__div__", op_t, Public); div.register_builtin_decl("__div__", op_t, Public);
div.register_builtin_decl("Output", Type, Public); div.register_builtin_decl("Output", Type, Public);
@ -324,22 +326,30 @@ impl Context {
self.register_builtin_type(builtin_mono("Mutable"), mutable, Const); self.register_builtin_type(builtin_mono("Mutable"), mutable, Const);
self.register_builtin_type(builtin_mono("Immutizable"), immutizable, Const); self.register_builtin_type(builtin_mono("Immutizable"), immutizable, Const);
self.register_builtin_type(builtin_mono("Mutizable"), mutizable, Const); self.register_builtin_type(builtin_mono("Mutizable"), mutizable, Const);
self.register_builtin_type(poly("Input", vec![ty_tp(mono_q("T"))]), input, Const);
self.register_builtin_type(poly("Output", vec![ty_tp(mono_q("T"))]), output, Const);
self.register_builtin_type(poly("In", vec![ty_tp(mono_q("T"))]), in_, Const);
self.register_builtin_type(poly("Eq", vec![ty_tp(mono_q("R"))]), eq, Const);
self.register_builtin_type( self.register_builtin_type(
poly("PartialOrd", vec![ty_tp(mono_q("R"))]), builtin_poly("Input", vec![ty_tp(mono_q("T"))]),
input,
Const,
);
self.register_builtin_type(
builtin_poly("Output", vec![ty_tp(mono_q("T"))]),
output,
Const,
);
self.register_builtin_type(builtin_poly("In", vec![ty_tp(mono_q("T"))]), in_, Const);
self.register_builtin_type(builtin_poly("Eq", vec![ty_tp(mono_q("R"))]), eq, Const);
self.register_builtin_type(
builtin_poly("PartialOrd", vec![ty_tp(mono_q("R"))]),
partial_ord, partial_ord,
Const, Const,
); );
self.register_builtin_type(builtin_mono("Ord"), ord, Const); self.register_builtin_type(builtin_mono("Ord"), ord, Const);
self.register_builtin_type(builtin_mono("Num"), num, Const); self.register_builtin_type(builtin_mono("Num"), num, Const);
self.register_builtin_type(poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Const); self.register_builtin_type(builtin_poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Const);
self.register_builtin_type(poly("Add", ty_params.clone()), add, Const); self.register_builtin_type(builtin_poly("Add", ty_params.clone()), add, Const);
self.register_builtin_type(poly("Sub", ty_params.clone()), sub, Const); self.register_builtin_type(builtin_poly("Sub", ty_params.clone()), sub, Const);
self.register_builtin_type(poly("Mul", ty_params.clone()), mul, Const); self.register_builtin_type(builtin_poly("Mul", ty_params.clone()), mul, Const);
self.register_builtin_type(poly("Div", ty_params), div, Const); self.register_builtin_type(builtin_poly("Div", ty_params), div, Const);
self.register_const_param_defaults( self.register_const_param_defaults(
"Eq", "Eq",
vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))], vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))],
@ -384,7 +394,7 @@ impl Context {
); );
let mut obj_in = Self::builtin_methods("In", 2); let mut obj_in = Self::builtin_methods("In", 2);
obj_in.register_builtin_impl("__in__", fn1_met(Obj, Type, Bool), Const, Public); obj_in.register_builtin_impl("__in__", fn1_met(Obj, Type, Bool), Const, Public);
obj.register_trait(Obj, poly("Eq", vec![ty_tp(Type)]), obj_in); obj.register_trait(Obj, builtin_poly("Eq", vec![ty_tp(Type)]), obj_in);
let mut obj_mutizable = Self::builtin_methods("Mutizable", 1); let mut obj_mutizable = Self::builtin_methods("Mutizable", 1);
obj_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Obj!"))); obj_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Obj!")));
obj.register_trait(Obj, builtin_mono("Mutizable"), obj_mutizable); obj.register_trait(Obj, builtin_mono("Mutizable"), obj_mutizable);
@ -405,7 +415,7 @@ impl Context {
); );
float.register_trait( float.register_trait(
Float, Float,
poly("PartialOrd", vec![ty_tp(Float)]), builtin_poly("PartialOrd", vec![ty_tp(Float)]),
float_partial_ord, float_partial_ord,
); );
// Float doesn't have an `Eq` implementation // Float doesn't have an `Eq` implementation
@ -413,21 +423,21 @@ impl Context {
let mut float_add = Self::builtin_methods("Add", 2); let mut float_add = Self::builtin_methods("Add", 2);
float_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); float_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
float_add.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_add.register_builtin_const("Output", ValueObj::builtin_t(Float));
float.register_trait(Float, poly("Add", vec![ty_tp(Float)]), float_add); float.register_trait(Float, builtin_poly("Add", vec![ty_tp(Float)]), float_add);
let mut float_sub = Self::builtin_methods("Sub", 2); let mut float_sub = Self::builtin_methods("Sub", 2);
float_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); float_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
float_sub.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_sub.register_builtin_const("Output", ValueObj::builtin_t(Float));
float.register_trait(Float, poly("Sub", vec![ty_tp(Float)]), float_sub); float.register_trait(Float, builtin_poly("Sub", vec![ty_tp(Float)]), float_sub);
let mut float_mul = Self::builtin_methods("Mul", 2); let mut float_mul = Self::builtin_methods("Mul", 2);
float_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public); float_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public);
float_mul.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_mul.register_builtin_const("Output", ValueObj::builtin_t(Float));
float_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Float)); float_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Float));
float.register_trait(Float, poly("Mul", vec![ty_tp(Float)]), float_mul); float.register_trait(Float, builtin_poly("Mul", vec![ty_tp(Float)]), float_mul);
let mut float_div = Self::builtin_methods("Div", 2); let mut float_div = Self::builtin_methods("Div", 2);
float_div.register_builtin_impl("__div__", op_t, Const, Public); float_div.register_builtin_impl("__div__", op_t, Const, Public);
float_div.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_div.register_builtin_const("Output", ValueObj::builtin_t(Float));
float_div.register_builtin_const("ModOutput", ValueObj::builtin_t(Float)); float_div.register_builtin_const("ModOutput", ValueObj::builtin_t(Float));
float.register_trait(Float, poly("Div", vec![ty_tp(Float)]), float_div); float.register_trait(Float, builtin_poly("Div", vec![ty_tp(Float)]), float_div);
let mut float_mutizable = Self::builtin_methods("Mutizable", 2); let mut float_mutizable = Self::builtin_methods("Mutizable", 2);
float_mutizable float_mutizable
.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Float!"))); .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Float!")));
@ -448,31 +458,31 @@ impl Context {
); );
ratio.register_trait( ratio.register_trait(
Ratio, Ratio,
poly("PartialOrd", vec![ty_tp(Ratio)]), builtin_poly("PartialOrd", vec![ty_tp(Ratio)]),
ratio_partial_ord, ratio_partial_ord,
); );
let mut ratio_eq = Self::builtin_methods("Eq", 2); let mut ratio_eq = Self::builtin_methods("Eq", 2);
ratio_eq.register_builtin_impl("__eq__", fn1_met(Ratio, Ratio, Bool), Const, Public); ratio_eq.register_builtin_impl("__eq__", fn1_met(Ratio, Ratio, Bool), Const, Public);
ratio.register_trait(Ratio, poly("Eq", vec![ty_tp(Ratio)]), ratio_eq); ratio.register_trait(Ratio, builtin_poly("Eq", vec![ty_tp(Ratio)]), ratio_eq);
let op_t = fn1_met(Ratio, Ratio, Ratio); let op_t = fn1_met(Ratio, Ratio, Ratio);
let mut ratio_add = Self::builtin_methods("Add", 2); let mut ratio_add = Self::builtin_methods("Add", 2);
ratio_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); ratio_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
ratio_add.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_add.register_builtin_const("Output", ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("Add", vec![ty_tp(Ratio)]), ratio_add); ratio.register_trait(Ratio, builtin_poly("Add", vec![ty_tp(Ratio)]), ratio_add);
let mut ratio_sub = Self::builtin_methods("Sub", 2); let mut ratio_sub = Self::builtin_methods("Sub", 2);
ratio_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); ratio_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
ratio_sub.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_sub.register_builtin_const("Output", ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("Sub", vec![ty_tp(Ratio)]), ratio_sub); ratio.register_trait(Ratio, builtin_poly("Sub", vec![ty_tp(Ratio)]), ratio_sub);
let mut ratio_mul = Self::builtin_methods("Mul", 2); let mut ratio_mul = Self::builtin_methods("Mul", 2);
ratio_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public); ratio_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public);
ratio_mul.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_mul.register_builtin_const("Output", ValueObj::builtin_t(Ratio));
ratio_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Ratio)); ratio_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("Mul", vec![ty_tp(Ratio)]), ratio_mul); ratio.register_trait(Ratio, builtin_poly("Mul", vec![ty_tp(Ratio)]), ratio_mul);
let mut ratio_div = Self::builtin_methods("Div", 2); let mut ratio_div = Self::builtin_methods("Div", 2);
ratio_div.register_builtin_impl("__div__", op_t, Const, Public); ratio_div.register_builtin_impl("__div__", op_t, Const, Public);
ratio_div.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_div.register_builtin_const("Output", ValueObj::builtin_t(Ratio));
ratio_div.register_builtin_const("ModOutput", ValueObj::builtin_t(Ratio)); ratio_div.register_builtin_const("ModOutput", ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("Div", vec![ty_tp(Ratio)]), ratio_div); ratio.register_trait(Ratio, builtin_poly("Div", vec![ty_tp(Ratio)]), ratio_div);
let mut ratio_mutizable = Self::builtin_methods("Mutizable", 2); let mut ratio_mutizable = Self::builtin_methods("Mutizable", 2);
ratio_mutizable ratio_mutizable
.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Ratio!"))); .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Ratio!")));
@ -482,7 +492,7 @@ impl Context {
int.register_superclass(Obj, &obj); int.register_superclass(Obj, &obj);
int.register_marker_trait(builtin_mono("Num")); int.register_marker_trait(builtin_mono("Num"));
int.register_marker_trait(builtin_mono("Ord")); int.register_marker_trait(builtin_mono("Ord"));
int.register_marker_trait(poly("Eq", vec![ty_tp(Int)])); int.register_marker_trait(builtin_poly("Eq", vec![ty_tp(Int)]));
// class("Rational"), // class("Rational"),
// class("Integral"), // class("Integral"),
int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public); int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public);
@ -493,25 +503,29 @@ impl Context {
Const, Const,
Public, Public,
); );
int.register_trait(Int, poly("PartialOrd", vec![ty_tp(Int)]), int_partial_ord); int.register_trait(
Int,
builtin_poly("PartialOrd", vec![ty_tp(Int)]),
int_partial_ord,
);
let mut int_eq = Self::builtin_methods("Eq", 2); let mut int_eq = Self::builtin_methods("Eq", 2);
int_eq.register_builtin_impl("__eq__", fn1_met(Int, Int, Bool), Const, Public); int_eq.register_builtin_impl("__eq__", fn1_met(Int, Int, Bool), Const, Public);
int.register_trait(Int, poly("Eq", vec![ty_tp(Int)]), int_eq); int.register_trait(Int, builtin_poly("Eq", vec![ty_tp(Int)]), int_eq);
// __div__ is not included in Int (cast to Ratio) // __div__ is not included in Int (cast to Ratio)
let op_t = fn1_met(Int, Int, Int); let op_t = fn1_met(Int, Int, Int);
let mut int_add = Self::builtin_methods("Add", 2); let mut int_add = Self::builtin_methods("Add", 2);
int_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); int_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
int_add.register_builtin_const("Output", ValueObj::builtin_t(Int)); int_add.register_builtin_const("Output", ValueObj::builtin_t(Int));
int.register_trait(Int, poly("Add", vec![ty_tp(Int)]), int_add); int.register_trait(Int, builtin_poly("Add", vec![ty_tp(Int)]), int_add);
let mut int_sub = Self::builtin_methods("Sub", 2); let mut int_sub = Self::builtin_methods("Sub", 2);
int_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); int_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
int_sub.register_builtin_const("Output", ValueObj::builtin_t(Int)); int_sub.register_builtin_const("Output", ValueObj::builtin_t(Int));
int.register_trait(Int, poly("Sub", vec![ty_tp(Int)]), int_sub); int.register_trait(Int, builtin_poly("Sub", vec![ty_tp(Int)]), int_sub);
let mut int_mul = Self::builtin_methods("Mul", 2); let mut int_mul = Self::builtin_methods("Mul", 2);
int_mul.register_builtin_impl("__mul__", op_t, Const, Public); int_mul.register_builtin_impl("__mul__", op_t, Const, Public);
int_mul.register_builtin_const("Output", ValueObj::builtin_t(Int)); int_mul.register_builtin_const("Output", ValueObj::builtin_t(Int));
int_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Nat)); int_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Nat));
int.register_trait(Int, poly("Mul", vec![ty_tp(Int)]), int_mul); int.register_trait(Int, builtin_poly("Mul", vec![ty_tp(Int)]), int_mul);
let mut int_mutizable = Self::builtin_methods("Mutizable", 2); let mut int_mutizable = Self::builtin_methods("Mutizable", 2);
int_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Int!"))); int_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Int!")));
int.register_trait(Int, builtin_mono("Mutizable"), int_mutizable); int.register_trait(Int, builtin_mono("Mutizable"), int_mutizable);
@ -539,7 +553,7 @@ impl Context {
nat.register_marker_trait(builtin_mono("Ord")); nat.register_marker_trait(builtin_mono("Ord"));
let mut nat_eq = Self::builtin_methods("Eq", 2); let mut nat_eq = Self::builtin_methods("Eq", 2);
nat_eq.register_builtin_impl("__eq__", fn1_met(Nat, Nat, Bool), Const, Public); nat_eq.register_builtin_impl("__eq__", fn1_met(Nat, Nat, Bool), Const, Public);
nat.register_trait(Nat, poly("Eq", vec![ty_tp(Nat)]), nat_eq); nat.register_trait(Nat, builtin_poly("Eq", vec![ty_tp(Nat)]), nat_eq);
let mut nat_partial_ord = Self::builtin_methods("PartialOrd", 2); let mut nat_partial_ord = Self::builtin_methods("PartialOrd", 2);
nat_partial_ord.register_builtin_impl( nat_partial_ord.register_builtin_impl(
"__cmp__", "__cmp__",
@ -547,17 +561,21 @@ impl Context {
Const, Const,
Public, Public,
); );
nat.register_trait(Nat, poly("PartialOrd", vec![ty_tp(Nat)]), nat_partial_ord); nat.register_trait(
Nat,
builtin_poly("PartialOrd", vec![ty_tp(Nat)]),
nat_partial_ord,
);
// __sub__, __div__ is not included in Nat (cast to Int/ Ratio) // __sub__, __div__ is not included in Nat (cast to Int/ Ratio)
let op_t = fn1_met(Nat, Nat, Nat); let op_t = fn1_met(Nat, Nat, Nat);
let mut nat_add = Self::builtin_methods("Add", 2); let mut nat_add = Self::builtin_methods("Add", 2);
nat_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); nat_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
nat_add.register_builtin_const("Output", ValueObj::builtin_t(Nat)); nat_add.register_builtin_const("Output", ValueObj::builtin_t(Nat));
nat.register_trait(Nat, poly("Add", vec![ty_tp(Nat)]), nat_add); nat.register_trait(Nat, builtin_poly("Add", vec![ty_tp(Nat)]), nat_add);
let mut nat_mul = Self::builtin_methods("Mul", 2); let mut nat_mul = Self::builtin_methods("Mul", 2);
nat_mul.register_builtin_impl("__mul__", op_t, Const, Public); nat_mul.register_builtin_impl("__mul__", op_t, Const, Public);
nat_mul.register_builtin_const("Output", ValueObj::builtin_t(Nat)); nat_mul.register_builtin_const("Output", ValueObj::builtin_t(Nat));
nat.register_trait(Nat, poly("Mul", vec![ty_tp(Nat)]), nat_mul); nat.register_trait(Nat, builtin_poly("Mul", vec![ty_tp(Nat)]), nat_mul);
let mut nat_mutizable = Self::builtin_methods("Mutizable", 2); let mut nat_mutizable = Self::builtin_methods("Mutizable", 2);
nat_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Nat!"))); nat_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Nat!")));
nat.register_trait(Nat, builtin_mono("Mutizable"), nat_mutizable); nat.register_trait(Nat, builtin_mono("Mutizable"), nat_mutizable);
@ -584,16 +602,16 @@ impl Context {
); );
bool_.register_trait( bool_.register_trait(
Bool, Bool,
poly("PartialOrd", vec![ty_tp(Bool)]), builtin_poly("PartialOrd", vec![ty_tp(Bool)]),
bool_partial_ord, bool_partial_ord,
); );
let mut bool_eq = Self::builtin_methods("Eq", 2); let mut bool_eq = Self::builtin_methods("Eq", 2);
bool_eq.register_builtin_impl("__eq__", fn1_met(Bool, Bool, Bool), Const, Public); bool_eq.register_builtin_impl("__eq__", fn1_met(Bool, Bool, Bool), Const, Public);
bool_.register_trait(Bool, poly("Eq", vec![ty_tp(Bool)]), bool_eq); bool_.register_trait(Bool, builtin_poly("Eq", vec![ty_tp(Bool)]), bool_eq);
let mut bool_add = Self::builtin_methods("Add", 2); let mut bool_add = Self::builtin_methods("Add", 2);
bool_add.register_builtin_impl("__add__", fn1_met(Bool, Bool, Int), Const, Public); bool_add.register_builtin_impl("__add__", fn1_met(Bool, Bool, Int), Const, Public);
bool_add.register_builtin_const("Output", ValueObj::builtin_t(Nat)); bool_add.register_builtin_const("Output", ValueObj::builtin_t(Nat));
bool_.register_trait(Bool, poly("Add", vec![ty_tp(Bool)]), bool_add); bool_.register_trait(Bool, builtin_poly("Add", vec![ty_tp(Bool)]), bool_add);
let mut bool_mutizable = Self::builtin_methods("Mutizable", 2); let mut bool_mutizable = Self::builtin_methods("Mutizable", 2);
bool_mutizable bool_mutizable
.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Bool!"))); .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Bool!")));
@ -627,19 +645,19 @@ impl Context {
); );
let mut str_eq = Self::builtin_methods("Eq", 2); let mut str_eq = Self::builtin_methods("Eq", 2);
str_eq.register_builtin_impl("__eq__", fn1_met(Str, Str, Bool), Const, Public); str_eq.register_builtin_impl("__eq__", fn1_met(Str, Str, Bool), Const, Public);
str_.register_trait(Str, poly("Eq", vec![ty_tp(Str)]), str_eq); str_.register_trait(Str, builtin_poly("Eq", vec![ty_tp(Str)]), str_eq);
let mut str_seq = Self::builtin_methods("Seq", 2); let mut str_seq = Self::builtin_methods("Seq", 2);
str_seq.register_builtin_impl("len", fn0_met(Str, Nat), Const, Public); str_seq.register_builtin_impl("len", fn0_met(Str, Nat), Const, Public);
str_seq.register_builtin_impl("get", fn1_met(Str, Nat, Str), Const, Public); str_seq.register_builtin_impl("get", fn1_met(Str, Nat, Str), Const, Public);
str_.register_trait(Str, poly("Seq", vec![ty_tp(Str)]), str_seq); str_.register_trait(Str, builtin_poly("Seq", vec![ty_tp(Str)]), str_seq);
let mut str_add = Self::builtin_methods("Add", 2); let mut str_add = Self::builtin_methods("Add", 2);
str_add.register_builtin_impl("__add__", fn1_met(Str, Str, Str), Const, Public); str_add.register_builtin_impl("__add__", fn1_met(Str, Str, Str), Const, Public);
str_add.register_builtin_const("Output", ValueObj::builtin_t(Str)); str_add.register_builtin_const("Output", ValueObj::builtin_t(Str));
str_.register_trait(Str, poly("Add", vec![ty_tp(Str)]), str_add); str_.register_trait(Str, builtin_poly("Add", vec![ty_tp(Str)]), str_add);
let mut str_mul = Self::builtin_methods("Mul", 2); let mut str_mul = Self::builtin_methods("Mul", 2);
str_mul.register_builtin_impl("__mul__", fn1_met(Str, Nat, Str), Const, Public); str_mul.register_builtin_impl("__mul__", fn1_met(Str, Nat, Str), Const, Public);
str_mul.register_builtin_const("Output", ValueObj::builtin_t(Str)); str_mul.register_builtin_const("Output", ValueObj::builtin_t(Str));
str_.register_trait(Str, poly("Mul", vec![ty_tp(Nat)]), str_mul); str_.register_trait(Str, builtin_poly("Mul", vec![ty_tp(Nat)]), str_mul);
let mut str_mutizable = Self::builtin_methods("Mutizable", 2); let mut str_mutizable = Self::builtin_methods("Mutizable", 2);
str_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Str!"))); str_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Str!")));
str_.register_trait(Str, builtin_mono("Mutizable"), str_mutizable); str_.register_trait(Str, builtin_mono("Mutizable"), str_mutizable);
@ -649,24 +667,37 @@ impl Context {
type_.register_marker_trait(builtin_mono("Named")); type_.register_marker_trait(builtin_mono("Named"));
let mut type_eq = Self::builtin_methods("Eq", 2); let mut type_eq = Self::builtin_methods("Eq", 2);
type_eq.register_builtin_impl("__eq__", fn1_met(Type, Type, Bool), Const, Public); type_eq.register_builtin_impl("__eq__", fn1_met(Type, Type, Bool), Const, Public);
type_.register_trait(Type, poly("Eq", vec![ty_tp(Type)]), type_eq); type_.register_trait(Type, builtin_poly("Eq", vec![ty_tp(Type)]), type_eq);
let mut class_type = Self::builtin_mono_class("ClassType", 2); let mut class_type = Self::builtin_mono_class("ClassType", 2);
class_type.register_superclass(Type, &type_); class_type.register_superclass(Type, &type_);
class_type.register_superclass(Obj, &obj); class_type.register_superclass(Obj, &obj);
class_type.register_marker_trait(builtin_mono("Named")); class_type.register_marker_trait(builtin_mono("Named"));
let mut class_eq = Self::builtin_methods("Eq", 2); let mut class_eq = Self::builtin_methods("Eq", 2);
class_eq.register_builtin_impl("__eq__", fn1_met(Class, Class, Bool), Const, Public); class_eq.register_builtin_impl("__eq__", fn1_met(Class, Class, Bool), Const, Public);
class_type.register_trait(Class, poly("Eq", vec![ty_tp(Class)]), class_eq); class_type.register_trait(Class, builtin_poly("Eq", vec![ty_tp(Class)]), class_eq);
let mut module = Self::builtin_mono_class("Module", 2); let g_module_t = builtin_mono("GenericModule");
module.register_superclass(Obj, &obj); let mut generic_module = Self::builtin_mono_class("GenericModule", 2);
module.register_marker_trait(builtin_mono("Named")); generic_module.register_superclass(Obj, &obj);
let mut module_eq = Self::builtin_methods("Eq", 2); generic_module.register_marker_trait(builtin_mono("Named"));
module_eq.register_builtin_impl("__eq__", fn1_met(Module, Module, Bool), Const, Public); let mut generic_module_eq = Self::builtin_methods("Eq", 2);
module.register_trait(Module, poly("Eq", vec![ty_tp(Module)]), module_eq); generic_module_eq.register_builtin_impl(
"__eq__",
fn1_met(g_module_t.clone(), g_module_t.clone(), Bool),
Const,
Public,
);
generic_module.register_trait(
g_module_t.clone(),
builtin_poly("Eq", vec![ty_tp(g_module_t.clone())]),
generic_module_eq,
);
let module_t = module(mono_q_tp("Path"));
let mut module = Self::builtin_poly_class("Module", vec![PS::named_nd("Path", Str)], 2);
module.register_superclass(g_module_t.clone(), &generic_module);
let mut array_ = let mut array_ =
Self::builtin_poly_class("Array", vec![PS::t_nd("T"), PS::named_nd("N", Nat)], 10); Self::builtin_poly_class("Array", vec![PS::t_nd("T"), PS::named_nd("N", Nat)], 10);
array_.register_superclass(Obj, &obj); array_.register_superclass(Obj, &obj);
array_.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))])); array_.register_marker_trait(builtin_poly("Output", vec![ty_tp(mono_q("T"))]));
let n = mono_q_tp("N"); let n = mono_q_tp("N");
let m = mono_q_tp("M"); let m = mono_q_tp("M");
let array_t = array(mono_q("T"), n.clone()); let array_t = array(mono_q("T"), n.clone());
@ -682,7 +713,7 @@ impl Context {
set! {static_instance("N", Nat), static_instance("M", Nat)}, set! {static_instance("N", Nat), static_instance("M", Nat)},
); );
array_.register_builtin_impl("concat", t, Immutable, Public); array_.register_builtin_impl("concat", t, Immutable, Public);
let mut_type = ValueObj::builtin_t(poly( let mut_type = ValueObj::builtin_t(builtin_poly(
"Array!", "Array!",
vec![TyParam::t(mono_q("T")), TyParam::mono_q("N").mutate()], vec![TyParam::t(mono_q("T")), TyParam::mono_q("N").mutate()],
)); ));
@ -695,9 +726,13 @@ impl Context {
Const, Const,
Public, Public,
); );
array_.register_trait(array_t.clone(), poly("Eq", vec![ty_tp(array_t)]), array_eq); array_.register_trait(
array_t.clone(),
builtin_poly("Eq", vec![ty_tp(array_t)]),
array_eq,
);
array_.register_marker_trait(builtin_mono("Mutizable")); array_.register_marker_trait(builtin_mono("Mutizable"));
array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))])); array_.register_marker_trait(builtin_poly("Seq", vec![ty_tp(mono_q("T"))]));
// TODO: make Tuple6, Tuple7, ... etc. // TODO: make Tuple6, Tuple7, ... etc.
let mut tuple_ = Self::builtin_mono_class("Tuple", 2); let mut tuple_ = Self::builtin_mono_class("Tuple", 2);
tuple_.register_superclass(Obj, &obj); tuple_.register_superclass(Obj, &obj);
@ -710,7 +745,7 @@ impl Context {
); );
tuple_.register_trait( tuple_.register_trait(
builtin_mono("Tuple"), builtin_mono("Tuple"),
poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]), builtin_poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]),
tuple_eq, tuple_eq,
); );
let mut tuple1 = Self::builtin_poly_class("Tuple1", vec![PS::t_nd("A")], 2); let mut tuple1 = Self::builtin_poly_class("Tuple1", vec![PS::t_nd("A")], 2);
@ -720,16 +755,19 @@ impl Context {
tuple1_eq.register_builtin_impl( tuple1_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
poly("Tuple1", vec![ty_tp(mono_q("A"))]), builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]),
poly("Tuple1", vec![ty_tp(mono_q("A"))]), builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]),
Bool, Bool,
), ),
Const, Const,
Public, Public,
); );
tuple1.register_trait( tuple1.register_trait(
poly("Tuple1", vec![ty_tp(mono_q("A"))]), builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]),
poly("Eq", vec![ty_tp(poly("Tuple1", vec![ty_tp(mono_q("A"))]))]), builtin_poly(
"Eq",
vec![ty_tp(builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]))],
),
tuple1_eq, tuple1_eq,
); );
let mut tuple2 = Self::builtin_poly_class("Tuple2", vec![PS::t_nd("A"), PS::t_nd("B")], 2); let mut tuple2 = Self::builtin_poly_class("Tuple2", vec![PS::t_nd("A"), PS::t_nd("B")], 2);
@ -739,18 +777,18 @@ impl Context {
tuple2_eq.register_builtin_impl( tuple2_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), builtin_poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]),
poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), builtin_poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]),
Bool, Bool,
), ),
Const, Const,
Public, Public,
); );
tuple2.register_trait( tuple2.register_trait(
poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]), builtin_poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]),
poly( builtin_poly(
"Eq", "Eq",
vec![ty_tp(poly( vec![ty_tp(builtin_poly(
"Tuple2", "Tuple2",
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))], vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))],
))], ))],
@ -768,11 +806,11 @@ impl Context {
tuple3_eq.register_builtin_impl( tuple3_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
poly( builtin_poly(
"Tuple3", "Tuple3",
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))], vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))],
), ),
poly( builtin_poly(
"Tuple3", "Tuple3",
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))], vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))],
), ),
@ -782,13 +820,13 @@ impl Context {
Public, Public,
); );
tuple3.register_trait( tuple3.register_trait(
poly( builtin_poly(
"Tuple3", "Tuple3",
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))], vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))],
), ),
poly( builtin_poly(
"Eq", "Eq",
vec![ty_tp(poly( vec![ty_tp(builtin_poly(
"Tuple3", "Tuple3",
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))], vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))],
))], ))],
@ -806,7 +844,7 @@ impl Context {
tuple4_eq.register_builtin_impl( tuple4_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
poly( builtin_poly(
"Tuple4", "Tuple4",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -815,7 +853,7 @@ impl Context {
ty_tp(mono_q("D")), ty_tp(mono_q("D")),
], ],
), ),
poly( builtin_poly(
"Tuple4", "Tuple4",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -830,7 +868,7 @@ impl Context {
Public, Public,
); );
tuple4.register_trait( tuple4.register_trait(
poly( builtin_poly(
"Tuple4", "Tuple4",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -839,9 +877,9 @@ impl Context {
ty_tp(mono_q("D")), ty_tp(mono_q("D")),
], ],
), ),
poly( builtin_poly(
"Eq", "Eq",
vec![ty_tp(poly( vec![ty_tp(builtin_poly(
"Tuple4", "Tuple4",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -870,7 +908,7 @@ impl Context {
tuple5_eq.register_builtin_impl( tuple5_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
poly( builtin_poly(
"Tuple5", "Tuple5",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -880,7 +918,7 @@ impl Context {
ty_tp(mono_q("E")), ty_tp(mono_q("E")),
], ],
), ),
poly( builtin_poly(
"Tuple5", "Tuple5",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -896,7 +934,7 @@ impl Context {
Public, Public,
); );
tuple5.register_trait( tuple5.register_trait(
poly( builtin_poly(
"Tuple5", "Tuple5",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -906,9 +944,9 @@ impl Context {
ty_tp(mono_q("E")), ty_tp(mono_q("E")),
], ],
), ),
poly( builtin_poly(
"Eq", "Eq",
vec![ty_tp(poly( vec![ty_tp(builtin_poly(
"Tuple5", "Tuple5",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -939,7 +977,7 @@ impl Context {
tuple6_eq.register_builtin_impl( tuple6_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
poly( builtin_poly(
"Tuple6", "Tuple6",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -950,7 +988,7 @@ impl Context {
ty_tp(mono_q("F")), ty_tp(mono_q("F")),
], ],
), ),
poly( builtin_poly(
"Tuple6", "Tuple6",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -967,7 +1005,7 @@ impl Context {
Public, Public,
); );
tuple6.register_trait( tuple6.register_trait(
poly( builtin_poly(
"Tuple6", "Tuple6",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -978,9 +1016,9 @@ impl Context {
ty_tp(mono_q("F")), ty_tp(mono_q("F")),
], ],
), ),
poly( builtin_poly(
"Eq", "Eq",
vec![ty_tp(poly( vec![ty_tp(builtin_poly(
"Tuple6", "Tuple6",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1013,7 +1051,7 @@ impl Context {
tuple7_eq.register_builtin_impl( tuple7_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
poly( builtin_poly(
"Tuple7", "Tuple7",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1025,7 +1063,7 @@ impl Context {
ty_tp(mono_q("G")), ty_tp(mono_q("G")),
], ],
), ),
poly( builtin_poly(
"Tuple7", "Tuple7",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1043,7 +1081,7 @@ impl Context {
Public, Public,
); );
tuple7.register_trait( tuple7.register_trait(
poly( builtin_poly(
"Tuple7", "Tuple7",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1055,9 +1093,9 @@ impl Context {
ty_tp(mono_q("G")), ty_tp(mono_q("G")),
], ],
), ),
poly( builtin_poly(
"Eq", "Eq",
vec![ty_tp(poly( vec![ty_tp(builtin_poly(
"Tuple7", "Tuple7",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1092,7 +1130,7 @@ impl Context {
tuple8_eq.register_builtin_impl( tuple8_eq.register_builtin_impl(
"__eq__", "__eq__",
fn1_met( fn1_met(
poly( builtin_poly(
"Tuple8", "Tuple8",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1105,7 +1143,7 @@ impl Context {
ty_tp(mono_q("H")), ty_tp(mono_q("H")),
], ],
), ),
poly( builtin_poly(
"Tuple8", "Tuple8",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1124,7 +1162,7 @@ impl Context {
Public, Public,
); );
tuple8.register_trait( tuple8.register_trait(
poly( builtin_poly(
"Tuple8", "Tuple8",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1137,9 +1175,9 @@ impl Context {
ty_tp(mono_q("H")), ty_tp(mono_q("H")),
], ],
), ),
poly( builtin_poly(
"Eq", "Eq",
vec![ty_tp(poly( vec![ty_tp(builtin_poly(
"Tuple8", "Tuple8",
vec![ vec![
ty_tp(mono_q("A")), ty_tp(mono_q("A")),
@ -1289,8 +1327,8 @@ impl Context {
builtin_mono("Mutable"), builtin_mono("Mutable"),
str_mut_mutable, str_mut_mutable,
); );
let array_t = poly("Array", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); let array_t = builtin_poly("Array", vec![ty_tp(mono_q("T")), mono_q_tp("N")]);
let array_mut_t = poly("Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); let array_mut_t = builtin_poly("Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]);
let mut array_mut_ = Self::builtin_poly_class( let mut array_mut_ = Self::builtin_poly_class(
"Array!", "Array!",
vec![PS::t_nd("T"), PS::named_nd("N", builtin_mono("Nat!"))], vec![PS::t_nd("T"), PS::named_nd("N", builtin_mono("Nat!"))],
@ -1301,7 +1339,7 @@ impl Context {
let t = pr_met( let t = pr_met(
ref_mut( ref_mut(
array_mut_t.clone(), array_mut_t.clone(),
Some(poly( Some(builtin_poly(
"Array!", "Array!",
vec![ty_tp(mono_q("T")), mono_q_tp("N") + value(1)], vec![ty_tp(mono_q("T")), mono_q_tp("N") + value(1)],
)), )),
@ -1354,10 +1392,10 @@ impl Context {
builtin_mono("Mutable"), builtin_mono("Mutable"),
array_mut_mutable, array_mut_mutable,
); );
let range_t = poly("Range", vec![TyParam::t(mono_q("T"))]); let range_t = builtin_poly("Range", vec![TyParam::t(mono_q("T"))]);
let mut range = Self::builtin_poly_class("Range", vec![PS::t_nd("T")], 2); let mut range = Self::builtin_poly_class("Range", vec![PS::t_nd("T")], 2);
range.register_superclass(Obj, &obj); range.register_superclass(Obj, &obj);
range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))])); range.register_marker_trait(builtin_poly("Output", vec![ty_tp(mono_q("T"))]));
let mut range_eq = Self::builtin_methods("Eq", 2); let mut range_eq = Self::builtin_methods("Eq", 2);
range_eq.register_builtin_impl( range_eq.register_builtin_impl(
"__eq__", "__eq__",
@ -1367,7 +1405,7 @@ impl Context {
); );
range.register_trait( range.register_trait(
range_t.clone(), range_t.clone(),
poly("Eq", vec![ty_tp(range_t.clone())]), builtin_poly("Eq", vec![ty_tp(range_t.clone())]),
range_eq, range_eq,
); );
let mut proc = Self::builtin_mono_class("Proc", 2); let mut proc = Self::builtin_mono_class("Proc", 2);
@ -1392,7 +1430,8 @@ impl Context {
self.register_builtin_type(Str, str_, Const); self.register_builtin_type(Str, str_, Const);
self.register_builtin_type(Type, type_, Const); self.register_builtin_type(Type, type_, Const);
self.register_builtin_type(Class, class_type, Const); self.register_builtin_type(Class, class_type, Const);
self.register_builtin_type(Module, module, Const); self.register_builtin_type(g_module_t, generic_module, Const);
self.register_builtin_type(module_t, module, Const);
self.register_builtin_type(array_t, array_, Const); self.register_builtin_type(array_t, array_, Const);
self.register_builtin_type(tuple(vec![mono_q("A")]), tuple1, Const); self.register_builtin_type(tuple(vec![mono_q("A")]), tuple1, Const);
self.register_builtin_type(tuple(vec![mono_q("A"), mono_q("B")]), tuple2, Const); self.register_builtin_type(tuple(vec![mono_q("A"), mono_q("B")]), tuple2, Const);
@ -1504,7 +1543,12 @@ impl Context {
option(mono_q("T")), option(mono_q("T")),
); );
let t_if = quant(t_if, set! {static_instance("T", Type)}); let t_if = quant(t_if, set! {static_instance("T", Type)});
let t_import = nd_func(vec![param_t("path", Str)], None, Module); let t_import = nd_func(
vec![anon(tp_enum(Str, set! {mono_q_tp("Path")}))],
None,
module(mono_q_tp("Path")),
);
let t_import = quant(t_import, set! {static_instance("Path", Str)});
let t_log = func( let t_log = func(
vec![], vec![],
Some(param_t("objects", ref_(Obj))), Some(param_t("objects", ref_(Obj))),
@ -1516,7 +1560,12 @@ impl Context {
], ],
NoneType, NoneType,
); );
let t_pyimport = nd_func(vec![param_t("path", Str)], None, Module); let t_pyimport = nd_func(
vec![anon(tp_enum(Str, set! {mono_q_tp("Path")}))],
None,
module(mono_q_tp("Path")),
);
let t_pyimport = quant(t_pyimport, set! {static_instance("Path", Str)});
let t_quit = func(vec![], None, vec![param_t("code", Int)], NoneType); let t_quit = func(vec![], None, vec![param_t("code", Int)], NoneType);
self.register_builtin_impl("abs", t_abs, Immutable, Private); self.register_builtin_impl("abs", t_abs, Immutable, Private);
self.register_builtin_impl("assert", t_assert, Const, Private); // assert casting に悪影響が出る可能性があるため、Constとしておく self.register_builtin_impl("assert", t_assert, Const, Private); // assert casting に悪影響が出る可能性があるため、Constとしておく
@ -1658,7 +1707,7 @@ impl Context {
op_t, op_t,
set! { set! {
static_instance("R", Type), static_instance("R", Type),
subtypeof(l.clone(), poly("Add", params.clone())) subtypeof(l.clone(), builtin_poly("Add", params.clone()))
}, },
); );
self.register_builtin_impl("__add__", op_t, Const, Private); self.register_builtin_impl("__add__", op_t, Const, Private);
@ -1667,7 +1716,7 @@ impl Context {
op_t, op_t,
set! { set! {
static_instance("R", Type), static_instance("R", Type),
subtypeof(l.clone(), poly("Sub", params.clone())) subtypeof(l.clone(), builtin_poly("Sub", params.clone()))
}, },
); );
self.register_builtin_impl("__sub__", op_t, Const, Private); self.register_builtin_impl("__sub__", op_t, Const, Private);
@ -1676,7 +1725,7 @@ impl Context {
op_t, op_t,
set! { set! {
static_instance("R", Type), static_instance("R", Type),
subtypeof(l.clone(), poly("Mul", params.clone())) subtypeof(l.clone(), builtin_poly("Mul", params.clone()))
}, },
); );
self.register_builtin_impl("__mul__", op_t, Const, Private); self.register_builtin_impl("__mul__", op_t, Const, Private);
@ -1685,22 +1734,22 @@ impl Context {
op_t, op_t,
set! { set! {
static_instance("R", Type), static_instance("R", Type),
subtypeof(l.clone(), poly("Div", params.clone())) subtypeof(l.clone(), builtin_poly("Div", params.clone()))
}, },
); );
self.register_builtin_impl("__div__", op_t, Const, Private); self.register_builtin_impl("__div__", op_t, Const, Private);
let m = mono_q("M"); let m = mono_q("M");
let op_t = bin_op(m.clone(), m.clone(), mono_proj(m.clone(), "PowOutput")); let op_t = bin_op(m.clone(), m.clone(), mono_proj(m.clone(), "PowOutput"));
let op_t = quant(op_t, set! {subtypeof(m, poly("Mul", vec![]))}); let op_t = quant(op_t, set! {subtypeof(m, builtin_poly("Mul", vec![]))});
// TODO: add bound: M == M.Output // TODO: add bound: M == M.Output
self.register_builtin_impl("__pow__", op_t, Const, Private); self.register_builtin_impl("__pow__", op_t, Const, Private);
let d = mono_q("D"); let d = mono_q("D");
let op_t = bin_op(d.clone(), d.clone(), mono_proj(d.clone(), "ModOutput")); let op_t = bin_op(d.clone(), d.clone(), mono_proj(d.clone(), "ModOutput"));
let op_t = quant(op_t, set! {subtypeof(d, poly("Div", vec![]))}); let op_t = quant(op_t, set! {subtypeof(d, builtin_poly("Div", vec![]))});
self.register_builtin_impl("__mod__", op_t, Const, Private); self.register_builtin_impl("__mod__", op_t, Const, Private);
let e = mono_q("E"); let e = mono_q("E");
let op_t = bin_op(e.clone(), e.clone(), Bool); let op_t = bin_op(e.clone(), e.clone(), Bool);
let op_t = quant(op_t, set! {subtypeof(e, poly("Eq", vec![]))}); let op_t = quant(op_t, set! {subtypeof(e, builtin_poly("Eq", vec![]))});
self.register_builtin_impl("__eq__", op_t.clone(), Const, Private); self.register_builtin_impl("__eq__", op_t.clone(), Const, Private);
self.register_builtin_impl("__ne__", op_t, Const, Private); self.register_builtin_impl("__ne__", op_t, Const, Private);
let op_t = bin_op(l.clone(), r, Bool); let op_t = bin_op(l.clone(), r, Bool);
@ -1708,7 +1757,7 @@ impl Context {
op_t, op_t,
set! { set! {
static_instance("R", Type), static_instance("R", Type),
subtypeof(l, poly("PartialOrd", params)) subtypeof(l, builtin_poly("PartialOrd", params))
}, },
); );
self.register_builtin_impl("__lt__", op_t.clone(), Const, Private); self.register_builtin_impl("__lt__", op_t.clone(), Const, Private);
@ -1728,7 +1777,7 @@ impl Context {
let op_t = bin_op(mono_q("T"), mono_q("I"), Bool); let op_t = bin_op(mono_q("T"), mono_q("I"), Bool);
let op_t = quant( let op_t = quant(
op_t, op_t,
set! { static_instance("T", Type), subtypeof(mono_q("I"), poly("In", vec![ty_tp(mono_q("T"))])) }, set! { static_instance("T", Type), subtypeof(mono_q("I"), builtin_poly("In", vec![ty_tp(mono_q("T"))])) },
); );
self.register_builtin_impl("__in__", op_t, Const, Private); self.register_builtin_impl("__in__", op_t, Const, Private);
/* unary */ /* unary */
@ -1772,7 +1821,7 @@ impl Context {
); );
interval.register_trait( interval.register_trait(
Type::from(&m..=&n), Type::from(&m..=&n),
poly("Add", vec![TyParam::from(&o..=&p)]), builtin_poly("Add", vec![TyParam::from(&o..=&p)]),
interval_add, interval_add,
); );
let mut interval_sub = Self::builtin_methods("Sub", 2); let mut interval_sub = Self::builtin_methods("Sub", 2);
@ -1788,7 +1837,7 @@ impl Context {
); );
interval.register_trait( interval.register_trait(
Type::from(&m..=&n), Type::from(&m..=&n),
poly("Sub", vec![TyParam::from(&o..=&p)]), builtin_poly("Sub", vec![TyParam::from(&o..=&p)]),
interval_sub, interval_sub,
); );
self.register_builtin_patch("Interval", interval, Const); self.register_builtin_patch("Interval", interval, Const);
@ -1800,7 +1849,7 @@ impl Context {
pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) { pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) {
// TODO: capacityを正確に把握する // TODO: capacityを正確に把握する
let mut ctx = Context::module("<builtins>".into(), ErgConfig::default(), None, None, 40); let mut ctx = Context::builtin_module("<builtins>", 40);
ctx.init_builtin_funcs(); ctx.init_builtin_funcs();
ctx.init_builtin_const_funcs(); ctx.init_builtin_const_funcs();
ctx.init_builtin_procs(); ctx.init_builtin_procs();
@ -1808,7 +1857,7 @@ impl Context {
ctx.init_builtin_traits(); ctx.init_builtin_traits();
ctx.init_builtin_classes(); ctx.init_builtin_classes();
ctx.init_builtin_patches(); ctx.init_builtin_patches();
mod_cache.register(VarName::from_static("<builtins>"), None, ctx); mod_cache.register(PathBuf::from("<builtins>"), None, ctx);
} }
pub fn new_module<S: Into<Str>>( pub fn new_module<S: Into<Str>>(

View file

@ -1,6 +1,6 @@
use erg_common::vis::Visibility; use erg_common::vis::Visibility;
use erg_type::constructors::proc1; use erg_type::constructors::{builtin_mono, proc1};
use erg_type::Type; use erg_type::Type;
use Type::*; use Type::*;
@ -12,7 +12,12 @@ use Visibility::*;
impl Context { impl Context {
pub(crate) fn init_py_importlib_mod() -> Self { pub(crate) fn init_py_importlib_mod() -> Self {
let mut importlib = Context::builtin_module("importlib", 15); let mut importlib = Context::builtin_module("importlib", 15);
importlib.register_builtin_impl("reload!", proc1(Module, NoneType), Immutable, Public); importlib.register_builtin_impl(
"reload!",
proc1(builtin_mono("GenericModule"), NoneType),
Immutable,
Public,
);
importlib importlib
} }
} }

View file

@ -2,7 +2,7 @@ use erg_common::set;
use erg_common::vis::Visibility; use erg_common::vis::Visibility;
use erg_type::constructors::{ use erg_type::constructors::{
builtin_mono, mono_q, nd_proc, param_t, poly, proc, quant, static_instance, ty_tp, builtin_mono, builtin_poly, mono_q, nd_proc, param_t, proc, quant, static_instance, ty_tp,
}; };
use erg_type::Type; use erg_type::Type;
use Type::*; use Type::*;
@ -36,7 +36,10 @@ impl Context {
Public, Public,
); );
let t = nd_proc( let t = nd_proc(
vec![param_t("seq", poly("Seq", vec![ty_tp(mono_q("T"))]))], vec![param_t(
"seq",
builtin_poly("Seq", vec![ty_tp(mono_q("T"))]),
)],
None, None,
mono_q("T"), mono_q("T"),
); );

View file

@ -1,20 +1,23 @@
// (type) getters & validators // (type) getters & validators
use std::option::Option; // conflicting to Type::Option use std::option::Option; // conflicting to Type::Option
use std::path::{Path, PathBuf};
use erg_common::config::Input;
use erg_common::error::{ErrorCore, ErrorKind, Location}; use erg_common::error::{ErrorCore, ErrorKind, Location};
use erg_common::levenshtein::get_similar_name; use erg_common::levenshtein::get_similar_name;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
use erg_common::vis::{Field, Visibility}; use erg_common::vis::{Field, Visibility};
use erg_common::Str;
use erg_common::{enum_unwrap, fmt_option, fmt_slice, log, set}; use erg_common::{enum_unwrap, fmt_option, fmt_slice, log, set};
use erg_common::{option_enum_unwrap, Str};
use Type::*; use Type::*;
use ast::VarName; use ast::VarName;
use erg_parser::ast::{self, Identifier}; use erg_parser::ast::{self, Identifier};
use erg_parser::token::Token; use erg_parser::token::Token;
use erg_type::constructors::{builtin_mono, func, mono, mono_proj}; use erg_type::constructors::{builtin_mono, func, module, mono, mono_proj, v_enum};
use erg_type::typaram::TyParam;
use erg_type::value::{GenTypeObj, TypeObj, ValueObj}; use erg_type::value::{GenTypeObj, TypeObj, ValueObj};
use erg_type::{HasType, ParamTy, SubrKind, SubrType, TyBound, Type}; use erg_type::{HasType, ParamTy, SubrKind, SubrType, TyBound, Type};
@ -86,21 +89,15 @@ impl Context {
self.locals.get_key_value(name) self.locals.get_key_value(name)
} }
fn get_singular_ctx(&self, obj: &hir::Expr, namespace: &Str) -> SingleTyCheckResult<&Context> { pub fn get_singular_ctx(
&self,
obj: &hir::Expr,
namespace: &Str,
) -> SingleTyCheckResult<&Context> {
match obj { match obj {
hir::Expr::Accessor(hir::Accessor::Ident(ident)) => self hir::Expr::Accessor(hir::Accessor::Ident(ident)) => {
.get_mod(ident.inspect()) self.get_singular_ctx_from_ident(&ident.clone().downcast(), namespace)
.or_else(|| self.rec_get_type(ident.inspect()).map(|(_, ctx)| ctx)) }
.ok_or_else(|| {
TyCheckError::no_var_error(
self.cfg.input.clone(),
line!() as usize,
obj.loc(),
namespace.into(),
ident.inspect(),
self.get_similar_name(ident.inspect()),
)
}),
hir::Expr::Accessor(hir::Accessor::Attr(attr)) => { hir::Expr::Accessor(hir::Accessor::Attr(attr)) => {
// REVIEW: 両方singularとは限らない? // REVIEW: 両方singularとは限らない?
let ctx = self.get_singular_ctx(&attr.obj, namespace)?; let ctx = self.get_singular_ctx(&attr.obj, namespace)?;
@ -111,6 +108,25 @@ impl Context {
} }
} }
pub fn get_singular_ctx_from_ident(
&self,
ident: &ast::Identifier,
namespace: &Str,
) -> SingleTyCheckResult<&Context> {
self.get_mod(ident)
.or_else(|| self.rec_get_type(ident.inspect()).map(|(_, ctx)| ctx))
.ok_or_else(|| {
TyCheckError::no_var_error(
self.cfg.input.clone(),
line!() as usize,
ident.loc(),
namespace.into(),
ident.inspect(),
self.get_similar_name(ident.inspect()),
)
})
}
fn get_match_call_t( fn get_match_call_t(
&self, &self,
pos_args: &[hir::PosArg], pos_args: &[hir::PosArg],
@ -197,31 +213,74 @@ impl Context {
Ok(t) Ok(t)
} }
pub(crate) fn get_local_uniq_obj_name(&self, name: &VarName) -> Option<Str> { fn get_import_call_t(
// TODO: types, functions, patches &self,
if let Some(ctx) = self.get_mod(name.inspect()) { pos_args: &[hir::PosArg],
return Some(ctx.name.clone()); kw_args: &[hir::KwArg],
} ) -> TyCheckResult<Type> {
if let Some((_, ctx)) = self.rec_get_type(name.inspect()) { let mod_name = pos_args
return Some(ctx.name.clone()); .get(0)
} .map(|a| &a.expr)
None .or_else(|| {
kw_args
.iter()
.find(|k| &k.keyword.inspect()[..] == "Path")
.map(|a| &a.expr)
})
.unwrap();
let path = match mod_name {
hir::Expr::Lit(lit) => {
if self.subtype_of(&lit.value.class(), &Str) {
enum_unwrap!(&lit.value, ValueObj::Str)
} else {
return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error(
self.cfg.input.clone(),
line!() as usize,
mod_name.loc(),
self.caused_by(),
"import::name",
&Str,
mod_name.ref_t(),
self.get_candidates(mod_name.ref_t()),
self.get_type_mismatch_hint(&Str, mod_name.ref_t()),
)));
}
}
_other => {
return Err(TyCheckErrors::from(TyCheckError::feature_error(
self.cfg.input.clone(),
mod_name.loc(),
"non-literal importing",
self.caused_by(),
)))
}
};
let path = PathBuf::from(&path[..]);
let s = ValueObj::Str(Str::rc(path.to_str().unwrap()));
let import_t = func(
vec![ParamTy::anonymous(v_enum(set! {s.clone()}))],
None,
vec![],
module(TyParam::Value(s)),
);
Ok(import_t)
} }
pub(crate) fn rec_get_var_t( pub(crate) fn rec_get_var_t(
&self, &self,
ident: &Identifier, ident: &Identifier,
input: &Input,
namespace: &Str, namespace: &Str,
) -> SingleTyCheckResult<Type> { ) -> SingleTyCheckResult<Type> {
if let Some(vi) = self.get_current_scope_var(&ident.inspect()[..]) { if let Some(vi) = self.get_current_scope_var(&ident.inspect()[..]) {
self.validate_visibility(ident, vi, namespace)?; self.validate_visibility(ident, vi, input, namespace)?;
Ok(vi.t()) Ok(vi.t())
} else { } else {
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
return parent.rec_get_var_t(ident, namespace); return parent.rec_get_var_t(ident, input, namespace);
} }
Err(TyCheckError::no_var_error( Err(TyCheckError::no_var_error(
self.cfg.input.clone(), input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
namespace.into(), namespace.into(),
@ -235,11 +294,12 @@ impl Context {
&self, &self,
obj: &hir::Expr, obj: &hir::Expr,
ident: &Identifier, ident: &Identifier,
input: &Input,
namespace: &Str, namespace: &Str,
) -> SingleTyCheckResult<Type> { ) -> SingleTyCheckResult<Type> {
let self_t = obj.t(); let self_t = obj.t();
let name = ident.name.token(); let name = ident.name.token();
match self.get_attr_t_from_attributive_t(obj, &self_t, ident, namespace) { match self.get_attr_t_from_attributive(obj, &self_t, ident, namespace) {
Ok(t) => { Ok(t) => {
return Ok(t); return Ok(t);
} }
@ -249,7 +309,7 @@ impl Context {
} }
} }
if let Ok(singular_ctx) = self.get_singular_ctx(obj, namespace) { if let Ok(singular_ctx) = self.get_singular_ctx(obj, namespace) {
match singular_ctx.rec_get_var_t(ident, namespace) { match singular_ctx.rec_get_var_t(ident, input, namespace) {
Ok(t) => { Ok(t) => {
return Ok(t); return Ok(t);
} }
@ -269,7 +329,7 @@ impl Context {
None, // TODO: None, // TODO:
) )
})? { })? {
match ctx.rec_get_var_t(ident, namespace) { match ctx.rec_get_var_t(ident, input, namespace) {
Ok(t) => { Ok(t) => {
return Ok(t); return Ok(t);
} }
@ -281,10 +341,10 @@ impl Context {
} }
// TODO: dependent type widening // TODO: dependent type widening
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
parent.rec_get_attr_t(obj, ident, namespace) parent.rec_get_attr_t(obj, ident, input, namespace)
} else { } else {
Err(TyCheckError::no_attr_error( Err(TyCheckError::no_attr_error(
self.cfg.input.clone(), input.clone(),
line!() as usize, line!() as usize,
name.loc(), name.loc(),
namespace.into(), namespace.into(),
@ -295,7 +355,9 @@ impl Context {
} }
} }
fn get_attr_t_from_attributive_t( /// get type from given attributive type (Record).
/// not ModuleType or ClassType etc.
fn get_attr_t_from_attributive(
&self, &self,
obj: &hir::Expr, obj: &hir::Expr,
t: &Type, t: &Type,
@ -304,18 +366,18 @@ impl Context {
) -> SingleTyCheckResult<Type> { ) -> SingleTyCheckResult<Type> {
match t { match t {
Type::FreeVar(fv) if fv.is_linked() => { Type::FreeVar(fv) if fv.is_linked() => {
self.get_attr_t_from_attributive_t(obj, &fv.crack(), ident, namespace) self.get_attr_t_from_attributive(obj, &fv.crack(), ident, namespace)
} }
Type::FreeVar(fv) => { Type::FreeVar(fv) => {
let sup = fv.get_sup().unwrap(); let sup = fv.get_sup().unwrap();
self.get_attr_t_from_attributive_t(obj, &sup, ident, namespace) self.get_attr_t_from_attributive(obj, &sup, ident, namespace)
} }
Type::Ref(t) => self.get_attr_t_from_attributive_t(obj, t, ident, namespace), Type::Ref(t) => self.get_attr_t_from_attributive(obj, t, ident, namespace),
Type::RefMut { before, .. } => { Type::RefMut { before, .. } => {
self.get_attr_t_from_attributive_t(obj, before, ident, namespace) self.get_attr_t_from_attributive(obj, before, ident, namespace)
} }
Type::Refinement(refine) => { Type::Refinement(refine) => {
self.get_attr_t_from_attributive_t(obj, &refine.t, ident, namespace) self.get_attr_t_from_attributive(obj, &refine.t, ident, namespace)
} }
Type::Record(record) => { Type::Record(record) => {
// REVIEW: `rec.get(name.inspect())` returns None (Borrow<Str> is implemented for Field). Why? // REVIEW: `rec.get(name.inspect())` returns None (Borrow<Str> is implemented for Field). Why?
@ -334,11 +396,6 @@ impl Context {
)) ))
} }
} }
Module => {
let mod_ctx = self.get_singular_ctx(obj, namespace)?;
let t = mod_ctx.rec_get_var_t(ident, namespace)?;
Ok(t)
}
other => { other => {
if let Some(v) = self.rec_get_const_obj(&other.name()) { if let Some(v) = self.rec_get_const_obj(&other.name()) {
match v { match v {
@ -372,6 +429,7 @@ impl Context {
&self, &self,
obj: &hir::Expr, obj: &hir::Expr,
method_name: &Option<Identifier>, method_name: &Option<Identifier>,
input: &Input,
namespace: &Str, namespace: &Str,
) -> SingleTyCheckResult<Type> { ) -> SingleTyCheckResult<Type> {
if let Some(method_name) = method_name.as_ref() { if let Some(method_name) = method_name.as_ref() {
@ -393,7 +451,7 @@ impl Context {
.get(method_name.inspect()) .get(method_name.inspect())
.or_else(|| ctx.decls.get(method_name.inspect())) .or_else(|| ctx.decls.get(method_name.inspect()))
{ {
self.validate_visibility(method_name, vi, namespace)?; self.validate_visibility(method_name, vi, input, namespace)?;
return Ok(vi.t()); return Ok(vi.t());
} }
for (_, methods_ctx) in ctx.methods_list.iter() { for (_, methods_ctx) in ctx.methods_list.iter() {
@ -402,7 +460,7 @@ impl Context {
.get(method_name.inspect()) .get(method_name.inspect())
.or_else(|| methods_ctx.decls.get(method_name.inspect())) .or_else(|| methods_ctx.decls.get(method_name.inspect()))
{ {
self.validate_visibility(method_name, vi, namespace)?; self.validate_visibility(method_name, vi, input, namespace)?;
return Ok(vi.t()); return Ok(vi.t());
} }
} }
@ -413,7 +471,7 @@ impl Context {
.get(method_name.inspect()) .get(method_name.inspect())
.or_else(|| singular_ctx.decls.get(method_name.inspect())) .or_else(|| singular_ctx.decls.get(method_name.inspect()))
{ {
self.validate_visibility(method_name, vi, namespace)?; self.validate_visibility(method_name, vi, input, namespace)?;
return Ok(vi.t()); return Ok(vi.t());
} }
for (_, method_ctx) in singular_ctx.methods_list.iter() { for (_, method_ctx) in singular_ctx.methods_list.iter() {
@ -422,7 +480,7 @@ impl Context {
.get(method_name.inspect()) .get(method_name.inspect())
.or_else(|| method_ctx.decls.get(method_name.inspect())) .or_else(|| method_ctx.decls.get(method_name.inspect()))
{ {
self.validate_visibility(method_name, vi, namespace)?; self.validate_visibility(method_name, vi, input, namespace)?;
return Ok(vi.t()); return Ok(vi.t());
} }
} }
@ -456,11 +514,12 @@ impl Context {
&self, &self,
ident: &Identifier, ident: &Identifier,
vi: &VarInfo, vi: &VarInfo,
input: &Input,
namespace: &str, namespace: &str,
) -> SingleTyCheckResult<()> { ) -> SingleTyCheckResult<()> {
if ident.vis() != vi.vis { if ident.vis() != vi.vis {
Err(TyCheckError::visibility_error( Err(TyCheckError::visibility_error(
self.cfg.input.clone(), input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
self.caused_by(), self.caused_by(),
@ -474,7 +533,7 @@ impl Context {
&& !namespace.contains(&self.name[..]) && !namespace.contains(&self.name[..])
{ {
Err(TyCheckError::visibility_error( Err(TyCheckError::visibility_error(
self.cfg.input.clone(), input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
self.caused_by(), self.caused_by(),
@ -490,6 +549,7 @@ impl Context {
&self, &self,
op: &Token, op: &Token,
args: &[hir::PosArg], args: &[hir::PosArg],
input: &Input,
namespace: &Str, namespace: &Str,
) -> TyCheckResult<Type> { ) -> TyCheckResult<Type> {
erg_common::debug_power_assert!(args.len() == 2); erg_common::debug_power_assert!(args.len() == 2);
@ -497,10 +557,11 @@ impl Context {
let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin); let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin);
let t = self.rec_get_var_t( let t = self.rec_get_var_t(
&Identifier::new(None, VarName::new(symbol.clone())), &Identifier::new(None, VarName::new(symbol.clone())),
input,
namespace, namespace,
)?; )?;
let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t));
self.get_call_t(&op, &None, args, &[], namespace) self.get_call_t(&op, &None, args, &[], input, namespace)
.map_err(|errs| { .map_err(|errs| {
let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_)));
let lhs = args[0].expr.clone(); let lhs = args[0].expr.clone();
@ -528,6 +589,7 @@ impl Context {
&self, &self,
op: &Token, op: &Token,
args: &[hir::PosArg], args: &[hir::PosArg],
input: &Input,
namespace: &Str, namespace: &Str,
) -> TyCheckResult<Type> { ) -> TyCheckResult<Type> {
erg_common::debug_power_assert!(args.len() == 1); erg_common::debug_power_assert!(args.len() == 1);
@ -535,10 +597,11 @@ impl Context {
let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin); let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin);
let t = self.rec_get_var_t( let t = self.rec_get_var_t(
&Identifier::new(None, VarName::new(symbol.clone())), &Identifier::new(None, VarName::new(symbol.clone())),
input,
namespace, namespace,
)?; )?;
let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t));
self.get_call_t(&op, &None, args, &[], namespace) self.get_call_t(&op, &None, args, &[], input, namespace)
.map_err(|errs| { .map_err(|errs| {
let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_)));
let expr = args[0].expr.clone(); let expr = args[0].expr.clone();
@ -880,17 +943,34 @@ impl Context {
method_name: &Option<Identifier>, method_name: &Option<Identifier>,
pos_args: &[hir::PosArg], pos_args: &[hir::PosArg],
kw_args: &[hir::KwArg], kw_args: &[hir::KwArg],
input: &Input,
namespace: &Str, namespace: &Str,
) -> TyCheckResult<Type> { ) -> TyCheckResult<Type> {
match obj { if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
hir::Expr::Accessor(hir::Accessor::Ident(local)) if local.vis().is_private() {
if local.vis().is_private() && &local.inspect()[..] == "match" => match &local.inspect()[..] {
{ "match" => {
return self.get_match_call_t(pos_args, kw_args); return self.get_match_call_t(pos_args, kw_args);
}
"import" | "pyimport" | "py" => {
return self.get_import_call_t(pos_args, kw_args);
}
// handle assert casting
/*"assert" => {
if let Some(arg) = pos_args.first() {
match &arg.expr {
hir::Expr::BinOp(bin) if bin.op.is(TokenKind::InOp) && bin.rhs.ref_t() == &Type => {
let t = self.eval_const_expr(bin.lhs.as_ref(), None)?.as_type().unwrap();
}
_ => {}
}
}
},*/
_ => {}
}
} }
_ => {}
} }
let found = self.search_callee_t(obj, method_name, namespace)?; let found = self.search_callee_t(obj, method_name, input, namespace)?;
log!( log!(
"Found:\ncallee: {obj}{}\nfound: {found}", "Found:\ncallee: {obj}{}\nfound: {found}",
fmt_option!(pre ".", method_name.as_ref().map(|ident| &ident.name)) fmt_option!(pre ".", method_name.as_ref().map(|ident| &ident.name))
@ -1192,9 +1272,31 @@ impl Context {
} }
} }
}, },
Type::Poly { name, params: _ } => { Type::BuiltinPoly { name, .. } => {
if let Some((t, ctx)) = self.rec_get_poly_type(name) { if let Some(res) = self.get_builtins().unwrap_or(self).rec_get_poly_type(name) {
return Some((t, ctx)); return Some(res);
}
}
Type::Poly { path, name, .. } => {
if self.path() == path {
if let Some((t, ctx)) = self.rec_get_mono_type(name) {
return Some((t, ctx));
}
}
let path = self.cfg.input.resolve(path.as_path()).ok()?;
if let Some(ctx) = self
.mod_cache
.as_ref()
.and_then(|cache| cache.ref_ctx(path.as_path()))
.or_else(|| {
self.py_mod_cache
.as_ref()
.and_then(|cache| cache.ref_ctx(path.as_path()))
})
{
if let Some((t, ctx)) = ctx.rec_get_mono_type(name) {
return Some((t, ctx));
}
} }
} }
Type::Record(rec) if rec.values().all(|attr| self.supertype_of(&Type, attr)) => { Type::Record(rec) if rec.values().all(|attr| self.supertype_of(&Type, attr)) => {
@ -1210,14 +1312,21 @@ impl Context {
.rec_get_mono_type("Record"); .rec_get_mono_type("Record");
} }
Type::Mono { path, name } => { Type::Mono { path, name } => {
if self.mod_name() == path { if self.path() == path {
if let Some((t, ctx)) = self.rec_get_mono_type(name) { if let Some((t, ctx)) = self.rec_get_mono_type(name) {
return Some((t, ctx)); return Some((t, ctx));
} }
} else if let Some(ctx) = self }
let path = self.cfg.input.resolve(path.as_path()).ok()?;
if let Some(ctx) = self
.mod_cache .mod_cache
.as_ref() .as_ref()
.and_then(|cache| cache.ref_ctx(path)) .and_then(|cache| cache.ref_ctx(path.as_path()))
.or_else(|| {
self.py_mod_cache
.as_ref()
.and_then(|cache| cache.ref_ctx(path.as_path()))
})
{ {
if let Some((t, ctx)) = ctx.rec_get_mono_type(name) { if let Some((t, ctx)) = ctx.rec_get_mono_type(name) {
return Some((t, ctx)); return Some((t, ctx));
@ -1274,7 +1383,7 @@ impl Context {
return Some(res); return Some(res);
} }
} }
Type::Poly { name, params: _ } => { Type::BuiltinPoly { name, params: _ } => {
if let Some((t, ctx)) = self.rec_get_mut_poly_type(name) { if let Some((t, ctx)) = self.rec_get_mut_poly_type(name) {
return Some((t, ctx)); return Some((t, ctx));
} }
@ -1327,15 +1436,27 @@ impl Context {
} }
// FIXME: 現在の実装だとimportしたモジュールはどこからでも見れる // FIXME: 現在の実装だとimportしたモジュールはどこからでも見れる
fn get_mod(&self, name: &Str) -> Option<&Context> { fn get_mod(&self, ident: &ast::Identifier) -> Option<&Context> {
self.mod_cache let t = self
.as_ref() .rec_get_var_t(ident, &self.cfg.input, &self.name)
.and_then(|cache| cache.ref_ctx(name)) .ok()?;
.or_else(|| { match t {
self.py_mod_cache Type::BuiltinPoly { name, mut params } if &name[..] == "Module" => {
let path =
option_enum_unwrap!(params.remove(0), TyParam::Value:(ValueObj::Str:(_)))?;
let path = Path::new(&path[..]);
let path = self.cfg.input.resolve(path).ok()?;
self.mod_cache
.as_ref() .as_ref()
.and_then(|cache| cache.ref_ctx(name)) .and_then(|cache| cache.ref_ctx(&path))
}) .or_else(|| {
self.py_mod_cache
.as_ref()
.and_then(|cache| cache.ref_ctx(&path))
})
}
_ => None,
}
} }
// rec_get_const_localとは違い、位置情報を持たないしエラーとならない // rec_get_const_localとは違い、位置情報を持たないしエラーとならない
@ -1370,7 +1491,7 @@ impl Context {
if self.kind.is_method_def() || self.kind.is_type() { if self.kind.is_method_def() || self.kind.is_type() {
// TODO: poly type // TODO: poly type
let name = self.name.split(&[':', '.']).last().unwrap(); let name = self.name.split(&[':', '.']).last().unwrap();
let mono_t = mono(self.mod_name(), Str::rc(name)); let mono_t = mono(self.path(), Str::rc(name));
if let Some((t, _)) = self.get_nominal_type_ctx(&mono_t) { if let Some((t, _)) = self.get_nominal_type_ctx(&mono_t) {
Some(t.clone()) Some(t.clone())
} else { } else {

View file

@ -106,7 +106,7 @@ impl TyVarContext {
) -> Type { ) -> Type {
if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(name) { if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(name) {
let (_, ctx) = ctx let (_, ctx) = ctx
.get_nominal_type_ctx(&poly(name.clone(), params.clone())) .get_nominal_type_ctx(&builtin_poly(name.clone(), params.clone()))
.unwrap_or_else(|| panic!("{} not found", name)); .unwrap_or_else(|| panic!("{} not found", name));
let defined_params_len = ctx.params.len(); let defined_params_len = ctx.params.len();
let given_params_len = params.len(); let given_params_len = params.len();
@ -123,9 +123,9 @@ impl TyVarContext {
self.push_or_init_typaram(&tp.tvar_name().unwrap(), &tp); self.push_or_init_typaram(&tp.tvar_name().unwrap(), &tp);
inst_defaults.push(tp); inst_defaults.push(tp);
} }
poly(name, [inst_non_defaults, inst_defaults].concat()) builtin_poly(name, [inst_non_defaults, inst_defaults].concat())
} else { } else {
poly(name, self.instantiate_params(params)) builtin_poly(name, self.instantiate_params(params))
} }
} }
@ -146,7 +146,10 @@ impl TyVarContext {
fn instantiate_bound_type(&mut self, mid: &Type, sub_or_sup: Type, ctx: &Context) -> Type { fn instantiate_bound_type(&mut self, mid: &Type, sub_or_sup: Type, ctx: &Context) -> Type {
match sub_or_sup { match sub_or_sup {
Type::Poly { name, params } => self.instantiate_poly(mid.name(), &name, params, ctx), Type::Poly { .. } => todo!(),
Type::BuiltinPoly { name, params } => {
self.instantiate_poly(mid.name(), &name, params, ctx)
}
Type::MonoProj { lhs, rhs } => { Type::MonoProj { lhs, rhs } => {
let lhs = if lhs.has_qvar() { let lhs = if lhs.has_qvar() {
self.instantiate_qvar(*lhs) self.instantiate_qvar(*lhs)
@ -174,9 +177,10 @@ impl TyVarContext {
} }
TyBound::Instance { name, t } => { TyBound::Instance { name, t } => {
let t = match t { let t = match t {
Type::Poly { name, params } => { Type::BuiltinPoly { name, params } => {
self.instantiate_poly(name.clone(), &name, params, ctx) self.instantiate_poly(name.clone(), &name, params, ctx)
} }
Type::Poly { .. } => todo!(),
t => t, t => t,
}; };
let constraint = Constraint::new_type_of(t.clone()); let constraint = Constraint::new_type_of(t.clone());
@ -385,7 +389,7 @@ impl Context {
mode: RegistrationMode, mode: RegistrationMode,
) -> TyCheckResult<Type> { ) -> TyCheckResult<Type> {
let opt_decl_sig_t = self let opt_decl_sig_t = self
.rec_get_var_t(&sig.ident, &self.name) .rec_get_var_t(&sig.ident, &self.cfg.input, &self.name)
.ok() .ok()
.map(|t| enum_unwrap!(t, Type::Subr)); .map(|t| enum_unwrap!(t, Type::Subr));
let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?; let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
@ -453,7 +457,7 @@ impl Context {
self.instantiate_typespec(&spec_with_op.t_spec, opt_decl_t, tv_ctx, mode)? self.instantiate_typespec(&spec_with_op.t_spec, opt_decl_t, tv_ctx, mode)?
} else { } else {
match &sig.pat { match &sig.pat {
ast::ParamPattern::Lit(lit) => enum_t(set![eval_lit(lit)]), ast::ParamPattern::Lit(lit) => v_enum(set![eval_lit(lit)]),
// TODO: Array<Lit> // TODO: Array<Lit>
_ => { _ => {
let level = if mode == PreRegister { let level = if mode == PreRegister {
@ -528,7 +532,7 @@ impl Context {
} else if let Some(decl_t) = opt_decl_t { } else if let Some(decl_t) = opt_decl_t {
Ok(decl_t.typ().clone()) Ok(decl_t.typ().clone())
} else { } else {
let typ = mono(self.mod_name(), Str::rc(other)); let typ = mono(self.path(), Str::rc(other));
if let Some((defined_t, _)) = self.get_nominal_type_ctx(&typ) { if let Some((defined_t, _)) = self.get_nominal_type_ctx(&typ) {
Ok(defined_t.clone()) Ok(defined_t.clone())
} else { } else {
@ -551,8 +555,8 @@ impl Context {
todo!() todo!()
} }
}); });
// FIXME: if type is a trait // FIXME: non-builtin
Ok(poly(Str::rc(other), params.collect())) Ok(builtin_poly(Str::rc(other), params.collect()))
} }
} }
} }
@ -573,7 +577,7 @@ impl Context {
) -> SingleTyCheckResult<Type> { ) -> SingleTyCheckResult<Type> {
match expr { match expr {
ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => { ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => {
Ok(mono(self.mod_name(), name.inspect())) Ok(mono(self.path(), name.inspect()))
} }
_ => todo!(), _ => todo!(),
} }
@ -632,7 +636,7 @@ impl Context {
.collect(), .collect(),
)), )),
// TODO: エラー処理(リテラルでない、ダブりがある)はパーサーにやらせる // TODO: エラー処理(リテラルでない、ダブりがある)はパーサーにやらせる
TypeSpec::Enum(set) => Ok(enum_t( TypeSpec::Enum(set) => Ok(v_enum(
set.pos_args() set.pos_args()
.map(|arg| { .map(|arg| {
if let ast::ConstExpr::Lit(lit) = &arg.expr { if let ast::ConstExpr::Lit(lit) = &arg.expr {
@ -861,11 +865,21 @@ impl Context {
let lhs = self.instantiate_t(*lhs, tv_ctx, loc)?; let lhs = self.instantiate_t(*lhs, tv_ctx, loc)?;
Ok(mono_proj(lhs, rhs)) Ok(mono_proj(lhs, rhs))
} }
Poly { name, mut params } => { BuiltinPoly { name, mut params } => {
for param in params.iter_mut() { for param in params.iter_mut() {
*param = self.instantiate_tp(mem::take(param), tv_ctx, loc)?; *param = self.instantiate_tp(mem::take(param), tv_ctx, loc)?;
} }
Ok(poly(name, params)) Ok(builtin_poly(name, params))
}
Poly {
path,
name,
mut params,
} => {
for param in params.iter_mut() {
*param = self.instantiate_tp(mem::take(param), tv_ctx, loc)?;
}
Ok(poly(path, name, params))
} }
Quantified(_) => { Quantified(_) => {
panic!("a quantified type should not be instantiated, instantiate the inner type") panic!("a quantified type should not be instantiated, instantiate the inner type")

View file

@ -16,6 +16,7 @@ pub mod tyvar;
use std::fmt; use std::fmt;
use std::mem; use std::mem;
use std::option::Option; // conflicting to Type::Option use std::option::Option; // conflicting to Type::Option
use std::path::Path;
use erg_common::astr::AtomicStr; use erg_common::astr::AtomicStr;
use erg_common::config::ErgConfig; use erg_common::config::ErgConfig;
@ -288,6 +289,11 @@ impl ImportKind {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ContextInfo {
mod_id: usize,
}
/// Represents the context of the current scope /// Represents the context of the current scope
/// ///
/// Recursive functions/methods are highlighted with the prefix `rec_`, as performance may be significantly degraded. /// Recursive functions/methods are highlighted with the prefix `rec_`, as performance may be significantly degraded.
@ -773,13 +779,13 @@ impl Context {
self.outer.as_ref().map(|x| x.as_ref()) self.outer.as_ref().map(|x| x.as_ref())
} }
pub(crate) fn mod_name(&self) -> &Str { pub(crate) fn path(&self) -> &Path {
if let Some(outer) = self.get_outer() { if let Some(outer) = self.get_outer() {
outer.mod_name() outer.path()
} else if self.kind == ContextKind::Module { } else if self.kind == ContextKind::Module {
&self.name Path::new(&self.name[..])
} else { } else {
BUILTINS Path::new(&BUILTINS[..])
} }
} }
@ -787,10 +793,10 @@ impl Context {
/// This avoids infinite loops. /// This avoids infinite loops.
pub(crate) fn get_builtins(&self) -> Option<&Context> { pub(crate) fn get_builtins(&self) -> Option<&Context> {
// builtins中で定義した型等はmod_cacheがNoneになっている // builtins中で定義した型等はmod_cacheがNoneになっている
if &self.mod_name()[..] != "<builtins>" { if self.path().to_string_lossy() != "<builtins>" {
self.mod_cache self.mod_cache
.as_ref() .as_ref()
.map(|cache| cache.ref_ctx("<builtins>").unwrap()) .map(|cache| cache.ref_ctx(Path::new("<builtins>")).unwrap())
} else { } else {
None None
} }
@ -809,6 +815,7 @@ impl Context {
}; };
log!(info "{}: current namespace: {name}", fn_name!()); log!(info "{}: current namespace: {name}", fn_name!());
self.outer = Some(Box::new(mem::take(self))); self.outer = Some(Box::new(mem::take(self)));
self.cfg = self.get_outer().unwrap().cfg.clone();
self.mod_cache = self.get_outer().unwrap().mod_cache.clone(); self.mod_cache = self.get_outer().unwrap().mod_cache.clone();
self.py_mod_cache = self.get_outer().unwrap().py_mod_cache.clone(); self.py_mod_cache = self.get_outer().unwrap().py_mod_cache.clone();
self.name = name.into(); self.name = name.into();

View file

@ -1,5 +1,5 @@
use std::option::Option; use std::option::Option;
use std::path::PathBuf; // conflicting to Type::Option use std::path::PathBuf;
use erg_common::config::{ErgConfig, Input}; use erg_common::config::{ErgConfig, Input};
use erg_common::levenshtein::get_similar_name; use erg_common::levenshtein::get_similar_name;
@ -12,10 +12,9 @@ use erg_type::free::HasLevel;
use ast::{DefId, Identifier, VarName}; use ast::{DefId, Identifier, VarName};
use erg_parser::ast; use erg_parser::ast;
use erg_type::constructors::{enum_t, func, func1, proc, ref_, ref_mut}; use erg_type::constructors::{func, func1, proc, ref_, ref_mut, v_enum};
use erg_type::value::{GenTypeObj, TypeKind, TypeObj, ValueObj}; use erg_type::value::{GenTypeObj, TypeKind, TypeObj, ValueObj};
use erg_type::{HasType, ParamTy, SubrType, TyBound, Type}; use erg_type::{ParamTy, SubrType, TyBound, Type};
use Type::*;
use crate::build_hir::HIRBuilder; use crate::build_hir::HIRBuilder;
use crate::context::{ClassDefType, Context, DefaultInfo, RegistrationMode, TraitInstance}; use crate::context::{ClassDefType, Context, DefaultInfo, RegistrationMode, TraitInstance};
@ -23,7 +22,7 @@ use crate::error::readable_name;
use crate::error::{ use crate::error::{
CompileResult, SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult, CompileResult, SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult,
}; };
use crate::hir::{self, Literal}; use crate::hir::Literal;
use crate::mod_cache::SharedModuleCache; use crate::mod_cache::SharedModuleCache;
use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind}; use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind};
use Mutability::*; use Mutability::*;
@ -484,7 +483,7 @@ impl Context {
let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?; let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
let mut tv_ctx = TyVarContext::new(self.level, bounds, self); let mut tv_ctx = TyVarContext::new(self.level, bounds, self);
let (obj, const_t) = match self.eval_const_block(&def.body.block, __name__) { let (obj, const_t) = match self.eval_const_block(&def.body.block, __name__) {
Ok(obj) => (obj.clone(), enum_t(set! {obj})), Ok(obj) => (obj.clone(), v_enum(set! {obj})),
Err(e) => { Err(e) => {
return Err(e); return Err(e);
} }
@ -505,7 +504,7 @@ impl Context {
} }
ast::Signature::Var(sig) if sig.is_const() => { ast::Signature::Var(sig) if sig.is_const() => {
let (obj, const_t) = match self.eval_const_block(&def.body.block, __name__) { let (obj, const_t) = match self.eval_const_block(&def.body.block, __name__) {
Ok(obj) => (obj.clone(), enum_t(set! {obj})), Ok(obj) => (obj.clone(), v_enum(set! {obj})),
Err(e) => { Err(e) => {
return Err(e); return Err(e);
} }
@ -609,7 +608,7 @@ impl Context {
other => { other => {
let id = DefId(get_hash(ident)); let id = DefId(get_hash(ident));
let vi = VarInfo::new( let vi = VarInfo::new(
enum_t(set! {other.clone()}), v_enum(set! {other.clone()}),
Const, Const,
ident.vis(), ident.vis(),
VarKind::Defined(id), VarKind::Defined(id),
@ -818,67 +817,33 @@ impl Context {
pub(crate) fn import_mod( pub(crate) fn import_mod(
&mut self, &mut self,
kind: ImportKind, kind: ImportKind,
var_name: &VarName, mod_name: &Literal,
mod_name: &hir::Expr, ) -> CompileResult<PathBuf> {
) -> CompileResult<()> { if kind.is_erg_import() {
match mod_name { self.import_erg_mod(mod_name)
hir::Expr::Lit(lit) => { } else {
if self.subtype_of(&lit.value.class(), &Str) { self.import_py_mod(mod_name)
if kind.is_erg_import() {
self.import_erg_mod(var_name, lit)?;
} else {
self.import_py_mod(var_name, lit)?;
}
} else {
return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error(
self.cfg.input.clone(),
line!() as usize,
mod_name.loc(),
self.caused_by(),
"import::name",
&Str,
mod_name.ref_t(),
self.get_candidates(mod_name.ref_t()),
self.get_type_mismatch_hint(&Str, mod_name.ref_t()),
)));
}
}
_other => {
return Err(TyCheckErrors::from(TyCheckError::feature_error(
self.cfg.input.clone(),
mod_name.loc(),
"non-literal importing",
self.caused_by(),
)))
}
} }
Ok(())
} }
fn import_erg_mod(&mut self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { fn import_erg_mod(&mut self, mod_name: &Literal) -> CompileResult<PathBuf> {
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
let mod_cache = self.mod_cache.as_ref().unwrap(); let mod_cache = self.mod_cache.as_ref().unwrap();
let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
#[allow(clippy::match_single_binding)] #[allow(clippy::match_single_binding)]
match &__name__[..] { match &__name__[..] {
// TODO: erg builtin modules // TODO: erg builtin modules
_ => self.import_user_erg_mod(var_name, __name__, lit, mod_cache, py_mod_cache)?, _ => self.import_user_erg_mod(__name__, mod_name, mod_cache, py_mod_cache),
} }
Ok(())
} }
fn import_user_erg_mod( fn import_user_erg_mod(
&self, &self,
var_name: &VarName,
__name__: Str, __name__: Str,
name_lit: &Literal, mod_name: &Literal,
mod_cache: &SharedModuleCache, mod_cache: &SharedModuleCache,
py_mod_cache: &SharedModuleCache, py_mod_cache: &SharedModuleCache,
) -> CompileResult<()> { ) -> CompileResult<PathBuf> {
if let Some((_, entry)) = mod_cache.get_by_name(&__name__) {
mod_cache.register_alias(var_name.clone(), entry);
return Ok(());
}
let mut dir = if let Input::File(mut path) = self.cfg.input.clone() { let mut dir = if let Input::File(mut path) = self.cfg.input.clone() {
path.pop(); path.pop();
path path
@ -893,7 +858,7 @@ impl Context {
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
err.to_string(), err.to_string(),
name_lit.loc(), mod_name.loc(),
self.caused_by(), self.caused_by(),
self.mod_cache.as_ref().unwrap().get_similar_name(&__name__), self.mod_cache.as_ref().unwrap().get_similar_name(&__name__),
self.similar_builtin_py_mod_name(&__name__).or_else(|| { self.similar_builtin_py_mod_name(&__name__).or_else(|| {
@ -906,56 +871,68 @@ impl Context {
return Err(err); return Err(err);
} }
}; };
let cfg = ErgConfig::with_path(path); if mod_cache.get(&path).is_some() {
return Ok(path);
}
let cfg = ErgConfig::with_path(path.clone());
let src = cfg.input.read(); let src = cfg.input.read();
let mut builder = HIRBuilder::new_with_cache( let mut builder =
cfg, HIRBuilder::new_with_cache(cfg, __name__, mod_cache.clone(), py_mod_cache.clone());
var_name.inspect(),
mod_cache.clone(),
py_mod_cache.clone(),
);
match builder.build(src, "exec") { match builder.build(src, "exec") {
Ok(hir) => { Ok(hir) => {
mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); mod_cache.register(path.clone(), Some(hir), builder.pop_ctx());
} }
Err((maybe_hir, errs)) => { Err((maybe_hir, errs)) => {
if let Some(hir) = maybe_hir { if let Some(hir) = maybe_hir {
mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); mod_cache.register(path, Some(hir), builder.pop_ctx());
} }
return Err(errs); return Err(errs);
} }
} }
Ok(()) Ok(path)
} }
fn import_py_mod(&mut self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { fn import_py_mod(&mut self, mod_name: &Literal) -> CompileResult<PathBuf> {
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
let mod_cache = self.mod_cache.as_ref().unwrap(); let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
match &__name__[..] { match &__name__[..] {
"importlib" => { "importlib" => {
mod_cache.register(var_name.clone(), None, Self::init_py_importlib_mod()); let path = PathBuf::from("<builtins>.importlib");
py_mod_cache.register(path.clone(), None, Self::init_py_importlib_mod());
Ok(path)
} }
"io" => { "io" => {
mod_cache.register(var_name.clone(), None, Self::init_py_io_mod()); let path = PathBuf::from("<builtins>.io");
py_mod_cache.register(path.clone(), None, Self::init_py_io_mod());
Ok(path)
} }
"math" => { "math" => {
mod_cache.register(var_name.clone(), None, Self::init_py_math_mod()); let path = PathBuf::from("<builtins>.math");
py_mod_cache.register(path.clone(), None, Self::init_py_math_mod());
Ok(path)
} }
"random" => { "random" => {
mod_cache.register(var_name.clone(), None, Self::init_py_random_mod()); let path = PathBuf::from("<builtins>.random");
py_mod_cache.register(path.clone(), None, Self::init_py_random_mod());
Ok(path)
} }
"socket" => { "socket" => {
mod_cache.register(var_name.clone(), None, Self::init_py_socket_mod()); let path = PathBuf::from("<builtins>.socket");
py_mod_cache.register(path.clone(), None, Self::init_py_socket_mod());
Ok(path)
} }
"sys" => { "sys" => {
mod_cache.register(var_name.clone(), None, Self::init_py_sys_mod()); let path = PathBuf::from("<builtins>.sys");
py_mod_cache.register(path.clone(), None, Self::init_py_sys_mod());
Ok(path)
} }
"time" => { "time" => {
mod_cache.register(var_name.clone(), None, Self::init_py_time_mod()); let path = PathBuf::from("<builtins>.time");
py_mod_cache.register(path.clone(), None, Self::init_py_time_mod());
Ok(path)
} }
_ => self.import_user_py_mod(var_name, lit)?, _ => self.import_user_py_mod(mod_name),
} }
Ok(())
} }
fn similar_builtin_py_mod_name(&self, name: &Str) -> Option<Str> { fn similar_builtin_py_mod_name(&self, name: &Str) -> Option<Str> {
@ -966,13 +943,9 @@ impl Context {
.map(Str::rc) .map(Str::rc)
} }
fn import_user_py_mod(&self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { fn import_user_py_mod(&self, mod_name: &Literal) -> CompileResult<PathBuf> {
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
if let Some((_, entry)) = py_mod_cache.get_by_name(&__name__) {
py_mod_cache.register_alias(var_name.clone(), entry);
return Ok(());
}
let mut dir = if let Input::File(mut path) = self.cfg.input.clone() { let mut dir = if let Input::File(mut path) = self.cfg.input.clone() {
path.pop(); path.pop();
path path
@ -987,39 +960,34 @@ impl Context {
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
err.to_string(), err.to_string(),
lit.loc(), mod_name.loc(),
self.caused_by(), self.caused_by(),
self.mod_cache.as_ref().unwrap().get_similar_name(&__name__), self.mod_cache.as_ref().unwrap().get_similar_name(&__name__),
self.similar_builtin_py_mod_name(&__name__).or_else(|| { self.similar_builtin_py_mod_name(&__name__)
self.py_mod_cache .or_else(|| py_mod_cache.get_similar_name(&__name__)),
.as_ref()
.unwrap()
.get_similar_name(&__name__)
}),
); );
return Err(TyCheckErrors::from(err)); return Err(TyCheckErrors::from(err));
} }
}; };
let cfg = ErgConfig::with_path(path); if py_mod_cache.get(&path).is_some() {
return Ok(path);
}
let cfg = ErgConfig::with_path(path.clone());
let src = cfg.input.read(); let src = cfg.input.read();
let mut builder = HIRBuilder::new_with_cache( let mut builder =
cfg, HIRBuilder::new_with_cache(cfg, __name__, py_mod_cache.clone(), py_mod_cache.clone());
var_name.inspect(),
py_mod_cache.clone(),
py_mod_cache.clone(),
);
match builder.build(src, "declare") { match builder.build(src, "declare") {
Ok(hir) => { Ok(hir) => {
py_mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); py_mod_cache.register(path.clone(), Some(hir), builder.pop_ctx());
} }
Err((maybe_hir, errs)) => { Err((maybe_hir, errs)) => {
if let Some(hir) = maybe_hir { if let Some(hir) = maybe_hir {
py_mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); py_mod_cache.register(path, Some(hir), builder.pop_ctx());
} }
return Err(errs); return Err(errs);
} }
} }
Ok(()) Ok(path)
} }
pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) { pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) {

View file

@ -4,7 +4,7 @@ use erg_common::Str;
// use erg_common::error::Location; // use erg_common::error::Location;
use erg_common::{enum_unwrap, set}; use erg_common::{enum_unwrap, set};
use erg_type::constructors::{func1, mono_q, poly, quant, refinement}; use erg_type::constructors::{builtin_poly, func1, mono_q, quant, refinement};
use erg_type::typaram::TyParam; use erg_type::typaram::TyParam;
use erg_type::{Predicate, TyBound, Type}; use erg_type::{Predicate, TyBound, Type};
use Type::*; use Type::*;
@ -32,7 +32,7 @@ impl Context {
pub fn test_resolve_trait_inner1(&self) -> Result<(), ()> { pub fn test_resolve_trait_inner1(&self) -> Result<(), ()> {
let name = Str::ever("Add"); let name = Str::ever("Add");
let params = vec![TyParam::t(Nat)]; let params = vec![TyParam::t(Nat)];
let maybe_trait = poly(name.clone(), params); let maybe_trait = builtin_poly(name.clone(), params);
let mut min = Type::Obj; let mut min = Type::Obj;
for pair in self.rec_get_trait_impls(&name) { for pair in self.rec_get_trait_impls(&name) {
if self.supertype_of(&pair.sup_trait, &maybe_trait) { if self.supertype_of(&pair.sup_trait, &maybe_trait) {
@ -48,7 +48,7 @@ impl Context {
pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> { pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> {
let t = mono_q("T"); let t = mono_q("T");
let eq = poly("Eq", vec![TyParam::t(t.clone())]); let eq = builtin_poly("Eq", vec![TyParam::t(t.clone())]);
let bound = TyBound::subtype_of(t.clone(), eq); let bound = TyBound::subtype_of(t.clone(), eq);
let bounds = set! {bound}; let bounds = set! {bound};
let unbound_t = func1(t.clone(), t); let unbound_t = func1(t.clone(), t);

View file

@ -22,6 +22,7 @@ use crate::hir;
use Predicate as Pred; use Predicate as Pred;
use Type::*; use Type::*;
use ValueObj::{Inf, NegInf}; use ValueObj::{Inf, NegInf};
use Variance::*;
impl Context { impl Context {
pub const TOP_LEVEL: usize = 1; pub const TOP_LEVEL: usize = 1;
@ -159,12 +160,23 @@ impl Context {
let after = after.map(|aft| self.generalize_t_inner(*aft, bounds, lazy_inits)); let after = after.map(|aft| self.generalize_t_inner(*aft, bounds, lazy_inits));
ref_mut(self.generalize_t_inner(*before, bounds, lazy_inits), after) ref_mut(self.generalize_t_inner(*before, bounds, lazy_inits), after)
} }
Poly { name, mut params } => { BuiltinPoly { name, mut params } => {
let params = params let params = params
.iter_mut() .iter_mut()
.map(|p| self.generalize_tp(mem::take(p), bounds, lazy_inits)) .map(|p| self.generalize_tp(mem::take(p), bounds, lazy_inits))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
poly(name, params) builtin_poly(name, params)
}
Poly {
path,
name,
mut params,
} => {
let params = params
.iter_mut()
.map(|p| self.generalize_tp(mem::take(p), bounds, lazy_inits))
.collect::<Vec<_>>();
poly(path, name, params)
} }
MonoProj { lhs, rhs } => { MonoProj { lhs, rhs } => {
let lhs = self.generalize_t_inner(*lhs, bounds, lazy_inits); let lhs = self.generalize_t_inner(*lhs, bounds, lazy_inits);
@ -203,21 +215,26 @@ impl Context {
} }
} }
fn deref_tp(&self, tp: TyParam, loc: Location) -> SingleTyCheckResult<TyParam> { fn deref_tp(
&self,
tp: TyParam,
variance: Variance,
loc: Location,
) -> SingleTyCheckResult<TyParam> {
match tp { match tp {
TyParam::FreeVar(fv) if fv.is_linked() => { TyParam::FreeVar(fv) if fv.is_linked() => {
let inner = fv.unwrap_linked(); let inner = fv.unwrap_linked();
self.deref_tp(inner, loc) self.deref_tp(inner, variance, loc)
} }
TyParam::FreeVar(_fv) if self.level == 0 => Err(TyCheckError::dummy_infer_error( TyParam::FreeVar(_fv) if self.level == 0 => Err(TyCheckError::dummy_infer_error(
self.cfg.input.clone(), self.cfg.input.clone(),
fn_name!(), fn_name!(),
line!(), line!(),
)), )),
TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t, loc)?)), TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t, variance, loc)?)),
TyParam::App { name, mut args } => { TyParam::App { name, mut args } => {
for param in args.iter_mut() { for param in args.iter_mut() {
*param = self.deref_tp(mem::take(param), loc)?; *param = self.deref_tp(mem::take(param), variance, loc)?;
} }
Ok(TyParam::App { name, args }) Ok(TyParam::App { name, args })
} }
@ -243,6 +260,7 @@ impl Context {
fn deref_constraint( fn deref_constraint(
&self, &self,
constraint: Constraint, constraint: Constraint,
variance: Variance,
loc: Location, loc: Location,
) -> SingleTyCheckResult<Constraint> { ) -> SingleTyCheckResult<Constraint> {
match constraint { match constraint {
@ -259,12 +277,14 @@ impl Context {
)); ));
} }
Ok(Constraint::new_sandwiched( Ok(Constraint::new_sandwiched(
self.deref_tyvar(sub, loc)?, self.deref_tyvar(sub, variance, loc)?,
self.deref_tyvar(sup, loc)?, self.deref_tyvar(sup, variance, loc)?,
cyclic, cyclic,
)) ))
} }
Constraint::TypeOf(t) => Ok(Constraint::new_type_of(self.deref_tyvar(t, loc)?)), Constraint::TypeOf(t) => {
Ok(Constraint::new_type_of(self.deref_tyvar(t, variance, loc)?))
}
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -273,10 +293,16 @@ impl Context {
/// ```python /// ```python
// ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n) // ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n)
// ?T(:> Nat, <: Sub(?U(:> {1}))) ==> Nat // ?T(:> Nat, <: Sub(?U(:> {1}))) ==> Nat
// ?T(:> Nat, <: Sub(?U(:> {1}))) -> ?U ==> |U: Type, T <: Sub(U)| T -> U
// ?T(:> Nat, <: Sub(Str)) ==> Error! // ?T(:> Nat, <: Sub(Str)) ==> Error!
// ?T(:> {1, "a"}, <: Eq(?T(:> {1, "a"}, ...)) ==> Error! // ?T(:> {1, "a"}, <: Eq(?T(:> {1, "a"}, ...)) ==> Error!
// ``` // ```
pub(crate) fn deref_tyvar(&self, t: Type, loc: Location) -> SingleTyCheckResult<Type> { pub(crate) fn deref_tyvar(
&self,
t: Type,
variance: Variance,
loc: Location,
) -> SingleTyCheckResult<Type> {
match t { match t {
// ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n) // ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n)
// ?T(:> Nat, <: Sub ?U(:> {1}))[n] ==> Nat // ?T(:> Nat, <: Sub ?U(:> {1}))[n] ==> Nat
@ -288,13 +314,31 @@ impl Context {
if self.level <= fv.level().unwrap() { if self.level <= fv.level().unwrap() {
// REVIEW: Even if type constraints can be satisfied, implementation may not exist // REVIEW: Even if type constraints can be satisfied, implementation may not exist
if self.subtype_of(sub_t, super_t) { if self.subtype_of(sub_t, super_t) {
Ok(sub_t.clone()) match variance {
Variance::Covariant => Ok(sub_t.clone()),
Variance::Contravariant => Ok(super_t.clone()),
Variance::Invariant => {
if self.supertype_of(sub_t, super_t) {
Ok(sub_t.clone())
} else {
Err(TyCheckError::subtyping_error(
self.cfg.input.clone(),
line!() as usize,
&self.deref_tyvar(sub_t.clone(), variance, loc)?,
&self.deref_tyvar(super_t.clone(), variance, loc)?,
None,
Some(loc),
self.caused_by(),
))
}
}
}
} else { } else {
Err(TyCheckError::subtyping_error( Err(TyCheckError::subtyping_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
&self.deref_tyvar(sub_t.clone(), loc)?, &self.deref_tyvar(sub_t.clone(), variance, loc)?,
&self.deref_tyvar(super_t.clone(), loc)?, &self.deref_tyvar(super_t.clone(), variance, loc)?,
None, None,
Some(loc), Some(loc),
self.caused_by(), self.caused_by(),
@ -318,42 +362,62 @@ impl Context {
} }
} else { } else {
let new_constraint = fv.crack_constraint().clone(); let new_constraint = fv.crack_constraint().clone();
let new_constraint = self.deref_constraint(new_constraint, loc)?; let new_constraint = self.deref_constraint(new_constraint, variance, loc)?;
fv.update_constraint(new_constraint); fv.update_constraint(new_constraint);
Ok(Type::FreeVar(fv)) Ok(Type::FreeVar(fv))
} }
} }
Type::FreeVar(fv) if fv.is_linked() => { Type::FreeVar(fv) if fv.is_linked() => {
let t = fv.unwrap_linked(); let t = fv.unwrap_linked();
self.deref_tyvar(t, loc) self.deref_tyvar(t, variance, loc)
} }
Type::Poly { name, mut params } => { Type::BuiltinPoly { name, mut params } => {
for param in params.iter_mut() { let typ = builtin_poly(&name, params.clone());
*param = self.deref_tp(mem::take(param), loc)?; let (_, ctx) = self.get_nominal_type_ctx(&typ).unwrap();
let variances = ctx.type_params_variance();
for (param, variance) in params.iter_mut().zip(variances.into_iter()) {
*param = self.deref_tp(mem::take(param), variance, loc)?;
} }
Ok(Type::Poly { name, params }) Ok(Type::BuiltinPoly { name, params })
}
Type::Poly {
path,
name,
mut params,
} => {
let typ = poly(path.clone(), &name, params.clone());
let (_, ctx) = self.get_nominal_type_ctx(&typ).unwrap();
let variances = ctx.type_params_variance();
for (param, variance) in params.iter_mut().zip(variances.into_iter()) {
*param = self.deref_tp(mem::take(param), variance, loc)?;
}
Ok(Type::Poly { path, name, params })
} }
Type::Subr(mut subr) => { Type::Subr(mut subr) => {
for param in subr.non_default_params.iter_mut() { for param in subr.non_default_params.iter_mut() {
*param.typ_mut() = self.deref_tyvar(mem::take(param.typ_mut()), loc)?; *param.typ_mut() =
self.deref_tyvar(mem::take(param.typ_mut()), Contravariant, loc)?;
} }
if let Some(var_args) = &mut subr.var_params { if let Some(var_args) = &mut subr.var_params {
*var_args.typ_mut() = self.deref_tyvar(mem::take(var_args.typ_mut()), loc)?; *var_args.typ_mut() =
self.deref_tyvar(mem::take(var_args.typ_mut()), Contravariant, loc)?;
} }
for d_param in subr.default_params.iter_mut() { for d_param in subr.default_params.iter_mut() {
*d_param.typ_mut() = self.deref_tyvar(mem::take(d_param.typ_mut()), loc)?; *d_param.typ_mut() =
self.deref_tyvar(mem::take(d_param.typ_mut()), Contravariant, loc)?;
} }
subr.return_t = Box::new(self.deref_tyvar(mem::take(&mut subr.return_t), loc)?); subr.return_t =
Box::new(self.deref_tyvar(mem::take(&mut subr.return_t), Covariant, loc)?);
Ok(Type::Subr(subr)) Ok(Type::Subr(subr))
} }
Type::Ref(t) => { Type::Ref(t) => {
let t = self.deref_tyvar(*t, loc)?; let t = self.deref_tyvar(*t, variance, loc)?;
Ok(ref_(t)) Ok(ref_(t))
} }
Type::RefMut { before, after } => { Type::RefMut { before, after } => {
let before = self.deref_tyvar(*before, loc)?; let before = self.deref_tyvar(*before, variance, loc)?;
let after = if let Some(after) = after { let after = if let Some(after) = after {
Some(self.deref_tyvar(*after, loc)?) Some(self.deref_tyvar(*after, variance, loc)?)
} else { } else {
None None
}; };
@ -362,12 +426,29 @@ impl Context {
Type::Callable { .. } => todo!(), Type::Callable { .. } => todo!(),
Type::Record(mut rec) => { Type::Record(mut rec) => {
for (_, field) in rec.iter_mut() { for (_, field) in rec.iter_mut() {
*field = self.deref_tyvar(mem::take(field), loc)?; *field = self.deref_tyvar(mem::take(field), variance, loc)?;
} }
Ok(Type::Record(rec)) Ok(Type::Record(rec))
} }
// |X <: T <: X| X -> X ==> T -> T
/*Type::Quantified(quant) => {
let mut replace_list = vec![];
let mut new_bounds = set!{};
for bound in quant.bounds.into_iter() {
if let Some((sub, mid, sup)) = bound.get_types() {
if self.subtype_of(sub, sup) && self.supertype_of(sub, sup) {
replace_list.push((mid, sub));
} else {
new_bounds.insert(bound);
}
} else {
new_bounds.insert(bound);
}
}
Ok(())
}*/
Type::Refinement(refine) => { Type::Refinement(refine) => {
let t = self.deref_tyvar(*refine.t, loc)?; let t = self.deref_tyvar(*refine.t, variance, loc)?;
// TODO: deref_predicate // TODO: deref_predicate
Ok(refinement(refine.var, t, refine.preds)) Ok(refinement(refine.var, t, refine.preds))
} }
@ -401,7 +482,7 @@ impl Context {
hir::Expr::Accessor(acc) => { hir::Expr::Accessor(acc) => {
let loc = acc.loc(); let loc = acc.loc();
let t = acc.ref_mut_t(); let t = acc.ref_mut_t();
*t = self.deref_tyvar(mem::take(t), loc)?; *t = self.deref_tyvar(mem::take(t), Covariant, loc)?;
match acc { match acc {
hir::Accessor::Attr(attr) => { hir::Accessor::Attr(attr) => {
self.resolve_expr_t(&mut attr.obj)?; self.resolve_expr_t(&mut attr.obj)?;
@ -420,7 +501,7 @@ impl Context {
hir::Expr::Array(array) => match array { hir::Expr::Array(array) => match array {
hir::Array::Normal(arr) => { hir::Array::Normal(arr) => {
let loc = arr.loc(); let loc = arr.loc();
arr.t = self.deref_tyvar(mem::take(&mut arr.t), loc)?; arr.t = self.deref_tyvar(mem::take(&mut arr.t), Covariant, loc)?;
for elem in arr.elems.pos_args.iter_mut() { for elem in arr.elems.pos_args.iter_mut() {
self.resolve_expr_t(&mut elem.expr)?; self.resolve_expr_t(&mut elem.expr)?;
} }
@ -443,10 +524,12 @@ impl Context {
for attr in record.attrs.iter_mut() { for attr in record.attrs.iter_mut() {
match &mut attr.sig { match &mut attr.sig {
hir::Signature::Var(var) => { hir::Signature::Var(var) => {
var.t = self.deref_tyvar(mem::take(&mut var.t), var.loc())?; var.t =
self.deref_tyvar(mem::take(&mut var.t), Covariant, var.loc())?;
} }
hir::Signature::Subr(subr) => { hir::Signature::Subr(subr) => {
subr.t = self.deref_tyvar(mem::take(&mut subr.t), subr.loc())?; subr.t =
self.deref_tyvar(mem::take(&mut subr.t), Covariant, subr.loc())?;
} }
} }
for chunk in attr.body.block.iter_mut() { for chunk in attr.body.block.iter_mut() {
@ -458,7 +541,7 @@ impl Context {
hir::Expr::BinOp(binop) => { hir::Expr::BinOp(binop) => {
let loc = binop.loc(); let loc = binop.loc();
let t = binop.signature_mut_t().unwrap(); let t = binop.signature_mut_t().unwrap();
*t = self.deref_tyvar(mem::take(t), loc)?; *t = self.deref_tyvar(mem::take(t), Covariant, loc)?;
self.resolve_expr_t(&mut binop.lhs)?; self.resolve_expr_t(&mut binop.lhs)?;
self.resolve_expr_t(&mut binop.rhs)?; self.resolve_expr_t(&mut binop.rhs)?;
Ok(()) Ok(())
@ -466,14 +549,14 @@ impl Context {
hir::Expr::UnaryOp(unaryop) => { hir::Expr::UnaryOp(unaryop) => {
let loc = unaryop.loc(); let loc = unaryop.loc();
let t = unaryop.signature_mut_t().unwrap(); let t = unaryop.signature_mut_t().unwrap();
*t = self.deref_tyvar(mem::take(t), loc)?; *t = self.deref_tyvar(mem::take(t), Covariant, loc)?;
self.resolve_expr_t(&mut unaryop.expr)?; self.resolve_expr_t(&mut unaryop.expr)?;
Ok(()) Ok(())
} }
hir::Expr::Call(call) => { hir::Expr::Call(call) => {
let loc = call.loc(); let loc = call.loc();
let t = call.signature_mut_t().unwrap(); let t = call.signature_mut_t().unwrap();
*t = self.deref_tyvar(mem::take(t), loc)?; *t = self.deref_tyvar(mem::take(t), Covariant, loc)?;
for arg in call.args.pos_args.iter_mut() { for arg in call.args.pos_args.iter_mut() {
self.resolve_expr_t(&mut arg.expr)?; self.resolve_expr_t(&mut arg.expr)?;
} }
@ -483,16 +566,16 @@ impl Context {
Ok(()) Ok(())
} }
hir::Expr::Decl(decl) => { hir::Expr::Decl(decl) => {
decl.t = self.deref_tyvar(mem::take(&mut decl.t), decl.loc())?; decl.t = self.deref_tyvar(mem::take(&mut decl.t), Covariant, decl.loc())?;
Ok(()) Ok(())
} }
hir::Expr::Def(def) => { hir::Expr::Def(def) => {
match &mut def.sig { match &mut def.sig {
hir::Signature::Var(var) => { hir::Signature::Var(var) => {
var.t = self.deref_tyvar(mem::take(&mut var.t), var.loc())?; var.t = self.deref_tyvar(mem::take(&mut var.t), Covariant, var.loc())?;
} }
hir::Signature::Subr(subr) => { hir::Signature::Subr(subr) => {
subr.t = self.deref_tyvar(mem::take(&mut subr.t), subr.loc())?; subr.t = self.deref_tyvar(mem::take(&mut subr.t), Covariant, subr.loc())?;
} }
} }
for chunk in def.body.block.iter_mut() { for chunk in def.body.block.iter_mut() {
@ -501,7 +584,7 @@ impl Context {
Ok(()) Ok(())
} }
hir::Expr::Lambda(lambda) => { hir::Expr::Lambda(lambda) => {
lambda.t = self.deref_tyvar(mem::take(&mut lambda.t), lambda.loc())?; lambda.t = self.deref_tyvar(mem::take(&mut lambda.t), Covariant, lambda.loc())?;
for chunk in lambda.body.iter_mut() { for chunk in lambda.body.iter_mut() {
self.resolve_expr_t(chunk)?; self.resolve_expr_t(chunk)?;
} }
@ -780,17 +863,46 @@ impl Context {
(l, Type::Ref(r)) => self.reunify(l, r, bef_loc, aft_loc), (l, Type::Ref(r)) => self.reunify(l, r, bef_loc, aft_loc),
(l, Type::RefMut { before, .. }) => self.reunify(l, before, bef_loc, aft_loc), (l, Type::RefMut { before, .. }) => self.reunify(l, before, bef_loc, aft_loc),
( (
Type::Poly { Type::BuiltinPoly {
name: ln, name: ln,
params: lps, params: lps,
}, },
Type::Poly { Type::BuiltinPoly {
name: rn, name: rn,
params: rps, params: rps,
}, },
) => { ) => {
if ln != rn { if ln != rn {
let before_t = poly(ln.clone(), lps.clone()); let before_t = builtin_poly(ln.clone(), lps.clone());
return Err(TyCheckError::re_unification_error(
self.cfg.input.clone(),
line!() as usize,
&before_t,
after_t,
bef_loc,
aft_loc,
self.caused_by(),
));
}
for (l, r) in lps.iter().zip(rps.iter()) {
self.reunify_tp(l, r)?;
}
Ok(())
}
(
Type::Poly {
path: lp,
name: ln,
params: lps,
},
Type::Poly {
path: rp,
name: rn,
params: rps,
},
) => {
if lp != rp || ln != rn {
let before_t = poly(lp.clone(), ln.clone(), lps.clone());
return Err(TyCheckError::re_unification_error( return Err(TyCheckError::re_unification_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
@ -1047,11 +1159,11 @@ impl Context {
Ok(()) Ok(())
} }
( (
Type::Poly { Type::BuiltinPoly {
name: ln, name: ln,
params: lps, params: lps,
}, },
Type::Poly { Type::BuiltinPoly {
name: rn, name: rn,
params: rps, params: rps,
}, },
@ -1072,6 +1184,34 @@ impl Context {
} }
Ok(()) Ok(())
} }
(
Type::Poly {
path: lp,
name: ln,
params: lps,
},
Type::Poly {
path: rp,
name: rn,
params: rps,
},
) => {
if lp != rp || ln != rn {
return Err(TyCheckErrors::from(TyCheckError::unification_error(
self.cfg.input.clone(),
line!() as usize,
maybe_sub,
maybe_sup,
sub_loc,
sup_loc,
self.caused_by(),
)));
}
for (l, r) in lps.iter().zip(rps.iter()) {
self.sub_unify_tp(l, r, None, false)?;
}
Ok(())
}
(_, Type::Ref(t)) => { (_, Type::Ref(t)) => {
self.sub_unify(maybe_sub, t, sub_loc, sup_loc, param_name)?; self.sub_unify(maybe_sub, t, sub_loc, sup_loc, param_name)?;
Ok(()) Ok(())
@ -1085,7 +1225,7 @@ impl Context {
(Refinement(_), Refinement(_)) => todo!(), (Refinement(_), Refinement(_)) => todo!(),
(Type::Subr(_) | Type::Record(_), Type) => Ok(()), (Type::Subr(_) | Type::Record(_), Type) => Ok(()),
// TODO Tuple2, ... // TODO Tuple2, ...
(Type::Poly{ name, .. }, Type) if &name[..] == "Array" || &name[..] == "Tuple" => Ok(()), (Type::BuiltinPoly{ name, .. }, Type) if &name[..] == "Array" || &name[..] == "Tuple" => Ok(()),
_ => todo!("{maybe_sub} can be a subtype of {maybe_sup}, but failed to semi-unify (or existential types are not supported)"), _ => todo!("{maybe_sub} can be a subtype of {maybe_sup}, but failed to semi-unify (or existential types are not supported)"),
} }
} }

View file

@ -385,6 +385,10 @@ impl Identifier {
pub fn is_procedural(&self) -> bool { pub fn is_procedural(&self) -> bool {
self.name.is_procedural() self.name.is_procedural()
} }
pub fn downcast(self) -> erg_parser::ast::Identifier {
erg_parser::ast::Identifier::new(self.dot, self.name)
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -1,5 +1,5 @@
use std::mem; use std::mem;
use std::path::PathBuf; use std::path::{Path, PathBuf};
use erg_common::config::{ErgConfig, Input}; use erg_common::config::{ErgConfig, Input};
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
@ -9,8 +9,9 @@ use erg_common::{enum_unwrap, log};
use erg_parser::ast::DefId; use erg_parser::ast::DefId;
use erg_parser::token::{Token, TokenKind}; use erg_parser::token::{Token, TokenKind};
use erg_type::typaram::TyParam;
use erg_type::value::ValueObj; use erg_type::value::ValueObj;
use erg_type::Type; use erg_type::{HasType, Type};
use crate::hir::{ use crate::hir::{
Accessor, Args, Block, Call, Def, DefBody, Expr, Identifier, Literal, PosArg, HIR, Accessor, Args, Block, Call, Def, DefBody, Expr, Identifier, Literal, PosArg, HIR,
@ -30,15 +31,16 @@ impl Linker {
// x = ModuleType("mod") // x = ModuleType("mod")
// exec(code, x.__dict__) # `code` is the mod's content // exec(code, x.__dict__) # `code` is the mod's content
Expr::Def(ref def) if def.def_kind().is_erg_import() => { Expr::Def(ref def) if def.def_kind().is_erg_import() => {
let path = enum_unwrap!(def.sig.ref_t().typarams().remove(0), TyParam::Value:(ValueObj::Str:(_)));
let path = Path::new(&path[..]);
let path = cfg.input.resolve(path).unwrap();
// In the case of REPL, entries cannot be used up // In the case of REPL, entries cannot be used up
let hir = if cfg.input.is_repl() { let hir = if cfg.input.is_repl() {
mod_cache mod_cache
.get(&def.sig.ident().inspect()[..]) .get(path.as_path())
.and_then(|entry| entry.hir.clone()) .and_then(|entry| entry.hir.clone())
} else { } else {
mod_cache mod_cache.remove(path.as_path()).and_then(|entry| entry.hir)
.remove(&def.sig.ident().inspect()[..])
.and_then(|entry| entry.hir)
}; };
let mod_name = enum_unwrap!(def.body.block.first().unwrap(), Expr::Call) let mod_name = enum_unwrap!(def.body.block.first().unwrap(), Expr::Call)
.args .args

View file

@ -16,7 +16,7 @@ use erg_parser::build_ast::ASTBuilder;
use erg_parser::token::{Token, TokenKind}; use erg_parser::token::{Token, TokenKind};
use erg_type::constructors::{ use erg_type::constructors::{
array, array_mut, builtin_mono, free_var, func, mono, poly, proc, quant, array, array_mut, builtin_mono, builtin_poly, free_var, func, mono, proc, quant,
}; };
use erg_type::free::Constraint; use erg_type::free::Constraint;
use erg_type::typaram::TyParam; use erg_type::typaram::TyParam;
@ -85,11 +85,8 @@ impl Runnable for ASTLowerer {
fn exec(&mut self) -> Result<(), Self::Errs> { fn exec(&mut self) -> Result<(), Self::Errs> {
let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let mut ast_builder = ASTBuilder::new(self.cfg.copy());
let ast = ast_builder.build(self.input().read())?; let ast = ast_builder.build(self.input().read())?;
let (hir, warns) = self let (hir, warns) = self.lower(ast, "exec").map_err(|(_, errs)| errs)?;
.lower(ast, "exec")
.map_err(|(_, errs)| self.convert(errs))?;
if self.cfg.verbose >= 2 { if self.cfg.verbose >= 2 {
let warns = self.convert(warns);
warns.fmt_all_stderr(); warns.fmt_all_stderr();
} }
println!("{hir}"); println!("{hir}");
@ -99,9 +96,7 @@ impl Runnable for ASTLowerer {
fn eval(&mut self, src: String) -> Result<String, Self::Errs> { fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let mut ast_builder = ASTBuilder::new(self.cfg.copy());
let ast = ast_builder.build(src)?; let ast = ast_builder.build(src)?;
let (hir, ..) = self let (hir, ..) = self.lower(ast, "eval").map_err(|(_, errs)| errs)?;
.lower(ast, "eval")
.map_err(|(_, errs)| self.convert(errs))?;
Ok(format!("{hir}")) Ok(format!("{hir}"))
} }
} }
@ -121,13 +116,6 @@ impl ASTLowerer {
} }
} }
fn convert(&self, errs: LowerErrors) -> CompileErrors {
errs.into_iter()
.map(|e| CompileError::new(e.core, self.input().clone(), e.caused_by))
.collect::<Vec<_>>()
.into()
}
fn return_t_check( fn return_t_check(
&self, &self,
loc: Location, loc: Location,
@ -160,7 +148,7 @@ impl ASTLowerer {
if mode != "eval" && !expr.ref_t().is_nonelike() && !expr.is_type_asc() { if mode != "eval" && !expr.ref_t().is_nonelike() && !expr.is_type_asc() {
Err(LowerError::syntax_error( Err(LowerError::syntax_error(
self.cfg.input.clone(), self.cfg.input.clone(),
0, line!() as usize,
expr.loc(), expr.loc(),
AtomicStr::arc(&self.ctx.name[..]), AtomicStr::arc(&self.ctx.name[..]),
switch_lang!( switch_lang!(
@ -264,7 +252,7 @@ impl ASTLowerer {
match maybe_len { match maybe_len {
Ok(v @ ValueObj::Nat(_)) => { Ok(v @ ValueObj::Nat(_)) => {
if elem.ref_t().is_mut() { if elem.ref_t().is_mut() {
poly( builtin_poly(
"ArrayWithMutType!", "ArrayWithMutType!",
vec![TyParam::t(elem.t()), TyParam::Value(v)], vec![TyParam::t(elem.t()), TyParam::Value(v)],
) )
@ -274,7 +262,7 @@ impl ASTLowerer {
} }
Ok(v @ ValueObj::Mut(_)) if v.class() == builtin_mono("Nat!") => { Ok(v @ ValueObj::Mut(_)) if v.class() == builtin_mono("Nat!") => {
if elem.ref_t().is_mut() { if elem.ref_t().is_mut() {
poly( builtin_poly(
"ArrayWithMutTypeAndLength!", "ArrayWithMutTypeAndLength!",
vec![TyParam::t(elem.t()), TyParam::Value(v)], vec![TyParam::t(elem.t()), TyParam::Value(v)],
) )
@ -286,7 +274,7 @@ impl ASTLowerer {
// REVIEW: is it ok to ignore the error? // REVIEW: is it ok to ignore the error?
Err(_e) => { Err(_e) => {
if elem.ref_t().is_mut() { if elem.ref_t().is_mut() {
poly( builtin_poly(
"ArrayWithMutType!", "ArrayWithMutType!",
vec![TyParam::t(elem.t()), TyParam::erased(Type::Nat)], vec![TyParam::t(elem.t()), TyParam::erased(Type::Nat)],
) )
@ -349,7 +337,9 @@ impl ASTLowerer {
} }
ast::Accessor::Attr(attr) => { ast::Accessor::Attr(attr) => {
let obj = self.lower_expr(*attr.obj)?; let obj = self.lower_expr(*attr.obj)?;
let t = self.ctx.rec_get_attr_t(&obj, &attr.ident, &self.ctx.name)?; let t =
self.ctx
.rec_get_attr_t(&obj, &attr.ident, &self.cfg.input, &self.ctx.name)?;
let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name); let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name);
let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident, t)); let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident, t));
Ok(acc) Ok(acc)
@ -389,8 +379,12 @@ impl ASTLowerer {
(Type::Failure, None) (Type::Failure, None)
} else { } else {
( (
self.ctx.rec_get_var_t(&ident, &self.ctx.name)?, self.ctx
self.ctx.get_local_uniq_obj_name(&ident.name), .rec_get_var_t(&ident, &self.cfg.input, &self.ctx.name)?,
self.ctx
.get_singular_ctx_from_ident(&ident, &self.ctx.name)
.ok()
.map(|ctx| ctx.name.clone()),
) )
}; };
let ident = hir::Identifier::new(ident.dot, ident.name, __name__, t); let ident = hir::Identifier::new(ident.dot, ident.name, __name__, t);
@ -403,7 +397,9 @@ impl ASTLowerer {
let lhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?); let lhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
let rhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?); let rhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
let args = [lhs, rhs]; let args = [lhs, rhs];
let t = self.ctx.get_binop_t(&bin.op, &args, &self.ctx.name)?; let t = self
.ctx
.get_binop_t(&bin.op, &args, &self.cfg.input, &self.ctx.name)?;
let mut args = args.into_iter(); let mut args = args.into_iter();
let lhs = args.next().unwrap().expr; let lhs = args.next().unwrap().expr;
let rhs = args.next().unwrap().expr; let rhs = args.next().unwrap().expr;
@ -415,7 +411,9 @@ impl ASTLowerer {
let mut args = unary.args.into_iter(); let mut args = unary.args.into_iter();
let arg = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?); let arg = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
let args = [arg]; let args = [arg];
let t = self.ctx.get_unaryop_t(&unary.op, &args, &self.ctx.name)?; let t = self
.ctx
.get_unaryop_t(&unary.op, &args, &self.cfg.input, &self.ctx.name)?;
let mut args = args.into_iter(); let mut args = args.into_iter();
let expr = args.next().unwrap().expr; let expr = args.next().unwrap().expr;
Ok(hir::UnaryOp::new(unary.op, expr, t)) Ok(hir::UnaryOp::new(unary.op, expr, t))
@ -443,6 +441,7 @@ impl ASTLowerer {
&call.method_name, &call.method_name,
&hir_args.pos_args, &hir_args.pos_args,
&hir_args.kw_args, &hir_args.kw_args,
&self.cfg.input,
&self.ctx.name, &self.ctx.name,
)?; )?;
let method_name = if let Some(method_name) = call.method_name { let method_name = if let Some(method_name) = call.method_name {
@ -455,7 +454,14 @@ impl ASTLowerer {
} else { } else {
None None
}; };
Ok(hir::Call::new(obj, method_name, hir_args, sig_t)) let call = hir::Call::new(obj, method_name, hir_args, sig_t);
if let Some(kind) = call.import_kind() {
let mod_name = enum_unwrap!(call.args.get_left_or_key("Path").unwrap(), hir::Expr::Lit);
if let Err(errs) = self.ctx.import_mod(kind, mod_name) {
self.errs.extend(errs.into_iter());
};
}
Ok(call)
} }
fn lower_pack(&mut self, pack: ast::DataPack) -> LowerResult<hir::Call> { fn lower_pack(&mut self, pack: ast::DataPack) -> LowerResult<hir::Call> {
@ -482,6 +488,7 @@ impl ASTLowerer {
&Some(method_name.clone()), &Some(method_name.clone()),
&args, &args,
&[], &[],
&self.cfg.input,
&self.ctx.name, &self.ctx.name,
)?; )?;
let args = hir::Args::new(args, None, vec![], None); let args = hir::Args::new(args, None, vec![], None);
@ -630,20 +637,6 @@ impl ASTLowerer {
.as_mut() .as_mut()
.unwrap() .unwrap()
.assign_var_sig(&sig, found_body_t, id)?; .assign_var_sig(&sig, found_body_t, id)?;
match block.first().unwrap() {
hir::Expr::Call(call) => {
if let Some(kind) = call.import_kind() {
if let Err(errs) = self.ctx.outer.as_mut().unwrap().import_mod(
kind,
&ident.name,
&call.args.pos_args.first().unwrap().expr,
) {
self.errs.extend(errs.into_iter());
};
}
}
_other => {}
}
let ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone()); let ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone());
let sig = hir::VarSignature::new(ident, found_body_t.clone()); let sig = hir::VarSignature::new(ident, found_body_t.clone());
let body = hir::DefBody::new(body.op, block, body.id); let body = hir::DefBody::new(body.op, block, body.id);
@ -785,7 +778,7 @@ impl ASTLowerer {
} }
let (_, ctx) = self let (_, ctx) = self
.ctx .ctx
.get_nominal_type_ctx(&mono(self.ctx.mod_name(), hir_def.sig.ident().inspect())) .get_nominal_type_ctx(&mono(self.ctx.path(), hir_def.sig.ident().inspect()))
.unwrap(); .unwrap();
let type_obj = enum_unwrap!(self.ctx.rec_get_const_obj(hir_def.sig.ident().inspect()).unwrap(), ValueObj::Type:(TypeObj::Generated:(_))); let type_obj = enum_unwrap!(self.ctx.rec_get_const_obj(hir_def.sig.ident().inspect()).unwrap(), ValueObj::Type:(TypeObj::Generated:(_)));
let sup_type = enum_unwrap!(&hir_def.body.block.first().unwrap(), hir::Expr::Call) let sup_type = enum_unwrap!(&hir_def.body.block.first().unwrap(), hir::Expr::Call)
@ -1224,7 +1217,7 @@ impl ASTLowerer {
Ok(hir) => hir, Ok(hir) => hir,
Err((hir, errs)) => { Err((hir, errs)) => {
self.errs.extend(errs.into_iter()); self.errs.extend(errs.into_iter());
log!(err "the AST lowering process has failed."); log!(err "the resolving process has failed. errs: {}", self.errs.len());
return Err((Some(hir), LowerErrors::from(self.errs.take_all()))); return Err((Some(hir), LowerErrors::from(self.errs.take_all())));
} }
}; };
@ -1239,7 +1232,7 @@ impl ASTLowerer {
log!(info "the AST lowering process has completed."); log!(info "the AST lowering process has completed.");
Ok((hir, LowerWarnings::from(self.warns.take_all()))) Ok((hir, LowerWarnings::from(self.warns.take_all())))
} else { } else {
log!(err "the AST lowering process has failed."); log!(err "the AST lowering process has failed. errs: {}", self.errs.len());
Err((Some(hir), LowerErrors::from(self.errs.take_all()))) Err((Some(hir), LowerErrors::from(self.errs.take_all())))
} }
} }

View file

@ -1,6 +1,7 @@
use std::borrow::Borrow; use std::borrow::Borrow;
use std::fmt; use std::fmt;
use std::hash::Hash; use std::hash::Hash;
use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use erg_common::dict::Dict; use erg_common::dict::Dict;
@ -8,8 +9,6 @@ use erg_common::levenshtein::get_similar_name;
use erg_common::shared::Shared; use erg_common::shared::Shared;
use erg_common::Str; use erg_common::Str;
use erg_parser::ast::VarName;
use crate::context::Context; use crate::context::Context;
use crate::hir::HIR; use crate::hir::HIR;
@ -65,13 +64,17 @@ impl ModuleEntry {
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct ModuleCache { pub struct ModuleCache {
cache: Dict<VarName, ModuleEntry>, cache: Dict<PathBuf, ModuleEntry>,
last_id: usize, last_id: usize,
} }
impl fmt::Display for ModuleCache { impl fmt::Display for ModuleCache {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ModuleCache {}", self.cache) write!(f, "ModuleCache {{")?;
for (path, entry) in self.cache.iter() {
writeln!(f, "{}: {}, ", path.display(), entry)?;
}
write!(f, "}}")
} }
} }
@ -83,42 +86,32 @@ impl ModuleCache {
} }
} }
pub fn get<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<&ModuleEntry> pub fn get<P: Eq + Hash + ?Sized>(&self, path: &P) -> Option<&ModuleEntry>
where where
VarName: Borrow<Q>, PathBuf: Borrow<P>,
{ {
self.cache.get(name) self.cache.get(path)
} }
pub fn get_by_name(&self, __name__: &str) -> Option<(&VarName, &ModuleEntry)> { pub fn get_mut<Q: Eq + Hash + ?Sized>(&mut self, path: &Q) -> Option<&mut ModuleEntry>
self.cache
.iter()
.find(|(_, ent)| &ent.ctx.name[..] == __name__)
}
pub fn get_mut<Q: Eq + Hash + ?Sized>(&mut self, name: &Q) -> Option<&mut ModuleEntry>
where where
VarName: Borrow<Q>, PathBuf: Borrow<Q>,
{ {
self.cache.get_mut(name) self.cache.get_mut(path)
} }
pub fn register(&mut self, name: VarName, hir: Option<HIR>, ctx: Context) { pub fn register(&mut self, path: PathBuf, hir: Option<HIR>, ctx: Context) {
self.last_id += 1; self.last_id += 1;
let id = ModId::new(self.last_id); let id = ModId::new(self.last_id);
let entry = ModuleEntry::new(id, hir, ctx); let entry = ModuleEntry::new(id, hir, ctx);
self.cache.insert(name, entry); self.cache.insert(path, entry);
} }
pub fn register_alias(&mut self, name: VarName, entry: &ModuleEntry) { pub fn remove<Q: Eq + Hash + ?Sized>(&mut self, path: &Q) -> Option<ModuleEntry>
self.cache.insert(name, entry.clone());
}
pub fn remove<Q: Eq + Hash + ?Sized>(&mut self, name: &Q) -> Option<ModuleEntry>
where where
VarName: Borrow<Q>, PathBuf: Borrow<Q>,
{ {
self.cache.remove(name) self.cache.remove(path)
} }
pub fn remove_by_id(&mut self, id: ModId) -> Option<ModuleEntry> { pub fn remove_by_id(&mut self, id: ModId) -> Option<ModuleEntry> {
@ -136,7 +129,7 @@ impl ModuleCache {
} }
pub fn get_similar_name(&self, name: &str) -> Option<Str> { pub fn get_similar_name(&self, name: &str) -> Option<Str> {
get_similar_name(self.cache.iter().map(|(v, _)| &v.inspect()[..]), name).map(Str::rc) get_similar_name(self.cache.iter().map(|(v, _)| v.to_str().unwrap()), name).map(Str::rc)
} }
} }
@ -156,55 +149,46 @@ impl SharedModuleCache {
self_ self_
} }
pub fn get<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<&ModuleEntry> pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&ModuleEntry>
where where
VarName: Borrow<Q>, PathBuf: Borrow<Q>,
{ {
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() }; let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
ref_.get(name) ref_.get(path)
} }
pub fn get_by_name(&self, __name__: &str) -> Option<(&VarName, &ModuleEntry)> { pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&mut ModuleEntry>
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
ref_.get_by_name(__name__)
}
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<&mut ModuleEntry>
where where
VarName: Borrow<Q>, PathBuf: Borrow<Q>,
{ {
let ref_ = unsafe { self.0.as_ptr().as_mut().unwrap() }; let ref_ = unsafe { self.0.as_ptr().as_mut().unwrap() };
ref_.get_mut(name) ref_.get_mut(path)
} }
pub fn get_ctx<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<Rc<Context>> pub fn get_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<Rc<Context>>
where where
VarName: Borrow<Q>, PathBuf: Borrow<Q>,
{ {
self.0.borrow().get(name).map(|entry| entry.ctx.clone()) self.0.borrow().get(path).map(|entry| entry.ctx.clone())
} }
pub fn ref_ctx<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<&Context> pub fn ref_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&Context>
where where
VarName: Borrow<Q>, PathBuf: Borrow<Q>,
{ {
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() }; let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
ref_.get(name).map(|entry| entry.ctx.as_ref()) ref_.get(path).map(|entry| entry.ctx.as_ref())
} }
pub fn register(&self, name: VarName, hir: Option<HIR>, ctx: Context) { pub fn register(&self, path: PathBuf, hir: Option<HIR>, ctx: Context) {
self.0.borrow_mut().register(name, hir, ctx); self.0.borrow_mut().register(path, hir, ctx);
} }
pub fn register_alias(&self, name: VarName, entry: &ModuleEntry) { pub fn remove<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<ModuleEntry>
self.0.borrow_mut().register_alias(name, entry);
}
pub fn remove<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<ModuleEntry>
where where
VarName: Borrow<Q>, PathBuf: Borrow<Q>,
{ {
self.0.borrow_mut().remove(name) self.0.borrow_mut().remove(path)
} }
pub fn remove_by_id(&self, id: ModId) -> Option<ModuleEntry> { pub fn remove_by_id(&self, id: ModId) -> Option<ModuleEntry> {

View file

@ -509,7 +509,28 @@ impl Parser {
let local = ConstLocal::new(local.name.into_token()); let local = ConstLocal::new(local.name.into_token());
Ok(ConstExpr::Accessor(ConstAccessor::Local(local))) Ok(ConstExpr::Accessor(ConstAccessor::Local(local)))
} }
// TODO: App, Array, Record, BinOp, UnaryOp, Expr::Array(array) => match array {
Array::Normal(arr) => {
let (elems, _, _) = arr.elems.deconstruct();
let mut const_elems = vec![];
for elem in elems.into_iter() {
let const_expr = self.validate_const_expr(elem.expr)?;
const_elems.push(ConstPosArg::new(const_expr));
}
let elems = ConstArgs::new(const_elems, vec![], None);
let const_arr = ConstArray::new(arr.l_sqbr, arr.r_sqbr, elems, None);
Ok(ConstExpr::Array(const_arr))
}
other => {
self.errs.push(ParseError::feature_error(
line!() as usize,
other.loc(),
"???",
));
Err(())
}
},
// TODO: App, Record, BinOp, UnaryOp,
other => { other => {
self.errs.push(ParseError::syntax_error( self.errs.push(ParseError::syntax_error(
0, 0,

View file

@ -23,35 +23,51 @@ pub fn named_free_var(name: Str, level: usize, constraint: Constraint) -> Type {
} }
pub fn array(elem_t: Type, len: TyParam) -> Type { pub fn array(elem_t: Type, len: TyParam) -> Type {
poly("Array", vec![TyParam::t(elem_t), len]) builtin_poly("Array", vec![TyParam::t(elem_t), len])
} }
pub fn array_mut(elem_t: Type, len: TyParam) -> Type { pub fn array_mut(elem_t: Type, len: TyParam) -> Type {
poly("Array!", vec![TyParam::t(elem_t), len]) builtin_poly("Array!", vec![TyParam::t(elem_t), len])
} }
pub fn dict(k_t: Type, v_t: Type) -> Type { pub fn dict(k_t: Type, v_t: Type) -> Type {
poly("Dict", vec![TyParam::t(k_t), TyParam::t(v_t)]) builtin_poly("Dict", vec![TyParam::t(k_t), TyParam::t(v_t)])
} }
pub fn tuple(args: Vec<Type>) -> Type { pub fn tuple(args: Vec<Type>) -> Type {
let name = format!("Tuple{}", args.len()); let name = format!("Tuple{}", args.len());
poly(name, args.into_iter().map(TyParam::t).collect()) builtin_poly(name, args.into_iter().map(TyParam::t).collect())
} }
#[inline] #[inline]
pub fn range(t: Type) -> Type { pub fn range(t: Type) -> Type {
poly("Range", vec![TyParam::t(t)]) builtin_poly("Range", vec![TyParam::t(t)])
} }
pub fn enum_t(s: Set<ValueObj>) -> Type { #[inline]
pub fn module(path: TyParam) -> Type {
builtin_poly("Module", vec![path])
}
pub fn v_enum(s: Set<ValueObj>) -> Type {
assert!(is_homogeneous(&s)); assert!(is_homogeneous(&s));
let name = Str::from(fresh_varname()); let name = Str::from(fresh_varname());
let t = inner_class(&s);
let preds = s let preds = s
.iter() .into_iter()
.map(|o| Predicate::eq(name.clone(), TyParam::value(o.clone()))) .map(|o| Predicate::eq(name.clone(), TyParam::value(o)))
.collect(); .collect();
let refine = RefinementType::new(name, inner_class(&s), preds); let refine = RefinementType::new(name, t, preds);
Type::Refinement(refine)
}
pub fn tp_enum(ty: Type, s: Set<TyParam>) -> Type {
let name = Str::from(fresh_varname());
let preds = s
.into_iter()
.map(|tp| Predicate::eq(name.clone(), tp))
.collect();
let refine = RefinementType::new(name, ty, preds);
Type::Refinement(refine) Type::Refinement(refine)
} }
@ -97,7 +113,7 @@ where
} }
pub fn iter(t: Type) -> Type { pub fn iter(t: Type) -> Type {
poly("Iter", vec![TyParam::t(t)]) builtin_poly("Iter", vec![TyParam::t(t)])
} }
pub fn ref_(t: Type) -> Type { pub fn ref_(t: Type) -> Type {
@ -112,11 +128,11 @@ pub fn ref_mut(before: Type, after: Option<Type>) -> Type {
} }
pub fn option(t: Type) -> Type { pub fn option(t: Type) -> Type {
poly("Option", vec![TyParam::t(t)]) builtin_poly("Option", vec![TyParam::t(t)])
} }
pub fn option_mut(t: Type) -> Type { pub fn option_mut(t: Type) -> Type {
poly("Option!", vec![TyParam::t(t)]) builtin_poly("Option!", vec![TyParam::t(t)])
} }
pub fn subr_t( pub fn subr_t(
@ -305,7 +321,7 @@ pub fn mono_q<S: Into<Str>>(name: S) -> Type {
} }
#[inline] #[inline]
pub fn mono<S: Into<Str>, T: Into<Str>>(path: S, name: T) -> Type { pub fn mono<P: Into<PathBuf>, S: Into<Str>>(path: P, name: S) -> Type {
Type::Mono { Type::Mono {
path: path.into(), path: path.into(),
name: name.into(), name: name.into(),
@ -313,8 +329,8 @@ pub fn mono<S: Into<Str>, T: Into<Str>>(path: S, name: T) -> Type {
} }
#[inline] #[inline]
pub fn poly<S: Into<Str>>(name: S, params: Vec<TyParam>) -> Type { pub fn builtin_poly<S: Into<Str>>(name: S, params: Vec<TyParam>) -> Type {
Type::Poly { Type::BuiltinPoly {
name: name.into(), name: name.into(),
params, params,
} }
@ -328,6 +344,15 @@ pub fn poly_q<S: Into<Str>>(name: S, params: Vec<TyParam>) -> Type {
} }
} }
#[inline]
pub fn poly<P: Into<PathBuf>, T: Into<Str>>(path: P, name: T, params: Vec<TyParam>) -> Type {
Type::Poly {
path: path.into(),
name: name.into(),
params,
}
}
#[inline] #[inline]
pub fn mono_proj<S: Into<Str>>(lhs: Type, rhs: S) -> Type { pub fn mono_proj<S: Into<Str>>(lhs: Type, rhs: S) -> Type {
Type::MonoProj { Type::MonoProj {

View file

@ -12,6 +12,7 @@ pub mod value;
use std::fmt; use std::fmt;
use std::ops::{Range, RangeInclusive}; use std::ops::{Range, RangeInclusive};
use std::path::PathBuf;
use erg_common::dict::Dict; use erg_common::dict::Dict;
use erg_common::set::Set; use erg_common::set::Set;
@ -181,7 +182,7 @@ impl ValueArgs {
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct BuiltinConstSubr { pub struct BuiltinConstSubr {
name: &'static str, name: &'static str,
subr: fn(ValueArgs, Str, Option<Str>) -> EvalValueResult<ValueObj>, subr: fn(ValueArgs, PathBuf, Option<Str>) -> EvalValueResult<ValueObj>,
sig_t: Type, sig_t: Type,
as_type: Option<Type>, as_type: Option<Type>,
} }
@ -195,7 +196,7 @@ impl fmt::Display for BuiltinConstSubr {
impl BuiltinConstSubr { impl BuiltinConstSubr {
pub const fn new( pub const fn new(
name: &'static str, name: &'static str,
subr: fn(ValueArgs, Str, Option<Str>) -> EvalValueResult<ValueObj>, subr: fn(ValueArgs, PathBuf, Option<Str>) -> EvalValueResult<ValueObj>,
sig_t: Type, sig_t: Type,
as_type: Option<Type>, as_type: Option<Type>,
) -> Self { ) -> Self {
@ -210,10 +211,10 @@ impl BuiltinConstSubr {
pub fn call( pub fn call(
&self, &self,
args: ValueArgs, args: ValueArgs,
mod_name: Str, path: PathBuf,
__name__: Option<Str>, __name__: Option<Str>,
) -> EvalValueResult<ValueObj> { ) -> EvalValueResult<ValueObj> {
(self.subr)(args, mod_name, __name__) (self.subr)(args, path, __name__)
} }
} }
@ -416,6 +417,13 @@ impl TyBound {
} }
} }
pub fn get_types(&self) -> Option<(&Type, &Type, &Type)> {
match self {
Self::Sandwiched { sub, mid, sup } => Some((sub, mid, sup)),
Self::Instance { .. } => None,
}
}
pub fn get_lhs(&self) -> Str { pub fn get_lhs(&self) -> Str {
match self { match self {
Self::Sandwiched { mid, .. } => mid.name(), Self::Sandwiched { mid, .. } => mid.name(),
@ -1095,7 +1103,6 @@ pub enum Type {
Str, Str,
NoneType, NoneType,
Code, Code,
Module,
Frame, Frame,
Error, Error,
Inf, // {∞} Inf, // {∞}
@ -1110,7 +1117,7 @@ pub enum Type {
Never, // {} Never, // {}
BuiltinMono(Str), BuiltinMono(Str),
Mono { Mono {
path: Str, path: PathBuf,
name: Str, name: Str,
}, },
/* Polymorphic types */ /* Polymorphic types */
@ -1138,7 +1145,12 @@ pub enum Type {
And(Box<Type>, Box<Type>), And(Box<Type>, Box<Type>),
Not(Box<Type>, Box<Type>), Not(Box<Type>, Box<Type>),
Or(Box<Type>, Box<Type>), Or(Box<Type>, Box<Type>),
BuiltinPoly {
name: Str,
params: Vec<TyParam>,
},
Poly { Poly {
path: PathBuf,
name: Str, name: Str,
params: Vec<TyParam>, params: Vec<TyParam>,
}, },
@ -1170,7 +1182,6 @@ impl PartialEq for Type {
| (Self::Str, Self::Str) | (Self::Str, Self::Str)
| (Self::NoneType, Self::NoneType) | (Self::NoneType, Self::NoneType)
| (Self::Code, Self::Code) | (Self::Code, Self::Code)
| (Self::Module, Self::Module)
| (Self::Frame, Self::Frame) | (Self::Frame, Self::Frame)
| (Self::Error, Self::Error) | (Self::Error, Self::Error)
| (Self::Inf, Self::Inf) | (Self::Inf, Self::Inf)
@ -1182,11 +1193,11 @@ impl PartialEq for Type {
| (Self::NotImplemented, Self::NotImplemented) | (Self::NotImplemented, Self::NotImplemented)
| (Self::Ellipsis, Self::Ellipsis) | (Self::Ellipsis, Self::Ellipsis)
| (Self::Never, Self::Never) => true, | (Self::Never, Self::Never) => true,
(Self::BuiltinMono(l), Self::BuiltinMono(r)) => l == r, (Self::BuiltinMono(l), Self::BuiltinMono(r))
| (Self::MonoQVar(l), Self::MonoQVar(r)) => l == r,
(Self::Mono { path: lp, name: ln }, Self::Mono { path: rp, name: rn }) => { (Self::Mono { path: lp, name: ln }, Self::Mono { path: rp, name: rn }) => {
lp == rp && ln == rn lp == rp && ln == rn
} }
(Self::MonoQVar(l), Self::MonoQVar(r)) => l == r,
(Self::Ref(l), Self::Ref(r)) => l == r, (Self::Ref(l), Self::Ref(r)) => l == r,
( (
Self::RefMut { Self::RefMut {
@ -1228,6 +1239,18 @@ impl PartialEq for Type {
| (Self::Or(ll, lr), Self::Or(rl, rr)) => ll == rl && lr == rr, | (Self::Or(ll, lr), Self::Or(rl, rr)) => ll == rl && lr == rr,
( (
Self::Poly { Self::Poly {
path: lp,
name: ln,
params: lps,
},
Self::Poly {
path: rp,
name: rn,
params: rps,
},
) => lp == rp && ln == rn && lps == rps,
(
Self::BuiltinPoly {
name: ln, name: ln,
params: lps, params: lps,
} }
@ -1235,7 +1258,7 @@ impl PartialEq for Type {
name: ln, name: ln,
params: lps, params: lps,
}, },
Self::Poly { Self::BuiltinPoly {
name: rn, name: rn,
params: rps, params: rps,
} }
@ -1281,7 +1304,7 @@ impl LimitedDisplay for Type {
} }
match self { match self {
Self::BuiltinMono(name) => write!(f, "{name}"), Self::BuiltinMono(name) => write!(f, "{name}"),
Self::Mono { path, name } => write!(f, "{name}(of {path})"), Self::Mono { path, name } => write!(f, "{}.{name}", path.display()),
Self::Ref(t) => { Self::Ref(t) => {
write!(f, "{}(", self.name())?; write!(f, "{}(", self.name())?;
t.limited_fmt(f, limit - 1)?; t.limited_fmt(f, limit - 1)?;
@ -1338,7 +1361,17 @@ impl LimitedDisplay for Type {
write!(f, " or ")?; write!(f, " or ")?;
rhs.limited_fmt(f, limit - 1) rhs.limited_fmt(f, limit - 1)
} }
Self::Poly { name, params } => { Self::Poly { path, name, params } => {
write!(f, "{}.{name}(", path.display())?;
for (i, tp) in params.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
tp.limited_fmt(f, limit - 1)?;
}
write!(f, ")")
}
Self::BuiltinPoly { name, params } => {
write!(f, "{name}(")?; write!(f, "{name}(")?;
for (i, tp) in params.iter().enumerate() { for (i, tp) in params.iter().enumerate() {
if i > 0 { if i > 0 {
@ -1430,7 +1463,9 @@ impl HasType for Type {
// Self::And(ts) | Self::Or(ts) => , // Self::And(ts) | Self::Or(ts) => ,
Self::Subr(_sub) => todo!(), Self::Subr(_sub) => todo!(),
Self::Callable { param_ts, .. } => param_ts.clone(), Self::Callable { param_ts, .. } => param_ts.clone(),
Self::Poly { params, .. } => params.iter().filter_map(get_t_from_tp).collect(), Self::BuiltinPoly { params, .. }
| Self::Poly { params, .. }
| Self::PolyQVar { params, .. } => params.iter().filter_map(get_t_from_tp).collect(),
_ => vec![], _ => vec![],
} }
} }
@ -1488,7 +1523,9 @@ impl HasLevel for Type {
t.update_level(level); t.update_level(level);
} }
} }
Self::Poly { params, .. } => { Self::Poly { params, .. }
| Self::BuiltinPoly { params, .. }
| Self::PolyQVar { params, .. } => {
for p in params.iter() { for p in params.iter() {
p.update_level(level); p.update_level(level);
} }
@ -1549,7 +1586,9 @@ impl HasLevel for Type {
t.lift(); t.lift();
} }
} }
Self::Poly { params, .. } => { Self::Poly { params, .. }
| Self::BuiltinPoly { params, .. }
| Self::PolyQVar { params, .. } => {
for p in params.iter() { for p in params.iter() {
p.lift(); p.lift();
} }
@ -1622,7 +1661,6 @@ impl Type {
| Self::Str | Self::Str
| Self::NoneType | Self::NoneType
| Self::Code | Self::Code
| Self::Module
| Self::Frame | Self::Frame
| Self::Error | Self::Error
| Self::Inf | Self::Inf
@ -1648,8 +1686,10 @@ impl Type {
} }
} }
Self::BuiltinMono(name) Self::BuiltinMono(name)
| Self::Mono { name, .. }
| Self::MonoQVar(name) | Self::MonoQVar(name)
| Self::Poly { name, .. } | Self::Poly { name, .. }
| Self::BuiltinPoly { name, .. }
| Self::PolyQVar { name, .. } | Self::PolyQVar { name, .. }
| Self::MonoProj { rhs: name, .. } => name.ends_with('!'), | Self::MonoProj { rhs: name, .. } => name.ends_with('!'),
Self::Refinement(refine) => refine.t.is_mut(), Self::Refinement(refine) => refine.t.is_mut(),
@ -1661,11 +1701,13 @@ impl Type {
match self { match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_nonelike(), Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_nonelike(),
Self::NoneType => true, Self::NoneType => true,
Self::Poly { name, params } if &name[..] == "Option" || &name[..] == "Option!" => { Self::BuiltinPoly { name, params, .. }
if &name[..] == "Option" || &name[..] == "Option!" =>
{
let inner_t = enum_unwrap!(params.first().unwrap(), TyParam::Type); let inner_t = enum_unwrap!(params.first().unwrap(), TyParam::Type);
inner_t.is_nonelike() inner_t.is_nonelike()
} }
Self::Poly { name, params } if &name[..] == "Tuple" => params.is_empty(), Self::BuiltinPoly { name, params, .. } if &name[..] == "Tuple" => params.is_empty(),
Self::Refinement(refine) => refine.t.is_nonelike(), Self::Refinement(refine) => refine.t.is_nonelike(),
_ => false, _ => false,
} }
@ -1693,7 +1735,9 @@ impl Type {
.map(|(sub, sup)| sub.contains_tvar(name) || sup.contains_tvar(name)) .map(|(sub, sup)| sub.contains_tvar(name) || sup.contains_tvar(name))
.unwrap_or(false) .unwrap_or(false)
} }
Self::Poly { params, .. } => { Self::Poly { params, .. }
| Self::BuiltinPoly { params, .. }
| Self::PolyQVar { params, .. } => {
for param in params.iter() { for param in params.iter() {
match param { match param {
TyParam::Type(t) if t.contains_tvar(name) => { TyParam::Type(t) if t.contains_tvar(name) => {
@ -1766,7 +1810,6 @@ impl Type {
Self::Trait => Str::ever("TraitType"), Self::Trait => Str::ever("TraitType"),
Self::Patch => Str::ever("Patch"), Self::Patch => Str::ever("Patch"),
Self::Code => Str::ever("Code"), Self::Code => Str::ever("Code"),
Self::Module => Str::ever("Module"),
Self::Frame => Str::ever("Frame"), Self::Frame => Str::ever("Frame"),
Self::Error => Str::ever("Error"), Self::Error => Str::ever("Error"),
Self::Inf => Str::ever("Inf"), Self::Inf => Str::ever("Inf"),
@ -1789,7 +1832,9 @@ impl Type {
}) => Str::ever("Proc"), }) => Str::ever("Proc"),
Self::Callable { .. } => Str::ever("Callable"), Self::Callable { .. } => Str::ever("Callable"),
Self::Record(_) => Str::ever("Record"), Self::Record(_) => Str::ever("Record"),
Self::Poly { name, .. } | Self::PolyQVar { name, .. } => name.clone(), Self::Poly { name, .. }
| Self::BuiltinPoly { name, .. }
| Self::PolyQVar { name, .. } => name.clone(),
// NOTE: compiler/codegen/convert_to_python_methodでクラス名を使うため、こうすると都合が良い // NOTE: compiler/codegen/convert_to_python_methodでクラス名を使うため、こうすると都合が良い
Self::Refinement(refine) => refine.t.name(), Self::Refinement(refine) => refine.t.name(),
Self::Quantified(_) => Str::ever("Quantified"), Self::Quantified(_) => Str::ever("Quantified"),
@ -1819,7 +1864,7 @@ impl Type {
match self { match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(), Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(),
Self::FreeVar(fv) => fv.unbound_name(), Self::FreeVar(fv) => fv.unbound_name(),
Self::MonoQVar(name) => Some(name.clone()), Self::MonoQVar(name) | Self::PolyQVar { name, .. } => Some(name.clone()),
_ => None, _ => None,
} }
} }
@ -1869,7 +1914,9 @@ impl Type {
quant.unbound_callable.has_unbound_var() quant.unbound_callable.has_unbound_var()
|| quant.bounds.iter().any(|tb| tb.has_qvar()) || quant.bounds.iter().any(|tb| tb.has_qvar())
} }
Self::Poly { params, .. } => params.iter().any(|tp| tp.has_qvar()), Self::Poly { params, .. } | Self::BuiltinPoly { params, .. } => {
params.iter().any(|tp| tp.has_qvar())
}
Self::MonoProj { lhs, .. } => lhs.has_qvar(), Self::MonoProj { lhs, .. } => lhs.has_qvar(),
_ => false, _ => false,
} }
@ -1907,9 +1954,9 @@ impl Type {
Self::Quantified(quant) => { Self::Quantified(quant) => {
quant.unbound_callable.is_cachable() || quant.bounds.iter().all(|b| b.is_cachable()) quant.unbound_callable.is_cachable() || quant.bounds.iter().all(|b| b.is_cachable())
} }
Self::Poly { params, .. } | Self::PolyQVar { params, .. } => { Self::Poly { params, .. }
params.iter().all(|p| p.is_cachable()) | Self::BuiltinPoly { params, .. }
} | Self::PolyQVar { params, .. } => params.iter().all(|p| p.is_cachable()),
Self::MonoProj { lhs, .. } => lhs.is_cachable(), Self::MonoProj { lhs, .. } => lhs.is_cachable(),
_ => true, _ => true,
} }
@ -1958,9 +2005,9 @@ impl Type {
quant.unbound_callable.has_unbound_var() quant.unbound_callable.has_unbound_var()
|| quant.bounds.iter().any(|b| b.has_unbound_var()) || quant.bounds.iter().any(|b| b.has_unbound_var())
} }
Self::Poly { params, .. } | Self::PolyQVar { params, .. } => { Self::Poly { params, .. }
params.iter().any(|p| p.has_unbound_var()) | Self::BuiltinPoly { params, .. }
} | Self::PolyQVar { params, .. } => params.iter().any(|p| p.has_unbound_var()),
Self::MonoProj { lhs, .. } => lhs.has_no_unbound_var(), Self::MonoProj { lhs, .. } => lhs.has_no_unbound_var(),
_ => false, _ => false,
} }
@ -1984,7 +2031,9 @@ impl Type {
+ 1, + 1,
), ),
Self::Callable { param_ts, .. } => Some(param_ts.len() + 1), Self::Callable { param_ts, .. } => Some(param_ts.len() + 1),
Self::Poly { params, .. } | Self::PolyQVar { params, .. } => Some(params.len()), Self::Poly { params, .. }
| Self::BuiltinPoly { params, .. }
| Self::PolyQVar { params, .. } => Some(params.len()),
_ => None, _ => None,
} }
} }
@ -2000,7 +2049,9 @@ impl Type {
} }
Self::Subr(subr) => subr.typarams(), Self::Subr(subr) => subr.typarams(),
Self::Callable { param_ts: _, .. } => todo!(), Self::Callable { param_ts: _, .. } => todo!(),
Self::Poly { params, .. } | Self::PolyQVar { params, .. } => params.clone(), Self::Poly { params, .. }
| Self::BuiltinPoly { params, .. }
| Self::PolyQVar { params, .. } => params.clone(),
_ => vec![], _ => vec![],
} }
} }

View file

@ -18,7 +18,7 @@ use erg_common::{dict, fmt_iter, impl_display_from_debug, switch_lang};
use erg_common::{RcArray, Str}; use erg_common::{RcArray, Str};
use crate::codeobj::CodeObj; use crate::codeobj::CodeObj;
use crate::constructors::{array, builtin_mono, poly, refinement, tuple}; use crate::constructors::{array, builtin_mono, builtin_poly, refinement, tuple};
use crate::free::fresh_varname; use crate::free::fresh_varname;
use crate::typaram::TyParam; use crate::typaram::TyParam;
use crate::{ConstSubr, HasType, Predicate, Type}; use crate::{ConstSubr, HasType, Predicate, Type};
@ -506,7 +506,7 @@ impl ValueObj {
Self::Float(_) => builtin_mono("Float!"), Self::Float(_) => builtin_mono("Float!"),
Self::Str(_) => builtin_mono("Str!"), Self::Str(_) => builtin_mono("Str!"),
Self::Bool(_) => builtin_mono("Bool!"), Self::Bool(_) => builtin_mono("Bool!"),
Self::Array(arr) => poly( Self::Array(arr) => builtin_poly(
"Array!", "Array!",
vec![ vec![
TyParam::t(arr.iter().next().unwrap().class()), TyParam::t(arr.iter().next().unwrap().class()),