1.1 --- a/templates/progops.c Tue Nov 29 23:13:18 2016 +0100
1.2 +++ b/templates/progops.c Wed Nov 30 16:18:17 2016 +0100
1.3 @@ -24,11 +24,40 @@
1.4
1.5 /* Generic internal data allocation. */
1.6
1.7 -__attr __newfragment(__attr args[], unsigned int number)
1.8 +__fragment *__new_fragment(unsigned int n)
1.9 +{
1.10 + /* Allocate space for the list. */
1.11 + __fragment *data = (__fragment *) __ALLOCATE(1, __FRAGMENT_SIZE(n));
1.12 +
1.13 + /* The initial capacity is the same as the given size. */
1.14 + data->size = 0;
1.15 + data->capacity = n;
1.16 + return data;
1.17 +}
1.18 +
1.19 +__mapping *__new_mapping(unsigned int n)
1.20 +{
1.21 + /* Allocate a number of buckets. */
1.22 + __mapping *data = (__mapping *) __ALLOCATE(1, __MAPPING_SIZE(__MAPPING_BUCKETS));
1.23 + unsigned int i;
1.24 +
1.25 + /* Allocate fragments with an initial size of 2 * n / __MAPPING_BUCKETS,
1.26 + assuming a mostly uniform distribution of values across the buckets. */
1.27 +
1.28 + for (i = 0; i < __MAPPING_BUCKETS; i++)
1.29 + {
1.30 + data->keys[i] = __new_fragment(2 * n / __MAPPING_BUCKETS);
1.31 + data->values[i] = __new_fragment(2 * n / __MAPPING_BUCKETS);
1.32 + }
1.33 +
1.34 + return data;
1.35 +}
1.36 +
1.37 +void __newdata_sequence(__attr args[], unsigned int number)
1.38 {
1.39 /* Calculate the size of the fragment. */
1.40
1.41 - __fragment *data = (__fragment *) __ALLOCATE(1, __FRAGMENT_SIZE(number));
1.42 + __fragment *data = __new_fragment(number);
1.43 __attr attr = {0, .seqvalue=data};
1.44 unsigned int i, j;
1.45
1.46 @@ -38,8 +67,39 @@
1.47 data->attrs[j] = args[i];
1.48
1.49 data->size = number;
1.50 - data->capacity = number;
1.51 - return attr;
1.52 +
1.53 + /* Store a reference to the data in the object's __data__ attribute. */
1.54 +
1.55 + __store_via_object(args[0].value, __pos___data__, attr);
1.56 +}
1.57 +
1.58 +void __newdata_mapping(__attr args[], unsigned int number)
1.59 +{
1.60 + __mapping *data = __new_mapping(number);
1.61 + __attr attr = {0, .mapvalue=data};
1.62 + __fragment *f;
1.63 + __attr callargs[3];
1.64 + unsigned int i;
1.65 +
1.66 + /* Store a reference to the data in the object's __data__ attribute. */
1.67 +
1.68 + __store_via_object(args[0].value, __pos___data__, attr);
1.69 +
1.70 + /* Store the given number of values, starting from the second element. */
1.71 +
1.72 + for (i = 1; i <= number; i++)
1.73 + {
1.74 + /* Obtain the tuple elements. */
1.75 +
1.76 + f = __load_via_object(args[i].value, __pos___data__).seqvalue;
1.77 + callargs[0] = args[0];
1.78 + callargs[1] = f->attrs[0];
1.79 + callargs[2] = f->attrs[1];
1.80 +
1.81 + /* Call __setitem__ with the key and value. */
1.82 +
1.83 + __fn___builtins___dict_dict___setitem__(callargs);
1.84 + }
1.85 }
1.86
1.87 /* A helper for raising type errors within common operations. */