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 void __newdata_mapping(__attr args[], unsigned int number) 62 { 63 __attr dict = args[0]; 64 __attr callargs[2]; 65 66 /* Create a temporary list using the arguments. */ 67 68 __newliteral___builtins___list_list(args, number); 69 70 /* Call __init__ with the dict object and list argument. */ 71 72 callargs[0] = dict; 73 callargs[1] = args[0]; 74 75 __fn___builtins___dict_dict___init__(callargs); 76 args[0] = dict; 77 } 78 #endif /* __HAVE___builtins___dict_dict */ 79 80 /* Helpers for raising errors within common operations. */ 81 82 #ifdef __HAVE___builtins___exception_io_EOFError 83 void __raise_eof_error() 84 { 85 __attr args[1]; 86 __attr exc = __new___builtins___exception_io_EOFError(args); 87 __Raise(exc); 88 } 89 #endif /* __HAVE___builtins___exception_io_EOFError */ 90 91 #ifdef __HAVE___builtins___exception_io_IOError 92 void __raise_io_error(__attr value) 93 { 94 __attr args[2] = {{0, 0}, value}; 95 __attr exc = __new___builtins___exception_io_IOError(args); 96 __Raise(exc); 97 } 98 #endif /* __HAVE___builtins___exception_io_IOError */ 99 100 void __raise_memory_error() 101 { 102 __attr args[1]; 103 __attr exc = __new___builtins___core_MemoryError(args); 104 __Raise(exc); 105 } 106 107 void __raise_overflow_error() 108 { 109 __attr args[1]; 110 __attr exc = __new___builtins___core_OverflowError(args); 111 __Raise(exc); 112 } 113 114 void __raise_type_error() 115 { 116 __attr args[1]; 117 __attr exc = __new___builtins___core_TypeError(args); 118 __Raise(exc); 119 } 120 121 void __raise_zero_division_error() 122 { 123 __attr args[1]; 124 __attr exc = __new___builtins___core_ZeroDivisionError(args); 125 __Raise(exc); 126 } 127 128 /* Helper for raising exception instances. */ 129 130 __attr __ensure_instance(__attr arg) 131 { 132 /* Reserve space for the instance. */ 133 134 __attr args[1]; 135 136 /* Return instances as provided. */ 137 138 if (__is_instance(arg.value)) 139 return arg; 140 141 /* Invoke non-instances to produce instances. */ 142 143 else 144 return __invoke(arg, 0, 0, 0, 0, 1, args); 145 } 146 147 /* Generic invocation operations. */ 148 149 /* Invoke the given callable, supplying keyword argument details in the given 150 codes and arguments arrays, indicating the number of arguments described. 151 The number of positional arguments is specified, and such arguments then 152 follow as conventional function arguments. Typically, at least one argument 153 is specified, starting with any context argument. 154 */ 155 156 __attr __invoke(__attr callable, int always_callable, 157 unsigned int nkwargs, __param kwcodes[], __attr kwargs[], 158 unsigned int nargs, __attr args[]) 159 { 160 /* Obtain the __args__ special member, referencing the parameter table. */ 161 162 __attr minparams = __check_and_load_via_object(callable.value, __pos___args__, __code___args__); 163 164 /* Refer to the table and minimum/maximum. */ 165 166 const __ptable *ptable = minparams.ptable; 167 const unsigned int min = minparams.min, max = ptable->size; 168 169 /* Reserve enough space for the arguments. */ 170 171 __attr allargs[max]; 172 173 /* Traverse the arguments. */ 174 175 unsigned int pos, kwpos; 176 177 /* Check the number of arguments. */ 178 179 if ((min > (nargs + nkwargs)) || ((nargs + nkwargs) > max)) 180 return __NULL; 181 182 /* Copy the arguments. */ 183 184 for (pos = 0; pos < nargs; pos++) 185 allargs[pos] = args[pos]; 186 187 /* Erase the remaining arguments. */ 188 189 for (pos = nargs; pos < max; pos++) 190 { 191 allargs[pos].value = 0; 192 } 193 194 /* Fill keyword arguments. */ 195 196 for (kwpos = 0; kwpos < nkwargs; kwpos++) 197 { 198 pos = __HASPARAM(ptable, kwcodes[kwpos].pos, kwcodes[kwpos].code); 199 200 /* Check the table entry against the supplied argument details. 201 Set the argument but only if it does not overwrite positional 202 arguments. */ 203 204 if ((pos == -1) || (pos < nargs)) 205 return __NULL; 206 207 /* Set the argument using the appropriate position. */ 208 209 allargs[pos] = kwargs[kwpos]; 210 } 211 212 /* Fill the defaults. */ 213 214 for (pos = nargs; pos < max; pos++) 215 { 216 if (allargs[pos].value == 0) 217 allargs[pos] = __GETDEFAULT(callable.value, pos - min); 218 } 219 220 /* Call with the prepared arguments. */ 221 222 return (always_callable ? __load_via_object(callable.value, __pos___fn__) 223 : __check_and_load_via_object(callable.value, __pos___fn__, __code___fn__) 224 ).fn(allargs); 225 } 226 227 /* Error routines. */ 228 229 __attr __unbound_method(__attr args[]) 230 { 231 __attr excargs[1]; 232 __attr exc = __new___builtins___core_UnboundMethodInvocation(excargs); 233 __Raise(exc); 234 return __builtins___none_None; /* superfluous */ 235 } 236 237 /* Generic operations depending on specific program details. */ 238 239 void __SETDEFAULT(__ref obj, int pos, __attr value) 240 { 241 __store_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos, value); 242 } 243 244 __attr __GETDEFAULT(__ref obj, int pos) 245 { 246 return __load_via_object(obj, __FUNCTION_INSTANCE_SIZE + pos); 247 } 248 249 int __BOOL(__attr attr) 250 { 251 __attr args[2] = {{0, 0}, attr}; 252 253 /* Invoke the bool function with the object and test against True. */ 254 255 return __fn___builtins___boolean_bool(args).value == __builtins___boolean_True.value; 256 }