Lichen

Annotated templates/types.h

1022:582d834d392d
14 months ago Paul Boddie Merged changes from the value-replacement branch. value-replacement-for-wrapper
paul@353 1
/* Runtime types.
paul@353 2
paul@1015 3
Copyright (C) 2015-2019, 2021, 2023 Paul Boddie <paul@boddie.org.uk>
paul@353 4
paul@353 5
This program is free software; you can redistribute it and/or modify it under
paul@353 6
the terms of the GNU General Public License as published by the Free Software
paul@353 7
Foundation; either version 3 of the License, or (at your option) any later
paul@353 8
version.
paul@353 9
paul@353 10
This program is distributed in the hope that it will be useful, but WITHOUT
paul@353 11
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@353 12
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@353 13
details.
paul@353 14
paul@353 15
You should have received a copy of the GNU General Public License along with
paul@353 16
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@353 17
*/
paul@126 18
paul@126 19
#ifndef __TYPES_H__
paul@126 20
#define __TYPES_H__
paul@126 21
paul@566 22
/* Define code and position types, populated by enum values defined for each
paul@566 23
   program specifically. */
paul@566 24
paul@578 25
#include <stdint.h>
paul@941 26
#include <stdlib.h>
paul@578 27
paul@649 28
/* Include the special instance position value. The pos member of __obj refers
paul@649 29
   to the special type attribute for classes, indicating which position holds
paul@649 30
   the attribute describing the class type. For instances, it is set to the same
paul@649 31
   attribute position as __class__ and is defined in the following file. */
paul@649 32
paul@649 33
#include "instancepos.h"
paul@649 34
paul@578 35
typedef uint16_t __code;
paul@578 36
typedef uint16_t __pos;
paul@578 37
typedef uint16_t __pcode;
paul@578 38
typedef uint16_t __ppos;
paul@566 39
paul@126 40
/* Attribute tables are lists of codes confirming the presence of attributes. */
paul@126 41
paul@126 42
typedef struct __table
paul@126 43
{
paul@566 44
    const __pos size;
paul@566 45
    const __code attrs[];
paul@126 46
} __table;
paul@126 47
paul@126 48
/* Parameter tables are lists of codes confirming the presence of parameters, as
paul@126 49
   well as the positions of those parameters in the list for a given function.
paul@126 50
*/
paul@126 51
paul@126 52
typedef struct __param
paul@126 53
{
paul@566 54
    __code code;
paul@566 55
    __pos pos;
paul@126 56
} __param;
paul@126 57
paul@126 58
typedef struct __ptable
paul@126 59
{
paul@579 60
    const __ppos min, max, size;
paul@126 61
    const __param params[];
paul@126 62
} __ptable;
paul@126 63
paul@577 64
/* Attributes are values referring to objects or encoding other information.
paul@126 65
   Objects are collections of attributes.
paul@126 66
   Object references are references to tables and collections of attributes.
paul@126 67
   Attribute references are references to single attributes. */
paul@126 68
paul@126 69
typedef struct __obj __obj;
paul@159 70
typedef struct __fragment __fragment;
paul@577 71
typedef union __attr __attr;
paul@577 72
typedef __obj * __ref;
paul@126 73
paul@945 74
/* Introduce an integer type that is interoperable with the size type. */
paul@941 75
paul@941 76
typedef ssize_t __int;
paul@941 77
paul@971 78
/* Introduce a tagged pointer type. */
paul@971 79
paul@971 80
typedef uintptr_t __ref_tagged;
paul@971 81
paul@941 82
/* Attribute value interpretations. */
paul@941 83
paul@577 84
typedef union __attr
paul@126 85
{
paul@758 86
    /* General attribute members. */
paul@758 87
paul@579 88
    __ref value;                /* attribute value */
paul@974 89
    __int intvalue;             /* integer value data or object-specific size
paul@974 90
                                   (shifted value, tagged) */
paul@971 91
    __ref_tagged refvalue;      /* attribute value with tag */
paul@758 92
paul@758 93
    /* Special case attribute members. */
paul@758 94
paul@579 95
    const __ptable * ptable;    /* parameter table */
paul@577 96
    struct {
paul@579 97
        __pcode code;           /* parameter table code for key */
paul@579 98
        __ppos pos;             /* parameter table position for key */
paul@577 99
    };
paul@580 100
    __attr (*fn)();             /* callable details */
paul@579 101
    char * strvalue;            /* string value */
paul@579 102
    __fragment * seqvalue;      /* sequence data */
paul@579 103
    void * datavalue;           /* object-specific data */
paul@126 104
} __attr;
paul@126 105
paul@126 106
typedef struct __obj
paul@126 107
{
paul@126 108
    const __table * table;      /* attribute table */
paul@566 109
    __ppos pos;                 /* position of attribute indicating class */
paul@126 110
    __attr attrs[];             /* attributes */
paul@850 111
paul@850 112
    /* Specialisations of this type may add other members.
paul@850 113
       See generator.py for type generation, progops.h for definitions, and
paul@850 114
       the generated progtypes.h for the final details. */
paul@850 115
paul@126 116
} __obj;
paul@126 117
paul@280 118
/* Fragments are simple collections of attributes employed by sequence types.
paul@280 119
   They provide the basis of lists and tuples. */
paul@159 120
paul@159 121
typedef struct __fragment
paul@159 122
{
paul@941 123
    __int size, capacity;
paul@159 124
    __attr attrs[];
paul@159 125
} __fragment;
paul@159 126
paul@941 127
#define __FRAGMENT_SIZE(NUMBER) ((NUMBER) * sizeof(__attr) + 2 * sizeof(__int))
paul@206 128
paul@758 129
/* Attribute interpretation. */
paul@758 130
paul@943 131
#define __NUM_TAG_BITS      2
paul@943 132
#define __TAG_INT           0b01
paul@971 133
#define __TAG_REPLACING     0b10
paul@971 134
#define __INTEGER(ATTR)     ((ATTR).intvalue & __TAG_INT)
paul@758 135
paul@626 136
/* Attribute value setting. */
paul@143 137
paul@875 138
#define __ATTRVALUE(VALUE)  ((__attr) {.value=(__ref) VALUE})
paul@875 139
#define __NULL              __ATTRVALUE(0)
paul@875 140
#define __SETNULL(ATTR)     ((ATTR).value = 0)
paul@758 141
paul@974 142
/* Attribute as instance value. */
paul@758 143
paul@974 144
#define __FROMINT(VALUE)    ((((__int) VALUE) << __NUM_TAG_BITS) | __TAG_INT)
paul@974 145
#define __INTVALUE(VALUE)   ((__attr) {.intvalue=__FROMINT(VALUE)})
paul@875 146
#define __TOINT(ATTR)       ((ATTR).intvalue >> __NUM_TAG_BITS)
paul@941 147
#define __MAXINT            ((((__int) 1) << ((sizeof(__int) * 8) - 1 - __NUM_TAG_BITS)) - 1)
paul@941 148
#define __MININT            (-(((__int) 1) << ((sizeof(__int) * 8) - 1 - __NUM_TAG_BITS)))
paul@126 149
paul@971 150
/* Attribute carrying replacement value. */
paul@971 151
paul@971 152
#define __REPLACEMENT(ATTR) ((__attr) {.refvalue=(((__ref_tagged) (ATTR).value) | __TAG_REPLACING)})
paul@971 153
#define __REPLACED(ATTR)    ((__attr) {.value=((__ref) ((ATTR).refvalue & ~__TAG_REPLACING))})
paul@971 154
#define __REPLACING(ATTR)   ((ATTR).refvalue & __TAG_REPLACING)
paul@971 155
paul@623 156
/* Argument lists. */
paul@126 157
paul@875 158
#define __ARGS(...)         ((__attr[]) {__VA_ARGS__})
paul@875 159
#define __KWARGS(...)       ((__param[]) {__VA_ARGS__})
paul@126 160
paul@623 161
/* Attribute codes and positions for attribute names. */
paul@623 162
paul@875 163
#define __ATTRCODE(ATTRNAME)    __code_##ATTRNAME
paul@875 164
#define __ATTRPOS(ATTRNAME)     __pos_##ATTRNAME
paul@875 165
#define __PARAMCODE(PARAMNAME)  __pcode_##PARAMNAME
paul@875 166
#define __PARAMPOS(PARAMNAME)   __ppos_##PARAMNAME
paul@623 167
paul@126 168
#endif /* __TYPES_H__ */