Lichen

templates/native/list.c

934:2989aab1b4f7
10 months ago Paul Boddie Renamed the utf8string class to unicode, eliminating the unicode function. This means that the simple case of merely returning an object if it is already a Unicode object no longer occurs when using the unicode callable, but such behaviour might be better supported with more general customised instantiation functionality.
     1 /* Native functions for list operations.     2      3 Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>     4      5 This program is free software; you can redistribute it and/or modify it under     6 the terms of the GNU General Public License as published by the Free Software     7 Foundation; either version 3 of the License, or (at your option) any later     8 version.     9     10 This program is distributed in the hope that it will be useful, but WITHOUT    11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    12 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    13 details.    14     15 You should have received a copy of the GNU General Public License along with    16 this program.  If not, see <http://www.gnu.org/licenses/>.    17 */    18     19 #include "native/common.h"    20 #include "types.h"    21 #include "exceptions.h"    22 #include "ops.h"    23 #include "progconsts.h"    24 #include "progops.h"    25 #include "progtypes.h"    26 #include "main.h"    27     28 /* List operations. */    29     30 __attr __fn_native_list_list_init(__attr __self, __attr size)    31 {    32     /* size interpreted as int */    33     unsigned int n = __TOINT(size);    34     __attr attr = {.seqvalue=__new_fragment(n)};    35     36     /* Return the __data__ attribute. */    37     return attr;    38 }    39     40 __attr __fn_native_list_list_setsize(__attr __self, __attr _data, __attr size)    41 {    42     /* _data interpreted as list.__data__ */    43     __fragment *data = _data.seqvalue;    44     /* size interpreted as int */    45     unsigned int n = __TOINT(size);    46     47     data->size = n;    48     return __builtins___none_None;    49 }    50     51 __attr __fn_native_list_list_append(__attr __self, __attr self, __attr value)    52 {    53     /* self.__data__ interpreted as list */    54     __fragment *data = __load_via_object(__VALUE(self), __data__).seqvalue;    55     __fragment *newdata = __fragment_append(data, value);    56     57     /* Replace the __data__ attribute if appropriate. */    58     if (newdata != data)    59         __store_via_object(__VALUE(self), __data__, ((__attr) {.seqvalue=newdata}));    60     return __builtins___none_None;    61 }    62     63 __attr __fn_native_list_list_concat(__attr __self, __attr self, __attr other)    64 {    65     /* self, interpreted as list, other interpreted as list.__data__ */    66     __fragment *data = __load_via_object(__VALUE(self), __data__).seqvalue;    67     __fragment *other_data = other.seqvalue;    68     __fragment *newdata = data;    69     unsigned int size = data->size, capacity = data->capacity;    70     unsigned int other_size = other_data->size;    71     unsigned int i, j, n = size + other_size;    72     73     /* Re-allocate the fragment if the capacity has been reached. */    74     if (n >= capacity)    75     {    76         newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n));    77         newdata->capacity = n;    78     }    79     80     /* Copy the elements from the other list and increment the list size. */    81     for (i = size, j = 0; j < other_size; i++, j++)    82         newdata->attrs[i] = other_data->attrs[j];    83     newdata->size = n;    84     85     /* Replace the __data__ attribute if appropriate. */    86     if (newdata != data)    87         __store_via_object(__VALUE(self), __data__, ((__attr) {.seqvalue=newdata}));    88     return __builtins___none_None;    89 }    90     91 __attr __fn_native_list_list_len(__attr self, __attr _data)    92 {    93     /* _data interpreted as list.__data__ */    94     unsigned int size = _data.seqvalue->size;    95     96     /* Return the new integer. */    97     return __new_int(size);    98 }    99    100 __attr __fn_native_list_list_nonempty(__attr __self, __attr _data)   101 {   102     return _data.seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False;   103 }   104    105 __attr __fn_native_list_list_element(__attr __self, __attr _data, __attr index)   106 {   107     /* _data interpreted as list.__data__ */   108     __attr *elements = _data.seqvalue->attrs;   109     /* index interpreted as int */   110     int i = __TOINT(index);   111    112     return elements[i];   113 }   114    115 __attr __fn_native_list_list_setelement(__attr __self, __attr _data, __attr index, __attr value)   116 {   117     /* _data interpreted as list.__data__ */   118     __attr *elements = _data.seqvalue->attrs;   119     /* index interpreted as int */   120     int i = __TOINT(index);   121    122     /* Set the element. */   123     elements[i] = value;   124     return __builtins___none_None;   125 }   126    127 /* Module initialisation. */   128    129 void __main_native_list()   130 {   131 }