Lichen

templates/progops.c

310:223ec1d88ca9
2016-12-03 Paul Boddie Include <var> as an unresolved reference kind.
     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 /* Helpers for raising errors within common operations. */    83     84 void __raise_memory_error()    85 {    86     __attr args[1];    87     __attr exc = __MEMORY_ERROR_INSTANTIATOR(args);    88     __Raise(exc);    89 }    90     91 void __raise_overflow_error()    92 {    93     __attr args[1];    94     __attr exc = __OVERFLOW_ERROR_INSTANTIATOR(args);    95     __Raise(exc);    96 }    97     98 void __raise_type_error()    99 {   100     __attr args[1];   101     __attr exc = __TYPE_ERROR_INSTANTIATOR(args);   102     __Raise(exc);   103 }   104    105 void __raise_zero_division_error()   106 {   107     __attr args[1];   108     __attr exc = __ZERO_DIVISION_ERROR_INSTANTIATOR(args);   109     __Raise(exc);   110 }   111    112 /* Generic invocation operations. */   113    114 /* Invoke the given callable, supplying keyword argument details in the given   115    codes and arguments arrays, indicating the number of arguments described.   116    The number of positional arguments is specified, and such arguments then   117    follow as conventional function arguments. Typically, at least one argument   118    is specified, starting with any context argument.   119 */   120    121 __attr __invoke(__attr callable, int always_callable,   122                 unsigned int nkwargs, __param kwcodes[], __attr kwargs[],   123                 unsigned int nargs, __attr args[])   124 {   125     /* Obtain the __args__ special member, referencing the parameter table. */   126    127     __attr minparams = __check_and_load_via_object(callable.value, __pos___args__, __code___args__);   128    129     /* Refer to the table and minimum/maximum. */   130    131     const __ptable *ptable = minparams.ptable;   132     const unsigned int min = minparams.min, max = ptable->size;   133    134     /* Reserve enough space for the arguments. */   135    136     __attr allargs[max];   137    138     /* Traverse the arguments. */   139    140     unsigned int pos, kwpos;   141    142     /* Check the number of arguments. */   143    144     if ((min > (nargs + nkwargs)) || ((nargs + nkwargs) > max))   145         return __NULL;   146    147     /* Copy the arguments. */   148    149     for (pos = 0; pos < nargs; pos++)   150         allargs[pos] = args[pos];   151    152     /* Erase the remaining arguments. */   153    154     for (pos = nargs; pos < max; pos++)   155     {   156         allargs[pos].value = 0;   157     }   158    159     /* Fill keyword arguments. */   160    161     for (kwpos = 0; kwpos < nkwargs; kwpos++)   162     {   163         pos = __HASPARAM(ptable, kwcodes[kwpos].pos, kwcodes[kwpos].code);   164    165         /* Check the table entry against the supplied argument details.   166            Set the argument but only if it does not overwrite positional   167            arguments. */   168    169         if ((pos == -1) || (pos < nargs))   170             return __NULL;   171    172         /* Set the argument using the appropriate position. */   173    174         allargs[pos] = kwargs[kwpos];   175     }   176    177     /* Fill the defaults. */   178    179     for (pos = nargs; pos < max; pos++)   180     {   181         if (allargs[pos].value == 0)   182             allargs[pos] = __GETDEFAULT(callable.value, pos - min);   183     }   184    185     /* Call with the prepared arguments. */   186    187     return (always_callable ? __load_via_object(callable.value, __pos___fn__)   188                             : __check_and_load_via_object(callable.value, __pos___fn__, __code___fn__)   189                             ).fn(allargs);   190 }   191    192 /* Error routines. */   193    194 __attr __unbound_method(__attr args[])   195 {   196     __attr excargs[1];   197     __attr exc = __new___builtins___core_UnboundMethodInvocation(excargs);   198     __Raise(exc);   199     return __builtins___none_None; /* superfluous */   200 }   201    202 /* Generic operations depending on specific program details. */   203    204 void __SETDEFAULT(__ref obj, int pos, __attr value)   205 {   206     __store_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos, value);   207 }   208    209 __attr __GETDEFAULT(__ref obj, int pos)   210 {   211     return __load_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos);   212 }   213    214 int __BOOL(__attr attr)   215 {   216     __attr args[2] = {{0, 0}, attr};   217    218     /* Invoke the bool function with the object and test against True. */   219    220     return __fn___builtins___boolean_bool(args).value == __builtins___boolean_True.value;   221 }