mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 10:49:54 +00:00
feat: const abs/all/any/len/map
This commit is contained in:
parent
f0e47201bf
commit
d59a4e82d3
5 changed files with 214 additions and 8 deletions
|
@ -646,7 +646,12 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
fn call(&self, subr: ConstSubr, args: ValueArgs, loc: Location) -> EvalResult<TyParam> {
|
||||
pub(crate) fn call(
|
||||
&self,
|
||||
subr: ConstSubr,
|
||||
args: ValueArgs,
|
||||
loc: Location,
|
||||
) -> EvalResult<TyParam> {
|
||||
match subr {
|
||||
ConstSubr::User(user) => {
|
||||
// HACK: should avoid cloning
|
||||
|
|
|
@ -2089,8 +2089,10 @@ impl Context {
|
|||
record.register_py_builtin_const(
|
||||
FUNC_AS_DICT,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
None,
|
||||
as_dict,
|
||||
Some("_asdict"),
|
||||
None,
|
||||
);
|
||||
let mut record_meta_type = Self::builtin_mono_class(RECORD_META_TYPE, 2);
|
||||
record_meta_type.register_superclass(mono(RECORD), &record);
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::path::Path;
|
|||
use erg_common::dict::Dict;
|
||||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::traits::Stream;
|
||||
use erg_common::{dict, set};
|
||||
|
||||
use crate::context::eval::UndoableLinkedList;
|
||||
|
@ -799,6 +800,127 @@ pub(crate) fn as_record(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<T
|
|||
Ok(ValueObj::builtin_type(Type::Record(dict)).into())
|
||||
}
|
||||
|
||||
pub(crate) fn abs_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
|
||||
let num = args
|
||||
.remove_left_or_key("num")
|
||||
.ok_or_else(|| not_passed("num"))?;
|
||||
match num {
|
||||
ValueObj::Nat(n) => Ok(ValueObj::Nat(n).into()),
|
||||
ValueObj::Int(n) => Ok(ValueObj::Nat(n.unsigned_abs() as u64).into()),
|
||||
ValueObj::Bool(b) => Ok(ValueObj::Nat(b as u64).into()),
|
||||
ValueObj::Float(n) => Ok(ValueObj::Float(n.abs()).into()),
|
||||
ValueObj::Inf => Ok(ValueObj::Inf.into()),
|
||||
ValueObj::NegInf => Ok(ValueObj::Inf.into()),
|
||||
_ => Err(type_mismatch("Num", num, "num")),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn all_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
|
||||
let iterable = args
|
||||
.remove_left_or_key("iterable")
|
||||
.ok_or_else(|| not_passed("iterable"))?;
|
||||
let arr = match iterable {
|
||||
ValueObj::Array(a) => a.to_vec(),
|
||||
ValueObj::Tuple(t) => t.to_vec(),
|
||||
ValueObj::Set(s) => s.into_iter().collect(),
|
||||
_ => {
|
||||
return Err(type_mismatch("Iterable(Bool)", iterable, "iterable"));
|
||||
}
|
||||
};
|
||||
let mut all = true;
|
||||
for v in arr.iter() {
|
||||
match v {
|
||||
ValueObj::Bool(b) => {
|
||||
all &= *b;
|
||||
}
|
||||
_ => {
|
||||
return Err(type_mismatch("Bool", v, "iterable.next()"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(ValueObj::Bool(all).into())
|
||||
}
|
||||
|
||||
pub(crate) fn any_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
|
||||
let iterable = args
|
||||
.remove_left_or_key("iterable")
|
||||
.ok_or_else(|| not_passed("iterable"))?;
|
||||
let arr = match iterable {
|
||||
ValueObj::Array(a) => a.to_vec(),
|
||||
ValueObj::Tuple(t) => t.to_vec(),
|
||||
ValueObj::Set(s) => s.into_iter().collect(),
|
||||
_ => {
|
||||
return Err(type_mismatch("Iterable(Bool)", iterable, "iterable"));
|
||||
}
|
||||
};
|
||||
let mut any = false;
|
||||
for v in arr.iter() {
|
||||
match v {
|
||||
ValueObj::Bool(b) => {
|
||||
any |= *b;
|
||||
}
|
||||
_ => {
|
||||
return Err(type_mismatch("Bool", v, "iterable.next()"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(ValueObj::Bool(any).into())
|
||||
}
|
||||
|
||||
pub(crate) fn len_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
|
||||
let container = args
|
||||
.remove_left_or_key("iterable")
|
||||
.ok_or_else(|| not_passed("iterable"))?;
|
||||
let len = match container {
|
||||
ValueObj::Array(a) => a.len(),
|
||||
ValueObj::Tuple(t) => t.len(),
|
||||
ValueObj::Set(s) => s.len(),
|
||||
ValueObj::Dict(d) => d.len(),
|
||||
ValueObj::Record(r) => r.len(),
|
||||
ValueObj::Str(s) => s.len(),
|
||||
_ => {
|
||||
return Err(type_mismatch("Container", container, "container"));
|
||||
}
|
||||
};
|
||||
Ok(ValueObj::Nat(len as u64).into())
|
||||
}
|
||||
|
||||
pub(crate) fn map_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
|
||||
let iterable = args
|
||||
.remove_left_or_key("iterable")
|
||||
.ok_or_else(|| not_passed("iterable"))?;
|
||||
let func = args
|
||||
.remove_left_or_key("func")
|
||||
.ok_or_else(|| not_passed("func"))?;
|
||||
let arr = match iterable {
|
||||
ValueObj::Array(a) => a.to_vec(),
|
||||
ValueObj::Tuple(t) => t.to_vec(),
|
||||
ValueObj::Set(s) => s.into_iter().collect(),
|
||||
_ => {
|
||||
return Err(type_mismatch("Iterable(Bool)", iterable, "iterable"));
|
||||
}
|
||||
};
|
||||
let subr = match func {
|
||||
ValueObj::Subr(f) => f,
|
||||
_ => {
|
||||
return Err(type_mismatch("Subr", func, "func"));
|
||||
}
|
||||
};
|
||||
let mut mapped = vec![];
|
||||
for v in arr.into_iter() {
|
||||
let args = ValueArgs::pos_only(vec![v]);
|
||||
match ctx.call(subr.clone(), args, Location::Unknown) {
|
||||
Ok(res) => {
|
||||
mapped.push(res);
|
||||
}
|
||||
Err(mut err) => {
|
||||
return Err(EvalValueError::from(*err.remove(0).core));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(TyParam::Array(mapped))
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_path_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
|
||||
let path = args
|
||||
.remove_left_or_key("Path")
|
||||
|
|
|
@ -24,16 +24,34 @@ impl Context {
|
|||
let U = mono_q(TY_U, instanceof(Type));
|
||||
let Path = mono_q_tp(PATH, instanceof(Str));
|
||||
let t_abs = nd_func(vec![kw(KW_N, mono(NUM))], None, Nat);
|
||||
let abs = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
FUNC_ABS,
|
||||
abs_func,
|
||||
t_abs.clone(),
|
||||
None,
|
||||
)));
|
||||
let t_all = no_var_func(
|
||||
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(Bool)]))],
|
||||
vec![],
|
||||
Bool,
|
||||
);
|
||||
let all = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
FUNC_ALL,
|
||||
all_func,
|
||||
t_all.clone(),
|
||||
None,
|
||||
)));
|
||||
let t_any = no_var_func(
|
||||
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(Bool)]))],
|
||||
vec![],
|
||||
Bool,
|
||||
);
|
||||
let any = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
FUNC_ANY,
|
||||
any_func,
|
||||
t_any.clone(),
|
||||
None,
|
||||
)));
|
||||
let t_ascii = nd_func(vec![kw(KW_OBJECT, Obj)], None, Str);
|
||||
let t_array = no_var_func(
|
||||
vec![],
|
||||
|
@ -169,6 +187,12 @@ impl Context {
|
|||
.structuralize();
|
||||
func1(S, Nat)
|
||||
};
|
||||
let len = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
FUNC_LEN,
|
||||
len_func,
|
||||
t_len.clone(),
|
||||
None,
|
||||
)));
|
||||
let t_log = func(
|
||||
vec![],
|
||||
Some(kw(KW_OBJECTS, ref_(Obj))),
|
||||
|
@ -190,6 +214,12 @@ impl Context {
|
|||
poly(MAP, vec![ty_tp(U.clone())]),
|
||||
)
|
||||
.quantify();
|
||||
let map = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
FUNC_MAP,
|
||||
map_func,
|
||||
t_map.clone(),
|
||||
None,
|
||||
)));
|
||||
let O = mono_q(TY_O, subtypeof(mono(ORD)));
|
||||
// TODO: iterable should be non-empty
|
||||
let t_max = nd_func(
|
||||
|
@ -286,9 +316,30 @@ impl Context {
|
|||
poly(ZIP, vec![ty_tp(T.clone()), ty_tp(U.clone())]),
|
||||
)
|
||||
.quantify();
|
||||
self.register_py_builtin(FUNC_ABS, t_abs, Some(FUNC_ABS), 11);
|
||||
self.register_py_builtin(FUNC_ALL, t_all, Some(FUNC_ALL), 22);
|
||||
self.register_py_builtin(FUNC_ANY, t_any, Some(FUNC_ANY), 33);
|
||||
self.register_py_builtin_const(
|
||||
FUNC_ABS,
|
||||
vis.clone(),
|
||||
Some(t_abs),
|
||||
abs,
|
||||
Some(FUNC_ABS),
|
||||
Some(11),
|
||||
);
|
||||
self.register_py_builtin_const(
|
||||
FUNC_ALL,
|
||||
vis.clone(),
|
||||
Some(t_all),
|
||||
all,
|
||||
Some(FUNC_ALL),
|
||||
Some(22),
|
||||
);
|
||||
self.register_py_builtin_const(
|
||||
FUNC_ANY,
|
||||
vis.clone(),
|
||||
Some(t_any),
|
||||
any,
|
||||
Some(FUNC_ANY),
|
||||
Some(33),
|
||||
);
|
||||
self.register_py_builtin(FUNC_ARRAY, t_array, Some(FUNC_LIST), 215);
|
||||
self.register_py_builtin(FUNC_ASCII, t_ascii, Some(FUNC_ASCII), 53);
|
||||
// Leave as `Const`, as it may negatively affect assert casting.
|
||||
|
@ -386,8 +437,22 @@ impl Context {
|
|||
Some(FUNC_ISSUBCLASS),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_ITER, t_iter, Immutable, vis.clone(), Some(FUNC_ITER));
|
||||
self.register_builtin_py_impl(FUNC_LEN, t_len, Immutable, vis.clone(), Some(FUNC_LEN));
|
||||
self.register_builtin_py_impl(FUNC_MAP, t_map, Immutable, vis.clone(), Some(FUNC_MAP));
|
||||
self.register_py_builtin_const(
|
||||
FUNC_LEN,
|
||||
vis.clone(),
|
||||
Some(t_len),
|
||||
len,
|
||||
Some(FUNC_LEN),
|
||||
None,
|
||||
);
|
||||
self.register_py_builtin_const(
|
||||
FUNC_MAP,
|
||||
vis.clone(),
|
||||
Some(t_map),
|
||||
map,
|
||||
Some(FUNC_MAP),
|
||||
None,
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_MAX, t_max, Immutable, vis.clone(), Some(FUNC_MAX));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_MEMORYVIEW,
|
||||
|
|
|
@ -774,8 +774,10 @@ impl Context {
|
|||
&mut self,
|
||||
name: &str,
|
||||
vis: Visibility,
|
||||
t: Option<Type>,
|
||||
obj: ValueObj,
|
||||
py_name: Option<&'static str>,
|
||||
lineno: Option<u32>,
|
||||
) {
|
||||
if self.rec_get_const_obj(name).is_some() {
|
||||
panic!("already registered: {} {name}", self.name);
|
||||
|
@ -791,16 +793,26 @@ impl Context {
|
|||
}
|
||||
}
|
||||
}
|
||||
let t = t.unwrap_or_else(|| v_enum(set! {obj.clone()}));
|
||||
let loc = lineno
|
||||
.map(|lineno| Location::range(lineno, 0, lineno, name.len() as u32))
|
||||
.unwrap_or(Location::Unknown);
|
||||
let module = if &self.name[..] == "<builtins>" {
|
||||
builtins_path()
|
||||
} else {
|
||||
erg_core_decl_path().join(format!("{}.d.er", self.name))
|
||||
};
|
||||
let abs_loc = AbsLocation::new(Some(module.into()), loc);
|
||||
// TODO: not all value objects are comparable
|
||||
let vi = VarInfo::new(
|
||||
v_enum(set! {obj.clone()}),
|
||||
t,
|
||||
Const,
|
||||
vis,
|
||||
Builtin,
|
||||
None,
|
||||
self.kind.clone(),
|
||||
py_name.map(Str::ever),
|
||||
AbsLocation::unknown(),
|
||||
abs_loc,
|
||||
);
|
||||
self.consts.insert(VarName::from_str(Str::rc(name)), obj);
|
||||
self.locals.insert(VarName::from_str(Str::rc(name)), vi);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue