From 74bc5843937b4fea07151a42ebd364c55dc19401 Mon Sep 17 00:00:00 2001 From: "A. R. Shajii" Date: Mon, 19 Sep 2022 09:55:56 -0400 Subject: [PATCH 1/2] Improve collection-to-str conversions --- stdlib/internal/types/collections/dict.codon | 17 ++++++------ stdlib/internal/types/collections/list.codon | 13 ++++++---- stdlib/internal/types/collections/set.codon | 13 +++++----- stdlib/internal/types/strbuf.codon | 27 ++++++++++++++++++++ test/core/containers.codon | 9 +++++++ 5 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 stdlib/internal/types/strbuf.codon diff --git a/stdlib/internal/types/collections/dict.codon b/stdlib/internal/types/collections/dict.codon index 4ce1141a..587d5f17 100644 --- a/stdlib/internal/types/collections/dict.codon +++ b/stdlib/internal/types/collections/dict.codon @@ -140,23 +140,24 @@ class Dict: return {k.__deepcopy__(): v.__deepcopy__() for k, v in self.items()} def __repr__(self) -> str: + from internal.types.strbuf import strbuf n = self.__len__() if n == 0: return "{}" else: - lst = [] - lst.append("{") + buf = strbuf() + buf.append("{") first = True for k, v in self.items(): if not first: - lst.append(", ") + buf.append(", ") else: first = False - lst.append(k.__repr__()) - lst.append(": ") - lst.append(v.__repr__()) - lst.append("}") - return str.cat(lst) + buf.append(k.__repr__()) + buf.append(": ") + buf.append(v.__repr__()) + buf.append("}") + return buf.__str__() # Helper methods diff --git a/stdlib/internal/types/collections/list.codon b/stdlib/internal/types/collections/list.codon index 7f7ad8a0..438e4ece 100644 --- a/stdlib/internal/types/collections/list.codon +++ b/stdlib/internal/types/collections/list.codon @@ -267,16 +267,19 @@ class List: return self def __repr__(self) -> str: + from internal.types.strbuf import strbuf n = self.__len__() if n == 0: return "[]" else: - y = ["[", self[0].__repr__()] + buf = strbuf() + buf.append("[") + buf.append(self[0].__repr__()) for i in range(1, n): - y.append(", ") - y.append(self[i].__repr__()) - y.append("]") - return str.cat(y) + buf.append(", ") + buf.append(self[i].__repr__()) + buf.append("]") + return buf.__str__() # Helper functions diff --git a/stdlib/internal/types/collections/set.codon b/stdlib/internal/types/collections/set.codon index 5922026a..08f07277 100644 --- a/stdlib/internal/types/collections/set.codon +++ b/stdlib/internal/types/collections/set.codon @@ -130,21 +130,22 @@ class Set: return {s.__deepcopy__() for s in self} def __repr__(self) -> str: + from internal.types.strbuf import strbuf n = self.__len__() if n == 0: return "{}" else: - lst = [] - lst.append("{") + buf = strbuf() + buf.append("{") first = True for k in self: if not first: - lst.append(", ") + buf.append(", ") else: first = False - lst.append(k.__repr__()) - lst.append("}") - return str.cat(lst) + buf.append(k.__repr__()) + buf.append("}") + return buf.__str__() # Helper methods diff --git a/stdlib/internal/types/strbuf.codon b/stdlib/internal/types/strbuf.codon new file mode 100644 index 00000000..42c0649e --- /dev/null +++ b/stdlib/internal/types/strbuf.codon @@ -0,0 +1,27 @@ +# (c) 2022 Exaloop Inc. All rights reserved. + +class strbuf: + data: Ptr[byte] + n: int + m: int + + def __init__(self, capacity: int = 16): + self.data = Ptr[byte](capacity) + self.n = 0 + self.m = capacity + + def append(self, s: str): + from internal.gc import realloc + adding = s.__len__() + needed = self.n + adding + if needed > self.m: + m = self.m + while m < needed: + m *= 2 + self.data = realloc(self.data, m, self.m) + self.m = m + str.memcpy(self.data + self.n, s.ptr, adding) + self.n = needed + + def __str__(self): + return str(self.data, self.n) diff --git a/test/core/containers.codon b/test/core/containers.codon index db662cca..7659bf30 100644 --- a/test/core/containers.codon +++ b/test/core/containers.codon @@ -304,6 +304,9 @@ def test_extendedslicing(): a = list(range(10)) a[::2] = (0, 1, 2, 3, 4) assert a == [0, 1, 1, 3, 2, 5, 3, 7, 4, 9] + + assert repr(['x', 'y', 'z']) == "['x', 'y', 'z']" + assert repr(List[int]()) == '[]' test_extendedslicing() @test @@ -378,6 +381,9 @@ def test_set(): assert False except ValueError: pass + + assert repr({(1,2)}) == '{(1, 2)}' + assert repr(Set[int]()) == '{}' test_set() @test @@ -417,6 +423,9 @@ def test_dict(): assert d3 | d4 == {1: 5, 42: 42, 2: 9} d3 |= d4 assert d3 == {1: 5, 42: 42, 2: 9} + + assert repr({1: ['x']}) == "{1: ['x']}" + assert repr(Dict[int,int]()) == '{}' test_dict() @test From ea48d68dc5a18bd31c252c1ed63dba2c27f52fd3 Mon Sep 17 00:00:00 2001 From: "A. R. Shajii" Date: Mon, 19 Sep 2022 09:58:57 -0400 Subject: [PATCH 2/2] Fix empty set repr --- stdlib/internal/types/collections/set.codon | 2 +- test/core/containers.codon | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/internal/types/collections/set.codon b/stdlib/internal/types/collections/set.codon index 08f07277..44e497c7 100644 --- a/stdlib/internal/types/collections/set.codon +++ b/stdlib/internal/types/collections/set.codon @@ -133,7 +133,7 @@ class Set: from internal.types.strbuf import strbuf n = self.__len__() if n == 0: - return "{}" + return "set()" else: buf = strbuf() buf.append("{") diff --git a/test/core/containers.codon b/test/core/containers.codon index 7659bf30..95fe639c 100644 --- a/test/core/containers.codon +++ b/test/core/containers.codon @@ -383,7 +383,7 @@ def test_set(): pass assert repr({(1,2)}) == '{(1, 2)}' - assert repr(Set[int]()) == '{}' + assert repr(Set[int]()) == 'set()' test_set() @test