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 __attr __newfragment(__attr args[], unsigned int number) 28 { 29 /* Calculate the size of the fragment. */ 30 31 __fragment *data = (__fragment *) __ALLOCATE(1, __FRAGMENT_SIZE(number)); 32 __attr attr = {0, .seqvalue=data}; 33 unsigned int i, j; 34 35 /* Copy the given number of values, starting from the second element. */ 36 37 for (i = 1, j = 0; i <= number; i++, j++) 38 data->attrs[j] = args[i]; 39 40 data->size = number; 41 data->capacity = number; 42 return attr; 43 } 44 45 /* A helper for raising type errors within common operations. */ 46 47 void __raise_type_error() 48 { 49 __attr args[1]; 50 __attr exc = __TYPE_ERROR_INSTANTIATOR(args); 51 __Raise(exc); 52 } 53 54 /* A helper for raising memory errors within common operations. */ 55 56 void __raise_memory_error() 57 { 58 __attr args[1]; 59 __attr exc = __MEMORY_ERROR_INSTANTIATOR(args); 60 __Raise(exc); 61 } 62 63 /* Generic invocation operations. */ 64 65 /* Invoke the given callable, supplying keyword argument details in the given 66 codes and arguments arrays, indicating the number of arguments described. 67 The number of positional arguments is specified, and such arguments then 68 follow as conventional function arguments. Typically, at least one argument 69 is specified, starting with any context argument. 70 */ 71 72 __attr __invoke(__attr callable, int always_callable, 73 unsigned int nkwargs, __param kwcodes[], __attr kwargs[], 74 unsigned int nargs, __attr args[]) 75 { 76 /* Obtain the __args__ special member, referencing the parameter table. */ 77 78 __attr minparams = __check_and_load_via_object(callable.value, __pos___args__, __code___args__); 79 80 /* Refer to the table and minimum/maximum. */ 81 82 const __ptable *ptable = minparams.ptable; 83 const unsigned int min = minparams.min, max = ptable->size; 84 85 /* Reserve enough space for the arguments. */ 86 87 __attr allargs[max]; 88 89 /* Traverse the arguments. */ 90 91 unsigned int pos, kwpos; 92 93 /* Check the number of arguments. */ 94 95 if ((min > (nargs + nkwargs)) || ((nargs + nkwargs) > max)) 96 return __NULL; 97 98 /* Copy the arguments. */ 99 100 for (pos = 0; pos < nargs; pos++) 101 allargs[pos] = args[pos]; 102 103 /* Erase the remaining arguments. */ 104 105 for (pos = nargs; pos < max; pos++) 106 { 107 allargs[pos].value = 0; 108 } 109 110 /* Fill keyword arguments. */ 111 112 for (kwpos = 0; kwpos < nkwargs; kwpos++) 113 { 114 pos = __HASPARAM(ptable, kwcodes[kwpos].pos, kwcodes[kwpos].code); 115 116 /* Check the table entry against the supplied argument details. 117 Set the argument but only if it does not overwrite positional 118 arguments. */ 119 120 if ((pos == -1) || (pos < nargs)) 121 return __NULL; 122 123 /* Set the argument using the appropriate position. */ 124 125 allargs[pos] = kwargs[kwpos]; 126 } 127 128 /* Fill the defaults. */ 129 130 for (pos = nargs; pos < max; pos++) 131 { 132 if (allargs[pos].value == 0) 133 allargs[pos] = __GETDEFAULT(callable.value, pos - min); 134 } 135 136 /* Call with the prepared arguments. */ 137 138 return (always_callable ? __load_via_object(callable.value, __pos___fn__) 139 : __check_and_load_via_object(callable.value, __pos___fn__, __code___fn__) 140 ).fn(allargs); 141 } 142 143 /* Error routines. */ 144 145 __attr __unbound_method(__attr args[]) 146 { 147 __attr excargs[1]; 148 __attr exc = __new___builtins___core_UnboundMethodInvocation(excargs); 149 __Raise(exc); 150 return __builtins___none_None; /* superfluous */ 151 } 152 153 /* Generic operations depending on specific program details. */ 154 155 void __SETDEFAULT(__ref obj, int pos, __attr value) 156 { 157 __store_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos, value); 158 } 159 160 __attr __GETDEFAULT(__ref obj, int pos) 161 { 162 return __load_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos); 163 } 164 165 int __BOOL(__attr attr) 166 { 167 __attr args[2] = {{0, 0}, attr}; 168 169 /* Invoke the bool function with the object and test against True. */ 170 171 return __fn___builtins___boolean_bool(args).value == __builtins___boolean_True.value; 172 }