Lichen

templates/progops.c

131:197ae84b7b28
2016-10-25 Paul Boddie Introduced an encoder function for special type attributes.
     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 <stdio.h>    11     12 /* Generic instantiation operations, defining common members. */    13     14 __attr __new(const __table * table, __ref cls, int size)    15 {    16     __ref obj = calloc(1, size);    17     __attr self = {obj, obj};    18     __attr tmp = {0, cls};    19     obj->table = table;    20     __store_via_object(obj, __pos___class__, tmp);    21     return self;    22 }    23     24 /* Generic invocation operations. */    25     26 /* Invoke the given callable, supplying keyword argument details in the given    27    codes and arguments arrays, indicating the number of arguments described.    28    The number of positional arguments is specified, and such arguments then    29    follow as conventional function arguments. Typically, at least one argument    30    is specified, starting with any context argument.    31 */    32     33 __attr __invoke(__attr callable,    34                 unsigned int nkwargs, __param kwcodes[], __attr kwargs[],    35                 unsigned int nargs, __attr args[])    36 {    37     /* Obtain the __args__ special member, referencing the parameter table. */    38     39     __attr minparams = __load_via_object(callable.value, __pos___args__);    40     41     /* Refer to the table and minimum/maximum. */    42     43     const __ptable *ptable = minparams.ptable;    44     const unsigned int min = minparams.min, max = ptable->size;    45     46     /* Reserve enough space for the arguments. */    47     48     __attr allargs[max];    49     50     /* Traverse the arguments. */    51     52     unsigned int pos, kwpos;    53     54     /* Check the number of arguments. */    55     56     if ((min > (nargs + nkwargs)) || ((nargs + nkwargs) > max))    57         return null;    58     59     /* Copy the arguments. */    60     61     for (pos = 0; pos < nargs; pos++)    62         allargs[pos] = args[pos];    63     64     /* Erase the remaining arguments. */    65     66     for (pos = nargs; pos < max; pos++)    67     {    68         allargs[pos].value = 0;    69     }    70     71     /* Fill keyword arguments. */    72     73     for (kwpos = 0; kwpos < nkwargs; kwpos++)    74     {    75         pos = __HASPARAM(ptable, kwcodes[kwpos].pos, kwcodes[kwpos].code);    76     77         /* Check the table entry against the supplied argument details.    78            Set the argument but only if it does not overwrite positional    79            arguments. */    80     81         if ((pos == -1) || (pos < nargs))    82             return null;    83     84         /* Set the argument using the appropriate position. */    85     86         allargs[pos] = kwargs[kwpos];    87     }    88     89     /* Fill the defaults. */    90     91     for (pos = nargs; pos < max; pos++)    92     {    93         if (allargs[pos].value == 0)    94             allargs[pos] = __GETDEFAULT(callable.value, pos - nargs);    95     }    96     97     /* Call with the prepared arguments. */    98     99     return __load_via_object(callable.value, __pos___fn__).fn(allargs);   100 }   101    102 /* Error routines. */   103    104 __attr __unbound_method(__attr args[])   105 {   106     /* NOTE: Should raise an exception. */   107    108     fprintf(stderr, "Unbound method called!\n");   109     exit(1);   110 }   111    112 /* Generic operations depending on specific program details. */   113    114 void __SETDEFAULT(__ref obj, int pos, __attr value)   115 {   116     __store_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos, value);   117 }   118    119 __attr __GETDEFAULT(__ref obj, int pos)   120 {   121     return __load_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos);   122 }