mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 02:39:20 +00:00
fix: range type definition bug
This commit is contained in:
parent
ac80cbba87
commit
f612340e80
8 changed files with 92 additions and 10 deletions
|
@ -1984,7 +1984,7 @@ impl Context {
|
|||
}
|
||||
|
||||
// sup/inf({±∞}) = ±∞ではあるが、Inf/NegInfにはOrdを実装しない
|
||||
fn sup(&self, t: &Type) -> Option<TyParam> {
|
||||
pub(crate) fn sup(&self, t: &Type) -> Option<TyParam> {
|
||||
match t {
|
||||
Int | Nat | Float => Some(TyParam::value(Inf)),
|
||||
Refinement(refine) => {
|
||||
|
@ -2011,7 +2011,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
fn inf(&self, t: &Type) -> Option<TyParam> {
|
||||
pub(crate) fn inf(&self, t: &Type) -> Option<TyParam> {
|
||||
match t {
|
||||
Int | Float => Some(TyParam::value(-Inf)),
|
||||
Nat => Some(TyParam::value(0usize)),
|
||||
|
|
|
@ -667,7 +667,7 @@ impl Context {
|
|||
&self,
|
||||
subr: ConstSubr,
|
||||
args: ValueArgs,
|
||||
loc: Location,
|
||||
loc: impl Locational,
|
||||
) -> EvalResult<TyParam> {
|
||||
match subr {
|
||||
ConstSubr::User(user) => {
|
||||
|
@ -695,7 +695,7 @@ impl Context {
|
|||
}
|
||||
ConstSubr::Builtin(builtin) => builtin.call(args, self).map_err(|mut e| {
|
||||
if e.0.loc.is_unknown() {
|
||||
e.0.loc = loc;
|
||||
e.0.loc = loc.loc();
|
||||
}
|
||||
EvalErrors::from(EvalError::new(
|
||||
*e.0,
|
||||
|
@ -705,7 +705,7 @@ impl Context {
|
|||
}),
|
||||
ConstSubr::Gen(gen) => gen.call(args, self).map_err(|mut e| {
|
||||
if e.0.loc.is_unknown() {
|
||||
e.0.loc = loc;
|
||||
e.0.loc = loc.loc();
|
||||
}
|
||||
EvalErrors::from(EvalError::new(
|
||||
*e.0,
|
||||
|
@ -1749,6 +1749,15 @@ impl Context {
|
|||
}
|
||||
};
|
||||
}
|
||||
if let Some(ValueObj::Subr(subr)) = self.rec_get_const_obj(&name) {
|
||||
if let Ok(args) = self.convert_args(None, subr, params.clone(), t_loc) {
|
||||
let ret = self.call(subr.clone(), args, t_loc);
|
||||
if let Some(t) = ret.ok().and_then(|tp| self.convert_tp_into_type(tp).ok())
|
||||
{
|
||||
return Ok(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(poly(name, params))
|
||||
}
|
||||
Type::And(l, r) => {
|
||||
|
|
|
@ -464,6 +464,10 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
Ok(TyParam::FreeVar(fv))
|
||||
}
|
||||
TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t)?)),
|
||||
TyParam::Value(ValueObj::Type(mut t)) => {
|
||||
t.try_map_t(|t| self.deref_tyvar(t.clone()))?;
|
||||
Ok(TyParam::Value(ValueObj::Type(t)))
|
||||
}
|
||||
TyParam::Erased(t) => Ok(TyParam::erased(self.deref_tyvar(*t)?)),
|
||||
TyParam::App { name, mut args } => {
|
||||
for param in args.iter_mut() {
|
||||
|
|
|
@ -9,6 +9,7 @@ use erg_common::traits::Stream;
|
|||
use erg_common::{dict, set};
|
||||
|
||||
use crate::context::eval::UndoableLinkedList;
|
||||
use crate::context::initialize::closed_range;
|
||||
use crate::context::Context;
|
||||
use crate::feature_error;
|
||||
use crate::ty::constructors::{and, mono, tuple_t, v_enum};
|
||||
|
@ -1522,3 +1523,45 @@ pub(crate) fn zip_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
|
|||
}
|
||||
Ok(TyParam::Value(ValueObj::Array(zipped.into())))
|
||||
}
|
||||
|
||||
/// ```erg
|
||||
/// derefine({X: T | ...}) == T
|
||||
/// ```
|
||||
pub(crate) fn derefine_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
|
||||
let val = args
|
||||
.remove_left_or_key("T")
|
||||
.ok_or_else(|| not_passed("T"))?;
|
||||
let t = match ctx.convert_value_into_type(val) {
|
||||
Ok(t) => t.derefine(),
|
||||
Err(val) => {
|
||||
return Err(type_mismatch("Type", val, "T"));
|
||||
}
|
||||
};
|
||||
Ok(TyParam::t(t))
|
||||
}
|
||||
|
||||
/// ```erg
|
||||
/// fill_ord({1, 4}) == {1, 2, 3, 4}
|
||||
/// fill_ord({"a", "c"}) == {"a", "b", "c"}
|
||||
/// ```
|
||||
pub(crate) fn fill_ord_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
|
||||
let val = args
|
||||
.remove_left_or_key("T")
|
||||
.ok_or_else(|| not_passed("T"))?;
|
||||
let t = match ctx.convert_value_into_type(val) {
|
||||
Ok(t) => {
|
||||
let coerced = ctx.coerce(t.clone(), &()).unwrap_or(t);
|
||||
let inf = ctx.inf(&coerced);
|
||||
let sup = ctx.sup(&coerced);
|
||||
let der = coerced.derefine();
|
||||
match (inf, sup) {
|
||||
(Some(inf), Some(sup)) => closed_range(der, inf, sup),
|
||||
_ => coerced,
|
||||
}
|
||||
}
|
||||
Err(val) => {
|
||||
return Err(type_mismatch("Type", val, "T"));
|
||||
}
|
||||
};
|
||||
Ok(TyParam::t(t))
|
||||
}
|
||||
|
|
|
@ -856,6 +856,22 @@ impl Context {
|
|||
let t_pred = nd_func(vec![kw(KW_N, Nat)], None, Nat);
|
||||
let pred = ConstSubr::Builtin(BuiltinConstSubr::new(FUNC_PRED, pred_func, t_pred, None));
|
||||
self.register_builtin_const(FUNC_PRED, vis.clone(), None, ValueObj::Subr(pred));
|
||||
let t_derefine = nd_func(vec![kw(KW_T, Type)], None, Type);
|
||||
let derefine = ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
FUNC_DEREFINE,
|
||||
derefine_func,
|
||||
t_derefine,
|
||||
None,
|
||||
));
|
||||
self.register_builtin_const(FUNC_DEREFINE, vis.clone(), None, ValueObj::Subr(derefine));
|
||||
let t_fill_ord = nd_func(vec![kw(KW_T, Type)], None, Type);
|
||||
let fill_ord = ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
FUNC_FILL_ORD,
|
||||
fill_ord_func,
|
||||
t_fill_ord,
|
||||
None,
|
||||
));
|
||||
self.register_builtin_const(FUNC_FILL_ORD, vis.clone(), None, ValueObj::Subr(fill_ord));
|
||||
}
|
||||
|
||||
pub(super) fn init_builtin_py_specific_funcs(&mut self) {
|
||||
|
@ -983,8 +999,8 @@ impl Context {
|
|||
Some("eq"),
|
||||
);
|
||||
self.register_builtin_py_impl(OP_NE, op_t, Const, Visibility::BUILTIN_PRIVATE, Some("ne"));
|
||||
let O = mono_q(TY_O, subtypeof(mono(PARTIAL_ORD)));
|
||||
let op_t = bin_op(O.clone(), O.clone(), Bool).quantify();
|
||||
let PO = mono_q(TY_O, subtypeof(mono(PARTIAL_ORD)));
|
||||
let op_t = bin_op(PO.clone(), PO.clone(), Bool).quantify();
|
||||
self.register_builtin_py_impl(
|
||||
OP_LT,
|
||||
op_t.clone(),
|
||||
|
@ -1055,7 +1071,13 @@ impl Context {
|
|||
Visibility::BUILTIN_PRIVATE,
|
||||
Some("rshift"),
|
||||
);
|
||||
let op_t = bin_op(O.clone(), O.clone(), range(O)).quantify();
|
||||
let O = mono_q(TY_O, subtypeof(mono(ORD)));
|
||||
let op_t = bin_op(
|
||||
O.clone(),
|
||||
O.clone(),
|
||||
range(poly(FUNC_FILL_ORD, vec![ty_tp(O)])),
|
||||
)
|
||||
.quantify();
|
||||
self.register_builtin_erg_decl(OP_RNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_decl(OP_LORNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_decl(OP_RORNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
|
||||
|
|
|
@ -152,6 +152,8 @@ const MUT_RATIO: &str = "Ratio!";
|
|||
const FUNC_ABS: &str = "abs";
|
||||
const FUNC_SUCC: &str = "succ";
|
||||
const FUNC_PRED: &str = "pred";
|
||||
const FUNC_DEREFINE: &str = "derefine";
|
||||
const FUNC_FILL_ORD: &str = "fill_ord";
|
||||
const FUNC_BIT_LENGTH: &str = "bit_length";
|
||||
const FUNC_BIT_COUNT: &str = "bit_count";
|
||||
const FUNC_BYTEORDER: &str = "byteorder";
|
||||
|
@ -535,6 +537,7 @@ const KW_C: &str = "c";
|
|||
const KW_N: &str = "n";
|
||||
const KW_S: &str = "s";
|
||||
const KW_X: &str = "X";
|
||||
const KW_T: &str = "T";
|
||||
const KW_SELF: &str = "self";
|
||||
const KW_LENGTH: &str = "length";
|
||||
const KW_PROC: &str = "proc!";
|
||||
|
|
|
@ -2789,10 +2789,10 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
|||
tasc.expr.loc(),
|
||||
self.module.context.caused_by(),
|
||||
switch_lang!(
|
||||
"japanese" => "無効な型宣言です(左辺には記名型のみ使用出来ます)".to_string(),
|
||||
"japanese" => "無効な型宣言です(左辺には変数のみ使用出来ます)".to_string(),
|
||||
"simplified_chinese" => "无效的类型声明".to_string(),
|
||||
"traditional_chinese" => "無效的型宣告".to_string(),
|
||||
"english" => "Invalid type declaration (currently only nominal types are allowed at LHS)".to_string(),
|
||||
"english" => "Invalid type declaration (currently only variables are allowed at LHS)".to_string(),
|
||||
),
|
||||
None,
|
||||
)));
|
||||
|
|
|
@ -1258,6 +1258,7 @@ impl ValueObj {
|
|||
}
|
||||
(Self::Inf, n) | (n, Self::NegInf) if n.is_num() => Some(Ordering::Greater),
|
||||
(n, Self::Inf) | (Self::NegInf, n) if n.is_num() => Some(Ordering::Less),
|
||||
(Self::Str(l), Self::Str(r)) => Some(l.cmp(r)),
|
||||
/* (Self::PlusEpsilon(l), r) => l.try_cmp(r)
|
||||
.map(|o| if matches!(o, Ordering::Equal) { Ordering::Less } else { o }),
|
||||
(l, Self::PlusEpsilon(r)) => l.try_cmp(r)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue