Lichen

templates/progops.c

305:92aaba8e1846
2016-12-03 Paul Boddie Added missing signatures.
     1 /* Operations depending on program specifics.     2 */     3      4 #include <stdlib.h>     5 #include "types.h"     6 #include "ops.h"     7 #include "progconsts.h"     8 #include "progops.h"     9 #include "progtypes.h"    10 #include "main.h"    11 #include "exceptions.h"    12     13 /* Generic instantiation operations, defining common members. */    14     15 __attr __new(const __table * table, __ref cls, size_t size)    16 {    17     __ref obj = (__ref) __ALLOCATE(1, size);    18     __attr self = {obj, obj};    19     __attr tmp = {0, cls};    20     obj->table = table;    21     __store_via_object(obj, __pos___class__, tmp);    22     return self;    23 }    24     25 /* Generic internal data allocation. */    26     27 __fragment *__new_fragment(unsigned int n)     28 {    29     /* Allocate space for the list. */    30     31     __fragment *data = (__fragment *) __ALLOCATE(1, __FRAGMENT_SIZE(n));    32     33     /* The initial capacity is the same as the given size. */    34     35     data->size = 0;    36     data->capacity = n;    37     return data;    38 }    39     40 void __newdata_sequence(__attr args[], unsigned int number)    41 {    42     /* Calculate the size of the fragment. */    43     44     __fragment *data = __new_fragment(number);    45     __attr attr = {0, .seqvalue=data};    46     unsigned int i, j;    47     48     /* Copy the given number of values, starting from the second element. */    49     50     for (i = 1, j = 0; i <= number; i++, j++)    51         data->attrs[j] = args[i];    52     53     data->size = number;    54     55     /* Store a reference to the data in the object's __data__ attribute. */    56     57     __store_via_object(args[0].value, __pos___data__, attr);    58 }    59     60 #ifdef __HAVE___builtins___dict_dict    61     62 void __newdata_mapping(__attr args[], unsigned int number)    63 {    64     __attr dict = args[0];    65     __attr callargs[2];    66     67     /* Create a temporary list using the arguments. */    68     69     __newliteral___builtins___list_list(args, number);    70     71     /* Call __init__ with the dict object and list argument. */    72     73     callargs[0] = dict;    74     callargs[1] = args[0];    75     76     __fn___builtins___dict_dict___init__(callargs);    77     args[0] = dict;    78 }    79     80 #endif /* __HAVE___builtins___dict_dict */    81     82 /* A helper for raising type errors within common operations. */    83     84 void __raise_type_error()    85 {    86     __attr args[1];    87     __attr exc = __TYPE_ERROR_INSTANTIATOR(args);    88     __Raise(exc);    89 }    90     91 /* A helper for raising memory errors within common operations. */    92     93 void __raise_memory_error()    94 {    95     __attr args[1];    96     __attr exc = __MEMORY_ERROR_INSTANTIATOR(args);    97     __Raise(exc);    98 }    99    100 /* Generic invocation operations. */   101    102 /* Invoke the given callable, supplying keyword argument details in the given   103    codes and arguments arrays, indicating the number of arguments described.   104    The number of positional arguments is specified, and such arguments then   105    follow as conventional function arguments. Typically, at least one argument   106    is specified, starting with any context argument.   107 */   108    109 __attr __invoke(__attr callable, int always_callable,   110                 unsigned int nkwargs, __param kwcodes[], __attr kwargs[],   111                 unsigned int nargs, __attr args[])   112 {   113     /* Obtain the __args__ special member, referencing the parameter table. */   114    115     __attr minparams = __check_and_load_via_object(callable.value, __pos___args__, __code___args__);   116    117     /* Refer to the table and minimum/maximum. */   118    119     const __ptable *ptable = minparams.ptable;   120     const unsigned int min = minparams.min, max = ptable->size;   121    122     /* Reserve enough space for the arguments. */   123    124     __attr allargs[max];   125    126     /* Traverse the arguments. */   127    128     unsigned int pos, kwpos;   129    130     /* Check the number of arguments. */   131    132     if ((min > (nargs + nkwargs)) || ((nargs + nkwargs) > max))   133         return __NULL;   134    135     /* Copy the arguments. */   136    137     for (pos = 0; pos < nargs; pos++)   138         allargs[pos] = args[pos];   139    140     /* Erase the remaining arguments. */   141    142     for (pos = nargs; pos < max; pos++)   143     {   144         allargs[pos].value = 0;   145     }   146    147     /* Fill keyword arguments. */   148    149     for (kwpos = 0; kwpos < nkwargs; kwpos++)   150     {   151         pos = __HASPARAM(ptable, kwcodes[kwpos].pos, kwcodes[kwpos].code);   152    153         /* Check the table entry against the supplied argument details.   154            Set the argument but only if it does not overwrite positional   155            arguments. */   156    157         if ((pos == -1) || (pos < nargs))   158             return __NULL;   159    160         /* Set the argument using the appropriate position. */   161    162         allargs[pos] = kwargs[kwpos];   163     }   164    165     /* Fill the defaults. */   166    167     for (pos = nargs; pos < max; pos++)   168     {   169         if (allargs[pos].value == 0)   170             allargs[pos] = __GETDEFAULT(callable.value, pos - min);   171     }   172    173     /* Call with the prepared arguments. */   174    175     return (always_callable ? __load_via_object(callable.value, __pos___fn__)   176                             : __check_and_load_via_object(callable.value, __pos___fn__, __code___fn__)   177                             ).fn(allargs);   178 }   179    180 /* Error routines. */   181    182 __attr __unbound_method(__attr args[])   183 {   184     __attr excargs[1];   185     __attr exc = __new___builtins___core_UnboundMethodInvocation(excargs);   186     __Raise(exc);   187     return __builtins___none_None; /* superfluous */   188 }   189    190 /* Generic operations depending on specific program details. */   191    192 void __SETDEFAULT(__ref obj, int pos, __attr value)   193 {   194     __store_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos, value);   195 }   196    197 __attr __GETDEFAULT(__ref obj, int pos)   198 {   199     return __load_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos);   200 }   201    202 int __BOOL(__attr attr)   203 {   204     __attr args[2] = {{0, 0}, attr};   205    206     /* Invoke the bool function with the object and test against True. */   207    208     return __fn___builtins___boolean_bool(args).value == __builtins___boolean_True.value;   209 }