# HG changeset patch # User Paul Boddie # Date 1479918778 -3600 # Node ID 3a4ba5788f0f5b3507b095e1ea07dbf973439bff # Parent fbef93224a106ff703871f96c3e549181dd893b3 Fixed list and tuple initialisation via their initialisers. Introduced generic string representation support for sequences. Removed superfluous tuple native functions. Added element-setting and size-setting native functions for fragments. Added __setitem__ support for sequences. Added initialisation and serialisation tests for lists and tuples. diff -r fbef93224a10 -r 3a4ba5788f0f lib/__builtins__/list.py --- a/lib/__builtins__/list.py Wed Nov 23 17:23:52 2016 +0100 +++ b/lib/__builtins__/list.py Wed Nov 23 17:32:58 2016 +0100 @@ -34,13 +34,12 @@ # Reserve an attribute for a fragment reference along with some space # for elements. - self.__data__ = native._list_init(len(args)) + self.__data__ = native._list_init(args is not None and len(args) or 0) if args is not None: self.extend(args) def __contains__(self, value): pass - def __setitem__(self, index, value): pass def __delitem__(self, index): pass def __setslice__(self, start, end, slice): pass def __delslice__(self, start, end): pass @@ -84,26 +83,9 @@ def __str__(self): - "Return a string representation of the list." - - b = buffer() - i = 0 - l = self.__len__() - first = True - - # NOTE: Should really show quoted forms of the items. + "Return a string representation." - b.append("[") - while i < l: - if first: - first = False - else: - b.append(", ") - b.append(repr(self.__get_single_item__(i))) - i += 1 - b.append("]") - - return str(b) + return self._str("[", "]") __repr__ = __str__ @@ -130,4 +112,13 @@ return native._list_element(self, index) + def __set_single_item__(self, index, value): + + "Set at the normalised (positive) 'index' the given 'value'." + + if index >= len(self): + raise IndexError(index) + + return native._list_setelement(self, index, value) + # vim: tabstop=4 expandtab shiftwidth=4 diff -r fbef93224a10 -r 3a4ba5788f0f lib/__builtins__/sequence.py --- a/lib/__builtins__/sequence.py Wed Nov 23 17:23:52 2016 +0100 +++ b/lib/__builtins__/sequence.py Wed Nov 23 17:32:58 2016 +0100 @@ -25,6 +25,27 @@ "A common base class for sequence types." + def _str(self, opening, closing): + + "Serialise this object with the given 'opening' and 'closing' strings." + + b = buffer() + i = 0 + l = self.__len__() + first = True + + b.append(opening) + while i < l: + if first: + first = False + else: + b.append(", ") + b.append(repr(self.__get_single_item__(i))) + i += 1 + b.append(closing) + + return str(b) + def __getitem__(self, index): "Return the item or slice specified by 'index'." @@ -46,6 +67,27 @@ else: raise TypeError + def __setitem__(self, index, value): + + "Set at 'index' the given 'value'." + + # Normalise any integer indexes, converting negative indexes to positive + # ones. + + if _isinstance(index, int): + index = _normalise_index(index, self.__len__()) + return self.__set_single_item__(index, value) + + # Handle slices separately. + + elif _isinstance(index, slice): + return self.__setslice__(index.start, index.end, value) + + # No other kinds of objects are supported as indexes. + + else: + raise TypeError + def __getslice__(self, start, end=None): "Return a slice starting from 'start', with the optional 'end'." diff -r fbef93224a10 -r 3a4ba5788f0f lib/__builtins__/str.py --- a/lib/__builtins__/str.py Wed Nov 23 17:23:52 2016 +0100 +++ b/lib/__builtins__/str.py Wed Nov 23 17:32:58 2016 +0100 @@ -79,7 +79,7 @@ return self def __repr__(self): - "Return a string literal representation." + "Return a program representation." # NOTE: To be implemented with proper quoting. b = buffer(['"', self, '"']) return str(b) diff -r fbef93224a10 -r 3a4ba5788f0f lib/__builtins__/tuple.py --- a/lib/__builtins__/tuple.py Wed Nov 23 17:23:52 2016 +0100 +++ b/lib/__builtins__/tuple.py Wed Nov 23 17:32:58 2016 +0100 @@ -31,23 +31,40 @@ "Initialise the tuple." - self.__data__ = native._tuple_init(args, len(args)) # allocate and copy elements + # Reserve an attribute for a fragment reference along with some space + # for elements. + + size = args is not None and len(args) or 0 + self.__data__ = native._list_init(size) + native._list_setsize(self, size) + + # Populate the tuple. + + if args is not None: + i = 0 + for arg in args: + native._list_setelement(self, i, arg) + i += 1 def __getslice__(self, start, end=None): "Return a slice starting from 'start', with the optional 'end'." - return native._list_to_tuple(get_using(sequence.__getslice__, self)(start, end)) + return tuple(get_using(sequence.__getslice__, self)(start, end)) def __len__(self): "Return the length of the tuple." - return native._tuple_len(self) + return native._list_len(self) def __add__(self, other): pass - def __str__(self): pass + def __str__(self): + + "Return a string representation." + + return self._str("(", ")") __repr__ = __str__ @@ -66,6 +83,18 @@ # Special implementation methods. def __get_single_item__(self, index): - return native._tuple_element(self, index) + + "Return the item at the normalised (positive) 'index'." + + if index >= len(self): + raise IndexError(index) + + return native._list_element(self, index) + + def __set_single_item__(self, index, value): + + "Set at the normalised (positive) 'index' the given 'value'." + + raise TypeError(self) # vim: tabstop=4 expandtab shiftwidth=4 diff -r fbef93224a10 -r 3a4ba5788f0f lib/native.py --- a/lib/native.py Wed Nov 23 17:23:52 2016 +0100 +++ b/lib/native.py Wed Nov 23 17:32:58 2016 +0100 @@ -53,20 +53,16 @@ def _str_nonempty(self): pass def _list_init(size): pass +def _list_setsize(self, size): pass def _list_append(self, value): pass def _list_concat(self, other): pass def _list_len(self): pass def _list_nonempty(self): pass def _list_element(self, index): pass +def _list_setelement(self, index, value): pass def _buffer_str(self): pass -def _list_to_tuple(l): pass - -def _tuple_init(args, size): pass -def _tuple_len(self): pass -def _tuple_element(self, index): pass - def _isinstance(obj, cls): pass def _read(fd, n): pass diff -r fbef93224a10 -r 3a4ba5788f0f templates/native.c --- a/templates/native.c Wed Nov 23 17:23:52 2016 +0100 +++ b/templates/native.c Wed Nov 23 17:32:58 2016 +0100 @@ -349,6 +349,19 @@ return attr; } +__attr __fn_native__list_setsize(__attr __args[]) +{ + __attr * const self = &__args[1]; + __attr * const size = &__args[2]; + /* self.__data__ interpreted as list */ + __fragment *data = __load_via_object(self->value, __pos___data__).data; + /* size.__data__ interpreted as int */ + unsigned int n = __load_via_object(size->value, __pos___data__).intvalue; + + data->size = n; + return __builtins___none_None; +} + __attr __fn_native__list_append(__attr __args[]) { __attr * const self = &__args[1]; @@ -438,11 +451,18 @@ return elements[i]; } -__attr __fn_native__list_to_tuple(__attr __args[]) +__attr __fn_native__list_setelement(__attr __args[]) { - __attr * const l = &__args[1]; + __attr * const self = &__args[1]; + __attr * const index = &__args[2]; + __attr * const value = &__args[3]; + /* self.__data__ interpreted as fragment */ + __attr *elements = __load_via_object(self->value, __pos___data__).data->attrs; + /* index.__data__ interpreted as int */ + int i = __load_via_object(index->value, __pos___data__).intvalue; - /* NOTE: To be written. */ + /* Set the element. */ + elements[i] = *value; return __builtins___none_None; } @@ -474,38 +494,6 @@ return __new_str(s); } -__attr __fn_native__tuple_init(__attr __args[]) -{ - __attr * const size = &__args[1]; - /* size.__data__ interpreted as fragment */ - __fragment *data = calloc(__load_via_object(size->value, __pos___data__).intvalue, sizeof(__attr)); - __attr attr = {0, .data=data}; - - return attr; -} - -__attr __fn_native__tuple_len(__attr __args[]) -{ - __attr * const self = &__args[1]; - /* self.__data__ interpreted as fragment */ - unsigned int size = __load_via_object(self->value, __pos___data__).data->size; - - /* Return the new integer. */ - return __new_int(size); -} - -__attr __fn_native__tuple_element(__attr __args[]) -{ - __attr * const self = &__args[1]; - __attr * const index = &__args[2]; - /* self.__data__ interpreted as fragment */ - __attr *elements = __load_via_object(self->value, __pos___data__).data->attrs; - /* index.__data__ interpreted as int */ - int i = __load_via_object(index->value, __pos___data__).intvalue; - - return elements[i]; -} - __attr __fn_native__isinstance(__attr __args[]) { __attr * const obj = &__args[1]; diff -r fbef93224a10 -r 3a4ba5788f0f templates/native.h --- a/templates/native.h Wed Nov 23 17:23:52 2016 +0100 +++ b/templates/native.h Wed Nov 23 17:32:58 2016 +0100 @@ -42,19 +42,16 @@ __attr __fn_native__str_nonempty(__attr __args[]); __attr __fn_native__list_init(__attr __args[]); +__attr __fn_native__list_setsize(__attr __args[]); __attr __fn_native__list_append(__attr __args[]); __attr __fn_native__list_concat(__attr __args[]); __attr __fn_native__list_len(__attr __args[]); __attr __fn_native__list_nonempty(__attr __args[]); __attr __fn_native__list_element(__attr __args[]); -__attr __fn_native__list_to_tuple(__attr __args[]); +__attr __fn_native__list_setelement(__attr __args[]); __attr __fn_native__buffer_str(__attr __args[]); -__attr __fn_native__tuple_init(__attr __args[]); -__attr __fn_native__tuple_len(__attr __args[]); -__attr __fn_native__tuple_element(__attr __args[]); - __attr __fn_native__isinstance(__attr __args[]); __attr __fn_native__read(__attr __args[]); diff -r fbef93224a10 -r 3a4ba5788f0f tests/list.py --- a/tests/list.py Wed Nov 23 17:23:52 2016 +0100 +++ b/tests/list.py Wed Nov 23 17:32:58 2016 +0100 @@ -10,3 +10,7 @@ print l[-3] print l[-4] print l + +t = (1, 2, 3, "four") +l = list(t) +print l diff -r fbef93224a10 -r 3a4ba5788f0f tests/tuple.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/tuple.py Wed Nov 23 17:32:58 2016 +0100 @@ -0,0 +1,15 @@ +l = (1, 2, 3, "four") +print len(l) +print l[0] +print l[1] +print l[2] +print l[3] +print l[-1] +print l[-2] +print l[-3] +print l[-4] +print l + +l = [1, 2, 3, "four"] +t = tuple(l) +print t