feat: add {Str, List}.from

This commit is contained in:
Shunsuke Shibayama 2024-04-30 18:44:31 +09:00
parent 65d05cb37b
commit 96f4c1cf98
10 changed files with 56 additions and 5 deletions

View file

@ -1247,6 +1247,13 @@ impl Context {
Visibility::BUILTIN_PUBLIC,
Some(FUNC_ISPRINTABLE),
);
str_.register_builtin_py_impl(
FUNC_FROM,
no_var_fn_met(Str, vec![kw(KW_NTH, Nat)], vec![], Str),
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_FROM_),
);
let str_getitem_t = fn1_kw_met(Str, kw(KW_IDX, Nat | poly(RANGE, vec![ty_tp(Int)])), Str);
str_.register_builtin_erg_impl(
FUNDAMENTAL_GETITEM,
@ -1796,6 +1803,20 @@ impl Context {
Some(list_remove_all_t),
list_remove_all,
);
let list_from = no_var_fn_met(
unknown_len_list_t(T.clone()),
vec![kw(KW_NTH, Nat)],
vec![],
unknown_len_list_t(T.clone()),
)
.quantify();
list_.register_builtin_py_impl(
FUNC_FROM,
list_from,
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_FROM_),
);
list_
.register_trait(self, poly(INDEXABLE, vec![ty_tp(input), ty_tp(T.clone())]))
.unwrap();

View file

@ -332,6 +332,8 @@ const FUNC_REMOVE: &str = "remove";
const PROC_REMOVE: &str = "remove!";
const FUNC_REMOVE_AT: &str = "remove_at";
const FUNC_REMOVE_ALL: &str = "remove_all";
const FUNC_FROM: &str = "from";
const FUNC_FROM_: &str = "from_";
const FUNC_POP: &str = "pop";
const PROC_POP: &str = "pop!";
const FUNC_CLEAR: &str = "clear";
@ -681,6 +683,7 @@ const KW_FILLCHAR: &str = "fillchar";
const KW_WIDTH: &str = "width";
const KW_ARGS: &str = "args";
const KW_KWARGS: &str = "kwargs";
const KW_NTH: &str = "nth";
const KW_IDX: &str = "idx";
const KW_LHS: &str = "lhs";
const KW_RHS: &str = "rhs";

View file

@ -1349,7 +1349,9 @@ impl Context {
}
match self.get_attr_type_by_name(obj, attr_name, namespace) {
Triple::Ok(method) => {
let def_t = self.instantiate_def_type(&method.definition_type).unwrap();
let def_t = self
.instantiate_def_type(&method.definition_type)
.map_err(|mut errs| errs.remove(0))?;
let list = UndoableLinkedList::new();
self.undoable_sub_unify(obj.ref_t(), &def_t, obj, &list, None)
// HACK: change this func's return type to TyCheckResult<Type>
@ -1473,7 +1475,9 @@ impl Context {
}
match self.get_attr_type_by_name(obj, attr_name, namespace) {
Triple::Ok(method) => {
let def_t = self.instantiate_def_type(&method.definition_type).unwrap();
let def_t = self
.instantiate_def_type(&method.definition_type)
.map_err(|mut errs| errs.remove(0))?;
let list = UndoableLinkedList::new();
self.undoable_sub_unify(obj.ref_t(), &def_t, obj, &list, None)
// HACK: change this func's return type to TyCheckResult<Type>

View file

@ -2572,7 +2572,7 @@ impl Context {
};
}
let ty = new_set.iter().fold(Type::Never, |t, tp| {
self.union(&t, &self.get_tp_t(tp).unwrap().derefine())
self.union(&t, &self.get_tp_t(tp).unwrap_or(Obj).derefine())
});
if errs.is_empty() {
Ok(tp_enum(ty, new_set))

View file

@ -56,3 +56,10 @@
assert [1, 2, 3].reversed() == [3, 2, 1]
'''
reversed: |T: Type, N: Nat|(self: List(T, N)) -> List(T, N)
'''
Returns the array with the first `nth` elements removed.
'''
'''erg
assert [1, 2, 3, 4, 5].from(2) == [3, 4, 5]
'''
from: |T: Type|(self: List(T, _), nth: Nat) -> List(T, _)

View file

@ -181,3 +181,10 @@
translate: (self: .Str, table: {Nat: Nat or NoneType}) -> .Str
upper: (self: .Str) -> .Str
zfill: (self: .Str, width: Nat) -> .Str
'''
Returns the substring of the string starting at the given index.
'''
'''erg
assert "abcde".from(2) == "cde"
'''
from: (self: Str, nth: Nat) -> Str

View file

@ -137,6 +137,8 @@ class List(list):
new.extend(deepcopy(self))
return List(new)
def from_(self, nth: int):
return self[nth:]
class UnsizedList:
elem: object

View file

@ -48,6 +48,8 @@ class Str(str):
else:
return str.__getitem__(self, index_or_slice)
def from_(self, nth: int):
return self[nth:]
class StrMut(MutType): # Inherits Str
value: Str

View file

@ -65,8 +65,8 @@
.Islice(T) <: Output T
.Islice(T) <: Iterable T
.Islice(T).
__call__: (iterable: Iterable(T), start := Int, stop := Int, step := Int) -> .Islice(T)
.islice: |T|(iterable: Iterable(T), start := Int, stop := Int, step := Int) -> .Islice(T)
__call__: (iterable: Iterable(T), start := Int or NoneType, stop := Int or NoneType, step := Int or NoneType) -> .Islice(T)
.islice: |T|(iterable: Iterable(T), start := Int or NoneType, stop := Int or NoneType, step := Int or NoneType) -> .Islice(T)
.Pairwise = 'pairwise': (T: Type) -> ClassType
.Pairwise(T) <: Output T

View file

@ -38,3 +38,8 @@ l2 = [![1]].repeat 3
l2[0].push! 2
ans: List(List(Nat)) = [[1, 2], [1], [1]]
assert l2 == ans
l3 = [1, 2, 3, 4]
assert l3.from(2) == [3, 4]
assert l3.from(2).from(1) == [4]
assert l3.from(5) == []