From 0fb996f28946c9f5dd26f5b7bf3dc203e3b759ac Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 3 Mar 2024 16:22:14 +0900 Subject: [PATCH] feat: add `Copy` trait --- .../context/initialize/classes.rs | 94 ++++++++++++++++--- crates/erg_compiler/context/initialize/mod.rs | 16 ++-- .../erg_compiler/context/initialize/traits.rs | 5 + crates/erg_compiler/lib/core.d/Set!.d.er | 15 +++ crates/erg_compiler/lib/core/_erg_bool.py | 3 + crates/erg_compiler/lib/core/_erg_float.py | 3 + crates/erg_compiler/lib/core/_erg_int.py | 3 + crates/erg_compiler/lib/core/_erg_nat.py | 3 + crates/erg_compiler/lib/core/_erg_str.py | 3 + 9 files changed, 122 insertions(+), 23 deletions(-) create mode 100644 crates/erg_compiler/lib/core.d/Set!.d.er diff --git a/crates/erg_compiler/context/initialize/classes.rs b/crates/erg_compiler/context/initialize/classes.rs index 0bc72f599..8f0e5bef0 100644 --- a/crates/erg_compiler/context/initialize/classes.rs +++ b/crates/erg_compiler/context/initialize/classes.rs @@ -2152,8 +2152,10 @@ impl Context { ) .quantify(); dict_.register_py_builtin(FUNC_GET, get_t, Some(FUNC_GET), 9); - let copy_t = fn0_met(dict_t.clone(), dict_t.clone()).quantify(); - dict_.register_py_builtin(COPY, copy_t, Some(COPY), 7); + let copy_t = fn0_met(ref_(dict_t.clone()), dict_t.clone()).quantify(); + let mut dict_copy = Self::builtin_methods(Some(mono(COPY)), 1); + dict_copy.register_py_builtin(FUNC_COPY, copy_t, Some(FUNC_COPY), 7); + dict_.register_trait(dict_t.clone(), dict_copy); let D2 = mono_q_tp(TY_D2, instanceof(mono(GENERIC_DICT))); let other_dict_t = poly(DICT, vec![D2.clone()]); let dict_concat_t = fn1_met( @@ -2555,18 +2557,20 @@ impl Context { .register_marker_trait(self, poly(OUTPUT, vec![ty_tp(T.clone())])) .unwrap(); let t = fn0_met(fset_t.clone(), fset_t.clone()).quantify(); - frozenset.register_py_builtin(COPY, t, Some(COPY), 3); - let bin_t = fn1_met(fset_t.clone(), fset_t.clone(), fset_t.clone()).quantify(); - frozenset.register_py_builtin(DIFFERENCE, bin_t.clone(), Some(DIFFERENCE), 3); - frozenset.register_py_builtin(INTERSECTION, bin_t.clone(), Some(INTERSECTION), 3); + let mut frozenset_copy = Self::builtin_methods(Some(mono(COPY)), 1); + frozenset_copy.register_py_builtin(FUNC_COPY, t, Some(FUNC_COPY), 3); + frozenset.register_trait(fset_t.clone(), frozenset_copy); + let bin_t = fn1_met(ref_(fset_t.clone()), fset_t.clone(), fset_t.clone()).quantify(); + frozenset.register_py_builtin(FUNC_DIFFERENCE, bin_t.clone(), Some(FUNC_DIFFERENCE), 3); + frozenset.register_py_builtin(FUNC_INTERSECTION, bin_t.clone(), Some(FUNC_INTERSECTION), 3); let bool_t = fn1_met(fset_t.clone(), fset_t.clone(), Bool).quantify(); - frozenset.register_py_builtin(ISDISJOINT, bool_t.clone(), Some(ISDISJOINT), 3); - frozenset.register_py_builtin(ISSUBSET, bool_t.clone(), Some(ISSUBSET), 3); - frozenset.register_py_builtin(ISSUPERSET, bool_t, Some(ISSUPERSET), 3); + frozenset.register_py_builtin(FUNC_ISDISJOINT, bool_t.clone(), Some(FUNC_ISDISJOINT), 3); + frozenset.register_py_builtin(FUNC_ISSUBSET, bool_t.clone(), Some(FUNC_ISSUBSET), 3); + frozenset.register_py_builtin(FUNC_ISSUPERSET, bool_t, Some(FUNC_ISSUPERSET), 3); frozenset.register_py_builtin( - SYMMETRIC_DIFFERENCE, + FUNC_SYMMETRIC_DIFFERENCE, bin_t.clone(), - Some(SYMMETRIC_DIFFERENCE), + Some(FUNC_SYMMETRIC_DIFFERENCE), 3, ); frozenset.register_py_builtin(FUNC_UNION, bin_t, Some(FUNC_UNION), 3); @@ -2651,6 +2655,14 @@ impl Context { Some(FUNC_DEC), ); float_mut.register_trait(mono(MUT_FLOAT), float_mut_mutable); + let mut float_mut_copy = Self::builtin_methods(Some(mono(COPY)), 1); + float_mut_copy.register_builtin_erg_impl( + FUNC_COPY, + fn0_met(ref_(mono(MUT_FLOAT)), mono(MUT_FLOAT)), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + float_mut.register_trait(mono(MUT_FLOAT), float_mut_copy); /* Ratio! */ let mut ratio_mut = Self::builtin_mono_class(MUT_RATIO, 2); ratio_mut.register_superclass(Ratio, &ratio); @@ -2677,6 +2689,14 @@ impl Context { Some(FUNC_UPDATE), ); ratio_mut.register_trait(mono(MUT_RATIO), ratio_mut_mutable); + let mut ratio_mut_copy = Self::builtin_methods(Some(mono(COPY)), 1); + ratio_mut_copy.register_builtin_erg_impl( + FUNC_COPY, + fn0_met(ref_(mono(MUT_RATIO)), mono(MUT_RATIO)), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + ratio_mut.register_trait(mono(MUT_RATIO), ratio_mut_copy); /* Int! */ let mut int_mut = Self::builtin_mono_class(MUT_INT, 2); int_mut.register_superclass(Int, &int); @@ -2719,6 +2739,14 @@ impl Context { Some(FUNC_UPDATE), ); int_mut.register_trait(mono(MUT_INT), int_mut_mutable); + let mut int_mut_copy = Self::builtin_methods(Some(mono(COPY)), 1); + int_mut_copy.register_builtin_erg_impl( + FUNC_COPY, + fn0_met(ref_(mono(MUT_INT)), mono(MUT_INT)), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + int_mut.register_trait(mono(MUT_INT), int_mut_copy); let mut nat_mut = Self::builtin_mono_class(MUT_NAT, 2); nat_mut.register_superclass(Nat, &nat); nat_mut.register_superclass(mono(MUT_INT), &int_mut); @@ -2746,6 +2774,14 @@ impl Context { Some(FUNC_UPDATE), ); nat_mut.register_trait(mono(MUT_NAT), nat_mut_mutable); + let mut nat_mut_copy = Self::builtin_methods(Some(mono(COPY)), 1); + nat_mut_copy.register_builtin_erg_impl( + FUNC_COPY, + fn0_met(ref_(mono(MUT_NAT)), mono(MUT_NAT)), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + nat_mut.register_trait(mono(MUT_NAT), nat_mut_copy); /* Bool! */ let mut bool_mut = Self::builtin_mono_class(MUT_BOOL, 2); bool_mut.register_superclass(Bool, &bool_); @@ -2773,6 +2809,14 @@ impl Context { Some(FUNC_UPDATE), ); bool_mut.register_trait(mono(MUT_BOOL), bool_mut_mutable); + let mut bool_mut_copy = Self::builtin_methods(Some(mono(COPY)), 1); + bool_mut_copy.register_builtin_erg_impl( + FUNC_COPY, + fn0_met(ref_(mono(MUT_BOOL)), mono(MUT_BOOL)), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + bool_mut.register_trait(mono(MUT_BOOL), bool_mut_copy); let t = pr0_met(mono(MUT_BOOL), NoneType); bool_mut.register_builtin_py_impl( PROC_INVERT, @@ -2807,6 +2851,14 @@ impl Context { Some(FUNC_UPDATE), ); str_mut.register_trait(mono(MUT_STR), str_mut_mutable); + let mut str_mut_copy = Self::builtin_methods(Some(mono(COPY)), 1); + str_mut_copy.register_builtin_erg_impl( + FUNC_COPY, + fn0_met(ref_(mono(MUT_STR)), mono(MUT_STR)), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + str_mut.register_trait(mono(MUT_STR), str_mut_copy); let t = pr_met( ref_mut(mono(MUT_STR), None), vec![kw(KW_S, Str)], @@ -2920,8 +2972,10 @@ impl Context { ) .quantify(); array_mut_.register_py_builtin(PROC_PUSH, t, Some(FUNC_APPEND), 15); - let t_copy = pr0_met(ref_(array_mut_t.clone()), array_mut_t.clone()).quantify(); - array_mut_.register_py_builtin(FUNC_COPY, t_copy, Some(FUNC_COPY), 116); + let t_copy = fn0_met(ref_(array_mut_t.clone()), array_mut_t.clone()).quantify(); + let mut array_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2); + array_mut_copy.register_py_builtin(FUNC_COPY, t_copy, Some(FUNC_COPY), 116); + array_mut_.register_trait(array_mut_t.clone(), array_mut_copy); let t_extend = pr_met( ref_mut( array_mut_t.clone(), @@ -3061,14 +3115,16 @@ impl Context { Visibility::BUILTIN_PUBLIC, Some(FUNC_APPEND), ); - let t_copy = pr0_met(bytearray_mut_t.clone(), bytearray_mut_t.clone()); - bytearray_mut.register_builtin_py_impl( + let t_copy = fn0_met(ref_(bytearray_mut_t.clone()), bytearray_mut_t.clone()); + let mut bytearray_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2); + bytearray_mut_copy.register_builtin_py_impl( FUNC_COPY, t_copy, Immutable, Visibility::BUILTIN_PUBLIC, Some(FUNC_COPY), ); + bytearray_mut.register_trait(bytearray_mut_t.clone(), bytearray_mut_copy); let t_extend = pr_met( ref_mut(bytearray_mut_t.clone(), None), vec![kw( @@ -3205,6 +3261,14 @@ impl Context { let mut set_mut_ = Self::builtin_poly_class(MUT_SET, vec![PS::t_nd(TY_T), PS::named_nd(TY_N, Nat)], 2); set_mut_.register_superclass(set_t.clone(), &set_); + let mut set_mut_copy = Self::builtin_methods(Some(mono(COPY)), 1); + set_mut_copy.register_py_builtin( + FUNC_COPY, + fn0_met(ref_(set_mut_t.clone()), set_mut_t.clone()).quantify(), + Some(FUNC_COPY), + 9, + ); + set_mut_.register_trait(set_mut_t.clone(), set_mut_copy); // `add!` will erase N let t = pr_met( ref_mut( diff --git a/crates/erg_compiler/context/initialize/mod.rs b/crates/erg_compiler/context/initialize/mod.rs index 12438b848..edbb21f15 100644 --- a/crates/erg_compiler/context/initialize/mod.rs +++ b/crates/erg_compiler/context/initialize/mod.rs @@ -52,6 +52,8 @@ const UNPACK: &str = "Unpack"; const INHERITABLE_TYPE: &str = "InheritableType"; const NAMED: &str = "Named"; const SIZED: &str = "Sized"; +const COPY: &str = "Copy"; +const FUNC_COPY: &str = "copy"; const MUTABLE: &str = "Mutable"; const SELF: &str = "Self"; const IMMUTIZABLE: &str = "Immutizable"; @@ -289,13 +291,12 @@ const MAP: &str = "Map"; const REVERSED: &str = "Reversed"; const ZIP: &str = "Zip"; const FROZENSET: &str = "FrozenSet"; -const COPY: &str = "copy"; -const DIFFERENCE: &str = "difference"; -const INTERSECTION: &str = "intersection"; -const ISDISJOINT: &str = "isdisjoint"; -const ISSUBSET: &str = "issubset"; -const ISSUPERSET: &str = "issuperset"; -const SYMMETRIC_DIFFERENCE: &str = "symmetric_difference"; +const FUNC_DIFFERENCE: &str = "difference"; +const FUNC_INTERSECTION: &str = "intersection"; +const FUNC_ISDISJOINT: &str = "isdisjoint"; +const FUNC_ISSUBSET: &str = "issubset"; +const FUNC_ISSUPERSET: &str = "issuperset"; +const FUNC_SYMMETRIC_DIFFERENCE: &str = "symmetric_difference"; const MEMORYVIEW: &str = "MemoryView"; const FUNC_UNION: &str = "union"; const FUNC_SHAPE: &str = "shape"; @@ -323,7 +324,6 @@ const FUNC_REMOVE_AT: &str = "remove_at"; const FUNC_REMOVE_ALL: &str = "remove_all"; const FUNC_POP: &str = "pop"; const PROC_POP: &str = "pop!"; -const FUNC_COPY: &str = "copy"; const FUNC_CLEAR: &str = "clear"; const PROC_CLEAR: &str = "clear!"; const FUNC_SORT: &str = "sort"; diff --git a/crates/erg_compiler/context/initialize/traits.rs b/crates/erg_compiler/context/initialize/traits.rs index 447fcc2bb..bdcf1ad0b 100644 --- a/crates/erg_compiler/context/initialize/traits.rs +++ b/crates/erg_compiler/context/initialize/traits.rs @@ -32,6 +32,10 @@ impl Context { let mut sized = Self::builtin_mono_trait(SIZED, 2); let t = fn0_met(mono(SIZED), Nat).quantify(); sized.register_builtin_erg_decl(FUNDAMENTAL_LEN, t, Visibility::BUILTIN_PUBLIC); + let mut copy = Self::builtin_mono_trait(COPY, 2); + let Slf = mono_q(SELF, subtypeof(mono(COPY))); + let t = fn0_met(Slf.clone(), Slf).quantify(); + copy.register_builtin_erg_decl(FUNC_COPY, t, Visibility::BUILTIN_PUBLIC); let mut mutable = Self::builtin_mono_trait(MUTABLE, 2); let Slf = mono_q(SELF, subtypeof(mono(IMMUTIZABLE))); let immut_t = proj(Slf.clone(), IMMUT_TYPE); @@ -451,6 +455,7 @@ impl Context { ); self.register_builtin_type(mono(NAMED), named, vis.clone(), Const, None); self.register_builtin_type(mono(SIZED), sized, vis.clone(), Const, None); + self.register_builtin_type(mono(COPY), copy, vis.clone(), Const, None); self.register_builtin_type(mono(MUTABLE), mutable, vis.clone(), Const, None); self.register_builtin_type(mono(IMMUTIZABLE), immutizable, vis.clone(), Const, None); self.register_builtin_type(mono(MUTIZABLE), mutizable, vis.clone(), Const, None); diff --git a/crates/erg_compiler/lib/core.d/Set!.d.er b/crates/erg_compiler/lib/core.d/Set!.d.er new file mode 100644 index 000000000..e0ed00bb9 --- /dev/null +++ b/crates/erg_compiler/lib/core.d/Set!.d.er @@ -0,0 +1,15 @@ +.Set!: ClassType +.Set!. + '''erg + s = !{} + s2 = s.copy() + s.add!(1) + assert s2 == {} + ''' + copy: (self: Ref Set!) -> Set! + '''erg + s = !{} + s.add!(1) + assert s == {1} + ''' + add!: |T|(self: RefMut(Set!(T)), x: T) => NoneType diff --git a/crates/erg_compiler/lib/core/_erg_bool.py b/crates/erg_compiler/lib/core/_erg_bool.py index 86bce18fc..f11e1f07b 100644 --- a/crates/erg_compiler/lib/core/_erg_bool.py +++ b/crates/erg_compiler/lib/core/_erg_bool.py @@ -59,3 +59,6 @@ def update(self, f): def invert(self): self.value = self.value.invert() + + def copy(self): + return BoolMut(self.value) diff --git a/crates/erg_compiler/lib/core/_erg_float.py b/crates/erg_compiler/lib/core/_erg_float.py index 4cef20738..260bf5cd0 100644 --- a/crates/erg_compiler/lib/core/_erg_float.py +++ b/crates/erg_compiler/lib/core/_erg_float.py @@ -158,3 +158,6 @@ def inc(self, value=1.0): def dec(self, value=1.0): self.value = Float(self.value - value) + + def copy(self): + return FloatMut(self.value) diff --git a/crates/erg_compiler/lib/core/_erg_int.py b/crates/erg_compiler/lib/core/_erg_int.py index 75e3ac98c..0c9157eb4 100644 --- a/crates/erg_compiler/lib/core/_erg_int.py +++ b/crates/erg_compiler/lib/core/_erg_int.py @@ -163,3 +163,6 @@ def succ(self): def pred(self): return self.value.pred() + + def copy(self): + return IntMut(self.value) diff --git a/crates/erg_compiler/lib/core/_erg_nat.py b/crates/erg_compiler/lib/core/_erg_nat.py index a78a49291..03ecea596 100644 --- a/crates/erg_compiler/lib/core/_erg_nat.py +++ b/crates/erg_compiler/lib/core/_erg_nat.py @@ -146,3 +146,6 @@ def try_new(i): # -> Result[Nat] def times(self, f): for _ in range(self.value): f() + + def copy(self): + return NatMut(self.value) diff --git a/crates/erg_compiler/lib/core/_erg_str.py b/crates/erg_compiler/lib/core/_erg_str.py index 691815edf..e4205e359 100644 --- a/crates/erg_compiler/lib/core/_erg_str.py +++ b/crates/erg_compiler/lib/core/_erg_str.py @@ -108,3 +108,6 @@ def remove(self, idx: int): def insert(self, idx: int, s: str): self.value = self.value[:idx] + s + self.value[idx:] + + def copy(self): + return StrMut(self.value)