Lichen

templates/native/common.c

601:adcdaeb19307
2017-02-19 Paul Boddie Fixed the context test and set operation to replace the local context with any applicable attribute context. Added a test of method rebinding that requires this fix. method-wrapper-for-context
     1 /* Common operations for native functions.     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 "types.h"    20 #include "exceptions.h"    21 #include "ops.h"    22 #include "progconsts.h"    23 #include "progops.h"    24 #include "progtypes.h"    25 #include "main.h"    26     27 /* Utility functions. */    28     29 __attr __new_int(int i)    30 {    31     /* Create a new integer and mutate the __data__ attribute. */    32     __attr attr = __NEWINSTANCE(__builtins___int_int);    33     attr.value->attrs[__pos___data__].intvalue = i;    34     return attr;    35 }    36     37 __attr __new_str(char *s, int size)    38 {    39     /* Create a new string and mutate the __data__, __size__ and __key__ attributes. */    40     __attr attr = __NEWINSTANCE(__builtins___str_string);    41     attr.value->attrs[__pos___data__].strvalue = s;    42     attr.value->attrs[__pos___size__].intvalue = size;    43     attr.value->attrs[__pos___key__] = __NULL;    44     return attr;    45 }    46     47 __attr __new_list(__fragment *f)    48 {    49     /* Create a new list and mutate the __data__ attribute. */    50     __attr attr = __NEWINSTANCE(__builtins___list_list);    51     attr.value->attrs[__pos___data__].seqvalue = f;    52     return attr;    53 }    54     55 __fragment *__fragment_append(__fragment *data, __attr * const value)    56 {    57     __fragment *newdata = data;    58     unsigned int size = data->size, capacity = data->capacity;    59     unsigned int n;    60     61     /* Re-allocate the fragment if the capacity has been reached. */    62     if (size >= capacity)    63     {    64         /* NOTE: Consider various restrictions on capacity increases. */    65         n = capacity ? capacity * 2 : 1;    66         newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n));    67         newdata->capacity = n;    68     }    69     70     /* Insert the new element and increment the list size. */    71     newdata->attrs[size] = *value;    72     newdata->size = size + 1;    73     74     return newdata;    75 }