1 #include <stdlib.h> /* abs, exit */ 2 #include <unistd.h> /* read, write */ 3 #include <math.h> /* ceil, log10, pow */ 4 #include <string.h> /* strcmp, strncpy, 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 static __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 static __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 static __attr __new_list(__fragment *f) 33 { 34 /* Create a new list and mutate the __data__ attribute. */ 35 __attr attr = __new(&__InstanceTable___builtins___list_list, &__builtins___list_list, sizeof(__obj___builtins___list_list)); 36 attr.value->attrs[__pos___data__].seqvalue = f; 37 return attr; 38 } 39 40 static __fragment *__fragment_append(__fragment *data, __attr * const value) 41 { 42 __fragment *newdata = data; 43 unsigned int size = data->size, capacity = data->capacity; 44 unsigned int n; 45 46 /* Re-allocate the fragment if the capacity has been reached. */ 47 if (size >= capacity) 48 { 49 /* NOTE: Consider various restrictions on capacity increases. */ 50 n = capacity ? capacity * 2 : 1; 51 newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n)); 52 newdata->capacity = n; 53 } 54 55 /* Insert the new element and increment the list size. */ 56 newdata->attrs[size] = *value; 57 newdata->size = size + 1; 58 59 return newdata; 60 } 61 62 /* Native functions. */ 63 64 __attr __fn_native__exit(__attr __args[]) 65 { 66 __attr * const status = &__args[1]; 67 68 exit(__load_via_object(status->value, __pos___data__).intvalue); 69 return __builtins___none_None; 70 } 71 72 __attr __fn_native__get_argv(__attr __args[]) 73 { 74 __attr * const status = &__args[1]; 75 76 /* NOTE: To be written. */ 77 return __builtins___none_None; 78 } 79 80 __attr __fn_native__get_path(__attr __args[]) 81 { 82 __attr * const status = &__args[1]; 83 84 /* NOTE: To be written. */ 85 return __builtins___none_None; 86 } 87 88 __attr __fn_native__is(__attr __args[]) 89 { 90 __attr * const x = &__args[1]; 91 __attr * const y = &__args[2]; 92 93 return x->value == y->value ? __builtins___boolean_True : __builtins___boolean_False; 94 } 95 96 __attr __fn_native__is_not(__attr __args[]) 97 { 98 __attr * const x = &__args[1]; 99 __attr * const y = &__args[2]; 100 101 return x->value != y->value ? __builtins___boolean_True : __builtins___boolean_False; 102 } 103 104 __attr __fn_native__int_add(__attr __args[]) 105 { 106 __attr * const _data = &__args[1]; 107 __attr * const other = &__args[2]; 108 /* _data and other interpreted as int */ 109 int i = _data->intvalue; 110 int j = other->intvalue; 111 112 /* Return the new integer. */ 113 /* NOTE: No overflow test applied. */ 114 return __new_int(i + j); 115 } 116 117 __attr __fn_native__int_sub(__attr __args[]) 118 { 119 __attr * const _data = &__args[1]; 120 __attr * const other = &__args[2]; 121 /* _data and other interpreted as int */ 122 int i = _data->intvalue; 123 int j = other->intvalue; 124 125 /* Return the new integer. */ 126 /* NOTE: No overflow test applied. */ 127 return __new_int(i - j); 128 } 129 130 __attr __fn_native__int_mul(__attr __args[]) 131 { 132 __attr * const _data = &__args[1]; 133 __attr * const other = &__args[2]; 134 /* _data and other interpreted as int */ 135 int i = _data->intvalue; 136 int j = other->intvalue; 137 138 /* Return the new integer. */ 139 /* NOTE: No overflow test applied. */ 140 return __new_int(i * j); 141 } 142 143 __attr __fn_native__int_div(__attr __args[]) 144 { 145 __attr * const _data = &__args[1]; 146 __attr * const other = &__args[2]; 147 /* _data and other interpreted as int */ 148 int i = _data->intvalue; 149 int j = other->intvalue; 150 151 /* Return the new integer. */ 152 /* NOTE: No overflow test applied. */ 153 return __new_int(i / j); 154 } 155 156 __attr __fn_native__int_mod(__attr __args[]) 157 { 158 __attr * const _data = &__args[1]; 159 __attr * const other = &__args[2]; 160 /* _data and other interpreted as int */ 161 int i = _data->intvalue; 162 int j = other->intvalue; 163 164 /* Return the new integer. */ 165 /* NOTE: No overflow test applied. */ 166 return __new_int(i % j); 167 } 168 169 __attr __fn_native__int_neg(__attr __args[]) 170 { 171 __attr * const _data = &__args[1]; 172 /* _data interpreted as int */ 173 int i = _data->intvalue; 174 175 /* Return the new integer. */ 176 return __new_int(-i); 177 } 178 179 __attr __fn_native__int_pow(__attr __args[]) 180 { 181 __attr * const _data = &__args[1]; 182 __attr * const other = &__args[2]; 183 /* _data and other interpreted as int */ 184 int i = _data->intvalue; 185 int j = other->intvalue; 186 187 /* Return the new integer. */ 188 /* NOTE: No overflow test applied. */ 189 return __new_int((int) pow(i, j)); 190 } 191 192 __attr __fn_native__int_and(__attr __args[]) 193 { 194 __attr * const _data = &__args[1]; 195 __attr * const other = &__args[2]; 196 /* _data and other interpreted as int */ 197 int i = _data->intvalue; 198 int j = other->intvalue; 199 200 /* Return the new integer. */ 201 /* NOTE: No overflow test applied. */ 202 return __new_int(i & j); 203 } 204 205 __attr __fn_native__int_or(__attr __args[]) 206 { 207 __attr * const _data = &__args[1]; 208 __attr * const other = &__args[2]; 209 /* _data and other interpreted as int */ 210 int i = _data->intvalue; 211 int j = other->intvalue; 212 213 /* Return the new integer. */ 214 /* NOTE: No overflow test applied. */ 215 return __new_int(i | j); 216 } 217 218 __attr __fn_native__int_xor(__attr __args[]) 219 { 220 __attr * const _data = &__args[1]; 221 __attr * const other = &__args[2]; 222 /* _data and other interpreted as int */ 223 int i = _data->intvalue; 224 int j = other->intvalue; 225 226 /* Return the new integer. */ 227 /* NOTE: No overflow test applied. */ 228 return __new_int(i ^ j); 229 } 230 231 __attr __fn_native__int_lt(__attr __args[]) 232 { 233 __attr * const _data = &__args[1]; 234 __attr * const other = &__args[2]; 235 /* _data and other interpreted as int */ 236 int i = _data->intvalue; 237 int j = other->intvalue; 238 239 /* Return a boolean result. */ 240 return i < j ? __builtins___boolean_True : __builtins___boolean_False; 241 } 242 243 __attr __fn_native__int_gt(__attr __args[]) 244 { 245 __attr * const _data = &__args[1]; 246 __attr * const other = &__args[2]; 247 /* _data and other interpreted as int */ 248 int i = _data->intvalue; 249 int j = other->intvalue; 250 251 /* Return a boolean result. */ 252 return i > j ? __builtins___boolean_True : __builtins___boolean_False; 253 } 254 255 __attr __fn_native__int_eq(__attr __args[]) 256 { 257 __attr * const _data = &__args[1]; 258 __attr * const other = &__args[2]; 259 /* _data and other interpreted as int */ 260 int i = _data->intvalue; 261 int j = other->intvalue; 262 263 /* Return a boolean result. */ 264 return i == j ? __builtins___boolean_True : __builtins___boolean_False; 265 } 266 267 __attr __fn_native__int_ne(__attr __args[]) 268 { 269 __attr * const _data = &__args[1]; 270 __attr * const other = &__args[2]; 271 /* _data and other interpreted as int */ 272 int i = _data->intvalue; 273 int j = other->intvalue; 274 275 /* Return a boolean result. */ 276 return i != j ? __builtins___boolean_True : __builtins___boolean_False; 277 } 278 279 __attr __fn_native__int_str(__attr __args[]) 280 { 281 __attr * const _data = &__args[1]; 282 /* _data interpreted as int */ 283 int i = _data->intvalue; 284 int n = i != 0 ? (int) ceil(log10(abs(i)+1)) + 1 : 2; 285 char *s = (char *) __ALLOCATE(n, sizeof(char)); 286 287 if (i < 0) n++; 288 snprintf(s, n, "%d", i); 289 290 /* Return a new string. */ 291 return __new_str(s); 292 } 293 294 __attr __fn_native__str_add(__attr __args[]) 295 { 296 __attr * const _data = &__args[1]; 297 __attr * const other = &__args[2]; 298 /* _data, other interpreted as string */ 299 char *s = _data->strvalue; 300 char *o = other->strvalue; 301 int n = strlen(s) + strlen(o) + 1; 302 char *r = (char *) __ALLOCATE(n, sizeof(char)); 303 304 strncpy(r, s, n); 305 strncpy(r + strlen(s), o, n - strlen(s)); /* should null terminate */ 306 307 /* Return a new string. */ 308 return __new_str(r); 309 } 310 311 __attr __fn_native__str_lt(__attr __args[]) 312 { 313 __attr * const _data = &__args[1]; 314 __attr * const other = &__args[2]; 315 /* _data, other interpreted as string */ 316 char *s = _data->strvalue; 317 char *o = other->strvalue; 318 319 /* NOTE: Using simple byte-level string operations. */ 320 return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False; 321 } 322 323 __attr __fn_native__str_gt(__attr __args[]) 324 { 325 __attr * const _data = &__args[1]; 326 __attr * const other = &__args[2]; 327 /* _data, other interpreted as string */ 328 char *s = _data->strvalue; 329 char *o = other->strvalue; 330 331 /* NOTE: Using simple byte-level string operations. */ 332 return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False; 333 } 334 335 __attr __fn_native__str_eq(__attr __args[]) 336 { 337 __attr * const _data = &__args[1]; 338 __attr * const other = &__args[2]; 339 /* _data, other interpreted as string */ 340 char *s = _data->strvalue; 341 char *o = other->strvalue; 342 343 /* NOTE: Using simple byte-level string operations. */ 344 return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False; 345 } 346 347 __attr __fn_native__str_len(__attr __args[]) 348 { 349 __attr * const _data = &__args[1]; 350 /* _data interpreted as string */ 351 char *s = _data->strvalue; 352 353 /* Return the new integer. */ 354 return __new_int(strlen(s)); 355 } 356 357 __attr __fn_native__str_nonempty(__attr __args[]) 358 { 359 __attr * const _data = &__args[1]; 360 /* _data interpreted as string */ 361 char *s = _data->strvalue; 362 363 return strlen(s) ? __builtins___boolean_True : __builtins___boolean_False; 364 } 365 366 __attr __fn_native__str_ord(__attr __args[]) 367 { 368 __attr * const _data = &__args[1]; 369 /* _data interpreted as string */ 370 char *s = _data->strvalue; 371 372 return __new_int((unsigned int) s[0]); 373 } 374 375 __attr __fn_native__str_substr(__attr __args[]) 376 { 377 __attr * const _data = &__args[1]; 378 __attr * const start = &__args[2]; 379 __attr * const size = &__args[3]; 380 /* _data interpreted as string */ 381 char *s = _data->strvalue, *sub; 382 /* start.__data__ interpreted as int */ 383 int i = __load_via_object(start->value, __pos___data__).intvalue; 384 /* size.__data__ interpreted as int */ 385 int l = __load_via_object(size->value, __pos___data__).intvalue; 386 387 /* Reserve space for a new string. */ 388 sub = (char *) __ALLOCATE(l + 1, sizeof(char)); 389 strncpy(sub, s + i, l); /* does not null terminate but final byte should be zero */ 390 return __new_str(sub); 391 } 392 393 __attr __fn_native__list_init(__attr __args[]) 394 { 395 __attr * const size = &__args[1]; 396 /* size.__data__ interpreted as int */ 397 unsigned int n = __load_via_object(size->value, __pos___data__).intvalue; 398 __attr attr = {0, .seqvalue=__new_fragment(n)}; 399 400 /* Return the __data__ attribute. */ 401 return attr; 402 } 403 404 __attr __fn_native__list_setsize(__attr __args[]) 405 { 406 __attr * const _data = &__args[1]; 407 __attr * const size = &__args[2]; 408 /* _data interpreted as list */ 409 __fragment *data = _data->seqvalue; 410 /* size.__data__ interpreted as int */ 411 unsigned int n = __load_via_object(size->value, __pos___data__).intvalue; 412 413 data->size = n; 414 return __builtins___none_None; 415 } 416 417 __attr __fn_native__list_append(__attr __args[]) 418 { 419 __attr * const self = &__args[1]; 420 __attr * const value = &__args[2]; 421 /* self.__data__ interpreted as list */ 422 __fragment *data = __load_via_object(self->value, __pos___data__).seqvalue; 423 __fragment *newdata = __fragment_append(data, value); 424 425 /* Replace the __data__ attribute if appropriate. */ 426 if (newdata != data) 427 __store_via_object(self->value, __pos___data__, ((__attr) {0, .seqvalue=newdata})); 428 return __builtins___none_None; 429 } 430 431 __attr __fn_native__list_concat(__attr __args[]) 432 { 433 __attr * const self = &__args[1]; 434 __attr * const other = &__args[2]; 435 /* self.__data__, other interpreted as list */ 436 __fragment *data = __load_via_object(self->value, __pos___data__).seqvalue; 437 __fragment *other_data = other->seqvalue; 438 __fragment *newdata = data; 439 unsigned int size = data->size, capacity = data->capacity; 440 unsigned int other_size = other_data->size; 441 unsigned int i, j, n; 442 443 /* Re-allocate the fragment if the capacity has been reached. */ 444 if (size + other_size >= capacity) 445 { 446 n = size + other_size; 447 newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n)); 448 newdata->capacity = n; 449 } 450 451 /* Copy the elements from the other list and increment the list size. */ 452 for (i = size, j = 0; j < other_size; i++, j++) 453 newdata->attrs[i] = other_data->attrs[j]; 454 newdata->size = n; 455 456 /* Replace the __data__ attribute if appropriate. */ 457 if (newdata != data) 458 __store_via_object(self->value, __pos___data__, ((__attr) {0, .seqvalue=newdata})); 459 return __builtins___none_None; 460 } 461 462 __attr __fn_native__list_len(__attr __args[]) 463 { 464 __attr * const _data = &__args[1]; 465 /* _data interpreted as fragment */ 466 unsigned int size = _data->seqvalue->size; 467 468 /* Return the new integer. */ 469 return __new_int(size); 470 } 471 472 __attr __fn_native__list_nonempty(__attr __args[]) 473 { 474 __attr * const _data = &__args[1]; 475 476 return _data->seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False; 477 } 478 479 __attr __fn_native__list_element(__attr __args[]) 480 { 481 __attr * const _data = &__args[1]; 482 __attr * const index = &__args[2]; 483 /* _data interpreted as fragment */ 484 __attr *elements = _data->seqvalue->attrs; 485 /* index.__data__ interpreted as int */ 486 int i = __load_via_object(index->value, __pos___data__).intvalue; 487 488 return elements[i]; 489 } 490 491 __attr __fn_native__list_setelement(__attr __args[]) 492 { 493 __attr * const _data = &__args[1]; 494 __attr * const index = &__args[2]; 495 __attr * const value = &__args[3]; 496 /* _data interpreted as fragment */ 497 __attr *elements = _data->seqvalue->attrs; 498 /* index.__data__ interpreted as int */ 499 int i = __load_via_object(index->value, __pos___data__).intvalue; 500 501 /* Set the element. */ 502 elements[i] = *value; 503 return __builtins___none_None; 504 } 505 506 __attr __fn_native__dict_init(__attr __args[]) 507 { 508 __attr * const size = &__args[1]; 509 /* size.__data__ interpreted as int */ 510 unsigned int n = __load_via_object(size->value, __pos___data__).intvalue; 511 __mapping *data = __new_mapping(n); 512 __attr attr = {0, .mapvalue=data}; 513 514 /* Return the __data__ attribute. */ 515 return attr; 516 } 517 518 __attr __fn_native__dict_items(__attr __args[]) 519 { 520 __attr * const _data = &__args[1]; 521 /* _data interpreted as dict */ 522 __mapping *data = _data->mapvalue; 523 524 return __new_int(data->size); 525 } 526 527 __attr __fn_native__dict_buckets(__attr __args[]) 528 { 529 __attr * const _data = &__args[1]; 530 /* _data interpreted as dict */ 531 __mapping *data = _data->mapvalue; 532 533 return __new_int(data->capacity); 534 } 535 536 __attr __fn_native__dict_bucketsize(__attr __args[]) 537 { 538 __attr * const _data = &__args[1]; 539 __attr * const index = &__args[2]; 540 /* _data interpreted as dict */ 541 __mapping *data = _data->mapvalue; 542 /* index.__data__ interpreted as int */ 543 int k = __load_via_object(index->value, __pos___data__).intvalue % data->capacity; 544 545 /* Return size of bucket k. */ 546 return __new_int(data->keys[k]->size); 547 } 548 549 __attr __fn_native__dict_keys(__attr __args[]) 550 { 551 __attr * const _data = &__args[1]; 552 /* _data interpreted as dict */ 553 __mapping *data = _data->mapvalue; 554 unsigned int k, i, j, size = 0; 555 __fragment *f; 556 557 /* Count the number of keys. */ 558 for (k = 0; k < data->capacity; k++) 559 size += data->keys[k]->size; 560 561 /* Create a fragment for the keys. */ 562 f = __new_fragment(size); 563 564 /* Populate the fragment with the keys. */ 565 for (j = 0, k = 0; k < data->capacity; k++) 566 for (i = 0; i < data->keys[k]->size; i++, j++) 567 f->attrs[j] = data->keys[k]->attrs[i]; 568 f->size = size; 569 570 /* Return a list. */ 571 return __new_list(f); 572 } 573 574 __attr __fn_native__dict_values(__attr __args[]) 575 { 576 __attr * const _data = &__args[1]; 577 /* _data interpreted as dict */ 578 __mapping *data = _data->mapvalue; 579 unsigned int k, i, j, size = 0; 580 __fragment *f; 581 582 /* Count the number of values. */ 583 for (k = 0; k < data->capacity; k++) 584 size += data->values[k]->size; 585 586 /* Create a fragment for the values. */ 587 f = __new_fragment(size); 588 589 /* Populate the fragment with the values. */ 590 for (j = 0, k = 0; k < data->capacity; k++) 591 for (i = 0; i < data->values[k]->size; i++, j++) 592 f->attrs[j] = data->values[k]->attrs[i]; 593 f->size = size; 594 595 /* Return a list. */ 596 return __new_list(f); 597 } 598 599 __attr __fn_native__dict_key(__attr __args[]) 600 { 601 __attr * const _data = &__args[1]; 602 __attr * const index = &__args[2]; 603 __attr * const element = &__args[3]; 604 /* _data interpreted as dict */ 605 __mapping *data = _data->mapvalue; 606 /* index.__data__ interpreted as int */ 607 int k = __load_via_object(index->value, __pos___data__).intvalue % data->capacity; 608 /* element.__data__ interpreted as int */ 609 int i = __load_via_object(element->value, __pos___data__).intvalue; 610 611 /* Return key from bucket k, element i. */ 612 return data->keys[k]->attrs[i]; 613 } 614 615 __attr __fn_native__dict_value(__attr __args[]) 616 { 617 __attr * const _data = &__args[1]; 618 __attr * const index = &__args[2]; 619 __attr * const element = &__args[3]; 620 /* _data interpreted as dict */ 621 __mapping *data = _data->mapvalue; 622 /* index.__data__ interpreted as int */ 623 int k = __load_via_object(index->value, __pos___data__).intvalue % data->capacity; 624 /* element.__data__ interpreted as int */ 625 int i = __load_via_object(element->value, __pos___data__).intvalue; 626 627 /* Return value from bucket k, element i. */ 628 return data->values[k]->attrs[i]; 629 } 630 631 __attr __fn_native__dict_additem(__attr __args[]) 632 { 633 __attr * const _data = &__args[1]; 634 __attr * const index = &__args[2]; 635 __attr * const key = &__args[3]; 636 __attr * const value = &__args[4]; 637 /* _data interpreted as dict */ 638 __mapping *data = _data->mapvalue; 639 /* index.__data__ interpreted as int */ 640 int k = __load_via_object(index->value, __pos___data__).intvalue % data->capacity; 641 unsigned int size = data->size; 642 __fragment *keys = data->keys[k], *newkeys; 643 __fragment *values = data->values[k], *newvalues; 644 645 /* Append the item. */ 646 newkeys = __fragment_append(keys, key); 647 newvalues = __fragment_append(values, value); 648 649 /* Replace the fragments if appropriate. */ 650 if (newkeys != keys) 651 data->keys[k] = newkeys; 652 if (newvalues != values) 653 data->values[k] = newvalues; 654 655 data->size = size + 1; 656 return __builtins___none_None; 657 } 658 659 __attr __fn_native__dict_setitem(__attr __args[]) 660 { 661 __attr * const _data = &__args[1]; 662 __attr * const index = &__args[2]; 663 __attr * const element = &__args[3]; 664 __attr * const key = &__args[4]; 665 __attr * const value = &__args[5]; 666 /* _data interpreted as dict */ 667 __mapping *data = _data->mapvalue; 668 /* index.__data__ interpreted as int */ 669 int k = __load_via_object(index->value, __pos___data__).intvalue % data->capacity; 670 /* element.__data__ interpreted as int */ 671 int i = __load_via_object(element->value, __pos___data__).intvalue; 672 673 /* Replace the item. */ 674 data->keys[k]->attrs[i] = *key; 675 data->values[k]->attrs[i] = *value; 676 677 return __builtins___none_None; 678 } 679 680 __attr __fn_native__buffer_str(__attr __args[]) 681 { 682 __attr * const _data = &__args[1]; 683 /* _data interpreted as buffer */ 684 __fragment *data = _data->seqvalue; 685 unsigned int size = 0, i, j, n; 686 char *s, *o; 687 688 /* Calculate the size of the string. */ 689 for (i = 0; i < data->size; i++) 690 size += strlen(__load_via_object(data->attrs[i].value, __pos___data__).strvalue); 691 692 /* Reserve space for a new string. */ 693 s = (char *) __ALLOCATE(size + 1, sizeof(char)); 694 695 /* Build a single string from the buffer contents. */ 696 for (i = 0, j = 0; i < data->size; i++) 697 { 698 o = __load_via_object(data->attrs[i].value, __pos___data__).strvalue; 699 n = strlen(o); 700 strncpy(s + j, o, n); /* does not null terminate but final byte should be zero */ 701 j += n; 702 } 703 704 /* Return a new string. */ 705 return __new_str(s); 706 } 707 708 __attr __fn_native__get_using(__attr __args[]) 709 { 710 __attr * const callable = &__args[1]; 711 __attr * const instance = &__args[2]; 712 713 return __replace_context(instance->value, *callable); 714 } 715 716 __attr __fn_native__object_getattr(__attr __args[]) 717 { 718 __attr * const obj = &__args[1]; 719 __attr * const name = &__args[2]; 720 __attr * const _default = &__args[3]; 721 722 /* NOTE: To be written. */ 723 return __builtins___none_None; 724 } 725 726 static int __issubclass(__ref obj, __attr cls) 727 { 728 return (__HASATTR(obj, __TYPEPOS(cls.value), __TYPECODE(cls.value))); 729 } 730 731 __attr __fn_native__isinstance(__attr __args[]) 732 { 733 __attr * const obj = &__args[1]; 734 __attr * const cls = &__args[2]; 735 736 /* cls must be a class. */ 737 if (__is_instance(obj->value) && __issubclass(__get_class(obj->value), *cls)) 738 return __builtins___boolean_True; 739 else 740 return __builtins___boolean_False; 741 } 742 743 __attr __fn_native__issubclass(__attr __args[]) 744 { 745 __attr * const obj = &__args[1]; 746 __attr * const cls = &__args[2]; 747 748 /* obj and cls must be classes. */ 749 if (__issubclass(obj->value, *cls)) 750 return __builtins___boolean_True; 751 else 752 return __builtins___boolean_False; 753 } 754 755 __attr __fn_native__read(__attr __args[]) 756 { 757 __attr * const fd = &__args[1]; 758 __attr * const n = &__args[2]; 759 760 /* NOTE: To be written. */ 761 return __builtins___none_None; 762 } 763 764 __attr __fn_native__write(__attr __args[]) 765 { 766 __attr * const fd = &__args[1]; 767 __attr * const str = &__args[2]; 768 /* fd.__data__ interpreted as int */ 769 int i = __load_via_object(fd->value, __pos___data__).intvalue; 770 /* str.__data__ interpreted as string */ 771 char *s = __load_via_object(str->value, __pos___data__).strvalue; 772 773 write(i, s, sizeof(char) * strlen(s)); 774 return __builtins___none_None; 775 } 776 777 /* Module initialisation. */ 778 779 void __main_native() 780 { 781 }