erg_compiler/context/initialize/
const_func.rs

1use std::fmt::Display;
2use std::mem;
3use std::path::Path;
4
5use erg_common::dict::Dict;
6#[allow(unused_imports)]
7use erg_common::log;
8use erg_common::traits::Stream;
9use erg_common::{dict, set, set_recursion_limit};
10
11use crate::context::eval::UndoableLinkedList;
12use crate::context::initialize::closed_range;
13use crate::context::Context;
14use crate::feature_error;
15use crate::ty::constructors::{and, dict_mut, list_mut, mono, tuple_t, v_enum};
16use crate::ty::value::{EvalValueError, EvalValueResult, GenTypeObj, TypeObj, ValueObj};
17use crate::ty::{Field, TyParam, Type, ValueArgs};
18use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
19use erg_common::style::{Color, StyledStr, StyledString, THEME};
20
21const ERR: Color = THEME.colors.error;
22const WARN: Color = THEME.colors.warning;
23
24fn not_passed(t: impl Display) -> EvalValueError {
25    let text = t.to_string();
26    let param = StyledStr::new(&text, Some(ERR), None);
27    ErrorCore::new(
28        vec![SubMessage::only_loc(Location::Unknown)],
29        format!("{param} is not passed"),
30        line!() as usize,
31        ErrorKind::KeyError,
32        Location::Unknown,
33    )
34    .into()
35}
36
37fn no_key(slf: impl Display, key: impl Display) -> EvalValueError {
38    ErrorCore::new(
39        vec![SubMessage::only_loc(Location::Unknown)],
40        format!("{slf} has no key {key}"),
41        line!() as usize,
42        ErrorKind::KeyError,
43        Location::Unknown,
44    )
45    .into()
46}
47
48fn type_mismatch(expected: impl Display, got: impl Display, param: &str) -> EvalValueError {
49    let got = StyledString::new(format!("{got}"), Some(ERR), None);
50    let param = StyledStr::new(param, Some(WARN), None);
51    ErrorCore::new(
52        vec![SubMessage::only_loc(Location::Unknown)],
53        format!("non-{expected} object {got} is passed to {param}"),
54        line!() as usize,
55        ErrorKind::TypeError,
56        Location::Unknown,
57    )
58    .into()
59}
60
61fn todo(msg: &str) -> EvalValueError {
62    ErrorCore::new(
63        vec![SubMessage::only_loc(Location::Unknown)],
64        format!("{msg} is not supported yet in const context"),
65        line!() as usize,
66        ErrorKind::FeatureError,
67        Location::Unknown,
68    )
69    .into()
70}
71
72/// Base := Type or NoneType, Impl := Type -> ClassType
73pub(crate) fn class_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
74    let base = args.remove_left_or_key("Base");
75    let impls = args.remove_left_or_key("Impl");
76    let impls = impls.and_then(|v| v.as_type(ctx));
77    let t = mono(ctx.name.clone());
78    match base {
79        Some(value) => {
80            if let Some(base) = value.as_type(ctx) {
81                Ok(ValueObj::gen_t(GenTypeObj::class(t, Some(base), impls, true)).into())
82            } else {
83                Err(type_mismatch("type", value, "Base"))
84            }
85        }
86        None => Ok(ValueObj::gen_t(GenTypeObj::class(t, None, impls, true)).into()),
87    }
88}
89
90/// Super: ClassType, Impl := Type, Additional := Type -> ClassType
91pub(crate) fn inherit_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
92    let sup = args
93        .remove_left_or_key("Super")
94        .ok_or_else(|| not_passed("Super"))?;
95    let Some(sup) = sup.as_type(ctx) else {
96        return Err(type_mismatch("class", sup, "Super"));
97    };
98    let impls = args.remove_left_or_key("Impl");
99    let impls = impls.and_then(|v| v.as_type(ctx));
100    let additional = args.remove_left_or_key("Additional");
101    let additional = additional.and_then(|v| v.as_type(ctx));
102    let t = mono(ctx.name.clone());
103    Ok(ValueObj::gen_t(GenTypeObj::inherited(t, sup, impls, additional)).into())
104}
105
106/// Class: ClassType -> ClassType (with `InheritableType`)
107/// This function is used by the compiler to mark a class as inheritable and does nothing in terms of actual operation.
108pub(crate) fn inheritable_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
109    let class = args
110        .remove_left_or_key("Class")
111        .ok_or_else(|| not_passed("Class"))?;
112    match class {
113        ValueObj::Type(TypeObj::Generated(mut gen)) => {
114            if let Some(typ) = gen.impls_mut() {
115                match typ.as_mut().map(|x| x.as_mut()) {
116                    Some(TypeObj::Generated(gen)) => {
117                        *gen.typ_mut() = and(mem::take(gen.typ_mut()), mono("InheritableType"));
118                    }
119                    Some(TypeObj::Builtin { t, .. }) => {
120                        *t = and(mem::take(t), mono("InheritableType"));
121                    }
122                    _ => {
123                        *typ = Some(Box::new(TypeObj::builtin_trait(mono("InheritableType"))));
124                    }
125                }
126            }
127            Ok(ValueObj::Type(TypeObj::Generated(gen)).into())
128        }
129        other => feature_error!(
130            EvalValueError,
131            _ctx,
132            Location::Unknown,
133            &format!("Inheritable {other}")
134        ),
135    }
136}
137
138pub(crate) fn override_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
139    let func = args
140        .remove_left_or_key("func")
141        .ok_or_else(|| not_passed("func"))?;
142    Ok(func.into())
143}
144
145/// Base: Type, Impl := Type -> TraitType
146pub(crate) fn trait_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
147    let req = args
148        .remove_left_or_key("Requirement")
149        .ok_or_else(|| not_passed("Requirement"))?;
150    let Some(req) = req.as_type(ctx) else {
151        return Err(type_mismatch("type", req, "Requirement"));
152    };
153    let impls = args.remove_left_or_key("Impl");
154    let impls = impls.and_then(|v| v.as_type(ctx));
155    let t = mono(ctx.name.clone());
156    Ok(ValueObj::gen_t(GenTypeObj::trait_(t, req, impls, true)).into())
157}
158
159/// Base: Type, Impl := Type -> Patch
160pub(crate) fn patch_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
161    let base = args
162        .remove_left_or_key("Base")
163        .ok_or_else(|| not_passed("Base"))?;
164    let Some(base) = base.as_type(ctx) else {
165        return Err(type_mismatch("type", base, "Base"));
166    };
167    let impls = args.remove_left_or_key("Impl");
168    let impls = impls.and_then(|v| v.as_type(ctx));
169    let t = mono(ctx.name.clone());
170    Ok(ValueObj::gen_t(GenTypeObj::patch(t, base, impls)).into())
171}
172
173/// Super: TraitType, Impl := Type, Additional := Type -> TraitType
174pub(crate) fn subsume_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
175    let sup = args
176        .remove_left_or_key("Super")
177        .ok_or_else(|| not_passed("Super"))?;
178    let Some(sup) = sup.as_type(ctx) else {
179        return Err(type_mismatch("trait", sup, "Super"));
180    };
181    let impls = args.remove_left_or_key("Impl");
182    let impls = impls.and_then(|v| v.as_type(ctx));
183    let additional = args.remove_left_or_key("Additional");
184    let additional = additional.and_then(|v| v.as_type(ctx));
185    let t = mono(ctx.name.clone());
186    Ok(ValueObj::gen_t(GenTypeObj::subsumed(t, sup, impls, additional)).into())
187}
188
189pub(crate) fn structural_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
190    let type_ = args
191        .remove_left_or_key("Type")
192        .ok_or_else(|| not_passed("Type"))?;
193    let Some(base) = type_.as_type(ctx) else {
194        return Err(type_mismatch("type", type_, "Type"));
195    };
196    let t = base.typ().clone().structuralize();
197    Ok(ValueObj::gen_t(GenTypeObj::structural(t, base)).into())
198}
199
200pub(crate) fn __list_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
201    let slf = args
202        .remove_left_or_key("Self")
203        .ok_or_else(|| not_passed("Self"))?;
204    let slf = match ctx.convert_value_into_list(slf) {
205        Ok(slf) => slf,
206        Err(val) => {
207            return Err(type_mismatch("List", val, "Self"));
208        }
209    };
210    let index = args
211        .remove_left_or_key("Index")
212        .ok_or_else(|| not_passed("Index"))?;
213    let Ok(index) = usize::try_from(&index) else {
214        return Err(type_mismatch("Nat", index, "Index"));
215    };
216    if let Some(v) = slf.get(index) {
217        Ok(v.clone().into())
218    } else {
219        Err(ErrorCore::new(
220            vec![SubMessage::only_loc(Location::Unknown)],
221            format!(
222                "[{}] has {} elements, but accessed {}th element",
223                erg_common::fmt_vec(&slf),
224                slf.len(),
225                index
226            ),
227            line!() as usize,
228            ErrorKind::IndexError,
229            Location::Unknown,
230        )
231        .into())
232    }
233}
234
235pub(crate) fn sub_vdict_get<'d>(
236    dict: &'d Dict<ValueObj, ValueObj>,
237    key: &ValueObj,
238    ctx: &Context,
239) -> Option<&'d ValueObj> {
240    set_recursion_limit!(None, 64);
241    let mut matches = vec![];
242    for (k, v) in dict.iter() {
243        if key == k {
244            return Some(v);
245        }
246        match (
247            ctx.convert_value_into_type(key.clone()),
248            ctx.convert_value_into_type(k.clone()),
249        ) {
250            (Ok(idx), Ok(kt))
251                if dict.len() == 1 || ctx.subtype_of(&idx.lower_bounded(), &kt.lower_bounded()) =>
252            {
253                matches.push((idx, kt, v));
254            }
255            _ => {}
256        }
257    }
258    for (idx, kt, v) in matches.into_iter() {
259        let list = UndoableLinkedList::new();
260        match ctx.undoable_sub_unify(&idx, &kt, &(), &list, None) {
261            Ok(_) => {
262                return Some(v);
263            }
264            Err(_err) => {
265                erg_common::log!(err "{idx} <!: {kt} => {v}");
266            }
267        }
268    }
269    None
270}
271
272pub(crate) fn sub_tpdict_get<'d>(
273    dict: &'d Dict<TyParam, TyParam>,
274    key: &TyParam,
275    ctx: &Context,
276) -> Option<&'d TyParam> {
277    let mut matches = vec![];
278    for (k, v) in dict.iter() {
279        if key == k {
280            return Some(v);
281        }
282        match (
283            ctx.convert_tp_into_type(key.clone()),
284            ctx.convert_tp_into_type(k.clone()),
285        ) {
286            (Ok(idx), Ok(kt))
287                if dict.len() == 1 || ctx.subtype_of(&idx.lower_bounded(), &kt.lower_bounded()) =>
288            {
289                matches.push((idx, kt, v));
290            }
291            _ => {}
292        }
293    }
294    for (idx, kt, v) in matches.into_iter() {
295        let list = UndoableLinkedList::new();
296        match ctx.undoable_sub_unify(&idx, &kt, &(), &list, None) {
297            Ok(_) => {
298                return Some(v);
299            }
300            Err(_err) => {
301                erg_common::log!(err "{idx} <!: {kt} => {v}");
302            }
303        }
304    }
305    None
306}
307
308/// `{{"a"}: Int, {"b"}: Float} ==> {{"a", "b"}: Float}`
309fn homogenize_dict_type(dict: &Dict<Type, Type>, ctx: &Context) -> Dict<Type, Type> {
310    let mut union_key = Type::Never;
311    let mut union_value = Type::Never;
312    for (k, v) in dict.iter() {
313        union_key = ctx.union(&union_key, k);
314        union_value = ctx.union(&union_value, v);
315    }
316    dict! { union_key => union_value }
317}
318
319/// see `homogenize_dict_type`
320fn homogenize_dict(dict: &Dict<ValueObj, ValueObj>, ctx: &Context) -> Dict<ValueObj, ValueObj> {
321    let mut type_dict = Dict::new();
322    for (k, v) in dict.iter() {
323        match (k, v) {
324            (ValueObj::Type(k), ValueObj::Type(v)) => {
325                type_dict.insert(k.typ().clone(), v.typ().clone());
326            }
327            _ => {
328                return dict.clone();
329            }
330        }
331    }
332    let dict_t = homogenize_dict_type(&type_dict, ctx);
333    let mut value_dict = Dict::new();
334    for (k, v) in dict_t.iter() {
335        let k = ValueObj::builtin_type(k.clone());
336        let v = ValueObj::builtin_type(v.clone());
337        value_dict.insert(k, v);
338    }
339    value_dict
340}
341
342pub(crate) fn __dict_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
343    let slf = args
344        .remove_left_or_key("Self")
345        .ok_or_else(|| not_passed("Self"))?;
346    let Ok(slf) = ctx.convert_value_to_dict(&slf) else {
347        return Err(type_mismatch("Dict", slf, "Self"));
348    };
349    let index = args
350        .remove_left_or_key("Index")
351        .ok_or_else(|| not_passed("Index"))?;
352    if let Some(v) = slf
353        .linear_get(&index)
354        .or_else(|| sub_vdict_get(&slf, &index, ctx))
355    {
356        Ok(v.clone().into())
357    } else if let Some(v) = sub_vdict_get(&homogenize_dict(&slf, ctx), &index, ctx).cloned() {
358        Ok(v.into())
359    } else {
360        let index = if let ValueObj::Type(t) = &index {
361            ValueObj::builtin_type(ctx.readable_type(t.typ().clone()))
362        } else {
363            index
364        };
365        Err(no_key(slf, index))
366    }
367}
368
369/// ```erg
370/// {"a": 1, "b": 2}.keys() == ["a", "b"]
371/// {Str: Int, Int: Float}.keys() == Str or Int
372/// ```
373pub(crate) fn dict_keys(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
374    let slf = args
375        .remove_left_or_key("Self")
376        .ok_or_else(|| not_passed("Self"))?;
377    let Ok(slf) = ctx.convert_value_to_dict(&slf) else {
378        return Err(type_mismatch("Dict", slf, "Self"));
379    };
380    let dict_type = slf
381        .iter()
382        .map(|(k, v)| {
383            let k = ctx.convert_value_into_type(k.clone())?;
384            let v = ctx.convert_value_into_type(v.clone())?;
385            Ok((k, v))
386        })
387        .collect::<Result<Dict<_, _>, ValueObj>>();
388    if let Ok(slf) = dict_type {
389        let union = slf
390            .keys()
391            .fold(Type::Never, |union, t| ctx.union(&union, t));
392        // let keys = poly(DICT_KEYS, vec![ty_tp(union)]);
393        Ok(ValueObj::builtin_type(union).into())
394    } else {
395        Ok(ValueObj::List(slf.into_keys().collect::<Vec<_>>().into()).into())
396    }
397}
398
399/// ```erg
400/// {"a": 1, "b": 2}.values() == [1, 2]
401/// {Str: Int, Int: Float}.values() == Int or Float
402/// ```
403pub(crate) fn dict_values(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
404    let slf = args
405        .remove_left_or_key("Self")
406        .ok_or_else(|| not_passed("Self"))?;
407    let Ok(slf) = ctx.convert_value_to_dict(&slf) else {
408        return Err(type_mismatch("Dict", slf, "Self"));
409    };
410    let dict_type = slf
411        .iter()
412        .map(|(k, v)| {
413            let k = ctx.convert_value_into_type(k.clone())?;
414            let v = ctx.convert_value_into_type(v.clone())?;
415            Ok((k, v))
416        })
417        .collect::<Result<Dict<_, _>, ValueObj>>();
418    if let Ok(slf) = dict_type {
419        let union = slf
420            .values()
421            .fold(Type::Never, |union, t| ctx.union(&union, t));
422        // let values = poly(DICT_VALUES, vec![ty_tp(union)]);
423        Ok(ValueObj::builtin_type(union).into())
424    } else {
425        Ok(ValueObj::List(slf.into_values().collect::<Vec<_>>().into()).into())
426    }
427}
428
429/// ```erg
430/// {"a": 1, "b": 2}.items() == [("a", 1), ("b", 2)]
431/// {Str: Int, Int: Float}.items() == (Str, Int) or (Int, Float)
432/// ```
433pub(crate) fn dict_items(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
434    let slf = args
435        .remove_left_or_key("Self")
436        .ok_or_else(|| not_passed("Self"))?;
437    let Ok(slf) = ctx.convert_value_to_dict(&slf) else {
438        return Err(type_mismatch("Dict", slf, "Self"));
439    };
440    let dict_type = slf
441        .iter()
442        .map(|(k, v)| {
443            let k = ctx.convert_value_into_type(k.clone())?;
444            let v = ctx.convert_value_into_type(v.clone())?;
445            Ok((k, v))
446        })
447        .collect::<Result<Dict<_, _>, ValueObj>>();
448    if let Ok(slf) = dict_type {
449        let union = slf.into_iter().fold(Type::Never, |union, (k, v)| {
450            ctx.union(&union, &tuple_t(vec![k, v]))
451        });
452        // let items = poly(DICT_ITEMS, vec![ty_tp(union)]);
453        Ok(ValueObj::builtin_type(union).into())
454    } else {
455        Ok(ValueObj::List(
456            slf.into_iter()
457                .map(|(k, v)| ValueObj::Tuple(vec![k, v].into()))
458                .collect::<Vec<_>>()
459                .into(),
460        )
461        .into())
462    }
463}
464
465/// If the key is duplicated, the value of the right dict is used.
466/// `{Str: Int, Int: Float}.concat({Int: Str, Float: Bool}) == {Str: Int, Int: Str, Float: Bool}`
467pub(crate) fn dict_concat(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
468    let slf = args
469        .remove_left_or_key("Self")
470        .ok_or_else(|| not_passed("Self"))?;
471    let Ok(slf) = ctx.convert_value_to_dict(&slf) else {
472        return Err(type_mismatch("Dict", slf, "Self"));
473    };
474    let other = args
475        .remove_left_or_key("Other")
476        .ok_or_else(|| not_passed("Other"))?;
477    let ValueObj::Dict(other) = other else {
478        return Err(type_mismatch("Dict", other, "Other"));
479    };
480    Ok(ValueObj::Dict(slf.concat(other)).into())
481}
482
483pub(crate) fn dict_diff(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
484    let slf = args
485        .remove_left_or_key("Self")
486        .ok_or_else(|| not_passed("Self"))?;
487    let Ok(slf) = ctx.convert_value_to_dict(&slf) else {
488        return Err(type_mismatch("Dict", slf, "Self"));
489    };
490    let other = args
491        .remove_left_or_key("Other")
492        .ok_or_else(|| not_passed("Other"))?;
493    let ValueObj::Dict(other) = other else {
494        return Err(type_mismatch("Dict", other, "Other"));
495    };
496    Ok(ValueObj::Dict(slf.diff(&other)).into())
497}
498
499pub(crate) fn list_constructor(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
500    let _cls = args
501        .remove_left_or_key("Cls")
502        .ok_or_else(|| not_passed("Cls"))?;
503    let elem = args
504        .remove_left_or_key("elem")
505        .ok_or_else(|| not_passed("elem"))?;
506    let Ok(elem_t) = ctx.convert_value_into_type(elem.clone()) else {
507        return Err(type_mismatch("Type", elem, "elem"));
508    };
509    let len = args
510        .remove_left_or_key("len")
511        .map(TyParam::value)
512        .unwrap_or(TyParam::erased(Type::Nat));
513    Ok(ValueObj::builtin_class(list_mut(elem_t, len)).into())
514}
515
516pub(crate) fn dict_constructor(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
517    let _cls = args
518        .remove_left_or_key("Cls")
519        .ok_or_else(|| not_passed("Cls"))?;
520    let key_value = args
521        .remove_left_or_key("key_value")
522        .ok_or_else(|| not_passed("key_value"))?;
523    let (key_t, value_t) = match key_value {
524        ValueObj::Tuple(ts) | ValueObj::List(ts) => {
525            let key = ts.first().ok_or_else(|| not_passed("key"))?;
526            let value = ts.get(1).ok_or_else(|| not_passed("value"))?;
527            let Ok(key_t) = ctx.convert_value_into_type(key.clone()) else {
528                return Err(type_mismatch("Type", key, "key"));
529            };
530            let Ok(value_t) = ctx.convert_value_into_type(value.clone()) else {
531                return Err(type_mismatch("Type", value, "value"));
532            };
533            (key_t, value_t)
534        }
535        _ => return Err(type_mismatch("Tuple", key_value, "key_value")),
536    };
537    Ok(ValueObj::builtin_class(dict_mut(dict! { key_t => value_t }.into())).into())
538}
539
540/// `[Int, Str].union() == Int or Str`
541pub(crate) fn list_union(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
542    let slf = args
543        .remove_left_or_key("Self")
544        .ok_or_else(|| not_passed("Self"))?;
545    let ValueObj::List(slf) = slf else {
546        return Err(type_mismatch("List", slf, "Self"));
547    };
548    let slf = slf
549        .iter()
550        .flat_map(|t| ctx.convert_value_into_type(t.clone()))
551        .collect::<Vec<_>>();
552    // args must already be evaluated
553    if slf.iter().any(|t| t.has_proj() || t.has_proj_call()) {
554        return Ok(TyParam::t(Type::Obj));
555    }
556    let union = slf
557        .iter()
558        .fold(Type::Never, |union, t| ctx.union(&union, t));
559    Ok(ValueObj::builtin_type(union).into())
560}
561
562fn _lis_shape(arr: ValueObj, ctx: &Context) -> Result<Vec<TyParam>, String> {
563    let mut shape = vec![];
564    let mut arr = arr;
565    loop {
566        match arr {
567            ValueObj::List(a) => {
568                shape.push(ValueObj::from(a.len()).into());
569                match a.first() {
570                    Some(arr_ @ (ValueObj::List(_) | ValueObj::Type(_))) => {
571                        arr = arr_.clone();
572                    }
573                    _ => {
574                        break;
575                    }
576                }
577            }
578            ValueObj::Type(ref t) if &t.typ().qual_name()[..] == "List" => {
579                let mut tps = t.typ().typarams();
580                let elem = match ctx.convert_tp_into_type(tps.remove(0)) {
581                    Ok(elem) => elem,
582                    Err(err) => {
583                        return Err(err.to_string());
584                    }
585                };
586                let len = tps.remove(0);
587                shape.push(len);
588                arr = ValueObj::builtin_type(elem);
589            }
590            _ => {
591                break;
592            }
593        }
594    }
595    Ok(shape)
596}
597
598/// ```erg
599/// List(Int, 2).shape() == [2,]
600/// List(List(Int, 2), N).shape() == [N, 2]
601/// [1, 2].shape() == [2,]
602/// [[1, 2], [3, 4], [5, 6]].shape() == [3, 2]
603/// ```
604pub(crate) fn list_shape(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
605    let val = args
606        .remove_left_or_key("Self")
607        .ok_or_else(|| not_passed("Self"))?;
608    let res = _lis_shape(val, ctx).unwrap();
609    let lis = TyParam::List(res);
610    Ok(lis)
611}
612
613fn _list_scalar_type(mut typ: Type, ctx: &Context) -> Result<Type, String> {
614    loop {
615        if matches!(&typ.qual_name()[..], "List" | "List!" | "UnsizedList") {
616            let tp = typ.typarams().remove(0);
617            match ctx.convert_tp_into_type(tp) {
618                Ok(typ_) => {
619                    typ = typ_;
620                }
621                Err(err) => {
622                    return Err(format!("Cannot convert {err} into type"));
623                }
624            }
625        } else {
626            return Ok(typ);
627        }
628    }
629}
630
631pub(crate) fn list_scalar_type(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
632    let slf = args
633        .remove_left_or_key("Self")
634        .ok_or_else(|| not_passed("Self"))?;
635    let Ok(slf) = ctx.convert_value_into_type(slf.clone()) else {
636        return Err(type_mismatch("Type", slf, "Self"));
637    };
638    let res = _list_scalar_type(slf, ctx).unwrap();
639    Ok(TyParam::t(res))
640}
641
642fn _scalar_type(mut value: ValueObj, _ctx: &Context) -> Result<Type, String> {
643    loop {
644        match value {
645            ValueObj::List(a) => match a.first() {
646                Some(elem) => {
647                    value = elem.clone();
648                }
649                None => {
650                    return Ok(Type::Never);
651                }
652            },
653            ValueObj::Set(s) => match s.iter().next() {
654                Some(elem) => {
655                    value = elem.clone();
656                }
657                None => {
658                    return Ok(Type::Never);
659                }
660            },
661            ValueObj::Tuple(t) => match t.first() {
662                Some(elem) => {
663                    value = elem.clone();
664                }
665                None => {
666                    return Ok(Type::Never);
667                }
668            },
669            ValueObj::UnsizedList(a) => {
670                value = *a.clone();
671            }
672            other => {
673                return Ok(other.class());
674            }
675        }
676    }
677}
678
679/// ```erg
680/// [1, 2].scalar_type() == Nat
681/// [[1, 2], [3, 4], [5, 6]].scalar_type() == Nat
682/// ```
683#[allow(unused)]
684pub(crate) fn scalar_type(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
685    let val = args
686        .remove_left_or_key("Self")
687        .ok_or_else(|| not_passed("Self"))?;
688    let res = _scalar_type(val, ctx).unwrap();
689    let lis = TyParam::t(res);
690    Ok(lis)
691}
692
693fn _list_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
694    match arr {
695        ValueObj::List(a) => {
696            let mut sum = 0f64;
697            for v in a.iter() {
698                match v {
699                    ValueObj::Nat(n) => {
700                        sum += *n as f64;
701                    }
702                    ValueObj::Int(n) => {
703                        sum += *n as f64;
704                    }
705                    ValueObj::Float(n) => {
706                        sum += **n;
707                    }
708                    ValueObj::Inf => {
709                        return Ok(ValueObj::Inf);
710                    }
711                    ValueObj::NegInf => {
712                        return Ok(ValueObj::NegInf);
713                    }
714                    _ => {
715                        return Err(format!("Cannot sum {v}"));
716                    }
717                }
718            }
719            if sum.round() == sum && sum >= 0.0 {
720                Ok(ValueObj::Nat(sum as u64))
721            } else if sum.round() == sum {
722                Ok(ValueObj::Int(sum as i32))
723            } else {
724                Ok(ValueObj::from(sum))
725            }
726        }
727        _ => Err(format!("Cannot sum {arr}")),
728    }
729}
730
731/// ```erg
732/// [1, 2].sum() == [3,]
733/// ```
734pub(crate) fn list_sum(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
735    let val = args
736        .remove_left_or_key("Self")
737        .ok_or_else(|| not_passed("Self"))?;
738    let res = _list_sum(val, ctx).unwrap();
739    let lis = TyParam::Value(res);
740    Ok(lis)
741}
742
743fn _list_prod(lis: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
744    match lis {
745        ValueObj::List(a) => {
746            let mut prod = 1f64;
747            for v in a.iter() {
748                match v {
749                    ValueObj::Nat(n) => {
750                        prod *= *n as f64;
751                    }
752                    ValueObj::Int(n) => {
753                        prod *= *n as f64;
754                    }
755                    ValueObj::Float(n) => {
756                        prod *= **n;
757                    }
758                    ValueObj::Inf => {
759                        return Ok(ValueObj::Inf);
760                    }
761                    ValueObj::NegInf => {
762                        return Ok(ValueObj::NegInf);
763                    }
764                    _ => {
765                        return Err(format!("Cannot prod {v}"));
766                    }
767                }
768            }
769            if prod.round() == prod && prod >= 0.0 {
770                Ok(ValueObj::Nat(prod as u64))
771            } else if prod.round() == prod {
772                Ok(ValueObj::Int(prod as i32))
773            } else {
774                Ok(ValueObj::from(prod))
775            }
776        }
777        _ => Err(format!("Cannot prod {lis}")),
778    }
779}
780
781/// ```erg
782/// [1, 2].prod() == [2,]
783/// ```
784pub(crate) fn list_prod(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
785    let val = args
786        .remove_left_or_key("Self")
787        .ok_or_else(|| not_passed("Self"))?;
788    let res = _list_prod(val, ctx).unwrap();
789    let lis = TyParam::Value(res);
790    Ok(lis)
791}
792
793fn _list_reversed(lis: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
794    match lis {
795        ValueObj::List(a) => {
796            let mut vec = a.to_vec();
797            vec.reverse();
798            Ok(ValueObj::List(vec.into()))
799        }
800        _ => Err(format!("Cannot reverse {lis}")),
801    }
802}
803
804pub(crate) fn list_reversed(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
805    let val = args
806        .remove_left_or_key("Self")
807        .ok_or_else(|| not_passed("Self"))?;
808    let res = _list_reversed(val, ctx).unwrap();
809    let lis = TyParam::Value(res);
810    Ok(lis)
811}
812
813fn _list_insert_at(
814    lis: ValueObj,
815    index: usize,
816    value: ValueObj,
817    _ctx: &Context,
818) -> Result<ValueObj, String> {
819    match lis {
820        ValueObj::List(a) => {
821            let mut a = a.to_vec();
822            if index > a.len() {
823                return Err(format!("Index out of range: {index}"));
824            }
825            a.insert(index, value);
826            Ok(ValueObj::List(a.into()))
827        }
828        _ => Err(format!("Cannot insert into {lis}")),
829    }
830}
831
832pub(crate) fn list_insert_at(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
833    let lis = args
834        .remove_left_or_key("Self")
835        .ok_or_else(|| not_passed("Self"))?;
836    let index = args
837        .remove_left_or_key("Index")
838        .ok_or_else(|| not_passed("Index"))?;
839    let value = args
840        .remove_left_or_key("Value")
841        .ok_or_else(|| not_passed("Value"))?;
842    let Ok(index) = usize::try_from(&index) else {
843        return Err(type_mismatch("Nat", index, "Index"));
844    };
845    let res = _list_insert_at(lis, index, value, ctx).unwrap();
846    let lis = TyParam::Value(res);
847    Ok(lis)
848}
849
850fn _list_remove_at(lis: ValueObj, index: usize, _ctx: &Context) -> Result<ValueObj, String> {
851    match lis {
852        ValueObj::List(a) => {
853            let mut a = a.to_vec();
854            if index >= a.len() {
855                return Err(format!("Index out of range: {index}"));
856            }
857            a.remove(index);
858            Ok(ValueObj::List(a.into()))
859        }
860        _ => Err(format!("Cannot remove from {lis}")),
861    }
862}
863
864pub(crate) fn list_remove_at(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
865    let val = args
866        .remove_left_or_key("Self")
867        .ok_or_else(|| not_passed("Self"))?;
868    let index = args
869        .remove_left_or_key("Index")
870        .ok_or_else(|| not_passed("Index"))?;
871    let Ok(index) = usize::try_from(&index) else {
872        return Err(type_mismatch("Nat", index, "Index"));
873    };
874    let res = _list_remove_at(val, index, ctx).unwrap();
875    let lis = TyParam::Value(res);
876    Ok(lis)
877}
878
879fn _list_remove_all(lis: ValueObj, value: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
880    match lis {
881        ValueObj::List(a) => {
882            let mut a = a.to_vec();
883            a.retain(|v| v != &value);
884            Ok(ValueObj::List(a.into()))
885        }
886        _ => Err(format!("Cannot remove from {lis}")),
887    }
888}
889
890pub(crate) fn list_remove_all(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
891    let val = args
892        .remove_left_or_key("Self")
893        .ok_or_else(|| not_passed("Self"))?;
894    let value = args
895        .remove_left_or_key("Value")
896        .ok_or_else(|| not_passed("Value"))?;
897    let res = _list_remove_all(val, value, ctx).unwrap();
898    let lis = TyParam::Value(res);
899    Ok(lis)
900}
901
902pub(crate) fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
903    let slf = args
904        .remove_left_or_key("Self")
905        .ok_or_else(|| not_passed("Self"))?;
906    let ValueObj::DataClass { name: _, fields } = slf else {
907        return Err(type_mismatch("Range", slf, "Self"));
908    };
909    let index = args
910        .remove_left_or_key("Index")
911        .ok_or_else(|| not_passed("Index"))?;
912    let Ok(index) = usize::try_from(&index) else {
913        return Err(type_mismatch("Nat", index, "Index"));
914    };
915    let start = fields
916        .get("start")
917        .ok_or_else(|| no_key(&fields, "start"))?;
918    let Ok(start) = usize::try_from(start) else {
919        return Err(type_mismatch("Nat", start, "start"));
920    };
921    let end = fields.get("end").ok_or_else(|| no_key(&fields, "end"))?;
922    let Ok(end) = usize::try_from(end) else {
923        return Err(type_mismatch("Nat", end, "end"));
924    };
925    // FIXME <= if inclusive
926    if start + index < end {
927        Ok(ValueObj::Nat((start + index) as u64).into())
928    } else {
929        Err(ErrorCore::new(
930            vec![SubMessage::only_loc(Location::Unknown)],
931            format!("Index out of range: {index}"),
932            line!() as usize,
933            ErrorKind::IndexError,
934            Location::Unknown,
935        )
936        .into())
937    }
938}
939
940pub(crate) fn __named_tuple_getitem__(
941    mut args: ValueArgs,
942    ctx: &Context,
943) -> EvalValueResult<TyParam> {
944    let slf = args
945        .remove_left_or_key("Self")
946        .ok_or_else(|| not_passed("Self"))?;
947    let fields = match ctx.convert_value_into_type(slf) {
948        Ok(Type::NamedTuple(fields)) => fields,
949        Ok(other) => {
950            return Err(type_mismatch("NamedTuple", other, "Self"));
951        }
952        Err(val) => {
953            return Err(type_mismatch("NamedTuple", val, "Self"));
954        }
955    };
956    let index = args
957        .remove_left_or_key("Index")
958        .ok_or_else(|| not_passed("Index"))?;
959    let Ok(index) = usize::try_from(&index) else {
960        return Err(type_mismatch("Nat", index, "Index"));
961    };
962    if let Some((_, t)) = fields.get(index) {
963        Ok(TyParam::t(t.clone()))
964    } else {
965        Err(no_key(Type::NamedTuple(fields), index))
966    }
967}
968
969/// `NamedTuple({ .x = Int; .y = Str }).union() == Int or Str`
970/// `GenericNamedTuple.union() == Obj`
971pub(crate) fn named_tuple_union(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
972    let slf = args
973        .remove_left_or_key("Self")
974        .ok_or_else(|| not_passed("Self"))?;
975    let fields = match ctx.convert_value_into_type(slf) {
976        Ok(Type::NamedTuple(fields)) => fields,
977        Ok(Type::Mono(n)) if &n == "GenericNamedTuple" => {
978            return Ok(ValueObj::builtin_type(Type::Obj).into());
979        }
980        Ok(other) => {
981            return Err(type_mismatch("NamedTuple", other, "Self"));
982        }
983        Err(val) => {
984            return Err(type_mismatch("NamedTuple", val, "Self"));
985        }
986    };
987    let union = fields
988        .iter()
989        .fold(Type::Never, |union, (_, t)| ctx.union(&union, t));
990    Ok(ValueObj::builtin_type(union).into())
991}
992
993/// `{ .x = Int; .y = Str }.as_dict() == { "x": Int, "y": Str }`
994/// `Record.as_dict() == { Obj: Obj }`
995pub(crate) fn as_dict(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
996    let slf = args
997        .remove_left_or_key("Self")
998        .ok_or_else(|| not_passed("Self"))?;
999    let fields = match ctx.convert_value_into_type(slf) {
1000        Ok(Type::Record(fields)) => fields,
1001        Ok(Type::Mono(n)) if &n == "Record" => {
1002            let dict = dict! { Type::Obj => Type::Obj };
1003            return Ok(ValueObj::builtin_type(Type::from(dict)).into());
1004        }
1005        Ok(other) => {
1006            return Err(type_mismatch("Record", other, "Self"));
1007        }
1008        Err(val) => {
1009            return Err(type_mismatch("Record", val, "Self"));
1010        }
1011    };
1012    let dict = fields
1013        .into_iter()
1014        .map(|(k, v)| (v_enum(set! {  k.symbol.into() }), v))
1015        .collect::<Dict<_, _>>();
1016    Ok(ValueObj::builtin_type(Type::from(dict)).into())
1017}
1018
1019/// `{ {"x"}: Int, {"y"}: Str }.as_record() == { .x = Int, .y = Str }`
1020pub(crate) fn as_record(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
1021    let slf = args
1022        .remove_left_or_key("Self")
1023        .ok_or_else(|| not_passed("Self"))?;
1024    let fields = match ctx.convert_value_into_type(slf) {
1025        Ok(Type::Poly { name, params }) if &name == "Dict" => {
1026            Dict::try_from(params[0].clone()).unwrap()
1027        }
1028        Ok(other) => {
1029            return Err(type_mismatch("Dict", other, "Self"));
1030        }
1031        Err(val) => {
1032            return Err(type_mismatch("Dict", val, "Self"));
1033        }
1034    };
1035    let mut dict = Dict::new();
1036    for (k, v) in fields {
1037        match (ctx.convert_tp_into_type(k), ctx.convert_tp_into_type(v)) {
1038            (Ok(k_t), Ok(v_t)) => {
1039                if let Some(values) = k_t.refinement_values() {
1040                    for value in values {
1041                        if let TyParam::Value(ValueObj::Str(field)) = value {
1042                            dict.insert(Field::public(field.clone()), v_t.clone());
1043                        } else {
1044                            return Err(type_mismatch("Str", value, "Key"));
1045                        }
1046                    }
1047                } else {
1048                    return Err(type_mismatch("Str refinement type", k_t, "Key"));
1049                }
1050            }
1051            (Ok(_), Err(err)) | (Err(err), Ok(_)) => {
1052                return Err(type_mismatch("Type", err, "Self"));
1053            }
1054            (Err(k), Err(_v)) => {
1055                return Err(type_mismatch("Type", k, "Self"));
1056            }
1057        };
1058    }
1059    Ok(ValueObj::builtin_type(Type::Record(dict)).into())
1060}
1061
1062pub(crate) fn int_abs(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1063    let slf = args
1064        .remove_left_or_key("self")
1065        .ok_or_else(|| not_passed("self"))?;
1066    let Some(slf) = slf.as_int() else {
1067        return Err(type_mismatch("Int", slf, "self"));
1068    };
1069    Ok(ValueObj::Int(slf.abs()).into())
1070}
1071
1072pub(crate) fn str_endswith(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1073    let slf = args
1074        .remove_left_or_key("self")
1075        .ok_or_else(|| not_passed("self"))?;
1076    let suffix = args
1077        .remove_left_or_key("suffix")
1078        .ok_or_else(|| not_passed("suffix"))?;
1079    let Some(slf) = slf.as_str() else {
1080        return Err(type_mismatch("Str", slf, "self"));
1081    };
1082    let Some(suffix) = suffix.as_str() else {
1083        return Err(type_mismatch("Str", suffix, "suffix"));
1084    };
1085    Ok(ValueObj::Bool(slf.ends_with(&suffix[..])).into())
1086}
1087
1088pub(crate) fn str_find(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1089    let slf = args
1090        .remove_left_or_key("self")
1091        .ok_or_else(|| not_passed("self"))?;
1092    let sub = args
1093        .remove_left_or_key("sub")
1094        .ok_or_else(|| not_passed("sub"))?;
1095    let Some(slf) = slf.as_str() else {
1096        return Err(type_mismatch("Str", slf, "self"));
1097    };
1098    let Some(sub) = sub.as_str() else {
1099        return Err(type_mismatch("Str", sub, "sub"));
1100    };
1101    Ok(ValueObj::Int(slf.find(&sub[..]).map_or(-1, |i| i as i32)).into())
1102}
1103
1104pub(crate) fn str_isalpha(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1105    let slf = args
1106        .remove_left_or_key("self")
1107        .ok_or_else(|| not_passed("self"))?;
1108    let Some(slf) = slf.as_str() else {
1109        return Err(type_mismatch("Str", slf, "self"));
1110    };
1111    Ok(ValueObj::Bool(slf.chars().all(|c| c.is_alphabetic())).into())
1112}
1113
1114pub(crate) fn str_isascii(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1115    let slf = args
1116        .remove_left_or_key("self")
1117        .ok_or_else(|| not_passed("self"))?;
1118    let Some(slf) = slf.as_str() else {
1119        return Err(type_mismatch("Str", slf, "self"));
1120    };
1121    Ok(ValueObj::Bool(slf.is_ascii()).into())
1122}
1123
1124pub(crate) fn str_isdecimal(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1125    let slf = args
1126        .remove_left_or_key("self")
1127        .ok_or_else(|| not_passed("self"))?;
1128    let Some(slf) = slf.as_str() else {
1129        return Err(type_mismatch("Str", slf, "self"));
1130    };
1131    Ok(ValueObj::Bool(slf.chars().all(|c| c.is_ascii_digit())).into())
1132}
1133
1134pub(crate) fn str_join(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1135    let slf = args
1136        .remove_left_or_key("self")
1137        .ok_or_else(|| not_passed("self"))?;
1138    let iterable = args
1139        .remove_left_or_key("iterable")
1140        .ok_or_else(|| not_passed("iterable"))?;
1141    let Some(slf) = slf.as_str() else {
1142        return Err(type_mismatch("Str", slf, "self"));
1143    };
1144    let arr = match iterable {
1145        ValueObj::List(a) => a.to_vec(),
1146        ValueObj::Tuple(t) => t.to_vec(),
1147        ValueObj::Set(s) => s.into_iter().collect(),
1148        ValueObj::Dict(d) => d.into_keys().collect(),
1149        _ => {
1150            return Err(type_mismatch("Iterable(Str)", iterable, "iterable"));
1151        }
1152    };
1153    let mut joined = String::new();
1154    for v in arr.iter() {
1155        let Some(v) = v.as_str() else {
1156            return Err(type_mismatch("Str", v, "arr.next()"));
1157        };
1158        joined.push_str(&v[..]);
1159        joined.push_str(&slf[..]);
1160    }
1161    joined.pop();
1162    Ok(ValueObj::Str(joined.into()).into())
1163}
1164
1165pub(crate) fn str_replace(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1166    let slf = args
1167        .remove_left_or_key("self")
1168        .ok_or_else(|| not_passed("self"))?;
1169    let old = args
1170        .remove_left_or_key("old")
1171        .ok_or_else(|| not_passed("old"))?;
1172    let new = args
1173        .remove_left_or_key("new")
1174        .ok_or_else(|| not_passed("new"))?;
1175    let Some(slf) = slf.as_str() else {
1176        return Err(type_mismatch("Str", slf, "self"));
1177    };
1178    let Some(old) = old.as_str() else {
1179        return Err(type_mismatch("Str", old, "old"));
1180    };
1181    let Some(new) = new.as_str() else {
1182        return Err(type_mismatch("Str", new, "new"));
1183    };
1184    Ok(ValueObj::Str(slf.replace(&old[..], new).into()).into())
1185}
1186
1187pub(crate) fn str_startswith(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1188    let slf = args
1189        .remove_left_or_key("self")
1190        .ok_or_else(|| not_passed("self"))?;
1191    let prefix = args
1192        .remove_left_or_key("prefix")
1193        .ok_or_else(|| not_passed("prefix"))?;
1194    let Some(slf) = slf.as_str() else {
1195        return Err(type_mismatch("Str", slf, "self"));
1196    };
1197    let Some(prefix) = prefix.as_str() else {
1198        return Err(type_mismatch("Str", prefix, "prefix"));
1199    };
1200    Ok(ValueObj::Bool(slf.starts_with(&prefix[..])).into())
1201}
1202
1203pub(crate) fn abs_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1204    let num = args
1205        .remove_left_or_key("num")
1206        .ok_or_else(|| not_passed("num"))?;
1207    match num {
1208        ValueObj::Nat(n) => Ok(ValueObj::Nat(n).into()),
1209        ValueObj::Int(n) => Ok(ValueObj::Nat(n.unsigned_abs() as u64).into()),
1210        ValueObj::Bool(b) => Ok(ValueObj::Nat(b as u64).into()),
1211        ValueObj::Float(n) => Ok(ValueObj::from(n.abs()).into()),
1212        ValueObj::Inf => Ok(ValueObj::Inf.into()),
1213        ValueObj::NegInf => Ok(ValueObj::Inf.into()),
1214        _ => Err(type_mismatch("Num", num, "num")),
1215    }
1216}
1217
1218pub(crate) fn all_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1219    let iterable = args
1220        .remove_left_or_key("iterable")
1221        .ok_or_else(|| not_passed("iterable"))?;
1222    let arr = match iterable {
1223        ValueObj::List(a) => a.to_vec(),
1224        ValueObj::Tuple(t) => t.to_vec(),
1225        ValueObj::Set(s) => s.into_iter().collect(),
1226        _ => {
1227            return Err(type_mismatch("Iterable(Bool)", iterable, "iterable"));
1228        }
1229    };
1230    let mut all = true;
1231    for v in arr.iter() {
1232        match v {
1233            ValueObj::Bool(b) => {
1234                all &= *b;
1235            }
1236            _ => {
1237                return Err(type_mismatch("Bool", v, "iterable.next()"));
1238            }
1239        }
1240    }
1241    Ok(ValueObj::Bool(all).into())
1242}
1243
1244pub(crate) fn any_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1245    let iterable = args
1246        .remove_left_or_key("iterable")
1247        .ok_or_else(|| not_passed("iterable"))?;
1248    let arr = match iterable {
1249        ValueObj::List(a) => a.to_vec(),
1250        ValueObj::Tuple(t) => t.to_vec(),
1251        ValueObj::Set(s) => s.into_iter().collect(),
1252        _ => {
1253            return Err(type_mismatch("Iterable(Bool)", iterable, "iterable"));
1254        }
1255    };
1256    let mut any = false;
1257    for v in arr.iter() {
1258        match v {
1259            ValueObj::Bool(b) => {
1260                any |= *b;
1261            }
1262            _ => {
1263                return Err(type_mismatch("Bool", v, "iterable.next()"));
1264            }
1265        }
1266    }
1267    Ok(ValueObj::Bool(any).into())
1268}
1269
1270pub(crate) fn filter_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
1271    let func = args
1272        .remove_left_or_key("func")
1273        .ok_or_else(|| not_passed("func"))?;
1274    let iterable = args
1275        .remove_left_or_key("iterable")
1276        .ok_or_else(|| not_passed("iterable"))?;
1277    let arr = match iterable {
1278        ValueObj::List(a) => a.to_vec(),
1279        ValueObj::Tuple(t) => t.to_vec(),
1280        ValueObj::Set(s) => s.into_iter().collect(),
1281        _ => {
1282            return Err(type_mismatch("Iterable(T)", iterable, "iterable"));
1283        }
1284    };
1285    let subr = match func {
1286        ValueObj::Subr(f) => f,
1287        _ => {
1288            return Err(type_mismatch("Subr", func, "func"));
1289        }
1290    };
1291    let mut filtered = vec![];
1292    for v in arr.into_iter() {
1293        let args = ValueArgs::pos_only(vec![v.clone()]);
1294        match ctx.call(subr.clone(), args, Location::Unknown) {
1295            Ok(res) => match ctx.convert_tp_into_value(res) {
1296                Ok(res) => {
1297                    if res.is_true() {
1298                        filtered.push(v);
1299                    }
1300                }
1301                Err(tp) => {
1302                    return Err(type_mismatch("Bool", tp, "func"));
1303                }
1304            },
1305            Err((_res, mut err)) => {
1306                return Err(EvalValueError::from(*err.remove(0).core));
1307            }
1308        }
1309    }
1310    Ok(TyParam::Value(ValueObj::List(filtered.into())))
1311}
1312
1313pub(crate) fn len_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1314    let container = args
1315        .remove_left_or_key("iterable")
1316        .ok_or_else(|| not_passed("iterable"))?;
1317    let len = match container {
1318        ValueObj::List(a) => a.len(),
1319        ValueObj::Tuple(t) => t.len(),
1320        ValueObj::Set(s) => s.len(),
1321        ValueObj::Dict(d) => d.len(),
1322        ValueObj::Record(r) => r.len(),
1323        ValueObj::Str(s) => s.len(),
1324        _ => {
1325            return Err(type_mismatch("Container", container, "container"));
1326        }
1327    };
1328    Ok(ValueObj::Nat(len as u64).into())
1329}
1330
1331pub(crate) fn map_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
1332    let func = args
1333        .remove_left_or_key("func")
1334        .ok_or_else(|| not_passed("func"))?;
1335    let iterable = args
1336        .remove_left_or_key("iterable")
1337        .ok_or_else(|| not_passed("iterable"))?;
1338    let arr = match iterable {
1339        ValueObj::List(a) => a.to_vec(),
1340        ValueObj::Tuple(t) => t.to_vec(),
1341        ValueObj::Set(s) => s.into_iter().collect(),
1342        _ => {
1343            return Err(type_mismatch("Iterable(Bool)", iterable, "iterable"));
1344        }
1345    };
1346    let subr = match func {
1347        ValueObj::Subr(f) => f,
1348        _ => {
1349            return Err(type_mismatch("Subr", func, "func"));
1350        }
1351    };
1352    let mut mapped = vec![];
1353    for v in arr.into_iter() {
1354        let args = ValueArgs::pos_only(vec![v]);
1355        match ctx.call(subr.clone(), args, Location::Unknown) {
1356            Ok(res) => {
1357                mapped.push(res);
1358            }
1359            Err((_res, mut err)) => {
1360                return Err(EvalValueError::from(*err.remove(0).core));
1361            }
1362        }
1363    }
1364    Ok(TyParam::List(mapped))
1365}
1366
1367pub(crate) fn max_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1368    let iterable = args
1369        .remove_left_or_key("iterable")
1370        .ok_or_else(|| not_passed("iterable"))?;
1371    let arr = match iterable {
1372        ValueObj::List(a) => a.to_vec(),
1373        ValueObj::Tuple(t) => t.to_vec(),
1374        ValueObj::Set(s) => s.into_iter().collect(),
1375        _ => {
1376            return Err(type_mismatch("Iterable(Ord)", iterable, "iterable"));
1377        }
1378    };
1379    let mut max = ValueObj::NegInf;
1380    if arr.is_empty() {
1381        return Err(ErrorCore::new(
1382            vec![SubMessage::only_loc(Location::Unknown)],
1383            "max() arg is an empty sequence",
1384            line!() as usize,
1385            ErrorKind::ValueError,
1386            Location::Unknown,
1387        )
1388        .into());
1389    }
1390    for v in arr.into_iter() {
1391        if v.is_num() {
1392            if max.clone().try_lt(v.clone()).is_some_and(|b| b.is_true()) {
1393                max = v;
1394            }
1395        } else {
1396            return Err(type_mismatch("Ord", v, "iterable.next()"));
1397        }
1398    }
1399    Ok(max.into())
1400}
1401
1402pub(crate) fn min_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1403    let iterable = args
1404        .remove_left_or_key("iterable")
1405        .ok_or_else(|| not_passed("iterable"))?;
1406    let arr = match iterable {
1407        ValueObj::List(a) => a.to_vec(),
1408        ValueObj::Tuple(t) => t.to_vec(),
1409        ValueObj::Set(s) => s.into_iter().collect(),
1410        _ => {
1411            return Err(type_mismatch("Iterable(Ord)", iterable, "iterable"));
1412        }
1413    };
1414    let mut min = ValueObj::Inf;
1415    if arr.is_empty() {
1416        return Err(ErrorCore::new(
1417            vec![SubMessage::only_loc(Location::Unknown)],
1418            "min() arg is an empty sequence",
1419            line!() as usize,
1420            ErrorKind::ValueError,
1421            Location::Unknown,
1422        )
1423        .into());
1424    }
1425    for v in arr.into_iter() {
1426        if v.is_num() {
1427            if min.clone().try_gt(v.clone()).is_some_and(|b| b.is_true()) {
1428                min = v;
1429            }
1430        } else {
1431            return Err(type_mismatch("Ord", v, "iterable.next()"));
1432        }
1433    }
1434    Ok(min.into())
1435}
1436
1437pub(crate) fn not_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1438    let val = args
1439        .remove_left_or_key("val")
1440        .ok_or_else(|| not_passed("val"))?;
1441    match val {
1442        ValueObj::Bool(b) => Ok(ValueObj::Bool(!b).into()),
1443        _ => Err(type_mismatch("Bool", val, "val")),
1444    }
1445}
1446
1447pub(crate) fn reversed_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1448    let reversible = args
1449        .remove_left_or_key("reversible")
1450        .ok_or_else(|| not_passed("reversible"))?;
1451    let arr = match reversible {
1452        ValueObj::List(a) => a.to_vec(),
1453        ValueObj::Tuple(t) => t.to_vec(),
1454        _ => {
1455            return Err(type_mismatch("Reversible", reversible, "reversible"));
1456        }
1457    };
1458    let mut reversed = vec![];
1459    for v in arr.into_iter().rev() {
1460        reversed.push(v);
1461    }
1462    Ok(TyParam::Value(ValueObj::List(reversed.into())))
1463}
1464
1465pub(crate) fn str_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1466    let val = args
1467        .remove_left_or_key("val")
1468        .ok_or_else(|| not_passed("val"))?;
1469    if let Some(_encoding) = args.remove_left_or_key("encoding") {
1470        return Err(todo("encoding"));
1471    }
1472    Ok(ValueObj::Str(val.to_string().into()).into())
1473}
1474
1475pub(crate) fn sum_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1476    let iterable = args
1477        .remove_left_or_key("iterable")
1478        .ok_or_else(|| not_passed("iterable"))?;
1479    let arr = match iterable {
1480        ValueObj::List(a) => a.to_vec(),
1481        ValueObj::Tuple(t) => t.to_vec(),
1482        ValueObj::Set(s) => s.into_iter().collect(),
1483        ValueObj::Dict(d) => d.into_keys().collect(),
1484        ValueObj::Record(r) => r.into_values().collect(),
1485        _ => {
1486            return Err(type_mismatch("Iterable(Add)", iterable, "iterable"));
1487        }
1488    };
1489    let mut sum = ValueObj::Nat(0);
1490    for v in arr.into_iter() {
1491        if v.is_num() {
1492            sum = sum.try_add(v).unwrap();
1493        } else {
1494            return Err(type_mismatch("Add", v, "iterable.next()"));
1495        }
1496    }
1497    Ok(sum.into())
1498}
1499
1500pub(crate) fn resolve_path_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
1501    let path = args
1502        .remove_left_or_key("Path")
1503        .ok_or_else(|| not_passed("Path"))?;
1504    let path = match &path {
1505        ValueObj::Str(s) => Path::new(&s[..]),
1506        other => {
1507            return Err(type_mismatch("Str", other, "Path"));
1508        }
1509    };
1510    let Some(path) = ctx.cfg.input.resolve_path(path, &ctx.cfg) else {
1511        return Err(ErrorCore::new(
1512            vec![SubMessage::only_loc(Location::Unknown)],
1513            format!("Path {} is not found", path.display()),
1514            line!() as usize,
1515            ErrorKind::IoError,
1516            Location::Unknown,
1517        )
1518        .into());
1519    };
1520    Ok(ValueObj::Str(path.to_string_lossy().into()).into())
1521}
1522
1523pub(crate) fn resolve_decl_path_func(
1524    mut args: ValueArgs,
1525    ctx: &Context,
1526) -> EvalValueResult<TyParam> {
1527    let path = args
1528        .remove_left_or_key("Path")
1529        .ok_or_else(|| not_passed("Path"))?;
1530    let path = match &path {
1531        ValueObj::Str(s) => Path::new(&s[..]),
1532        other => {
1533            return Err(type_mismatch("Str", other, "Path"));
1534        }
1535    };
1536    let Some(path) = ctx.cfg.input.resolve_decl_path(path, &ctx.cfg) else {
1537        return Err(ErrorCore::new(
1538            vec![SubMessage::only_loc(Location::Unknown)],
1539            format!("Path {} is not found", path.display()),
1540            line!() as usize,
1541            ErrorKind::IoError,
1542            Location::Unknown,
1543        )
1544        .into());
1545    };
1546    Ok(ValueObj::Str(path.to_string_lossy().into()).into())
1547}
1548
1549pub(crate) fn succ_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1550    let val = args
1551        .remove_left_or_key("Value")
1552        .ok_or_else(|| not_passed("Value"))?;
1553    let val = match &val {
1554        ValueObj::Bool(b) => ValueObj::Nat(*b as u64 + 1),
1555        ValueObj::Nat(n) => ValueObj::Nat(n + 1),
1556        ValueObj::Int(n) => ValueObj::Int(n + 1),
1557        ValueObj::Float(n) => ValueObj::from(**n + f64::EPSILON),
1558        v @ (ValueObj::Inf | ValueObj::NegInf) => v.clone(),
1559        _ => {
1560            return Err(type_mismatch("Number", val, "Value"));
1561        }
1562    };
1563    Ok(val.into())
1564}
1565
1566pub(crate) fn pred_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1567    let val = args
1568        .remove_left_or_key("Value")
1569        .ok_or_else(|| not_passed("Value"))?;
1570    let val = match &val {
1571        ValueObj::Bool(b) => ValueObj::Nat((*b as u64).saturating_sub(1)),
1572        ValueObj::Nat(n) => ValueObj::Nat(n.saturating_sub(1)),
1573        ValueObj::Int(n) => ValueObj::Int(n - 1),
1574        ValueObj::Float(n) => ValueObj::from(**n - f64::EPSILON),
1575        v @ (ValueObj::Inf | ValueObj::NegInf) => v.clone(),
1576        _ => {
1577            return Err(type_mismatch("Number", val, "Value"));
1578        }
1579    };
1580    Ok(val.into())
1581}
1582
1583// TODO: varargs
1584pub(crate) fn zip_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1585    let iterable1 = args
1586        .remove_left_or_key("iterable1")
1587        .ok_or_else(|| not_passed("iterable1"))?;
1588    let iterable2 = args
1589        .remove_left_or_key("iterable2")
1590        .ok_or_else(|| not_passed("iterable2"))?;
1591    let iterable1 = match iterable1 {
1592        ValueObj::List(a) => a.to_vec(),
1593        ValueObj::Tuple(t) => t.to_vec(),
1594        ValueObj::Set(s) => s.into_iter().collect(),
1595        _ => {
1596            return Err(type_mismatch("Iterable(T)", iterable1, "iterable1"));
1597        }
1598    };
1599    let iterable2 = match iterable2 {
1600        ValueObj::List(a) => a.to_vec(),
1601        ValueObj::Tuple(t) => t.to_vec(),
1602        ValueObj::Set(s) => s.into_iter().collect(),
1603        _ => {
1604            return Err(type_mismatch("Iterable(T)", iterable2, "iterable2"));
1605        }
1606    };
1607    let mut zipped = vec![];
1608    for (v1, v2) in iterable1.into_iter().zip(iterable2.into_iter()) {
1609        zipped.push(ValueObj::Tuple(vec![v1, v2].into()));
1610    }
1611    Ok(TyParam::Value(ValueObj::List(zipped.into())))
1612}
1613
1614/// ```erg
1615/// derefine({X: T | ...}) == T
1616/// derefine({1}) == Nat
1617/// derefine(List!({1, 2}, 2)) == List!(Nat, 2)
1618/// ```
1619pub(crate) fn derefine_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
1620    let val = args
1621        .remove_left_or_key("T")
1622        .ok_or_else(|| not_passed("T"))?;
1623    let t = match ctx.convert_value_into_type(val) {
1624        Ok(t) => t.derefine(),
1625        Err(val) => {
1626            return Err(type_mismatch("Type", val, "T"));
1627        }
1628    };
1629    Ok(TyParam::t(t))
1630}
1631
1632/// ```erg
1633/// fill_ord({1, 4}) == {1, 2, 3, 4}
1634/// fill_ord({"a", "c"}) == {"a", "b", "c"}
1635/// ```
1636pub(crate) fn fill_ord_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
1637    let val = args
1638        .remove_left_or_key("T")
1639        .ok_or_else(|| not_passed("T"))?;
1640    let t = match ctx.convert_value_into_type(val) {
1641        Ok(t) => {
1642            let coerced = ctx.coerce(t.clone(), &()).unwrap_or(t);
1643            let inf = ctx.inf(&coerced);
1644            let sup = ctx.sup(&coerced);
1645            let der = coerced.derefine();
1646            match (inf, sup) {
1647                (Some(inf), Some(sup)) => closed_range(der, inf, sup),
1648                _ => coerced,
1649            }
1650        }
1651        Err(val) => {
1652            return Err(type_mismatch("Type", val, "T"));
1653        }
1654    };
1655    Ok(TyParam::t(t))
1656}
1657
1658/// TODO: accept non-const expr
1659/// ```erg
1660/// classof(1) == Nat
1661/// ```
1662pub(crate) fn classof_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
1663    let val = args
1664        .remove_left_or_key("obj")
1665        .ok_or_else(|| not_passed("obj"))?;
1666    Ok(TyParam::t(val.class()))
1667}
1668
1669#[cfg(test)]
1670mod tests {
1671    use erg_common::config::ErgConfig;
1672
1673    use crate::module::SharedCompilerResource;
1674    use crate::ty::constructors::*;
1675
1676    use super::*;
1677
1678    #[test]
1679    fn test_dict_items() {
1680        let cfg = ErgConfig::default();
1681        let shared = SharedCompilerResource::default();
1682        Context::init_builtins(cfg, shared.clone());
1683        let ctx = &shared.raw_ref_builtins_ctx().unwrap().context;
1684
1685        let a = singleton(Type::Str, TyParam::value("a"));
1686        let b = singleton(Type::Str, TyParam::value("b"));
1687        let c = singleton(Type::Str, TyParam::value("c"));
1688        // FIXME: order dependency
1689        let k_union = ctx.union(&ctx.union(&c, &a), &b);
1690        let g_dic = singleton(Type::Type, TyParam::t(mono("GenericDict")));
1691        let g_lis = singleton(Type::Type, TyParam::t(mono("GenericList")));
1692        let sub = func0(singleton(Type::NoneType, TyParam::value(ValueObj::None)));
1693        let v_union = ctx.union(&ctx.union(&g_lis, &sub), &g_dic);
1694        let dic = dict! {
1695            a.clone() => sub.clone(),
1696            b.clone() => g_dic.clone(),
1697            c.clone() => g_lis.clone(),
1698        };
1699        match ctx.eval_proj_call_t(dic.clone().into(), "items".into(), vec![], 1, &()) {
1700            Ok(t) => {
1701                let items = tuple_t(vec![k_union, v_union]);
1702                assert_eq!(t, items, "{t} != {items}");
1703            }
1704            Err(e) => {
1705                panic!("ERR: {e}");
1706            }
1707        }
1708    }
1709}