mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Fix import
to be called from anywhere
This commit is contained in:
parent
f548f9e6ef
commit
23a6f630c9
21 changed files with 979 additions and 549 deletions
|
@ -4,7 +4,7 @@
|
|||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, BufRead, BufReader, Read};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use std::str::FromStr;
|
||||
|
||||
|
@ -35,7 +35,7 @@ impl Input {
|
|||
|
||||
pub fn enclosed_name(&self) -> &str {
|
||||
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::Str(_) => "<string>",
|
||||
Self::Dummy => "<dummy>",
|
||||
|
@ -45,7 +45,7 @@ impl Input {
|
|||
/// ファイルに書き出すとき使う
|
||||
pub fn filename(&self) -> &str {
|
||||
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::Str(_) => "string",
|
||||
Self::Dummy => "dummy",
|
||||
|
@ -116,6 +116,21 @@ impl Input {
|
|||
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)]
|
||||
|
|
|
@ -594,11 +594,11 @@ impl Context {
|
|||
(Ref(l), r) => self.supertype_of(l, r),
|
||||
(RefMut { before: l, .. }, r) => self.supertype_of(l, r),
|
||||
(
|
||||
Poly {
|
||||
BuiltinPoly {
|
||||
name: ln,
|
||||
params: lparams,
|
||||
},
|
||||
Poly {
|
||||
BuiltinPoly {
|
||||
name: rn,
|
||||
params: rparams,
|
||||
},
|
||||
|
@ -608,6 +608,23 @@ impl Context {
|
|||
}
|
||||
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) => {
|
||||
panic!("internal error: not instantiated type variable: '{name}, r: {r}")
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use erg_parser::ast::*;
|
|||
use erg_parser::token::{Token, TokenKind};
|
||||
|
||||
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::value::ValueObj;
|
||||
|
@ -305,7 +305,7 @@ impl Context {
|
|||
match subr {
|
||||
ConstSubr::User(_user) => todo!(),
|
||||
ConstSubr::Builtin(builtin) => builtin
|
||||
.call(args, self.mod_name().clone(), __name__)
|
||||
.call(args, self.path().to_path_buf(), __name__)
|
||||
.map_err(|mut e| {
|
||||
e.loc = loc;
|
||||
EvalErrors::from(EvalError::new(e, self.cfg.input.clone(), self.caused_by()))
|
||||
|
@ -445,7 +445,7 @@ impl Context {
|
|||
non_default_params.clone(),
|
||||
var_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 as_type = subr_t(
|
||||
|
@ -791,11 +791,21 @@ impl Context {
|
|||
};
|
||||
Ok(ref_mut(before, after))
|
||||
}
|
||||
Type::Poly { name, mut params } => {
|
||||
Type::BuiltinPoly { name, mut params } => {
|
||||
for p in params.iter_mut() {
|
||||
*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 => todo!("{other}"),
|
||||
|
@ -839,7 +849,7 @@ impl Context {
|
|||
let p = self.eval_tp(p)?;
|
||||
match p {
|
||||
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::FreeVar(fv) => {
|
||||
if let Some(t) = fv.get_type() {
|
||||
|
@ -852,7 +862,7 @@ impl Context {
|
|||
TyParam::Type(_) => Ok(Type::Type),
|
||||
TyParam::Mono(name) => self
|
||||
.rec_get_const_obj(&name)
|
||||
.map(|v| enum_t(set![v.clone()]))
|
||||
.map(|v| v_enum(set![v.clone()]))
|
||||
.ok_or_else(|| {
|
||||
EvalErrors::from(EvalError::unreachable(
|
||||
self.cfg.input.clone(),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use erg_common::Str;
|
||||
|
||||
|
@ -12,7 +13,7 @@ use erg_type::ValueArgs;
|
|||
/// Requirement: Type, Impl := Type -> ClassType
|
||||
pub fn class_func(
|
||||
mut args: ValueArgs,
|
||||
mod_name: Str,
|
||||
path: PathBuf,
|
||||
__name__: Option<Str>,
|
||||
) -> EvalValueResult<ValueObj> {
|
||||
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 = 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))
|
||||
}
|
||||
|
||||
/// Super: ClassType, Impl := Type, Additional := Type -> ClassType
|
||||
pub fn inherit_func(
|
||||
mut args: ValueArgs,
|
||||
mod_name: Str,
|
||||
path: PathBuf,
|
||||
__name__: Option<Str>,
|
||||
) -> EvalValueResult<ValueObj> {
|
||||
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 additional = args.remove_left_or_key("Additional");
|
||||
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(
|
||||
TypeKind::Subclass,
|
||||
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.
|
||||
pub fn inheritable_func(
|
||||
mut args: ValueArgs,
|
||||
_mod_name: Str,
|
||||
_path: PathBuf,
|
||||
__name__: Option<Str>,
|
||||
) -> EvalValueResult<ValueObj> {
|
||||
let class = args.remove_left_or_key("Class").ok_or_else(|| {
|
||||
|
@ -124,7 +125,7 @@ pub fn inheritable_func(
|
|||
/// Requirement: Type, Impl := Type -> TraitType
|
||||
pub fn trait_func(
|
||||
mut args: ValueArgs,
|
||||
mod_name: Str,
|
||||
path: PathBuf,
|
||||
__name__: Option<Str>,
|
||||
) -> EvalValueResult<ValueObj> {
|
||||
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 = 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))
|
||||
}
|
||||
|
||||
/// Super: TraitType, Impl := Type, Additional := Type -> TraitType
|
||||
pub fn subsume_func(
|
||||
mut args: ValueArgs,
|
||||
mod_name: Str,
|
||||
path: PathBuf,
|
||||
__name__: Option<Str>,
|
||||
) -> EvalValueResult<ValueObj> {
|
||||
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 additional = args.remove_left_or_key("Additional");
|
||||
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(
|
||||
TypeKind::Subtrait,
|
||||
t,
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
pub mod const_func;
|
||||
pub mod py_mods;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use erg_common::config::ErgConfig;
|
||||
use erg_common::error::Location;
|
||||
use erg_common::vis::Visibility;
|
||||
|
@ -61,7 +63,7 @@ impl Context {
|
|||
panic!("already registered: {name}");
|
||||
} else {
|
||||
// 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.locals.insert(VarName::from_str(Str::rc(name)), vi);
|
||||
}
|
||||
|
@ -206,31 +208,31 @@ impl Context {
|
|||
let params = vec![PS::t("T", NonDefault)];
|
||||
let input = Self::builtin_poly_trait("Input", params.clone(), 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 = quant(
|
||||
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);
|
||||
// Erg does not have a trait equivalent to `PartialEq` in Rust
|
||||
// This means, Erg's `Float` cannot be compared with other `Float`
|
||||
// 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);
|
||||
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
|
||||
let op_t = fn1_met(mono_q("Self"), mono_q("R"), Bool);
|
||||
let op_t = quant(
|
||||
op_t,
|
||||
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)
|
||||
},
|
||||
);
|
||||
eq.register_builtin_decl("__eq__", op_t, Public);
|
||||
let mut partial_ord =
|
||||
Self::builtin_poly_trait("PartialOrd", vec![PS::t("R", WithDefault)], 2);
|
||||
partial_ord.register_superclass(poly("Eq", vec![ty_tp(mono_q("R"))]), &eq);
|
||||
partial_ord.register_superclass(builtin_poly("Eq", vec![ty_tp(mono_q("R"))]), &eq);
|
||||
let op_t = fn1_met(
|
||||
mono_q("Self"),
|
||||
mono_q("R"),
|
||||
|
@ -239,15 +241,15 @@ impl Context {
|
|||
let op_t = quant(
|
||||
op_t,
|
||||
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)
|
||||
},
|
||||
);
|
||||
partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public);
|
||||
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(
|
||||
poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]),
|
||||
builtin_poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]),
|
||||
&partial_ord,
|
||||
);
|
||||
// FIXME: poly trait
|
||||
|
@ -258,18 +260,18 @@ impl Context {
|
|||
poly("Mul", vec![]),
|
||||
], */
|
||||
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 t = fn0_met(self_t.clone(), Nat);
|
||||
let t = quant(
|
||||
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);
|
||||
let t = fn1_met(self_t.clone(), Nat, mono_q("T"));
|
||||
let t = quant(
|
||||
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.register_builtin_decl("get", t, Public);
|
||||
|
@ -279,8 +281,8 @@ impl Context {
|
|||
let ty_params = vec![ty_tp(mono_q("R"))];
|
||||
let mut add = Self::builtin_poly_trait("Add", params.clone(), 2);
|
||||
// Rについて共変(__add__の型とは関係ない)
|
||||
add.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output);
|
||||
let self_bound = subtypeof(mono_q("Self"), poly("Add", ty_params.clone()));
|
||||
add.register_superclass(builtin_poly("Output", vec![ty_tp(mono_q("R"))]), &output);
|
||||
let self_bound = subtypeof(mono_q("Self"), builtin_poly("Add", ty_params.clone()));
|
||||
let op_t = fn1_met(
|
||||
mono_q("Self"),
|
||||
r.clone(),
|
||||
|
@ -290,31 +292,31 @@ impl Context {
|
|||
add.register_builtin_decl("__add__", op_t, Public);
|
||||
add.register_builtin_decl("Output", Type, Public);
|
||||
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(
|
||||
mono_q("Self"),
|
||||
r.clone(),
|
||||
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});
|
||||
sub.register_builtin_decl("__sub__", op_t, Public);
|
||||
sub.register_builtin_decl("Output", Type, Public);
|
||||
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(
|
||||
mono_q("Self"),
|
||||
r.clone(),
|
||||
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});
|
||||
mul.register_builtin_decl("__mul__", op_t, Public);
|
||||
mul.register_builtin_decl("Output", Type, Public);
|
||||
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 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});
|
||||
div.register_builtin_decl("__div__", op_t, 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("Immutizable"), immutizable, 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(
|
||||
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,
|
||||
Const,
|
||||
);
|
||||
self.register_builtin_type(builtin_mono("Ord"), ord, 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(poly("Add", ty_params.clone()), add, Const);
|
||||
self.register_builtin_type(poly("Sub", ty_params.clone()), sub, Const);
|
||||
self.register_builtin_type(poly("Mul", ty_params.clone()), mul, Const);
|
||||
self.register_builtin_type(poly("Div", ty_params), div, Const);
|
||||
self.register_builtin_type(builtin_poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Const);
|
||||
self.register_builtin_type(builtin_poly("Add", ty_params.clone()), add, Const);
|
||||
self.register_builtin_type(builtin_poly("Sub", ty_params.clone()), sub, Const);
|
||||
self.register_builtin_type(builtin_poly("Mul", ty_params.clone()), mul, Const);
|
||||
self.register_builtin_type(builtin_poly("Div", ty_params), div, Const);
|
||||
self.register_const_param_defaults(
|
||||
"Eq",
|
||||
vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))],
|
||||
|
@ -384,7 +394,7 @@ impl Context {
|
|||
);
|
||||
let mut obj_in = Self::builtin_methods("In", 2);
|
||||
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);
|
||||
obj_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Obj!")));
|
||||
obj.register_trait(Obj, builtin_mono("Mutizable"), obj_mutizable);
|
||||
|
@ -405,7 +415,7 @@ impl Context {
|
|||
);
|
||||
float.register_trait(
|
||||
Float,
|
||||
poly("PartialOrd", vec![ty_tp(Float)]),
|
||||
builtin_poly("PartialOrd", vec![ty_tp(Float)]),
|
||||
float_partial_ord,
|
||||
);
|
||||
// Float doesn't have an `Eq` implementation
|
||||
|
@ -413,21 +423,21 @@ impl Context {
|
|||
let mut float_add = Self::builtin_methods("Add", 2);
|
||||
float_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
|
||||
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);
|
||||
float_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
|
||||
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);
|
||||
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("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);
|
||||
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("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);
|
||||
float_mutizable
|
||||
.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Float!")));
|
||||
|
@ -448,31 +458,31 @@ impl Context {
|
|||
);
|
||||
ratio.register_trait(
|
||||
Ratio,
|
||||
poly("PartialOrd", vec![ty_tp(Ratio)]),
|
||||
builtin_poly("PartialOrd", vec![ty_tp(Ratio)]),
|
||||
ratio_partial_ord,
|
||||
);
|
||||
let mut ratio_eq = Self::builtin_methods("Eq", 2);
|
||||
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 mut ratio_add = Self::builtin_methods("Add", 2);
|
||||
ratio_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
|
||||
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);
|
||||
ratio_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
|
||||
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);
|
||||
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("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);
|
||||
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("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);
|
||||
ratio_mutizable
|
||||
.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Ratio!")));
|
||||
|
@ -482,7 +492,7 @@ impl Context {
|
|||
int.register_superclass(Obj, &obj);
|
||||
int.register_marker_trait(builtin_mono("Num"));
|
||||
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("Integral"),
|
||||
int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public);
|
||||
|
@ -493,25 +503,29 @@ impl Context {
|
|||
Const,
|
||||
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);
|
||||
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)
|
||||
let op_t = fn1_met(Int, Int, Int);
|
||||
let mut int_add = Self::builtin_methods("Add", 2);
|
||||
int_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
|
||||
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);
|
||||
int_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
|
||||
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);
|
||||
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("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);
|
||||
int_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Int!")));
|
||||
int.register_trait(Int, builtin_mono("Mutizable"), int_mutizable);
|
||||
|
@ -539,7 +553,7 @@ impl Context {
|
|||
nat.register_marker_trait(builtin_mono("Ord"));
|
||||
let mut nat_eq = Self::builtin_methods("Eq", 2);
|
||||
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);
|
||||
nat_partial_ord.register_builtin_impl(
|
||||
"__cmp__",
|
||||
|
@ -547,17 +561,21 @@ impl Context {
|
|||
Const,
|
||||
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)
|
||||
let op_t = fn1_met(Nat, Nat, Nat);
|
||||
let mut nat_add = Self::builtin_methods("Add", 2);
|
||||
nat_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
|
||||
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);
|
||||
nat_mul.register_builtin_impl("__mul__", op_t, Const, Public);
|
||||
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);
|
||||
nat_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Nat!")));
|
||||
nat.register_trait(Nat, builtin_mono("Mutizable"), nat_mutizable);
|
||||
|
@ -584,16 +602,16 @@ impl Context {
|
|||
);
|
||||
bool_.register_trait(
|
||||
Bool,
|
||||
poly("PartialOrd", vec![ty_tp(Bool)]),
|
||||
builtin_poly("PartialOrd", vec![ty_tp(Bool)]),
|
||||
bool_partial_ord,
|
||||
);
|
||||
let mut bool_eq = Self::builtin_methods("Eq", 2);
|
||||
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);
|
||||
bool_add.register_builtin_impl("__add__", fn1_met(Bool, Bool, Int), Const, Public);
|
||||
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);
|
||||
bool_mutizable
|
||||
.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);
|
||||
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);
|
||||
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_.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);
|
||||
str_add.register_builtin_impl("__add__", fn1_met(Str, Str, Str), Const, Public);
|
||||
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);
|
||||
str_mul.register_builtin_impl("__mul__", fn1_met(Str, Nat, Str), Const, Public);
|
||||
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);
|
||||
str_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Str!")));
|
||||
str_.register_trait(Str, builtin_mono("Mutizable"), str_mutizable);
|
||||
|
@ -649,24 +667,37 @@ impl Context {
|
|||
type_.register_marker_trait(builtin_mono("Named"));
|
||||
let mut type_eq = Self::builtin_methods("Eq", 2);
|
||||
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);
|
||||
class_type.register_superclass(Type, &type_);
|
||||
class_type.register_superclass(Obj, &obj);
|
||||
class_type.register_marker_trait(builtin_mono("Named"));
|
||||
let mut class_eq = Self::builtin_methods("Eq", 2);
|
||||
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);
|
||||
let mut module = Self::builtin_mono_class("Module", 2);
|
||||
module.register_superclass(Obj, &obj);
|
||||
module.register_marker_trait(builtin_mono("Named"));
|
||||
let mut module_eq = Self::builtin_methods("Eq", 2);
|
||||
module_eq.register_builtin_impl("__eq__", fn1_met(Module, Module, Bool), Const, Public);
|
||||
module.register_trait(Module, poly("Eq", vec![ty_tp(Module)]), module_eq);
|
||||
class_type.register_trait(Class, builtin_poly("Eq", vec![ty_tp(Class)]), class_eq);
|
||||
let g_module_t = builtin_mono("GenericModule");
|
||||
let mut generic_module = Self::builtin_mono_class("GenericModule", 2);
|
||||
generic_module.register_superclass(Obj, &obj);
|
||||
generic_module.register_marker_trait(builtin_mono("Named"));
|
||||
let mut generic_module_eq = Self::builtin_methods("Eq", 2);
|
||||
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_ =
|
||||
Self::builtin_poly_class("Array", vec![PS::t_nd("T"), PS::named_nd("N", Nat)], 10);
|
||||
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 m = mono_q_tp("M");
|
||||
let array_t = array(mono_q("T"), n.clone());
|
||||
|
@ -682,7 +713,7 @@ impl Context {
|
|||
set! {static_instance("N", Nat), static_instance("M", Nat)},
|
||||
);
|
||||
array_.register_builtin_impl("concat", t, Immutable, Public);
|
||||
let mut_type = ValueObj::builtin_t(poly(
|
||||
let mut_type = ValueObj::builtin_t(builtin_poly(
|
||||
"Array!",
|
||||
vec![TyParam::t(mono_q("T")), TyParam::mono_q("N").mutate()],
|
||||
));
|
||||
|
@ -695,9 +726,13 @@ impl Context {
|
|||
Const,
|
||||
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(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.
|
||||
let mut tuple_ = Self::builtin_mono_class("Tuple", 2);
|
||||
tuple_.register_superclass(Obj, &obj);
|
||||
|
@ -710,7 +745,7 @@ impl Context {
|
|||
);
|
||||
tuple_.register_trait(
|
||||
builtin_mono("Tuple"),
|
||||
poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]),
|
||||
builtin_poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]),
|
||||
tuple_eq,
|
||||
);
|
||||
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(
|
||||
"__eq__",
|
||||
fn1_met(
|
||||
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"))]),
|
||||
builtin_poly("Tuple1", vec![ty_tp(mono_q("A"))]),
|
||||
Bool,
|
||||
),
|
||||
Const,
|
||||
Public,
|
||||
);
|
||||
tuple1.register_trait(
|
||||
poly("Tuple1", vec![ty_tp(mono_q("A"))]),
|
||||
poly("Eq", vec![ty_tp(poly("Tuple1", vec![ty_tp(mono_q("A"))]))]),
|
||||
builtin_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,
|
||||
);
|
||||
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(
|
||||
"__eq__",
|
||||
fn1_met(
|
||||
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"))]),
|
||||
builtin_poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]),
|
||||
Bool,
|
||||
),
|
||||
Const,
|
||||
Public,
|
||||
);
|
||||
tuple2.register_trait(
|
||||
poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]),
|
||||
poly(
|
||||
builtin_poly("Tuple2", vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))]),
|
||||
builtin_poly(
|
||||
"Eq",
|
||||
vec![ty_tp(poly(
|
||||
vec![ty_tp(builtin_poly(
|
||||
"Tuple2",
|
||||
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B"))],
|
||||
))],
|
||||
|
@ -768,11 +806,11 @@ impl Context {
|
|||
tuple3_eq.register_builtin_impl(
|
||||
"__eq__",
|
||||
fn1_met(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple3",
|
||||
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple3",
|
||||
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))],
|
||||
),
|
||||
|
@ -782,13 +820,13 @@ impl Context {
|
|||
Public,
|
||||
);
|
||||
tuple3.register_trait(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple3",
|
||||
vec![ty_tp(mono_q("A")), ty_tp(mono_q("B")), ty_tp(mono_q("C"))],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Eq",
|
||||
vec![ty_tp(poly(
|
||||
vec![ty_tp(builtin_poly(
|
||||
"Tuple3",
|
||||
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(
|
||||
"__eq__",
|
||||
fn1_met(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple4",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -815,7 +853,7 @@ impl Context {
|
|||
ty_tp(mono_q("D")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple4",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -830,7 +868,7 @@ impl Context {
|
|||
Public,
|
||||
);
|
||||
tuple4.register_trait(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple4",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -839,9 +877,9 @@ impl Context {
|
|||
ty_tp(mono_q("D")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Eq",
|
||||
vec![ty_tp(poly(
|
||||
vec![ty_tp(builtin_poly(
|
||||
"Tuple4",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -870,7 +908,7 @@ impl Context {
|
|||
tuple5_eq.register_builtin_impl(
|
||||
"__eq__",
|
||||
fn1_met(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple5",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -880,7 +918,7 @@ impl Context {
|
|||
ty_tp(mono_q("E")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple5",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -896,7 +934,7 @@ impl Context {
|
|||
Public,
|
||||
);
|
||||
tuple5.register_trait(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple5",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -906,9 +944,9 @@ impl Context {
|
|||
ty_tp(mono_q("E")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Eq",
|
||||
vec![ty_tp(poly(
|
||||
vec![ty_tp(builtin_poly(
|
||||
"Tuple5",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -939,7 +977,7 @@ impl Context {
|
|||
tuple6_eq.register_builtin_impl(
|
||||
"__eq__",
|
||||
fn1_met(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple6",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -950,7 +988,7 @@ impl Context {
|
|||
ty_tp(mono_q("F")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple6",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -967,7 +1005,7 @@ impl Context {
|
|||
Public,
|
||||
);
|
||||
tuple6.register_trait(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple6",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -978,9 +1016,9 @@ impl Context {
|
|||
ty_tp(mono_q("F")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Eq",
|
||||
vec![ty_tp(poly(
|
||||
vec![ty_tp(builtin_poly(
|
||||
"Tuple6",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1013,7 +1051,7 @@ impl Context {
|
|||
tuple7_eq.register_builtin_impl(
|
||||
"__eq__",
|
||||
fn1_met(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple7",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1025,7 +1063,7 @@ impl Context {
|
|||
ty_tp(mono_q("G")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple7",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1043,7 +1081,7 @@ impl Context {
|
|||
Public,
|
||||
);
|
||||
tuple7.register_trait(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple7",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1055,9 +1093,9 @@ impl Context {
|
|||
ty_tp(mono_q("G")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Eq",
|
||||
vec![ty_tp(poly(
|
||||
vec![ty_tp(builtin_poly(
|
||||
"Tuple7",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1092,7 +1130,7 @@ impl Context {
|
|||
tuple8_eq.register_builtin_impl(
|
||||
"__eq__",
|
||||
fn1_met(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple8",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1105,7 +1143,7 @@ impl Context {
|
|||
ty_tp(mono_q("H")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple8",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1124,7 +1162,7 @@ impl Context {
|
|||
Public,
|
||||
);
|
||||
tuple8.register_trait(
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Tuple8",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1137,9 +1175,9 @@ impl Context {
|
|||
ty_tp(mono_q("H")),
|
||||
],
|
||||
),
|
||||
poly(
|
||||
builtin_poly(
|
||||
"Eq",
|
||||
vec![ty_tp(poly(
|
||||
vec![ty_tp(builtin_poly(
|
||||
"Tuple8",
|
||||
vec![
|
||||
ty_tp(mono_q("A")),
|
||||
|
@ -1289,8 +1327,8 @@ impl Context {
|
|||
builtin_mono("Mutable"),
|
||||
str_mut_mutable,
|
||||
);
|
||||
let array_t = 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_t = builtin_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(
|
||||
"Array!",
|
||||
vec![PS::t_nd("T"), PS::named_nd("N", builtin_mono("Nat!"))],
|
||||
|
@ -1301,7 +1339,7 @@ impl Context {
|
|||
let t = pr_met(
|
||||
ref_mut(
|
||||
array_mut_t.clone(),
|
||||
Some(poly(
|
||||
Some(builtin_poly(
|
||||
"Array!",
|
||||
vec![ty_tp(mono_q("T")), mono_q_tp("N") + value(1)],
|
||||
)),
|
||||
|
@ -1354,10 +1392,10 @@ impl Context {
|
|||
builtin_mono("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);
|
||||
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);
|
||||
range_eq.register_builtin_impl(
|
||||
"__eq__",
|
||||
|
@ -1367,7 +1405,7 @@ impl Context {
|
|||
);
|
||||
range.register_trait(
|
||||
range_t.clone(),
|
||||
poly("Eq", vec![ty_tp(range_t.clone())]),
|
||||
builtin_poly("Eq", vec![ty_tp(range_t.clone())]),
|
||||
range_eq,
|
||||
);
|
||||
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(Type, 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(tuple(vec![mono_q("A")]), tuple1, 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")),
|
||||
);
|
||||
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(
|
||||
vec![],
|
||||
Some(param_t("objects", ref_(Obj))),
|
||||
|
@ -1516,7 +1560,12 @@ impl Context {
|
|||
],
|
||||
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);
|
||||
self.register_builtin_impl("abs", t_abs, Immutable, Private);
|
||||
self.register_builtin_impl("assert", t_assert, Const, Private); // assert casting に悪影響が出る可能性があるため、Constとしておく
|
||||
|
@ -1658,7 +1707,7 @@ impl Context {
|
|||
op_t,
|
||||
set! {
|
||||
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);
|
||||
|
@ -1667,7 +1716,7 @@ impl Context {
|
|||
op_t,
|
||||
set! {
|
||||
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);
|
||||
|
@ -1676,7 +1725,7 @@ impl Context {
|
|||
op_t,
|
||||
set! {
|
||||
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);
|
||||
|
@ -1685,22 +1734,22 @@ impl Context {
|
|||
op_t,
|
||||
set! {
|
||||
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);
|
||||
let m = mono_q("M");
|
||||
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
|
||||
self.register_builtin_impl("__pow__", op_t, Const, Private);
|
||||
let d = mono_q("D");
|
||||
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);
|
||||
let e = mono_q("E");
|
||||
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("__ne__", op_t, Const, Private);
|
||||
let op_t = bin_op(l.clone(), r, Bool);
|
||||
|
@ -1708,7 +1757,7 @@ impl Context {
|
|||
op_t,
|
||||
set! {
|
||||
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);
|
||||
|
@ -1728,7 +1777,7 @@ impl Context {
|
|||
let op_t = bin_op(mono_q("T"), mono_q("I"), Bool);
|
||||
let op_t = quant(
|
||||
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);
|
||||
/* unary */
|
||||
|
@ -1772,7 +1821,7 @@ impl Context {
|
|||
);
|
||||
interval.register_trait(
|
||||
Type::from(&m..=&n),
|
||||
poly("Add", vec![TyParam::from(&o..=&p)]),
|
||||
builtin_poly("Add", vec![TyParam::from(&o..=&p)]),
|
||||
interval_add,
|
||||
);
|
||||
let mut interval_sub = Self::builtin_methods("Sub", 2);
|
||||
|
@ -1788,7 +1837,7 @@ impl Context {
|
|||
);
|
||||
interval.register_trait(
|
||||
Type::from(&m..=&n),
|
||||
poly("Sub", vec![TyParam::from(&o..=&p)]),
|
||||
builtin_poly("Sub", vec![TyParam::from(&o..=&p)]),
|
||||
interval_sub,
|
||||
);
|
||||
self.register_builtin_patch("Interval", interval, Const);
|
||||
|
@ -1800,7 +1849,7 @@ impl Context {
|
|||
|
||||
pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) {
|
||||
// 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_const_funcs();
|
||||
ctx.init_builtin_procs();
|
||||
|
@ -1808,7 +1857,7 @@ impl Context {
|
|||
ctx.init_builtin_traits();
|
||||
ctx.init_builtin_classes();
|
||||
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>>(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use erg_common::vis::Visibility;
|
||||
|
||||
use erg_type::constructors::proc1;
|
||||
use erg_type::constructors::{builtin_mono, proc1};
|
||||
use erg_type::Type;
|
||||
use Type::*;
|
||||
|
||||
|
@ -12,7 +12,12 @@ use Visibility::*;
|
|||
impl Context {
|
||||
pub(crate) fn init_py_importlib_mod() -> Self {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use erg_common::set;
|
|||
use erg_common::vis::Visibility;
|
||||
|
||||
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 Type::*;
|
||||
|
@ -36,7 +36,10 @@ impl Context {
|
|||
Public,
|
||||
);
|
||||
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,
|
||||
mono_q("T"),
|
||||
);
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
// (type) getters & validators
|
||||
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::levenshtein::get_similar_name;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::vis::{Field, Visibility};
|
||||
use erg_common::Str;
|
||||
use erg_common::{enum_unwrap, fmt_option, fmt_slice, log, set};
|
||||
use erg_common::{option_enum_unwrap, Str};
|
||||
use Type::*;
|
||||
|
||||
use ast::VarName;
|
||||
use erg_parser::ast::{self, Identifier};
|
||||
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::{HasType, ParamTy, SubrKind, SubrType, TyBound, Type};
|
||||
|
||||
|
@ -86,21 +89,15 @@ impl Context {
|
|||
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 {
|
||||
hir::Expr::Accessor(hir::Accessor::Ident(ident)) => self
|
||||
.get_mod(ident.inspect())
|
||||
.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::Ident(ident)) => {
|
||||
self.get_singular_ctx_from_ident(&ident.clone().downcast(), namespace)
|
||||
}
|
||||
hir::Expr::Accessor(hir::Accessor::Attr(attr)) => {
|
||||
// REVIEW: 両方singularとは限らない?
|
||||
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(
|
||||
&self,
|
||||
pos_args: &[hir::PosArg],
|
||||
|
@ -197,31 +213,74 @@ impl Context {
|
|||
Ok(t)
|
||||
}
|
||||
|
||||
pub(crate) fn get_local_uniq_obj_name(&self, name: &VarName) -> Option<Str> {
|
||||
// TODO: types, functions, patches
|
||||
if let Some(ctx) = self.get_mod(name.inspect()) {
|
||||
return Some(ctx.name.clone());
|
||||
fn get_import_call_t(
|
||||
&self,
|
||||
pos_args: &[hir::PosArg],
|
||||
kw_args: &[hir::KwArg],
|
||||
) -> TyCheckResult<Type> {
|
||||
let mod_name = pos_args
|
||||
.get(0)
|
||||
.map(|a| &a.expr)
|
||||
.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()),
|
||||
)));
|
||||
}
|
||||
if let Some((_, ctx)) = self.rec_get_type(name.inspect()) {
|
||||
return Some(ctx.name.clone());
|
||||
}
|
||||
None
|
||||
_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(
|
||||
&self,
|
||||
ident: &Identifier,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> SingleTyCheckResult<Type> {
|
||||
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())
|
||||
} else {
|
||||
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(
|
||||
self.cfg.input.clone(),
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
|
@ -235,11 +294,12 @@ impl Context {
|
|||
&self,
|
||||
obj: &hir::Expr,
|
||||
ident: &Identifier,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> SingleTyCheckResult<Type> {
|
||||
let self_t = obj.t();
|
||||
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) => {
|
||||
return Ok(t);
|
||||
}
|
||||
|
@ -249,7 +309,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
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) => {
|
||||
return Ok(t);
|
||||
}
|
||||
|
@ -269,7 +329,7 @@ impl Context {
|
|||
None, // TODO:
|
||||
)
|
||||
})? {
|
||||
match ctx.rec_get_var_t(ident, namespace) {
|
||||
match ctx.rec_get_var_t(ident, input, namespace) {
|
||||
Ok(t) => {
|
||||
return Ok(t);
|
||||
}
|
||||
|
@ -281,10 +341,10 @@ impl Context {
|
|||
}
|
||||
// TODO: dependent type widening
|
||||
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 {
|
||||
Err(TyCheckError::no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
name.loc(),
|
||||
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,
|
||||
obj: &hir::Expr,
|
||||
t: &Type,
|
||||
|
@ -304,18 +366,18 @@ impl Context {
|
|||
) -> SingleTyCheckResult<Type> {
|
||||
match t {
|
||||
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) => {
|
||||
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, .. } => {
|
||||
self.get_attr_t_from_attributive_t(obj, before, ident, namespace)
|
||||
self.get_attr_t_from_attributive(obj, before, ident, namespace)
|
||||
}
|
||||
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) => {
|
||||
// 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 => {
|
||||
if let Some(v) = self.rec_get_const_obj(&other.name()) {
|
||||
match v {
|
||||
|
@ -372,6 +429,7 @@ impl Context {
|
|||
&self,
|
||||
obj: &hir::Expr,
|
||||
method_name: &Option<Identifier>,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> SingleTyCheckResult<Type> {
|
||||
if let Some(method_name) = method_name.as_ref() {
|
||||
|
@ -393,7 +451,7 @@ impl Context {
|
|||
.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());
|
||||
}
|
||||
for (_, methods_ctx) in ctx.methods_list.iter() {
|
||||
|
@ -402,7 +460,7 @@ impl Context {
|
|||
.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());
|
||||
}
|
||||
}
|
||||
|
@ -413,7 +471,7 @@ impl Context {
|
|||
.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());
|
||||
}
|
||||
for (_, method_ctx) in singular_ctx.methods_list.iter() {
|
||||
|
@ -422,7 +480,7 @@ impl Context {
|
|||
.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());
|
||||
}
|
||||
}
|
||||
|
@ -456,11 +514,12 @@ impl Context {
|
|||
&self,
|
||||
ident: &Identifier,
|
||||
vi: &VarInfo,
|
||||
input: &Input,
|
||||
namespace: &str,
|
||||
) -> SingleTyCheckResult<()> {
|
||||
if ident.vis() != vi.vis {
|
||||
Err(TyCheckError::visibility_error(
|
||||
self.cfg.input.clone(),
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
self.caused_by(),
|
||||
|
@ -474,7 +533,7 @@ impl Context {
|
|||
&& !namespace.contains(&self.name[..])
|
||||
{
|
||||
Err(TyCheckError::visibility_error(
|
||||
self.cfg.input.clone(),
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
self.caused_by(),
|
||||
|
@ -490,6 +549,7 @@ impl Context {
|
|||
&self,
|
||||
op: &Token,
|
||||
args: &[hir::PosArg],
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> TyCheckResult<Type> {
|
||||
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 t = self.rec_get_var_t(
|
||||
&Identifier::new(None, VarName::new(symbol.clone())),
|
||||
input,
|
||||
namespace,
|
||||
)?;
|
||||
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| {
|
||||
let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_)));
|
||||
let lhs = args[0].expr.clone();
|
||||
|
@ -528,6 +589,7 @@ impl Context {
|
|||
&self,
|
||||
op: &Token,
|
||||
args: &[hir::PosArg],
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> TyCheckResult<Type> {
|
||||
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 t = self.rec_get_var_t(
|
||||
&Identifier::new(None, VarName::new(symbol.clone())),
|
||||
input,
|
||||
namespace,
|
||||
)?;
|
||||
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| {
|
||||
let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_)));
|
||||
let expr = args[0].expr.clone();
|
||||
|
@ -880,17 +943,34 @@ impl Context {
|
|||
method_name: &Option<Identifier>,
|
||||
pos_args: &[hir::PosArg],
|
||||
kw_args: &[hir::KwArg],
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> TyCheckResult<Type> {
|
||||
match obj {
|
||||
hir::Expr::Accessor(hir::Accessor::Ident(local))
|
||||
if local.vis().is_private() && &local.inspect()[..] == "match" =>
|
||||
{
|
||||
if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
|
||||
if local.vis().is_private() {
|
||||
match &local.inspect()[..] {
|
||||
"match" => {
|
||||
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!(
|
||||
"Found:\ncallee: {obj}{}\nfound: {found}",
|
||||
fmt_option!(pre ".", method_name.as_ref().map(|ident| &ident.name))
|
||||
|
@ -1192,11 +1272,33 @@ impl Context {
|
|||
}
|
||||
}
|
||||
},
|
||||
Type::Poly { name, params: _ } => {
|
||||
if let Some((t, ctx)) = self.rec_get_poly_type(name) {
|
||||
Type::BuiltinPoly { name, .. } => {
|
||||
if let Some(res) = self.get_builtins().unwrap_or(self).rec_get_poly_type(name) {
|
||||
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)) => {
|
||||
return self
|
||||
.get_builtins()
|
||||
|
@ -1210,14 +1312,21 @@ impl Context {
|
|||
.rec_get_mono_type("Record");
|
||||
}
|
||||
Type::Mono { path, name } => {
|
||||
if self.mod_name() == path {
|
||||
if self.path() == path {
|
||||
if let Some((t, ctx)) = self.rec_get_mono_type(name) {
|
||||
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
|
||||
.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) {
|
||||
return Some((t, ctx));
|
||||
|
@ -1274,7 +1383,7 @@ impl Context {
|
|||
return Some(res);
|
||||
}
|
||||
}
|
||||
Type::Poly { name, params: _ } => {
|
||||
Type::BuiltinPoly { name, params: _ } => {
|
||||
if let Some((t, ctx)) = self.rec_get_mut_poly_type(name) {
|
||||
return Some((t, ctx));
|
||||
}
|
||||
|
@ -1327,16 +1436,28 @@ impl Context {
|
|||
}
|
||||
|
||||
// FIXME: 現在の実装だとimportしたモジュールはどこからでも見れる
|
||||
fn get_mod(&self, name: &Str) -> Option<&Context> {
|
||||
fn get_mod(&self, ident: &ast::Identifier) -> Option<&Context> {
|
||||
let t = self
|
||||
.rec_get_var_t(ident, &self.cfg.input, &self.name)
|
||||
.ok()?;
|
||||
match t {
|
||||
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()
|
||||
.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(name))
|
||||
.and_then(|cache| cache.ref_ctx(&path))
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// rec_get_const_localとは違い、位置情報を持たないしエラーとならない
|
||||
pub(crate) fn rec_get_const_obj(&self, name: &str) -> Option<&ValueObj> {
|
||||
|
@ -1370,7 +1491,7 @@ impl Context {
|
|||
if self.kind.is_method_def() || self.kind.is_type() {
|
||||
// TODO: poly type
|
||||
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) {
|
||||
Some(t.clone())
|
||||
} else {
|
||||
|
|
|
@ -106,7 +106,7 @@ impl TyVarContext {
|
|||
) -> Type {
|
||||
if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(name) {
|
||||
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));
|
||||
let defined_params_len = ctx.params.len();
|
||||
let given_params_len = params.len();
|
||||
|
@ -123,9 +123,9 @@ impl TyVarContext {
|
|||
self.push_or_init_typaram(&tp.tvar_name().unwrap(), &tp);
|
||||
inst_defaults.push(tp);
|
||||
}
|
||||
poly(name, [inst_non_defaults, inst_defaults].concat())
|
||||
builtin_poly(name, [inst_non_defaults, inst_defaults].concat())
|
||||
} 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 {
|
||||
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 } => {
|
||||
let lhs = if lhs.has_qvar() {
|
||||
self.instantiate_qvar(*lhs)
|
||||
|
@ -174,9 +177,10 @@ impl TyVarContext {
|
|||
}
|
||||
TyBound::Instance { name, t } => {
|
||||
let t = match t {
|
||||
Type::Poly { name, params } => {
|
||||
Type::BuiltinPoly { name, params } => {
|
||||
self.instantiate_poly(name.clone(), &name, params, ctx)
|
||||
}
|
||||
Type::Poly { .. } => todo!(),
|
||||
t => t,
|
||||
};
|
||||
let constraint = Constraint::new_type_of(t.clone());
|
||||
|
@ -385,7 +389,7 @@ impl Context {
|
|||
mode: RegistrationMode,
|
||||
) -> TyCheckResult<Type> {
|
||||
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()
|
||||
.map(|t| enum_unwrap!(t, Type::Subr));
|
||||
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)?
|
||||
} else {
|
||||
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>
|
||||
_ => {
|
||||
let level = if mode == PreRegister {
|
||||
|
@ -528,7 +532,7 @@ impl Context {
|
|||
} else if let Some(decl_t) = opt_decl_t {
|
||||
Ok(decl_t.typ().clone())
|
||||
} 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) {
|
||||
Ok(defined_t.clone())
|
||||
} else {
|
||||
|
@ -551,8 +555,8 @@ impl Context {
|
|||
todo!()
|
||||
}
|
||||
});
|
||||
// FIXME: if type is a trait
|
||||
Ok(poly(Str::rc(other), params.collect()))
|
||||
// FIXME: non-builtin
|
||||
Ok(builtin_poly(Str::rc(other), params.collect()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -573,7 +577,7 @@ impl Context {
|
|||
) -> SingleTyCheckResult<Type> {
|
||||
match expr {
|
||||
ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => {
|
||||
Ok(mono(self.mod_name(), name.inspect()))
|
||||
Ok(mono(self.path(), name.inspect()))
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
|
@ -632,7 +636,7 @@ impl Context {
|
|||
.collect(),
|
||||
)),
|
||||
// TODO: エラー処理(リテラルでない、ダブりがある)はパーサーにやらせる
|
||||
TypeSpec::Enum(set) => Ok(enum_t(
|
||||
TypeSpec::Enum(set) => Ok(v_enum(
|
||||
set.pos_args()
|
||||
.map(|arg| {
|
||||
if let ast::ConstExpr::Lit(lit) = &arg.expr {
|
||||
|
@ -861,11 +865,21 @@ impl Context {
|
|||
let lhs = self.instantiate_t(*lhs, tv_ctx, loc)?;
|
||||
Ok(mono_proj(lhs, rhs))
|
||||
}
|
||||
Poly { name, mut params } => {
|
||||
BuiltinPoly { name, mut params } => {
|
||||
for param in params.iter_mut() {
|
||||
*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(_) => {
|
||||
panic!("a quantified type should not be instantiated, instantiate the inner type")
|
||||
|
|
|
@ -16,6 +16,7 @@ pub mod tyvar;
|
|||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::option::Option; // conflicting to Type::Option
|
||||
use std::path::Path;
|
||||
|
||||
use erg_common::astr::AtomicStr;
|
||||
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
|
||||
///
|
||||
/// 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())
|
||||
}
|
||||
|
||||
pub(crate) fn mod_name(&self) -> &Str {
|
||||
pub(crate) fn path(&self) -> &Path {
|
||||
if let Some(outer) = self.get_outer() {
|
||||
outer.mod_name()
|
||||
outer.path()
|
||||
} else if self.kind == ContextKind::Module {
|
||||
&self.name
|
||||
Path::new(&self.name[..])
|
||||
} else {
|
||||
BUILTINS
|
||||
Path::new(&BUILTINS[..])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -787,10 +793,10 @@ impl Context {
|
|||
/// This avoids infinite loops.
|
||||
pub(crate) fn get_builtins(&self) -> Option<&Context> {
|
||||
// builtins中で定義した型等はmod_cacheがNoneになっている
|
||||
if &self.mod_name()[..] != "<builtins>" {
|
||||
if self.path().to_string_lossy() != "<builtins>" {
|
||||
self.mod_cache
|
||||
.as_ref()
|
||||
.map(|cache| cache.ref_ctx("<builtins>").unwrap())
|
||||
.map(|cache| cache.ref_ctx(Path::new("<builtins>")).unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -809,6 +815,7 @@ impl Context {
|
|||
};
|
||||
log!(info "{}: current namespace: {name}", fn_name!());
|
||||
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.py_mod_cache = self.get_outer().unwrap().py_mod_cache.clone();
|
||||
self.name = name.into();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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::levenshtein::get_similar_name;
|
||||
|
@ -12,10 +12,9 @@ use erg_type::free::HasLevel;
|
|||
use ast::{DefId, Identifier, VarName};
|
||||
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::{HasType, ParamTy, SubrType, TyBound, Type};
|
||||
use Type::*;
|
||||
use erg_type::{ParamTy, SubrType, TyBound, Type};
|
||||
|
||||
use crate::build_hir::HIRBuilder;
|
||||
use crate::context::{ClassDefType, Context, DefaultInfo, RegistrationMode, TraitInstance};
|
||||
|
@ -23,7 +22,7 @@ use crate::error::readable_name;
|
|||
use crate::error::{
|
||||
CompileResult, SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult,
|
||||
};
|
||||
use crate::hir::{self, Literal};
|
||||
use crate::hir::Literal;
|
||||
use crate::mod_cache::SharedModuleCache;
|
||||
use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind};
|
||||
use Mutability::*;
|
||||
|
@ -484,7 +483,7 @@ impl Context {
|
|||
let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
|
||||
let mut tv_ctx = TyVarContext::new(self.level, bounds, self);
|
||||
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) => {
|
||||
return Err(e);
|
||||
}
|
||||
|
@ -505,7 +504,7 @@ impl Context {
|
|||
}
|
||||
ast::Signature::Var(sig) if sig.is_const() => {
|
||||
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) => {
|
||||
return Err(e);
|
||||
}
|
||||
|
@ -609,7 +608,7 @@ impl Context {
|
|||
other => {
|
||||
let id = DefId(get_hash(ident));
|
||||
let vi = VarInfo::new(
|
||||
enum_t(set! {other.clone()}),
|
||||
v_enum(set! {other.clone()}),
|
||||
Const,
|
||||
ident.vis(),
|
||||
VarKind::Defined(id),
|
||||
|
@ -818,67 +817,33 @@ impl Context {
|
|||
pub(crate) fn import_mod(
|
||||
&mut self,
|
||||
kind: ImportKind,
|
||||
var_name: &VarName,
|
||||
mod_name: &hir::Expr,
|
||||
) -> CompileResult<()> {
|
||||
match mod_name {
|
||||
hir::Expr::Lit(lit) => {
|
||||
if self.subtype_of(&lit.value.class(), &Str) {
|
||||
mod_name: &Literal,
|
||||
) -> CompileResult<PathBuf> {
|
||||
if kind.is_erg_import() {
|
||||
self.import_erg_mod(var_name, lit)?;
|
||||
self.import_erg_mod(mod_name)
|
||||
} else {
|
||||
self.import_py_mod(var_name, lit)?;
|
||||
self.import_py_mod(mod_name)
|
||||
}
|
||||
} 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<()> {
|
||||
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str);
|
||||
fn import_erg_mod(&mut self, mod_name: &Literal) -> CompileResult<PathBuf> {
|
||||
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();
|
||||
#[allow(clippy::match_single_binding)]
|
||||
match &__name__[..] {
|
||||
// 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(
|
||||
&self,
|
||||
var_name: &VarName,
|
||||
__name__: Str,
|
||||
name_lit: &Literal,
|
||||
mod_name: &Literal,
|
||||
mod_cache: &SharedModuleCache,
|
||||
py_mod_cache: &SharedModuleCache,
|
||||
) -> CompileResult<()> {
|
||||
if let Some((_, entry)) = mod_cache.get_by_name(&__name__) {
|
||||
mod_cache.register_alias(var_name.clone(), entry);
|
||||
return Ok(());
|
||||
}
|
||||
) -> CompileResult<PathBuf> {
|
||||
let mut dir = if let Input::File(mut path) = self.cfg.input.clone() {
|
||||
path.pop();
|
||||
path
|
||||
|
@ -893,7 +858,7 @@ impl Context {
|
|||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
err.to_string(),
|
||||
name_lit.loc(),
|
||||
mod_name.loc(),
|
||||
self.caused_by(),
|
||||
self.mod_cache.as_ref().unwrap().get_similar_name(&__name__),
|
||||
self.similar_builtin_py_mod_name(&__name__).or_else(|| {
|
||||
|
@ -906,56 +871,68 @@ impl Context {
|
|||
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 mut builder = HIRBuilder::new_with_cache(
|
||||
cfg,
|
||||
var_name.inspect(),
|
||||
mod_cache.clone(),
|
||||
py_mod_cache.clone(),
|
||||
);
|
||||
let mut builder =
|
||||
HIRBuilder::new_with_cache(cfg, __name__, mod_cache.clone(), py_mod_cache.clone());
|
||||
match builder.build(src, "exec") {
|
||||
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)) => {
|
||||
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);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
fn import_py_mod(&mut self, var_name: &VarName, lit: &Literal) -> CompileResult<()> {
|
||||
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str);
|
||||
let mod_cache = self.mod_cache.as_ref().unwrap();
|
||||
fn import_py_mod(&mut self, mod_name: &Literal) -> CompileResult<PathBuf> {
|
||||
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
||||
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
||||
match &__name__[..] {
|
||||
"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" => {
|
||||
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" => {
|
||||
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" => {
|
||||
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" => {
|
||||
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" => {
|
||||
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" => {
|
||||
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> {
|
||||
|
@ -966,13 +943,9 @@ impl Context {
|
|||
.map(Str::rc)
|
||||
}
|
||||
|
||||
fn import_user_py_mod(&self, var_name: &VarName, lit: &Literal) -> CompileResult<()> {
|
||||
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str);
|
||||
fn import_user_py_mod(&self, mod_name: &Literal) -> CompileResult<PathBuf> {
|
||||
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
||||
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() {
|
||||
path.pop();
|
||||
path
|
||||
|
@ -987,39 +960,34 @@ impl Context {
|
|||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
err.to_string(),
|
||||
lit.loc(),
|
||||
mod_name.loc(),
|
||||
self.caused_by(),
|
||||
self.mod_cache.as_ref().unwrap().get_similar_name(&__name__),
|
||||
self.similar_builtin_py_mod_name(&__name__).or_else(|| {
|
||||
self.py_mod_cache
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get_similar_name(&__name__)
|
||||
}),
|
||||
self.similar_builtin_py_mod_name(&__name__)
|
||||
.or_else(|| py_mod_cache.get_similar_name(&__name__)),
|
||||
);
|
||||
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 mut builder = HIRBuilder::new_with_cache(
|
||||
cfg,
|
||||
var_name.inspect(),
|
||||
py_mod_cache.clone(),
|
||||
py_mod_cache.clone(),
|
||||
);
|
||||
let mut builder =
|
||||
HIRBuilder::new_with_cache(cfg, __name__, py_mod_cache.clone(), py_mod_cache.clone());
|
||||
match builder.build(src, "declare") {
|
||||
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)) => {
|
||||
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);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) {
|
||||
|
|
|
@ -4,7 +4,7 @@ use erg_common::Str;
|
|||
// use erg_common::error::Location;
|
||||
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::{Predicate, TyBound, Type};
|
||||
use Type::*;
|
||||
|
@ -32,7 +32,7 @@ impl Context {
|
|||
pub fn test_resolve_trait_inner1(&self) -> Result<(), ()> {
|
||||
let name = Str::ever("Add");
|
||||
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;
|
||||
for pair in self.rec_get_trait_impls(&name) {
|
||||
if self.supertype_of(&pair.sup_trait, &maybe_trait) {
|
||||
|
@ -48,7 +48,7 @@ impl Context {
|
|||
|
||||
pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> {
|
||||
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 bounds = set! {bound};
|
||||
let unbound_t = func1(t.clone(), t);
|
||||
|
|
|
@ -22,6 +22,7 @@ use crate::hir;
|
|||
use Predicate as Pred;
|
||||
use Type::*;
|
||||
use ValueObj::{Inf, NegInf};
|
||||
use Variance::*;
|
||||
|
||||
impl Context {
|
||||
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));
|
||||
ref_mut(self.generalize_t_inner(*before, bounds, lazy_inits), after)
|
||||
}
|
||||
Poly { name, mut params } => {
|
||||
BuiltinPoly { name, mut params } => {
|
||||
let params = params
|
||||
.iter_mut()
|
||||
.map(|p| self.generalize_tp(mem::take(p), bounds, lazy_inits))
|
||||
.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 } => {
|
||||
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 {
|
||||
TyParam::FreeVar(fv) if fv.is_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(
|
||||
self.cfg.input.clone(),
|
||||
fn_name!(),
|
||||
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 } => {
|
||||
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 })
|
||||
}
|
||||
|
@ -243,6 +260,7 @@ impl Context {
|
|||
fn deref_constraint(
|
||||
&self,
|
||||
constraint: Constraint,
|
||||
variance: Variance,
|
||||
loc: Location,
|
||||
) -> SingleTyCheckResult<Constraint> {
|
||||
match constraint {
|
||||
|
@ -259,12 +277,14 @@ impl Context {
|
|||
));
|
||||
}
|
||||
Ok(Constraint::new_sandwiched(
|
||||
self.deref_tyvar(sub, loc)?,
|
||||
self.deref_tyvar(sup, loc)?,
|
||||
self.deref_tyvar(sub, variance, loc)?,
|
||||
self.deref_tyvar(sup, variance, loc)?,
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
|
@ -273,10 +293,16 @@ impl Context {
|
|||
/// ```python
|
||||
// ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n)
|
||||
// ?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(:> {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 {
|
||||
// ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n)
|
||||
// ?T(:> Nat, <: Sub ?U(:> {1}))[n] ==> Nat
|
||||
|
@ -288,13 +314,31 @@ impl Context {
|
|||
if self.level <= fv.level().unwrap() {
|
||||
// REVIEW: Even if type constraints can be satisfied, implementation may not exist
|
||||
if self.subtype_of(sub_t, super_t) {
|
||||
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(), loc)?,
|
||||
&self.deref_tyvar(super_t.clone(), loc)?,
|
||||
&self.deref_tyvar(sub_t.clone(), variance, loc)?,
|
||||
&self.deref_tyvar(super_t.clone(), variance, loc)?,
|
||||
None,
|
||||
Some(loc),
|
||||
self.caused_by(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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(),
|
||||
|
@ -318,42 +362,62 @@ impl Context {
|
|||
}
|
||||
} else {
|
||||
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);
|
||||
Ok(Type::FreeVar(fv))
|
||||
}
|
||||
}
|
||||
Type::FreeVar(fv) if fv.is_linked() => {
|
||||
let t = fv.unwrap_linked();
|
||||
self.deref_tyvar(t, loc)
|
||||
self.deref_tyvar(t, variance, loc)
|
||||
}
|
||||
Type::Poly { name, mut params } => {
|
||||
for param in params.iter_mut() {
|
||||
*param = self.deref_tp(mem::take(param), loc)?;
|
||||
Type::BuiltinPoly { name, mut params } => {
|
||||
let typ = builtin_poly(&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 { 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) => {
|
||||
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 {
|
||||
*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() {
|
||||
*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))
|
||||
}
|
||||
Type::Ref(t) => {
|
||||
let t = self.deref_tyvar(*t, loc)?;
|
||||
let t = self.deref_tyvar(*t, variance, loc)?;
|
||||
Ok(ref_(t))
|
||||
}
|
||||
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 {
|
||||
Some(self.deref_tyvar(*after, loc)?)
|
||||
Some(self.deref_tyvar(*after, variance, loc)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -362,12 +426,29 @@ impl Context {
|
|||
Type::Callable { .. } => todo!(),
|
||||
Type::Record(mut rec) => {
|
||||
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))
|
||||
}
|
||||
// |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) => {
|
||||
let t = self.deref_tyvar(*refine.t, loc)?;
|
||||
let t = self.deref_tyvar(*refine.t, variance, loc)?;
|
||||
// TODO: deref_predicate
|
||||
Ok(refinement(refine.var, t, refine.preds))
|
||||
}
|
||||
|
@ -401,7 +482,7 @@ impl Context {
|
|||
hir::Expr::Accessor(acc) => {
|
||||
let loc = acc.loc();
|
||||
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 {
|
||||
hir::Accessor::Attr(attr) => {
|
||||
self.resolve_expr_t(&mut attr.obj)?;
|
||||
|
@ -420,7 +501,7 @@ impl Context {
|
|||
hir::Expr::Array(array) => match array {
|
||||
hir::Array::Normal(arr) => {
|
||||
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() {
|
||||
self.resolve_expr_t(&mut elem.expr)?;
|
||||
}
|
||||
|
@ -443,10 +524,12 @@ impl Context {
|
|||
for attr in record.attrs.iter_mut() {
|
||||
match &mut attr.sig {
|
||||
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) => {
|
||||
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() {
|
||||
|
@ -458,7 +541,7 @@ impl Context {
|
|||
hir::Expr::BinOp(binop) => {
|
||||
let loc = binop.loc();
|
||||
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.rhs)?;
|
||||
Ok(())
|
||||
|
@ -466,14 +549,14 @@ impl Context {
|
|||
hir::Expr::UnaryOp(unaryop) => {
|
||||
let loc = unaryop.loc();
|
||||
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)?;
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::Call(call) => {
|
||||
let loc = call.loc();
|
||||
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() {
|
||||
self.resolve_expr_t(&mut arg.expr)?;
|
||||
}
|
||||
|
@ -483,16 +566,16 @@ impl Context {
|
|||
Ok(())
|
||||
}
|
||||
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(())
|
||||
}
|
||||
hir::Expr::Def(def) => {
|
||||
match &mut def.sig {
|
||||
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) => {
|
||||
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() {
|
||||
|
@ -501,7 +584,7 @@ impl Context {
|
|||
Ok(())
|
||||
}
|
||||
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() {
|
||||
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::RefMut { before, .. }) => self.reunify(l, before, bef_loc, aft_loc),
|
||||
(
|
||||
Type::Poly {
|
||||
Type::BuiltinPoly {
|
||||
name: ln,
|
||||
params: lps,
|
||||
},
|
||||
Type::Poly {
|
||||
Type::BuiltinPoly {
|
||||
name: rn,
|
||||
params: rps,
|
||||
},
|
||||
) => {
|
||||
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(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1047,11 +1159,11 @@ impl Context {
|
|||
Ok(())
|
||||
}
|
||||
(
|
||||
Type::Poly {
|
||||
Type::BuiltinPoly {
|
||||
name: ln,
|
||||
params: lps,
|
||||
},
|
||||
Type::Poly {
|
||||
Type::BuiltinPoly {
|
||||
name: rn,
|
||||
params: rps,
|
||||
},
|
||||
|
@ -1072,6 +1184,34 @@ impl Context {
|
|||
}
|
||||
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)) => {
|
||||
self.sub_unify(maybe_sub, t, sub_loc, sup_loc, param_name)?;
|
||||
Ok(())
|
||||
|
@ -1085,7 +1225,7 @@ impl Context {
|
|||
(Refinement(_), Refinement(_)) => todo!(),
|
||||
(Type::Subr(_) | Type::Record(_), Type) => Ok(()),
|
||||
// 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)"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,6 +385,10 @@ impl Identifier {
|
|||
pub fn is_procedural(&self) -> bool {
|
||||
self.name.is_procedural()
|
||||
}
|
||||
|
||||
pub fn downcast(self) -> erg_parser::ast::Identifier {
|
||||
erg_parser::ast::Identifier::new(self.dot, self.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use erg_common::config::{ErgConfig, Input};
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
|
@ -9,8 +9,9 @@ use erg_common::{enum_unwrap, log};
|
|||
use erg_parser::ast::DefId;
|
||||
use erg_parser::token::{Token, TokenKind};
|
||||
|
||||
use erg_type::typaram::TyParam;
|
||||
use erg_type::value::ValueObj;
|
||||
use erg_type::Type;
|
||||
use erg_type::{HasType, Type};
|
||||
|
||||
use crate::hir::{
|
||||
Accessor, Args, Block, Call, Def, DefBody, Expr, Identifier, Literal, PosArg, HIR,
|
||||
|
@ -30,15 +31,16 @@ impl Linker {
|
|||
// x = ModuleType("mod")
|
||||
// exec(code, x.__dict__) # `code` is the mod's content
|
||||
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
|
||||
let hir = if cfg.input.is_repl() {
|
||||
mod_cache
|
||||
.get(&def.sig.ident().inspect()[..])
|
||||
.get(path.as_path())
|
||||
.and_then(|entry| entry.hir.clone())
|
||||
} else {
|
||||
mod_cache
|
||||
.remove(&def.sig.ident().inspect()[..])
|
||||
.and_then(|entry| entry.hir)
|
||||
mod_cache.remove(path.as_path()).and_then(|entry| entry.hir)
|
||||
};
|
||||
let mod_name = enum_unwrap!(def.body.block.first().unwrap(), Expr::Call)
|
||||
.args
|
||||
|
|
|
@ -16,7 +16,7 @@ use erg_parser::build_ast::ASTBuilder;
|
|||
use erg_parser::token::{Token, TokenKind};
|
||||
|
||||
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::typaram::TyParam;
|
||||
|
@ -85,11 +85,8 @@ impl Runnable for ASTLowerer {
|
|||
fn exec(&mut self) -> Result<(), Self::Errs> {
|
||||
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
||||
let ast = ast_builder.build(self.input().read())?;
|
||||
let (hir, warns) = self
|
||||
.lower(ast, "exec")
|
||||
.map_err(|(_, errs)| self.convert(errs))?;
|
||||
let (hir, warns) = self.lower(ast, "exec").map_err(|(_, errs)| errs)?;
|
||||
if self.cfg.verbose >= 2 {
|
||||
let warns = self.convert(warns);
|
||||
warns.fmt_all_stderr();
|
||||
}
|
||||
println!("{hir}");
|
||||
|
@ -99,9 +96,7 @@ impl Runnable for ASTLowerer {
|
|||
fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
|
||||
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
||||
let ast = ast_builder.build(src)?;
|
||||
let (hir, ..) = self
|
||||
.lower(ast, "eval")
|
||||
.map_err(|(_, errs)| self.convert(errs))?;
|
||||
let (hir, ..) = self.lower(ast, "eval").map_err(|(_, errs)| errs)?;
|
||||
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(
|
||||
&self,
|
||||
loc: Location,
|
||||
|
@ -160,7 +148,7 @@ impl ASTLowerer {
|
|||
if mode != "eval" && !expr.ref_t().is_nonelike() && !expr.is_type_asc() {
|
||||
Err(LowerError::syntax_error(
|
||||
self.cfg.input.clone(),
|
||||
0,
|
||||
line!() as usize,
|
||||
expr.loc(),
|
||||
AtomicStr::arc(&self.ctx.name[..]),
|
||||
switch_lang!(
|
||||
|
@ -264,7 +252,7 @@ impl ASTLowerer {
|
|||
match maybe_len {
|
||||
Ok(v @ ValueObj::Nat(_)) => {
|
||||
if elem.ref_t().is_mut() {
|
||||
poly(
|
||||
builtin_poly(
|
||||
"ArrayWithMutType!",
|
||||
vec![TyParam::t(elem.t()), TyParam::Value(v)],
|
||||
)
|
||||
|
@ -274,7 +262,7 @@ impl ASTLowerer {
|
|||
}
|
||||
Ok(v @ ValueObj::Mut(_)) if v.class() == builtin_mono("Nat!") => {
|
||||
if elem.ref_t().is_mut() {
|
||||
poly(
|
||||
builtin_poly(
|
||||
"ArrayWithMutTypeAndLength!",
|
||||
vec![TyParam::t(elem.t()), TyParam::Value(v)],
|
||||
)
|
||||
|
@ -286,7 +274,7 @@ impl ASTLowerer {
|
|||
// REVIEW: is it ok to ignore the error?
|
||||
Err(_e) => {
|
||||
if elem.ref_t().is_mut() {
|
||||
poly(
|
||||
builtin_poly(
|
||||
"ArrayWithMutType!",
|
||||
vec![TyParam::t(elem.t()), TyParam::erased(Type::Nat)],
|
||||
)
|
||||
|
@ -349,7 +337,9 @@ impl ASTLowerer {
|
|||
}
|
||||
ast::Accessor::Attr(attr) => {
|
||||
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 acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident, t));
|
||||
Ok(acc)
|
||||
|
@ -389,8 +379,12 @@ impl ASTLowerer {
|
|||
(Type::Failure, None)
|
||||
} else {
|
||||
(
|
||||
self.ctx.rec_get_var_t(&ident, &self.ctx.name)?,
|
||||
self.ctx.get_local_uniq_obj_name(&ident.name),
|
||||
self.ctx
|
||||
.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);
|
||||
|
@ -403,7 +397,9 @@ impl ASTLowerer {
|
|||
let lhs = 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 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 lhs = args.next().unwrap().expr;
|
||||
let rhs = args.next().unwrap().expr;
|
||||
|
@ -415,7 +411,9 @@ impl ASTLowerer {
|
|||
let mut args = unary.args.into_iter();
|
||||
let arg = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
|
||||
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 expr = args.next().unwrap().expr;
|
||||
Ok(hir::UnaryOp::new(unary.op, expr, t))
|
||||
|
@ -443,6 +441,7 @@ impl ASTLowerer {
|
|||
&call.method_name,
|
||||
&hir_args.pos_args,
|
||||
&hir_args.kw_args,
|
||||
&self.cfg.input,
|
||||
&self.ctx.name,
|
||||
)?;
|
||||
let method_name = if let Some(method_name) = call.method_name {
|
||||
|
@ -455,7 +454,14 @@ impl ASTLowerer {
|
|||
} else {
|
||||
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> {
|
||||
|
@ -482,6 +488,7 @@ impl ASTLowerer {
|
|||
&Some(method_name.clone()),
|
||||
&args,
|
||||
&[],
|
||||
&self.cfg.input,
|
||||
&self.ctx.name,
|
||||
)?;
|
||||
let args = hir::Args::new(args, None, vec![], None);
|
||||
|
@ -630,20 +637,6 @@ impl ASTLowerer {
|
|||
.as_mut()
|
||||
.unwrap()
|
||||
.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 sig = hir::VarSignature::new(ident, found_body_t.clone());
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
|
@ -785,7 +778,7 @@ impl ASTLowerer {
|
|||
}
|
||||
let (_, ctx) = self
|
||||
.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();
|
||||
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)
|
||||
|
@ -1224,7 +1217,7 @@ impl ASTLowerer {
|
|||
Ok(hir) => hir,
|
||||
Err((hir, errs)) => {
|
||||
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())));
|
||||
}
|
||||
};
|
||||
|
@ -1239,7 +1232,7 @@ impl ASTLowerer {
|
|||
log!(info "the AST lowering process has completed.");
|
||||
Ok((hir, LowerWarnings::from(self.warns.take_all())))
|
||||
} 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())))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
use erg_common::dict::Dict;
|
||||
|
@ -8,8 +9,6 @@ use erg_common::levenshtein::get_similar_name;
|
|||
use erg_common::shared::Shared;
|
||||
use erg_common::Str;
|
||||
|
||||
use erg_parser::ast::VarName;
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::hir::HIR;
|
||||
|
||||
|
@ -65,13 +64,17 @@ impl ModuleEntry {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ModuleCache {
|
||||
cache: Dict<VarName, ModuleEntry>,
|
||||
cache: Dict<PathBuf, ModuleEntry>,
|
||||
last_id: usize,
|
||||
}
|
||||
|
||||
impl fmt::Display for ModuleCache {
|
||||
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
|
||||
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)> {
|
||||
self.cache
|
||||
.iter()
|
||||
.find(|(_, ent)| &ent.ctx.name[..] == __name__)
|
||||
}
|
||||
|
||||
pub fn get_mut<Q: Eq + Hash + ?Sized>(&mut self, name: &Q) -> Option<&mut ModuleEntry>
|
||||
pub fn get_mut<Q: Eq + Hash + ?Sized>(&mut self, path: &Q) -> Option<&mut ModuleEntry>
|
||||
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;
|
||||
let id = ModId::new(self.last_id);
|
||||
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) {
|
||||
self.cache.insert(name, entry.clone());
|
||||
}
|
||||
|
||||
pub fn remove<Q: Eq + Hash + ?Sized>(&mut self, name: &Q) -> Option<ModuleEntry>
|
||||
pub fn remove<Q: Eq + Hash + ?Sized>(&mut self, path: &Q) -> Option<ModuleEntry>
|
||||
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> {
|
||||
|
@ -136,7 +129,7 @@ impl ModuleCache {
|
|||
}
|
||||
|
||||
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_
|
||||
}
|
||||
|
||||
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
|
||||
VarName: Borrow<Q>,
|
||||
PathBuf: Borrow<Q>,
|
||||
{
|
||||
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)> {
|
||||
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>
|
||||
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&mut ModuleEntry>
|
||||
where
|
||||
VarName: Borrow<Q>,
|
||||
PathBuf: Borrow<Q>,
|
||||
{
|
||||
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
|
||||
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
|
||||
VarName: Borrow<Q>,
|
||||
PathBuf: Borrow<Q>,
|
||||
{
|
||||
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) {
|
||||
self.0.borrow_mut().register(name, hir, ctx);
|
||||
pub fn register(&self, path: PathBuf, hir: Option<HIR>, ctx: Context) {
|
||||
self.0.borrow_mut().register(path, hir, ctx);
|
||||
}
|
||||
|
||||
pub fn register_alias(&self, name: VarName, entry: &ModuleEntry) {
|
||||
self.0.borrow_mut().register_alias(name, entry);
|
||||
}
|
||||
|
||||
pub fn remove<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<ModuleEntry>
|
||||
pub fn remove<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<ModuleEntry>
|
||||
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> {
|
||||
|
|
|
@ -509,7 +509,28 @@ impl Parser {
|
|||
let local = ConstLocal::new(local.name.into_token());
|
||||
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 => {
|
||||
self.errs.push(ParseError::syntax_error(
|
||||
0,
|
||||
|
|
|
@ -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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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]
|
||||
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));
|
||||
let name = Str::from(fresh_varname());
|
||||
let t = inner_class(&s);
|
||||
let preds = s
|
||||
.iter()
|
||||
.map(|o| Predicate::eq(name.clone(), TyParam::value(o.clone())))
|
||||
.into_iter()
|
||||
.map(|o| Predicate::eq(name.clone(), TyParam::value(o)))
|
||||
.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)
|
||||
}
|
||||
|
||||
|
@ -97,7 +113,7 @@ where
|
|||
}
|
||||
|
||||
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 {
|
||||
|
@ -112,11 +128,11 @@ pub fn ref_mut(before: Type, after: Option<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 {
|
||||
poly("Option!", vec![TyParam::t(t)])
|
||||
builtin_poly("Option!", vec![TyParam::t(t)])
|
||||
}
|
||||
|
||||
pub fn subr_t(
|
||||
|
@ -305,7 +321,7 @@ pub fn mono_q<S: Into<Str>>(name: S) -> Type {
|
|||
}
|
||||
|
||||
#[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 {
|
||||
path: path.into(),
|
||||
name: name.into(),
|
||||
|
@ -313,8 +329,8 @@ pub fn mono<S: Into<Str>, T: Into<Str>>(path: S, name: T) -> Type {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn poly<S: Into<Str>>(name: S, params: Vec<TyParam>) -> Type {
|
||||
Type::Poly {
|
||||
pub fn builtin_poly<S: Into<Str>>(name: S, params: Vec<TyParam>) -> Type {
|
||||
Type::BuiltinPoly {
|
||||
name: name.into(),
|
||||
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]
|
||||
pub fn mono_proj<S: Into<Str>>(lhs: Type, rhs: S) -> Type {
|
||||
Type::MonoProj {
|
||||
|
|
|
@ -12,6 +12,7 @@ pub mod value;
|
|||
|
||||
use std::fmt;
|
||||
use std::ops::{Range, RangeInclusive};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::set::Set;
|
||||
|
@ -181,7 +182,7 @@ impl ValueArgs {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct BuiltinConstSubr {
|
||||
name: &'static str,
|
||||
subr: fn(ValueArgs, Str, Option<Str>) -> EvalValueResult<ValueObj>,
|
||||
subr: fn(ValueArgs, PathBuf, Option<Str>) -> EvalValueResult<ValueObj>,
|
||||
sig_t: Type,
|
||||
as_type: Option<Type>,
|
||||
}
|
||||
|
@ -195,7 +196,7 @@ impl fmt::Display for BuiltinConstSubr {
|
|||
impl BuiltinConstSubr {
|
||||
pub const fn new(
|
||||
name: &'static str,
|
||||
subr: fn(ValueArgs, Str, Option<Str>) -> EvalValueResult<ValueObj>,
|
||||
subr: fn(ValueArgs, PathBuf, Option<Str>) -> EvalValueResult<ValueObj>,
|
||||
sig_t: Type,
|
||||
as_type: Option<Type>,
|
||||
) -> Self {
|
||||
|
@ -210,10 +211,10 @@ impl BuiltinConstSubr {
|
|||
pub fn call(
|
||||
&self,
|
||||
args: ValueArgs,
|
||||
mod_name: Str,
|
||||
path: PathBuf,
|
||||
__name__: Option<Str>,
|
||||
) -> 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 {
|
||||
match self {
|
||||
Self::Sandwiched { mid, .. } => mid.name(),
|
||||
|
@ -1095,7 +1103,6 @@ pub enum Type {
|
|||
Str,
|
||||
NoneType,
|
||||
Code,
|
||||
Module,
|
||||
Frame,
|
||||
Error,
|
||||
Inf, // {∞}
|
||||
|
@ -1110,7 +1117,7 @@ pub enum Type {
|
|||
Never, // {}
|
||||
BuiltinMono(Str),
|
||||
Mono {
|
||||
path: Str,
|
||||
path: PathBuf,
|
||||
name: Str,
|
||||
},
|
||||
/* Polymorphic types */
|
||||
|
@ -1138,7 +1145,12 @@ pub enum Type {
|
|||
And(Box<Type>, Box<Type>),
|
||||
Not(Box<Type>, Box<Type>),
|
||||
Or(Box<Type>, Box<Type>),
|
||||
BuiltinPoly {
|
||||
name: Str,
|
||||
params: Vec<TyParam>,
|
||||
},
|
||||
Poly {
|
||||
path: PathBuf,
|
||||
name: Str,
|
||||
params: Vec<TyParam>,
|
||||
},
|
||||
|
@ -1170,7 +1182,6 @@ impl PartialEq for Type {
|
|||
| (Self::Str, Self::Str)
|
||||
| (Self::NoneType, Self::NoneType)
|
||||
| (Self::Code, Self::Code)
|
||||
| (Self::Module, Self::Module)
|
||||
| (Self::Frame, Self::Frame)
|
||||
| (Self::Error, Self::Error)
|
||||
| (Self::Inf, Self::Inf)
|
||||
|
@ -1182,11 +1193,11 @@ impl PartialEq for Type {
|
|||
| (Self::NotImplemented, Self::NotImplemented)
|
||||
| (Self::Ellipsis, Self::Ellipsis)
|
||||
| (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 }) => {
|
||||
lp == rp && ln == rn
|
||||
}
|
||||
(Self::MonoQVar(l), Self::MonoQVar(r)) => l == r,
|
||||
(Self::Ref(l), Self::Ref(r)) => l == r,
|
||||
(
|
||||
Self::RefMut {
|
||||
|
@ -1228,6 +1239,18 @@ impl PartialEq for Type {
|
|||
| (Self::Or(ll, lr), Self::Or(rl, rr)) => ll == rl && lr == rr,
|
||||
(
|
||||
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,
|
||||
params: lps,
|
||||
}
|
||||
|
@ -1235,7 +1258,7 @@ impl PartialEq for Type {
|
|||
name: ln,
|
||||
params: lps,
|
||||
},
|
||||
Self::Poly {
|
||||
Self::BuiltinPoly {
|
||||
name: rn,
|
||||
params: rps,
|
||||
}
|
||||
|
@ -1281,7 +1304,7 @@ impl LimitedDisplay for Type {
|
|||
}
|
||||
match self {
|
||||
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) => {
|
||||
write!(f, "{}(", self.name())?;
|
||||
t.limited_fmt(f, limit - 1)?;
|
||||
|
@ -1338,7 +1361,17 @@ impl LimitedDisplay for Type {
|
|||
write!(f, " or ")?;
|
||||
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}(")?;
|
||||
for (i, tp) in params.iter().enumerate() {
|
||||
if i > 0 {
|
||||
|
@ -1430,7 +1463,9 @@ impl HasType for Type {
|
|||
// Self::And(ts) | Self::Or(ts) => ,
|
||||
Self::Subr(_sub) => todo!(),
|
||||
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![],
|
||||
}
|
||||
}
|
||||
|
@ -1488,7 +1523,9 @@ impl HasLevel for Type {
|
|||
t.update_level(level);
|
||||
}
|
||||
}
|
||||
Self::Poly { params, .. } => {
|
||||
Self::Poly { params, .. }
|
||||
| Self::BuiltinPoly { params, .. }
|
||||
| Self::PolyQVar { params, .. } => {
|
||||
for p in params.iter() {
|
||||
p.update_level(level);
|
||||
}
|
||||
|
@ -1549,7 +1586,9 @@ impl HasLevel for Type {
|
|||
t.lift();
|
||||
}
|
||||
}
|
||||
Self::Poly { params, .. } => {
|
||||
Self::Poly { params, .. }
|
||||
| Self::BuiltinPoly { params, .. }
|
||||
| Self::PolyQVar { params, .. } => {
|
||||
for p in params.iter() {
|
||||
p.lift();
|
||||
}
|
||||
|
@ -1622,7 +1661,6 @@ impl Type {
|
|||
| Self::Str
|
||||
| Self::NoneType
|
||||
| Self::Code
|
||||
| Self::Module
|
||||
| Self::Frame
|
||||
| Self::Error
|
||||
| Self::Inf
|
||||
|
@ -1648,8 +1686,10 @@ impl Type {
|
|||
}
|
||||
}
|
||||
Self::BuiltinMono(name)
|
||||
| Self::Mono { name, .. }
|
||||
| Self::MonoQVar(name)
|
||||
| Self::Poly { name, .. }
|
||||
| Self::BuiltinPoly { name, .. }
|
||||
| Self::PolyQVar { name, .. }
|
||||
| Self::MonoProj { rhs: name, .. } => name.ends_with('!'),
|
||||
Self::Refinement(refine) => refine.t.is_mut(),
|
||||
|
@ -1661,11 +1701,13 @@ impl Type {
|
|||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_nonelike(),
|
||||
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);
|
||||
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(),
|
||||
_ => false,
|
||||
}
|
||||
|
@ -1693,7 +1735,9 @@ impl Type {
|
|||
.map(|(sub, sup)| sub.contains_tvar(name) || sup.contains_tvar(name))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
Self::Poly { params, .. } => {
|
||||
Self::Poly { params, .. }
|
||||
| Self::BuiltinPoly { params, .. }
|
||||
| Self::PolyQVar { params, .. } => {
|
||||
for param in params.iter() {
|
||||
match param {
|
||||
TyParam::Type(t) if t.contains_tvar(name) => {
|
||||
|
@ -1766,7 +1810,6 @@ impl Type {
|
|||
Self::Trait => Str::ever("TraitType"),
|
||||
Self::Patch => Str::ever("Patch"),
|
||||
Self::Code => Str::ever("Code"),
|
||||
Self::Module => Str::ever("Module"),
|
||||
Self::Frame => Str::ever("Frame"),
|
||||
Self::Error => Str::ever("Error"),
|
||||
Self::Inf => Str::ever("Inf"),
|
||||
|
@ -1789,7 +1832,9 @@ impl Type {
|
|||
}) => Str::ever("Proc"),
|
||||
Self::Callable { .. } => Str::ever("Callable"),
|
||||
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でクラス名を使うため、こうすると都合が良い
|
||||
Self::Refinement(refine) => refine.t.name(),
|
||||
Self::Quantified(_) => Str::ever("Quantified"),
|
||||
|
@ -1819,7 +1864,7 @@ impl Type {
|
|||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(),
|
||||
Self::FreeVar(fv) => fv.unbound_name(),
|
||||
Self::MonoQVar(name) => Some(name.clone()),
|
||||
Self::MonoQVar(name) | Self::PolyQVar { name, .. } => Some(name.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1869,7 +1914,9 @@ impl Type {
|
|||
quant.unbound_callable.has_unbound_var()
|
||||
|| 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(),
|
||||
_ => false,
|
||||
}
|
||||
|
@ -1907,9 +1954,9 @@ impl Type {
|
|||
Self::Quantified(quant) => {
|
||||
quant.unbound_callable.is_cachable() || quant.bounds.iter().all(|b| b.is_cachable())
|
||||
}
|
||||
Self::Poly { params, .. } | Self::PolyQVar { params, .. } => {
|
||||
params.iter().all(|p| p.is_cachable())
|
||||
}
|
||||
Self::Poly { params, .. }
|
||||
| Self::BuiltinPoly { params, .. }
|
||||
| Self::PolyQVar { params, .. } => params.iter().all(|p| p.is_cachable()),
|
||||
Self::MonoProj { lhs, .. } => lhs.is_cachable(),
|
||||
_ => true,
|
||||
}
|
||||
|
@ -1958,9 +2005,9 @@ impl Type {
|
|||
quant.unbound_callable.has_unbound_var()
|
||||
|| quant.bounds.iter().any(|b| b.has_unbound_var())
|
||||
}
|
||||
Self::Poly { params, .. } | Self::PolyQVar { params, .. } => {
|
||||
params.iter().any(|p| p.has_unbound_var())
|
||||
}
|
||||
Self::Poly { params, .. }
|
||||
| Self::BuiltinPoly { params, .. }
|
||||
| Self::PolyQVar { params, .. } => params.iter().any(|p| p.has_unbound_var()),
|
||||
Self::MonoProj { lhs, .. } => lhs.has_no_unbound_var(),
|
||||
_ => false,
|
||||
}
|
||||
|
@ -1984,7 +2031,9 @@ impl Type {
|
|||
+ 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,
|
||||
}
|
||||
}
|
||||
|
@ -2000,7 +2049,9 @@ impl Type {
|
|||
}
|
||||
Self::Subr(subr) => subr.typarams(),
|
||||
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![],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use erg_common::{dict, fmt_iter, impl_display_from_debug, switch_lang};
|
|||
use erg_common::{RcArray, Str};
|
||||
|
||||
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::typaram::TyParam;
|
||||
use crate::{ConstSubr, HasType, Predicate, Type};
|
||||
|
@ -506,7 +506,7 @@ impl ValueObj {
|
|||
Self::Float(_) => builtin_mono("Float!"),
|
||||
Self::Str(_) => builtin_mono("Str!"),
|
||||
Self::Bool(_) => builtin_mono("Bool!"),
|
||||
Self::Array(arr) => poly(
|
||||
Self::Array(arr) => builtin_poly(
|
||||
"Array!",
|
||||
vec![
|
||||
TyParam::t(arr.iter().next().unwrap().class()),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue