feat: add Dict.items/copy

This commit is contained in:
Shunsuke Shibayama 2023-04-20 10:44:57 +09:00
parent e0d8306b3e
commit 325d237f09
4 changed files with 54 additions and 14 deletions

View file

@ -1444,22 +1444,28 @@ impl Context {
None,
)));
dict_.register_builtin_const(VALUES, Visibility::BUILTIN_PUBLIC, values);
let get_t = fn1_met(
let dict_items_t = fn0_met(dict_t.clone(), proj_call(D.clone(), ITEMS, vec![])).quantify();
let items = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
ITEMS,
dict_items,
dict_items_t,
None,
)));
dict_.register_builtin_const(ITEMS, Visibility::BUILTIN_PUBLIC, items);
let Def = type_q("Default");
let get_t = fn_met(
dict_t.clone(),
T.clone(),
vec![kw("key", T.clone())],
None,
vec![kw_default("default", Def.clone(), NoneType)],
or(
proj_call(D, FUNDAMENTAL_GETITEM, vec![ty_tp(T.clone())]),
NoneType,
Def,
),
)
.quantify();
dict_.register_builtin_py_impl(
FUNC_GET,
get_t,
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_GET),
);
dict_.register_py_builtin(FUNC_GET, get_t, Some(FUNC_GET), 9);
dict_.register_py_builtin(COPY, fn0_met(dict_t.clone(), dict_t.clone()), Some(COPY), 7);
/* Bytes */
let mut bytes = Self::builtin_mono_class(BYTES, 2);
bytes.register_superclass(Obj, &obj);
@ -1541,6 +1547,10 @@ impl Context {
dict_values.register_superclass(Obj, &obj);
dict_values.register_marker_trait(poly(ITERABLE, vec![ty_tp(T.clone())]));
dict_values.register_marker_trait(poly(OUTPUT, vec![ty_tp(T.clone())]));
let mut dict_items = Self::builtin_poly_class(DICT_ITEMS, vec![PS::t_nd(TY_T)], 1);
dict_items.register_superclass(Obj, &obj);
dict_items.register_marker_trait(poly(ITERABLE, vec![ty_tp(T.clone())]));
dict_items.register_marker_trait(poly(OUTPUT, vec![ty_tp(T.clone())]));
/* Enumerate */
let mut enumerate = Self::builtin_poly_class(ENUMERATE, vec![PS::t_nd(TY_T)], 2);
enumerate.register_superclass(Obj, &obj);
@ -2260,6 +2270,13 @@ impl Context {
Const,
Some(FUNC_DICT_VALUES),
);
self.register_builtin_type(
poly(DICT_ITEMS, vec![ty_tp(T.clone())]),
dict_items,
Visibility::BUILTIN_PRIVATE,
Const,
Some(FUNC_DICT_ITEMS),
);
self.register_builtin_type(
poly(ENUMERATE, vec![ty_tp(T.clone())]),
enumerate,

View file

@ -5,13 +5,13 @@ use erg_common::enum_unwrap;
use crate::context::Context;
use crate::feature_error;
use crate::ty::constructors::{and, mono, poly, ty_tp};
use crate::ty::constructors::{and, mono, poly, tuple_t, ty_tp};
use crate::ty::value::{EvalValueError, EvalValueResult, GenTypeObj, TypeObj, ValueObj};
use crate::ty::{Type, ValueArgs};
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
use erg_common::style::{Color, StyledStr, StyledString, THEME};
use super::{DICT_KEYS, DICT_VALUES};
use super::{DICT_ITEMS, DICT_KEYS, DICT_VALUES};
const ERR: Color = THEME.colors.error;
const WARN: Color = THEME.colors.warning;
@ -333,6 +333,21 @@ pub(crate) fn dict_values(mut args: ValueArgs, _ctx: &Context) -> EvalValueResul
Ok(ValueObj::builtin_type(values))
}
/// `{Str: Int, Int: Float}.items() == DictItems((Str, Int) or (Int, Float))`
pub(crate) fn dict_items(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<ValueObj> {
let slf = args.remove_left_or_key("Self").unwrap();
let slf = enum_unwrap!(slf, ValueObj::Dict);
let slf = slf
.into_iter()
.map(|(k, v)| (Type::try_from(k).unwrap(), Type::try_from(v).unwrap()))
.collect::<Dict<_, _>>();
let union = slf.iter().fold(Type::Never, |union, (k, v)| {
_ctx.union(&union, &tuple_t(vec![k.clone(), v.clone()]))
});
let items = poly(DICT_ITEMS, vec![ty_tp(union)]);
Ok(ValueObj::builtin_type(items))
}
pub(crate) fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<ValueObj> {
let (_name, fields) = enum_unwrap!(
args.remove_left_or_key("Self").unwrap(),

View file

@ -321,10 +321,13 @@ const PATCH: &str = "Patch";
const STRUCTURAL: &str = "Structural";
const KEYS: &str = "keys";
const VALUES: &str = "values";
const ITEMS: &str = "items";
const DICT_KEYS: &str = "DictKeys";
const DICT_VALUES: &str = "DictValues";
const DICT_ITEMS: &str = "DictItems";
const FUNC_DICT_KEYS: &str = "dict_keys";
const FUNC_DICT_VALUES: &str = "dict_values";
const FUNC_DICT_ITEMS: &str = "dict_items";
const OP_IN: &str = "__in__";
const OP_NOT_IN: &str = "__notin__";

View file

@ -1,9 +1,14 @@
immut_dict = {"Alice": 1, "Bob": 2, "Charlie": 3}
assert immut_dict["Alice"] == 1
print! immut_dict["Bob"]
print! immut_dict.get("Charlie")
_ = immut_dict["Bob"]
_ = immut_dict.get("Charlie")
_ = immut_dict.get("Charlie", 4)
for! immut_dict.keys(), k =>
print! k
for! immut_dict.values(), v =>
print! v
for! immut_dict.items(), ((k, v),) =>
print! k, v
_ = immut_dict.copy()