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, size_t size) 15 { 16 __ref obj = (__ref) 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 internal data allocation. */ 25 26 __attr __newdata(__attr args[], unsigned int number) 27 { 28 /* Manually calculate the size of the fragment. */ 29 __fragment *data = (__fragment *) calloc(1, number * sizeof(__attr) + sizeof(unsigned int)); 30 __attr attr = {0, .data=data}; 31 unsigned int i, j; 32 33 /* Copy the given number of values, starting from the second element. */ 34 35 for (i = 1, j = 0; i <= number; i++, j++) 36 data->attrs[j] = args[i]; 37 38 data->size = number; 39 return attr; 40 } 41 42 /* Generic invocation operations. */ 43 44 /* Invoke the given callable, supplying keyword argument details in the given 45 codes and arguments arrays, indicating the number of arguments described. 46 The number of positional arguments is specified, and such arguments then 47 follow as conventional function arguments. Typically, at least one argument 48 is specified, starting with any context argument. 49 */ 50 51 __attr __invoke(__attr callable, int always_callable, 52 unsigned int nkwargs, __param kwcodes[], __attr kwargs[], 53 unsigned int nargs, __attr args[]) 54 { 55 /* Obtain the __args__ special member, referencing the parameter table. */ 56 57 __attr minparams = __load_via_object(callable.value, __pos___args__); 58 59 /* Refer to the table and minimum/maximum. */ 60 61 const __ptable *ptable = minparams.ptable; 62 const unsigned int min = minparams.min, max = ptable->size; 63 64 /* Reserve enough space for the arguments. */ 65 66 __attr allargs[max]; 67 68 /* Traverse the arguments. */ 69 70 unsigned int pos, kwpos; 71 72 /* Check the number of arguments. */ 73 74 if ((min > (nargs + nkwargs)) || ((nargs + nkwargs) > max)) 75 return __NULL; 76 77 /* Copy the arguments. */ 78 79 for (pos = 0; pos < nargs; pos++) 80 allargs[pos] = args[pos]; 81 82 /* Erase the remaining arguments. */ 83 84 for (pos = nargs; pos < max; pos++) 85 { 86 allargs[pos].value = 0; 87 } 88 89 /* Fill keyword arguments. */ 90 91 for (kwpos = 0; kwpos < nkwargs; kwpos++) 92 { 93 pos = __HASPARAM(ptable, kwcodes[kwpos].pos, kwcodes[kwpos].code); 94 95 /* Check the table entry against the supplied argument details. 96 Set the argument but only if it does not overwrite positional 97 arguments. */ 98 99 if ((pos == -1) || (pos < nargs)) 100 return __NULL; 101 102 /* Set the argument using the appropriate position. */ 103 104 allargs[pos] = kwargs[kwpos]; 105 } 106 107 /* Fill the defaults. */ 108 109 for (pos = nargs; pos < max; pos++) 110 { 111 if (allargs[pos].value == 0) 112 allargs[pos] = __GETDEFAULT(callable.value, pos - nargs); 113 } 114 115 /* Call with the prepared arguments. */ 116 117 return (always_callable ? __load_via_object(callable.value, __pos___fn__) 118 : __check_and_load_via_object(callable.value, __pos___fn__, __code___fn__) 119 ).fn(allargs); 120 } 121 122 /* Error routines. */ 123 124 __attr __unbound_method(__attr args[]) 125 { 126 /* NOTE: Should raise an exception. */ 127 128 fprintf(stderr, "Unbound method called!\n"); 129 exit(1); 130 } 131 132 /* Generic operations depending on specific program details. */ 133 134 void __SETDEFAULT(__ref obj, int pos, __attr value) 135 { 136 __store_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos, value); 137 } 138 139 __attr __GETDEFAULT(__ref obj, int pos) 140 { 141 return __load_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos); 142 } 143 144 int __BOOL(__attr attr) 145 { 146 return attr.value == __builtins___boolean_True.value; 147 }