1 #include <stdlib.h> /* calloc, exit */ 2 #include <unistd.h> /* read, write */ 3 #include <math.h> /* ceil, log10, pow */ 4 #include <string.h> /* strcmp, strlen */ 5 #include <stdio.h> /* snprintf */ 6 #include "types.h" 7 #include "exceptions.h" 8 #include "ops.h" 9 #include "progconsts.h" 10 #include "progops.h" 11 #include "progtypes.h" 12 #include "main.h" 13 14 /* Utility functions. */ 15 16 inline __attr __new_int(int i) 17 { 18 /* Create a new integer and mutate the __data__ attribute. */ 19 __attr attr = __new(&__InstanceTable___builtins___int_int, &__builtins___int_int, sizeof(__obj___builtins___int_int)); 20 attr.value->attrs[__pos___data__].intvalue = i; 21 return attr; 22 } 23 24 inline __attr __new_str(char *s) 25 { 26 /* Create a new string and mutate the __data__ attribute. */ 27 __attr attr = __new(&__InstanceTable___builtins___str_string, &__builtins___str_string, sizeof(__obj___builtins___str_string)); 28 attr.value->attrs[__pos___data__].strvalue = s; 29 return attr; 30 } 31 32 /* Native functions. */ 33 34 __attr __fn_native__exit(__attr __args[]) 35 { 36 #define status (__args[1]) 37 38 exit(__load_via_object(status.value, __pos___data__).intvalue); 39 return __builtins___none_None; 40 #undef status 41 } 42 43 __attr __fn_native__get_argv(__attr __args[]) 44 { 45 #define status (__args[1]) 46 47 /* NOTE: To be written. */ 48 return __builtins___none_None; 49 #undef status 50 } 51 52 __attr __fn_native__get_path(__attr __args[]) 53 { 54 #define status (__args[1]) 55 56 /* NOTE: To be written. */ 57 return __builtins___none_None; 58 #undef status 59 } 60 61 __attr __fn_native__is(__attr __args[]) 62 { 63 #define x (__args[1]) 64 #define y (__args[2]) 65 66 return x.value == y.value ? __builtins___boolean_True : __builtins___boolean_False; 67 #undef x 68 #undef y 69 } 70 71 __attr __fn_native__is_not(__attr __args[]) 72 { 73 #define x (__args[1]) 74 #define y (__args[2]) 75 76 return x.value != y.value ? __builtins___boolean_True : __builtins___boolean_False; 77 #undef x 78 #undef y 79 } 80 81 __attr __fn_native__int_add(__attr __args[]) 82 { 83 #define self (__args[1]) 84 #define other (__args[2]) 85 /* self.__data__ and other.__data__ interpreted as int */ 86 int i = __load_via_object(self.value, __pos___data__).intvalue; 87 int j = __load_via_object(other.value, __pos___data__).intvalue; 88 89 /* Return the new integer. */ 90 /* NOTE: No overflow test applied. */ 91 return __new_int(i + j); 92 #undef self 93 #undef other 94 } 95 96 __attr __fn_native__int_sub(__attr __args[]) 97 { 98 #define self (__args[1]) 99 #define other (__args[2]) 100 /* self.__data__ and other.__data__ interpreted as int */ 101 int i = __load_via_object(self.value, __pos___data__).intvalue; 102 int j = __load_via_object(other.value, __pos___data__).intvalue; 103 104 /* Return the new integer. */ 105 /* NOTE: No overflow test applied. */ 106 return __new_int(i - j); 107 #undef self 108 #undef other 109 } 110 111 __attr __fn_native__int_mul(__attr __args[]) 112 { 113 #define self (__args[1]) 114 #define other (__args[2]) 115 /* self.__data__ and other.__data__ interpreted as int */ 116 int i = __load_via_object(self.value, __pos___data__).intvalue; 117 int j = __load_via_object(other.value, __pos___data__).intvalue; 118 119 /* Return the new integer. */ 120 /* NOTE: No overflow test applied. */ 121 return __new_int(i * j); 122 #undef self 123 #undef other 124 } 125 126 __attr __fn_native__int_div(__attr __args[]) 127 { 128 #define self (__args[1]) 129 #define other (__args[2]) 130 /* self.__data__ and other.__data__ interpreted as int */ 131 int i = __load_via_object(self.value, __pos___data__).intvalue; 132 int j = __load_via_object(other.value, __pos___data__).intvalue; 133 134 /* Return the new integer. */ 135 /* NOTE: No overflow test applied. */ 136 return __new_int(i / j); 137 #undef self 138 #undef other 139 } 140 141 __attr __fn_native__int_mod(__attr __args[]) 142 { 143 #define self (__args[1]) 144 #define other (__args[2]) 145 /* self.__data__ and other.__data__ interpreted as int */ 146 int i = __load_via_object(self.value, __pos___data__).intvalue; 147 int j = __load_via_object(other.value, __pos___data__).intvalue; 148 149 /* Return the new integer. */ 150 /* NOTE: No overflow test applied. */ 151 return __new_int(i % j); 152 #undef self 153 #undef other 154 } 155 156 __attr __fn_native__int_pow(__attr __args[]) 157 { 158 #define self (__args[1]) 159 #define other (__args[2]) 160 /* self.__data__ and other.__data__ interpreted as int */ 161 int i = __load_via_object(self.value, __pos___data__).intvalue; 162 int j = __load_via_object(other.value, __pos___data__).intvalue; 163 164 /* Return the new integer. */ 165 /* NOTE: No overflow test applied. */ 166 return __new_int((int) pow(i, j)); 167 #undef self 168 #undef other 169 } 170 171 __attr __fn_native__int_and(__attr __args[]) 172 { 173 #define self (__args[1]) 174 #define other (__args[2]) 175 /* self.__data__ and other.__data__ interpreted as int */ 176 int i = __load_via_object(self.value, __pos___data__).intvalue; 177 int j = __load_via_object(other.value, __pos___data__).intvalue; 178 179 /* Return the new integer. */ 180 /* NOTE: No overflow test applied. */ 181 return __new_int(i & j); 182 #undef self 183 #undef other 184 } 185 186 __attr __fn_native__int_or(__attr __args[]) 187 { 188 #define self (__args[1]) 189 #define other (__args[2]) 190 /* self.__data__ and other.__data__ interpreted as int */ 191 int i = __load_via_object(self.value, __pos___data__).intvalue; 192 int j = __load_via_object(other.value, __pos___data__).intvalue; 193 194 /* Return the new integer. */ 195 /* NOTE: No overflow test applied. */ 196 return __new_int(i | j); 197 #undef self 198 #undef other 199 } 200 201 __attr __fn_native__int_xor(__attr __args[]) 202 { 203 #define self (__args[1]) 204 #define other (__args[2]) 205 /* self.__data__ and other.__data__ interpreted as int */ 206 int i = __load_via_object(self.value, __pos___data__).intvalue; 207 int j = __load_via_object(other.value, __pos___data__).intvalue; 208 209 /* Return the new integer. */ 210 /* NOTE: No overflow test applied. */ 211 return __new_int(i ^ j); 212 #undef self 213 #undef other 214 } 215 216 __attr __fn_native__int_lt(__attr __args[]) 217 { 218 #define self (__args[1]) 219 #define other (__args[2]) 220 /* self.__data__ and other.__data__ interpreted as int */ 221 int i = __load_via_object(self.value, __pos___data__).intvalue; 222 int j = __load_via_object(other.value, __pos___data__).intvalue; 223 224 /* Return a boolean result. */ 225 return i < j ? __builtins___boolean_True : __builtins___boolean_False; 226 #undef self 227 #undef other 228 } 229 230 __attr __fn_native__int_gt(__attr __args[]) 231 { 232 #define self (__args[1]) 233 #define other (__args[2]) 234 /* self.__data__ and other.__data__ interpreted as int */ 235 int i = __load_via_object(self.value, __pos___data__).intvalue; 236 int j = __load_via_object(other.value, __pos___data__).intvalue; 237 238 /* Return a boolean result. */ 239 return i > j ? __builtins___boolean_True : __builtins___boolean_False; 240 #undef self 241 #undef other 242 } 243 244 __attr __fn_native__int_eq(__attr __args[]) 245 { 246 #define self (__args[1]) 247 #define other (__args[2]) 248 /* self.__data__ and other.__data__ interpreted as int */ 249 int i = __load_via_object(self.value, __pos___data__).intvalue; 250 int j = __load_via_object(other.value, __pos___data__).intvalue; 251 252 /* Return a boolean result. */ 253 return i == j ? __builtins___boolean_True : __builtins___boolean_False; 254 #undef self 255 #undef other 256 } 257 258 __attr __fn_native__int_ne(__attr __args[]) 259 { 260 #define self (__args[1]) 261 #define other (__args[2]) 262 /* self.__data__ and other.__data__ interpreted as int */ 263 int i = __load_via_object(self.value, __pos___data__).intvalue; 264 int j = __load_via_object(other.value, __pos___data__).intvalue; 265 266 /* Return a boolean result. */ 267 return i != j ? __builtins___boolean_True : __builtins___boolean_False; 268 #undef self 269 #undef other 270 } 271 272 __attr __fn_native__int_str(__attr __args[]) 273 { 274 #define self (__args[1]) 275 /* self.__data__ interpreted as int */ 276 int i = __load_via_object(self.value, __pos___data__).intvalue; 277 int n = i != 0 ? (int) ceil(log10(i+1)) + 1 : 2; 278 char *s = calloc(n, sizeof(char)); 279 280 if (i < 0) n++; 281 snprintf(s, n, "%d", i); 282 283 /* Return a new string. */ 284 return __new_str(s); 285 #undef self 286 #undef other 287 } 288 289 __attr __fn_native__str_add(__attr __args[]) 290 { 291 #define self (__args[1]) 292 #define other (__args[2]) 293 /* self.__data__, other.__data__ interpreted as string */ 294 char *s = __load_via_object(self.value, __pos___data__).strvalue; 295 char *o = __load_via_object(other.value, __pos___data__).strvalue; 296 int n = strlen(s) + strlen(o) + 1; 297 char *r = calloc(n, sizeof(char)); 298 299 strncpy(r, s, n); 300 strncpy(r + strlen(s), o, n - strlen(s)); 301 302 /* Return a new string. */ 303 return __new_str(r); 304 #undef self 305 #undef other 306 } 307 308 __attr __fn_native__str_lt(__attr __args[]) 309 { 310 #define self (__args[1]) 311 #define other (__args[2]) 312 /* self.__data__, other.__data__ interpreted as string */ 313 char *s = __load_via_object(self.value, __pos___data__).strvalue; 314 char *o = __load_via_object(other.value, __pos___data__).strvalue; 315 316 /* NOTE: Using simple byte-level string operations. */ 317 return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False; 318 #undef self 319 #undef other 320 } 321 322 __attr __fn_native__str_gt(__attr __args[]) 323 { 324 #define self (__args[1]) 325 #define other (__args[2]) 326 /* self.__data__, other.__data__ interpreted as string */ 327 char *s = __load_via_object(self.value, __pos___data__).strvalue; 328 char *o = __load_via_object(other.value, __pos___data__).strvalue; 329 330 /* NOTE: Using simple byte-level string operations. */ 331 return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False; 332 #undef self 333 #undef other 334 } 335 336 __attr __fn_native__str_eq(__attr __args[]) 337 { 338 #define self (__args[1]) 339 #define other (__args[2]) 340 /* self.__data__, other.__data__ interpreted as string */ 341 char *s = __load_via_object(self.value, __pos___data__).strvalue; 342 char *o = __load_via_object(other.value, __pos___data__).strvalue; 343 344 /* NOTE: Using simple byte-level string operations. */ 345 return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False; 346 #undef self 347 #undef other 348 } 349 350 __attr __fn_native__str_len(__attr __args[]) 351 { 352 #define self (__args[1]) 353 /* self.__data__ interpreted as string */ 354 char *s = __load_via_object(self.value, __pos___data__).strvalue; 355 356 /* Return the new integer. */ 357 return __new_int(strlen(s)); 358 #undef self 359 } 360 361 __attr __fn_native__str_nonempty(__attr __args[]) 362 { 363 #define self (__args[1]) 364 /* self.__data__ interpreted as string */ 365 char *s = __load_via_object(self.value, __pos___data__).strvalue; 366 367 return strlen(s) ? __builtins___boolean_True : __builtins___boolean_False; 368 #undef self 369 } 370 371 __attr __fn_native__list_init(__attr __args[]) 372 { 373 #define size (__args[1]) 374 /* size.__data__ interpreted as fragment */ 375 __fragment *data = calloc(__load_via_object(size.value, __pos___data__).intvalue, sizeof(__attr)); 376 __attr attr = {0, .data=data}; 377 378 return attr; 379 #undef size 380 } 381 382 __attr __fn_native__list_len(__attr __args[]) 383 { 384 #define self (__args[1]) 385 /* self.__data__ interpreted as fragment */ 386 unsigned int size = __load_via_object(self.value, __pos___data__).data->size; 387 388 /* Return the new integer. */ 389 return __new_int(size); 390 #undef self 391 } 392 393 __attr __fn_native__list_nonempty(__attr __args[]) 394 { 395 #define self (__args[1]) 396 397 return __load_via_object(self.value, __pos___data__).data->size ? __builtins___boolean_True : __builtins___boolean_False; 398 #undef self 399 } 400 401 __attr __fn_native__list_element(__attr __args[]) 402 { 403 #define self (__args[1]) 404 #define index (__args[2]) 405 /* self.__data__ interpreted as fragment */ 406 __attr *elements = __load_via_object(self.value, __pos___data__).data->attrs; 407 /* index.__data__ interpreted as int */ 408 int i = __load_via_object(index.value, __pos___data__).intvalue; 409 410 return elements[i]; 411 #undef self 412 #undef index 413 } 414 415 __attr __fn_native__list_to_tuple(__attr __args[]) 416 { 417 #define l (__args[1]) 418 419 /* NOTE: To be written. */ 420 return __builtins___none_None; 421 #undef l 422 } 423 424 __attr __fn_native__tuple_init(__attr __args[]) 425 { 426 #define size (__args[1]) 427 /* size.__data__ interpreted as fragment */ 428 __fragment *data = calloc(__load_via_object(size.value, __pos___data__).intvalue, sizeof(__attr)); 429 __attr attr = {0, .data=data}; 430 431 return attr; 432 #undef size 433 } 434 435 __attr __fn_native__tuple_len(__attr __args[]) 436 { 437 #define self (__args[1]) 438 /* self.__data__ interpreted as fragment */ 439 unsigned int size = __load_via_object(self.value, __pos___data__).data->size; 440 441 /* Return the new integer. */ 442 return __new_int(size); 443 #undef self 444 } 445 446 __attr __fn_native__tuple_element(__attr __args[]) 447 { 448 #define self (__args[1]) 449 #define index (__args[2]) 450 /* self.__data__ interpreted as fragment */ 451 __attr *elements = __load_via_object(self.value, __pos___data__).data->attrs; 452 /* index.__data__ interpreted as int */ 453 int i = __load_via_object(index.value, __pos___data__).intvalue; 454 455 return elements[i]; 456 #undef self 457 #undef index 458 } 459 460 __attr __fn_native__isinstance(__attr __args[]) 461 { 462 #define obj (__args[1]) 463 #define cls (__args[2]) 464 465 if (__is_instance(obj.value) && __HASATTR(__get_class(obj.value), __TYPEPOS(cls.value), __TYPECODE(cls.value))) 466 return __builtins___boolean_True; 467 else 468 return __builtins___boolean_False; 469 #undef obj 470 #undef cls 471 } 472 473 __attr __fn_native__read(__attr __args[]) 474 { 475 #define fd (__args[1]) 476 #define n (__args[2]) 477 478 /* NOTE: To be written. */ 479 return __builtins___none_None; 480 #undef fd 481 #undef n 482 } 483 484 __attr __fn_native__write(__attr __args[]) 485 { 486 #define fd (__args[1]) 487 #define str (__args[2]) 488 /* fd.__data__ interpreted as int */ 489 int i = __load_via_object(fd.value, __pos___data__).intvalue; 490 /* str.__data__ interpreted as string */ 491 char *s = __load_via_object(str.value, __pos___data__).strvalue; 492 493 write(i, s, sizeof(char) * strlen(s)); 494 return __builtins___none_None; 495 #undef fd 496 #undef str 497 } 498 499 /* Module initialisation. */ 500 501 void __main_native() 502 { 503 }