Lichen

templates/native/list.c

750:44ea0968a550
2017-03-20 Paul Boddie Added the context identity to the AttrResult string representation.
     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 __args[])    31 {    32     __attr * const size = &__args[1];    33     /* size.__data__ interpreted as int */    34     unsigned int n = __load_via_object(size->value, __data__).intvalue;    35     __attr attr = {.seqvalue=__new_fragment(n)};    36     37     /* Return the __data__ attribute. */    38     return attr;    39 }    40     41 __attr __fn_native_list_list_setsize(__attr __args[])    42 {    43     __attr * const _data = &__args[1];    44     __attr * const size = &__args[2];    45     /* _data interpreted as list */    46     __fragment *data = _data->seqvalue;    47     /* size.__data__ interpreted as int */    48     unsigned int n = __load_via_object(size->value, __data__).intvalue;    49     50     data->size = n;    51     return __builtins___none_None;    52 }    53     54 __attr __fn_native_list_list_append(__attr __args[])    55 {    56     __attr * const self = &__args[1];    57     __attr * const value = &__args[2];    58     /* self.__data__ interpreted as list */    59     __fragment *data = __load_via_object(self->value, __data__).seqvalue;    60     __fragment *newdata = __fragment_append(data, value);    61     62     /* Replace the __data__ attribute if appropriate. */    63     if (newdata != data)    64         __store_via_object(self->value, __data__, ((__attr) {.seqvalue=newdata}));    65     return __builtins___none_None;    66 }    67     68 __attr __fn_native_list_list_concat(__attr __args[])    69 {    70     __attr * const self = &__args[1];    71     __attr * const other = &__args[2];    72     /* self.__data__, other interpreted as list */    73     __fragment *data = __load_via_object(self->value, __data__).seqvalue;    74     __fragment *other_data = other->seqvalue;    75     __fragment *newdata = data;    76     unsigned int size = data->size, capacity = data->capacity;    77     unsigned int other_size = other_data->size;    78     unsigned int i, j, n = size + other_size;    79     80     /* Re-allocate the fragment if the capacity has been reached. */    81     if (n >= capacity)    82     {    83         newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n));    84         newdata->capacity = n;    85     }    86     87     /* Copy the elements from the other list and increment the list size. */    88     for (i = size, j = 0; j < other_size; i++, j++)    89         newdata->attrs[i] = other_data->attrs[j];    90     newdata->size = n;    91     92     /* Replace the __data__ attribute if appropriate. */    93     if (newdata != data)    94         __store_via_object(self->value, __data__, ((__attr) {.seqvalue=newdata}));    95     return __builtins___none_None;    96 }    97     98 __attr __fn_native_list_list_len(__attr __args[])    99 {   100     __attr * const _data = &__args[1];   101     /* _data interpreted as fragment */   102     unsigned int size = _data->seqvalue->size;   103    104     /* Return the new integer. */   105     return __new_int(size);   106 }   107    108 __attr __fn_native_list_list_nonempty(__attr __args[])   109 {   110     __attr * const _data = &__args[1];   111    112     return _data->seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False;   113 }   114    115 __attr __fn_native_list_list_element(__attr __args[])   116 {   117     __attr * const _data = &__args[1];   118     __attr * const index = &__args[2];   119     /* _data interpreted as fragment */   120     __attr *elements = _data->seqvalue->attrs;   121     /* index.__data__ interpreted as int */   122     int i = __load_via_object(index->value, __data__).intvalue;   123    124     return elements[i];   125 }   126    127 __attr __fn_native_list_list_setelement(__attr __args[])   128 {   129     __attr * const _data = &__args[1];   130     __attr * const index = &__args[2];   131     __attr * const value = &__args[3];   132     /* _data interpreted as fragment */   133     __attr *elements = _data->seqvalue->attrs;   134     /* index.__data__ interpreted as int */   135     int i = __load_via_object(index->value, __data__).intvalue;   136    137     /* Set the element. */   138     elements[i] = *value;   139     return __builtins___none_None;   140 }   141    142 /* Module initialisation. */   143    144 void __main_native_list()   145 {   146 }