1.1 --- a/templates/native.c Mon Nov 21 22:56:52 2016 +0100
1.2 +++ b/templates/native.c Tue Nov 22 01:28:58 2016 +0100
1.3 @@ -1,4 +1,4 @@
1.4 -#include <stdlib.h> /* calloc, exit */
1.5 +#include <stdlib.h> /* calloc, exit, realloc */
1.6 #include <unistd.h> /* read, write */
1.7 #include <math.h> /* ceil, log10, pow */
1.8 #include <string.h> /* strcmp, strlen */
1.9 @@ -370,13 +370,73 @@
1.10
1.11 __attr __fn_native__list_init(__attr __args[])
1.12 {
1.13 - #define size (__args[1])
1.14 - /* size.__data__ interpreted as fragment */
1.15 - __fragment *data = calloc(__load_via_object(size.value, __pos___data__).intvalue, sizeof(__attr));
1.16 + #define __size (__args[1])
1.17 + /* __size.__data__ interpreted as int */
1.18 + unsigned int n = __load_via_object(__size.value, __pos___data__).intvalue;
1.19 +
1.20 + /* Allocate space for the list. */
1.21 + __fragment *data = calloc(1, __FRAGMENT_SIZE(n));
1.22 __attr attr = {0, .data=data};
1.23
1.24 + /* The initial capacity is the same as the given size. */
1.25 + data->size = 0;
1.26 + data->capacity = n;
1.27 return attr;
1.28 - #undef size
1.29 + #undef __size
1.30 +}
1.31 +
1.32 +__attr __fn_native__list_append(__attr __args[])
1.33 +{
1.34 + #define self (__args[1])
1.35 + #define __value (__args[2])
1.36 + /* self.__data__ interpreted as list */
1.37 + __fragment *data = __load_via_object(self.value, __pos___data__).data;
1.38 + unsigned int size = data->size, capacity = data->capacity;
1.39 + unsigned int n;
1.40 +
1.41 + /* Re-allocate the fragment if the capacity has been reached. */
1.42 + if (size >= capacity)
1.43 + {
1.44 + /* NOTE: Consider various restrictions on capacity increases. */
1.45 + n = data->capacity * 2;
1.46 + data = realloc(data, __FRAGMENT_SIZE(n));
1.47 + data->capacity = n;
1.48 + }
1.49 +
1.50 + /* Insert the new element and increment the list size. */
1.51 + data->attrs[size] = __value;
1.52 + data->size = size + 1;
1.53 + return __builtins___none_None;
1.54 + #undef self
1.55 + #undef __value
1.56 +}
1.57 +
1.58 +__attr __fn_native__list_concat(__attr __args[])
1.59 +{
1.60 + #define self (__args[1])
1.61 + #define __other (__args[2])
1.62 + /* self.__data__, __other.__data__ interpreted as list */
1.63 + __fragment *data = __load_via_object(self.value, __pos___data__).data;
1.64 + __fragment *other_data = __load_via_object(__other.value, __pos___data__).data;
1.65 + unsigned int size = data->size, capacity = data->capacity;
1.66 + unsigned int other_size = other_data->size;
1.67 + unsigned int i, j, n;
1.68 +
1.69 + /* Re-allocate the fragment if the capacity has been reached. */
1.70 + if (size + other_size >= capacity)
1.71 + {
1.72 + n = size + other_size;
1.73 + data = realloc(data, __FRAGMENT_SIZE(n));
1.74 + data->capacity = n;
1.75 + }
1.76 +
1.77 + /* Copy the elements from the other list and increment the list size. */
1.78 + for (i = size, j = 0; j < other_size; i++, j++)
1.79 + data->attrs[i] = other_data->attrs[j];
1.80 + data->size = n;
1.81 + return __builtins___none_None;
1.82 + #undef self
1.83 + #undef __other
1.84 }
1.85
1.86 __attr __fn_native__list_len(__attr __args[])
1.87 @@ -421,6 +481,30 @@
1.88 #undef l
1.89 }
1.90
1.91 +__attr __fn_native__buffer_str(__attr __args[])
1.92 +{
1.93 + #define self (__args[1])
1.94 + /* self.__data__ interpreted as buffer */
1.95 + __fragment *data = __load_via_object(self.value, __pos___data__).data;
1.96 + unsigned int size = 0, i, j;
1.97 + char *s;
1.98 +
1.99 + /* Calculate the size of the string. */
1.100 + for (i = 0; i < data->size; i++)
1.101 + size += strlen(data->attrs[i].strvalue);
1.102 +
1.103 + /* Reserve space for a new string. */
1.104 + s = calloc(size + 1, sizeof(char));
1.105 +
1.106 + /* Build a single string from the buffer contents. */
1.107 + for (i = 0, j = 0; i < data->size; j += strlen(data->attrs[i].strvalue), i++)
1.108 + strcpy(s + j, data->attrs[i].strvalue);
1.109 +
1.110 + /* Return a new string. */
1.111 + return __new_str(s);
1.112 + #undef self
1.113 +}
1.114 +
1.115 __attr __fn_native__tuple_init(__attr __args[])
1.116 {
1.117 #define size (__args[1])