Lichen

Annotated templates/native/common.c

919:326570523de5
2021-06-22 Paul Boddie Merged changes from the default branch. trailing-data
paul@354 1
/* Common operations for native functions.
paul@354 2
paul@849 3
Copyright (C) 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
paul@354 4
paul@354 5
This program is free software; you can redistribute it and/or modify it under
paul@354 6
the terms of the GNU General Public License as published by the Free Software
paul@354 7
Foundation; either version 3 of the License, or (at your option) any later
paul@354 8
version.
paul@354 9
paul@354 10
This program is distributed in the hope that it will be useful, but WITHOUT
paul@354 11
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@354 12
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@354 13
details.
paul@354 14
paul@354 15
You should have received a copy of the GNU General Public License along with
paul@354 16
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@354 17
*/
paul@354 18
paul@354 19
#include "types.h"
paul@354 20
#include "exceptions.h"
paul@354 21
#include "ops.h"
paul@354 22
#include "progconsts.h"
paul@354 23
#include "progops.h"
paul@354 24
#include "progtypes.h"
paul@354 25
#include "main.h"
paul@354 26
paul@354 27
/* Utility functions. */
paul@354 28
paul@583 29
__attr __new_str(char *s, int size)
paul@354 30
{
paul@583 31
    /* Create a new string and mutate the __data__, __size__ and __key__ attributes. */
paul@573 32
    __attr attr = __NEWINSTANCE(__builtins___str_string);
paul@849 33
    __store_via_object(__VALUE(attr), __data__, (__attr) {.strvalue=s});
paul@849 34
    __store_via_object(__VALUE(attr), __size__, __INTVALUE(size));
paul@849 35
    __store_via_object(__VALUE(attr), __key__, __NULL);
paul@354 36
    return attr;
paul@354 37
}
paul@354 38
paul@354 39
__attr __new_list(__fragment *f)
paul@354 40
{
paul@354 41
    /* Create a new list and mutate the __data__ attribute. */
paul@573 42
    __attr attr = __NEWINSTANCE(__builtins___list_list);
paul@849 43
    __store_via_object(__VALUE(attr), __data__, (__attr) {.seqvalue=f});
paul@354 44
    return attr;
paul@354 45
}
paul@354 46
paul@850 47
__attr __new_float(double n)
paul@850 48
{
paul@850 49
    /* Create a new float and set the trailing data. */
paul@874 50
    __attr attr = __NEWINSTANCEIM(__builtins___float_float);
paul@850 51
    __set_trailing_data(attr, __builtins___float_float, n);
paul@850 52
    return attr;
paul@850 53
}
paul@850 54
paul@664 55
__fragment *__fragment_append(__fragment *data, __attr value)
paul@354 56
{
paul@354 57
    __fragment *newdata = data;
paul@354 58
    unsigned int size = data->size, capacity = data->capacity;
paul@354 59
    unsigned int n;
paul@354 60
paul@354 61
    /* Re-allocate the fragment if the capacity has been reached. */
paul@354 62
    if (size >= capacity)
paul@354 63
    {
paul@354 64
        /* NOTE: Consider various restrictions on capacity increases. */
paul@354 65
        n = capacity ? capacity * 2 : 1;
paul@354 66
        newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n));
paul@354 67
        newdata->capacity = n;
paul@354 68
    }
paul@354 69
paul@354 70
    /* Insert the new element and increment the list size. */
paul@664 71
    newdata->attrs[size] = value;
paul@354 72
    newdata->size = size + 1;
paul@354 73
paul@354 74
    return newdata;
paul@354 75
}