From 3532f24c75058f4cdd2e594e9d6d43f806d6079a Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Sun, 10 Jan 2021 18:23:28 +0900 Subject: [PATCH] Rewrite complex argument processor because that old stack-juggling version was awful --- builtins.c | 8 +- builtins.krk | 8 +- kuroko.c | 2 + table.c | 18 +- test/testKeywordArgs.krk.expect | 2 +- test/testMoreArgExpansions.krk | 16 + test/testMoreArgExpansions.krk.expect | 1002 +++++++++++++++++++++++++ value.c | 2 + vm.c | 376 +++++----- 9 files changed, 1217 insertions(+), 217 deletions(-) create mode 100644 test/testMoreArgExpansions.krk create mode 100644 test/testMoreArgExpansions.krk.expect diff --git a/builtins.c b/builtins.c index 1b7b61f..4499ae0 100644 --- a/builtins.c +++ b/builtins.c @@ -34,13 +34,13 @@ const char krk_builtinsSrc[] = " let i=0\n" " let c=self.t.capacity()\n" " def _():\n" -" let o=None\n" -" while o==None and ifields, "argv", argList); + krk_pop(); for (int arg = optind; arg < argc + (optind == argc); ++arg) krk_pop(); /* Bind interrupt signal */ diff --git a/table.c b/table.c index caa7594..83142b7 100644 --- a/table.c +++ b/table.c @@ -34,7 +34,7 @@ KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue KrkTableEntry * tombstone = NULL; for (;;) { KrkTableEntry * entry = &entries[index]; - if (entry->key.type == VAL_NONE) { + if (entry->key.type == VAL_KWARGS) { if (IS_NONE(entry->value)) { return tombstone != NULL ? tombstone : entry; } else { @@ -50,14 +50,14 @@ KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue static void adjustCapacity(KrkTable * table, size_t capacity) { KrkTableEntry * entries = ALLOCATE(KrkTableEntry, capacity); for (size_t i = 0; i < capacity; ++i) { - entries[i].key = NONE_VAL(); + entries[i].key = KWARGS_VAL(0); entries[i].value = NONE_VAL(); } table->count = 0; for (size_t i = 0; i < table->capacity; ++i) { KrkTableEntry * entry = &table->entries[i]; - if (entry->key.type == VAL_NONE) continue; + if (entry->key.type == VAL_KWARGS) continue; KrkTableEntry * dest = krk_findEntry(entries, capacity, entry->key); dest->key = entry->key; dest->value = entry->value; @@ -75,7 +75,7 @@ int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value) { adjustCapacity(table, capacity); } KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); - int isNewKey = entry->key.type == VAL_NONE; + int isNewKey = entry->key.type == VAL_KWARGS; if (isNewKey && IS_NONE(entry->value)) table->count++; entry->key = key; entry->value = value; @@ -85,7 +85,7 @@ int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value) { void krk_tableAddAll(KrkTable * from, KrkTable * to) { for (size_t i = 0; i < from->capacity; ++i) { KrkTableEntry * entry = &from->entries[i]; - if (entry->key.type != VAL_NONE) { + if (entry->key.type != VAL_KWARGS) { krk_tableSet(to, entry->key, entry->value); } } @@ -94,7 +94,7 @@ void krk_tableAddAll(KrkTable * from, KrkTable * to) { int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value) { if (table->count == 0) return 0; KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); - if (entry->key.type == VAL_NONE) return 0; + if (entry->key.type == VAL_KWARGS) return 0; *value = entry->value; return 1; } @@ -102,8 +102,8 @@ int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value) { int krk_tableDelete(KrkTable * table, KrkValue key) { if (table->count == 0) return 0; KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); - if (entry->key.type == VAL_NONE) return 0; - entry->key = NONE_VAL(); + if (entry->key.type == VAL_KWARGS) return 0; + entry->key = KWARGS_VAL(0); entry->value = BOOLEAN_VAL(1); return 1; } @@ -114,7 +114,7 @@ KrkString * krk_tableFindString(KrkTable * table, const char * chars, size_t len uint32_t index = hash % table->capacity; for (;;) { KrkTableEntry * entry = &table->entries[index]; - if (entry->key.type == VAL_NONE) { + if (entry->key.type == VAL_KWARGS) { if (IS_NONE(entry->value)) return NULL; } else if (AS_STRING(entry->key)->length == length && AS_STRING(entry->key)->hash == hash && diff --git a/test/testKeywordArgs.krk.expect b/test/testKeywordArgs.krk.expect index 27f27ce..f1147a1 100644 --- a/test/testKeywordArgs.krk.expect +++ b/test/testKeywordArgs.krk.expect @@ -6,7 +6,7 @@ None None None 5 function() missing required positional argument: 'positional2' function() got multiple values for argument 'positional1' -function() got multiple values for argument 'keyword2' +got multiple values for argument 'keyword2' 1 abc None 4 function() got multiple values for argument 'positional1' diff --git a/test/testMoreArgExpansions.krk b/test/testMoreArgExpansions.krk new file mode 100644 index 0000000..8665a7f --- /dev/null +++ b/test/testMoreArgExpansions.krk @@ -0,0 +1,16 @@ +import kuroko +let l = [x for x in range(1,1000)] + +print(l) +#print(kuroko.getstackstatus()) + +def foo(*args): + #print(kuroko.getstackstatus()) + print(len(args)) + print(args) + for i in args: + print(i) + +foo(*l) +#foo(*l,*l) +#foo(*l,*l,*l) diff --git a/test/testMoreArgExpansions.krk.expect b/test/testMoreArgExpansions.krk.expect new file mode 100644 index 0000000..bdd32f4 --- /dev/null +++ b/test/testMoreArgExpansions.krk.expect @@ -0,0 +1,1002 @@ +[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999] +999 +[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999] +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 diff --git a/value.c b/value.c index bd95953..46a7d60 100644 --- a/value.c +++ b/value.c @@ -42,6 +42,8 @@ void krk_printValue(FILE * f, KrkValue printable) { fprintf(f, "{unpack list}"); } else if (AS_INTEGER(printable) == LONG_MAX-2) { fprintf(f, "{unpack dict}"); + } else if (AS_INTEGER(printable) == LONG_MAX-3) { + fprintf(f, "{unpack nil}"); } else if (AS_INTEGER(printable) == 0) { fprintf(f, "{unset default}"); } else { diff --git a/vm.c b/vm.c index cd2e6f7..edb5163 100644 --- a/vm.c +++ b/vm.c @@ -412,7 +412,13 @@ static KrkValue _dict_key_at_index(int argc, KrkValue argv[]) { return NONE_VAL(); } KrkTableEntry entry = AS_DICT(_dict_internal)->entries[i]; - return entry.key; + KrkTuple * outValue = krk_newTuple(2); + krk_push(OBJECT_VAL(outValue)); + outValue->values.values[0] = IS_KWARGS(entry.key) ? BOOLEAN_VAL(0) : BOOLEAN_VAL(1); + outValue->values.values[1] = IS_KWARGS(entry.key) ? NONE_VAL() : entry.key; + outValue->values.count = 2; + krk_pop(); + return OBJECT_VAL(outValue); } /** @@ -659,7 +665,7 @@ KrkValue krk_dirObject(int argc, KrkValue argv[]) { /* First add each method of the class */ for (size_t i = 0; i < self->_class->methods.capacity; ++i) { - if (self->_class->methods.entries[i].key.type != VAL_NONE) { + if (self->_class->methods.entries[i].key.type != VAL_KWARGS) { krk_writeValueArray(AS_LIST(_list_internal), self->_class->methods.entries[i].key); } @@ -667,7 +673,7 @@ KrkValue krk_dirObject(int argc, KrkValue argv[]) { /* Then add each field of the instance */ for (size_t i = 0; i < self->fields.capacity; ++i) { - if (self->fields.entries[i].key.type != VAL_NONE) { + if (self->fields.entries[i].key.type != VAL_KWARGS) { krk_writeValueArray(AS_LIST(_list_internal), self->fields.entries[i].key); } @@ -676,7 +682,7 @@ KrkValue krk_dirObject(int argc, KrkValue argv[]) { KrkClass * type = AS_CLASS(krk_typeOf(1, (KrkValue[]){argv[0]})); for (size_t i = 0; i < type->methods.capacity; ++i) { - if (type->methods.entries[i].key.type != VAL_NONE) { + if (type->methods.entries[i].key.type != VAL_KWARGS) { krk_writeValueArray(AS_LIST(_list_internal), type->methods.entries[i].key); } @@ -837,7 +843,76 @@ static void multipleDefs(KrkClosure * closure, int destination) { krk_runtimeError(vm.exceptions.typeError, "%s() got multiple values for argument '%s'", closure->function->name ? closure->function->name->chars : "", (destination < closure->function->requiredArgs ? AS_CSTRING(closure->function->requiredArgNames.values[destination]) : - AS_CSTRING(closure->function->keywordArgNames.values[destination - closure->function->requiredArgs]))); + (destination - closure->function->requiredArgs < closure->function->keywordArgs ? AS_CSTRING(closure->function->keywordArgNames.values[destination - closure->function->requiredArgs]) : + "(unnamed arg)"))); +} + +int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTable * keywords) { + size_t kwargsCount = AS_INTEGER(vm.stackTop[-1]); + krk_pop(); /* Pop the arg counter */ + argCount--; + + krk_initValueArray(positionals); + krk_initTable(keywords); + + /* First, process all the positionals, including any from extractions. */ + size_t existingPositionalArgs = argCount - kwargsCount * 2; + for (size_t i = 0; i < existingPositionalArgs; ++i) { + krk_writeValueArray(positionals, vm.stackTop[-argCount + i]); + } + + KrkValue * startOfExtras = &vm.stackTop[-kwargsCount * 2]; + /* Now unpack everything else. */ + for (size_t i = 0; i < kwargsCount; ++i) { + KrkValue key = startOfExtras[i*2]; + KrkValue value = startOfExtras[i*2 + 1]; + if (IS_KWARGS(key)) { + if (AS_INTEGER(key) == LONG_MAX-1) { /* unpack list */ + if (!IS_INSTANCE(value) || !AS_INSTANCE(value)->_internal || !(((KrkObj*)(AS_INSTANCE(value)->_internal))->type == OBJ_FUNCTION)) { + krk_runtimeError(vm.exceptions.typeError, "*expresssion value is not a list."); + return 0; + } + KrkValue _list_internal = OBJECT_VAL(AS_INSTANCE(value)->_internal); + /* Add all values from 'value' to 'positionals' */ + if (positionals->count + AS_LIST(_list_internal)->count > positionals->capacity) { + size_t old = positionals->capacity; + positionals->capacity = positionals->count + AS_LIST(_list_internal)->count; + positionals->values = GROW_ARRAY(KrkValue,positionals->values,old,positionals->capacity); + } + KrkValue * destination = &positionals->values[positionals->count]; + memcpy(destination, AS_LIST(_list_internal)->values, AS_LIST(_list_internal)->count * sizeof(KrkValue)); + positionals->count = positionals->count + AS_LIST(_list_internal)->count; + } else if (AS_INTEGER(key) == LONG_MAX-2) { /* unpack dict */ + if (!IS_INSTANCE(value) || !AS_INSTANCE(value)->_internal || !(((KrkObj*)(AS_INSTANCE(value)->_internal))->type == OBJ_CLASS)) { + krk_runtimeError(vm.exceptions.typeError, "**expresssion value is not a dict."); + return 0; + } + KrkValue _dict_internal = OBJECT_VAL(AS_INSTANCE(value)->_internal); + for (size_t i = 0; i < AS_DICT(_dict_internal)->capacity; ++i) { + KrkTableEntry * entry = &AS_DICT(_dict_internal)->entries[i]; + if (entry->key.type != VAL_KWARGS) { + if (!IS_STRING(entry->key)) { + krk_runtimeError(vm.exceptions.typeError, "**expression contains non-string key"); + return 0; + } + if (!krk_tableSet(keywords, entry->key, entry->value)) { + krk_runtimeError(vm.exceptions.typeError, "got multiple values for argument '%s'", AS_CSTRING(entry->key)); + return 0; + } + } + } + } else if (AS_INTEGER(key) == LONG_MAX) { /* single value */ + krk_writeValueArray(positionals, value); + } + } else if (IS_STRING(key)) { + if (!krk_tableSet(keywords, key, value)) { + krk_runtimeError(vm.exceptions.typeError, "got multiple values for argument '%s'", AS_CSTRING(key)); + return 0; + } + } + } + + return 1; } /** @@ -855,223 +930,118 @@ static int call(KrkClosure * closure, int argCount, int extra) { size_t potentialPositionalArgs = closure->function->requiredArgs + closure->function->keywordArgs; size_t totalArguments = closure->function->requiredArgs + closure->function->keywordArgs + closure->function->collectsArguments + closure->function->collectsKeywords; size_t offsetOfExtraArgs = closure->function->requiredArgs + closure->function->keywordArgs; - size_t offsetOfExtraKeys = offsetOfExtraArgs + closure->function->collectsArguments; size_t argCountX = argCount; + KrkValueArray positionals; + KrkTable keywords; if (argCount && IS_KWARGS(vm.stackTop[-1])) { - /** - * Process keyword arguments. - * First, we make sure there is enough space on the stack to fit all of - * the potential arguments to this function. We need to call it with - * all of its arguments - positional and keyword - ready to go, even - * if they weren't specified. - * - * Then we go through all of the kwargs and figure out where they go, - * building a table at the top of the stack of final offsets and values. - * - * Then we clear through all of the spaces that were previously - * kwarg name/value pairs and replace them with a sentinel value. - * - * Then we go through our table and place values into their destination - * spots. If we find that something is already there (because it's not - * the expected sentinel value), we raise a TypeError indicating a - * duplicate argument. - * - * Finally, we do one last pass to see if any of the sentinel values - * indicating missing positional arguments is still there and raise - * another TypeError to indicate missing required arguments. - * - * At this point we can reset the stack head and continue to the actual - * call with all of the arguments, including the defaults, in the right - * place for the function to pull them as locals. - */ - long kwargsCount = AS_INTEGER(vm.stackTop[-1]); - krk_pop(); /* Pop the arg counter */ - argCount--; - size_t existingPositionalArgs = argCount - kwargsCount * 2; - int found = 0; - int extraKwargs = 0; - intptr_t positionalsOffset = &vm.stackTop[-argCount] - vm.stack; - intptr_t endOffset = &vm.stackTop[-kwargsCount * 2] - vm.stack; + KRK_PAUSE_GC(); - for (size_t availableSlots = argCount; availableSlots < (totalArguments); ++availableSlots) { - krk_push(KWARGS_VAL(0)); /* Make sure we definitely have enough space */ + /* This processes the existing argument list into a ValueArray and a Table with the args and keywords */ + if (!krk_processComplexArguments(argCount, &positionals, &keywords)) goto _errorDuringPositionals; + argCount--; /* It popped the KWARGS value from the top, so we have one less argument */ + + /* Do we already know we have too many arguments? Let's bail before doing a bunch of work. */ + if ((positionals.count > potentialPositionalArgs) && (!closure->function->collectsArguments)) { + checkArgumentCount(closure,positionals.count); + goto _errorDuringPositionals; } - /* Expand the stack a bunch to make sure we have space */ - for (int i = 0; i < argCount * 2; ++i) { + /* Prepare stack space for all potential positionals, mark them unset */ + for (size_t i = 0; i < (size_t)argCount; ++i) { + vm.stackTop[-argCount + i] = KWARGS_VAL(0); + } + + /* Do we have a bunch of unused keyword argument slots? Fill them in. */ + while ((size_t)argCount < potentialPositionalArgs) { krk_push(KWARGS_VAL(0)); - } - for (int i = 0; i < argCount * 2; ++i) { - krk_pop(); + argCount++; } - /* We may have moved the stack, recalculate positions. */ - startOfPositionals = vm.stack + positionalsOffset; - KrkValue * endOfPositionals = vm.stack + endOffset; - KrkValue * startOfExtras = vm.stackTop; - for (long i = 0; i < kwargsCount; ++i) { - KrkValue name = endOfPositionals[i*2]; - KrkValue value = endOfPositionals[i*2+1]; - if (IS_KWARGS(name)) { - krk_push(name); - krk_push(value); - found++; - goto _finishArg; - } - /* First, see if it's a positional arg. */ - for (int j = 0; j < (int)closure->function->requiredArgs; ++j) { - if (krk_valuesEqual(name, closure->function->requiredArgNames.values[j])) { - krk_push(INTEGER_VAL(j)); - krk_push(value); - found++; - goto _finishArg; + /* Did we have way more arguments than we needed? Put the stack where it should be. */ + while ((size_t)argCount > potentialPositionalArgs) { + krk_pop(); + argCount--; + } + + /* Place positional arguments */ + for (size_t i = 0; i < potentialPositionalArgs && i < positionals.count; ++i) { + vm.stackTop[-argCount + i] = positionals.values[i]; + } + + if (closure->function->collectsArguments) { + size_t count = (positionals.count > potentialPositionalArgs) ? (positionals.count - potentialPositionalArgs) : 0; + KrkValue * offset = (count == 0) ? NULL : &positionals.values[potentialPositionalArgs]; + krk_push(krk_list_of(count, offset)); + argCount++; + } + + krk_freeValueArray(&positionals); + + /* Now place keyword arguments */ + for (size_t i = 0; i < keywords.capacity; ++i) { + KrkTableEntry * entry = &keywords.entries[i]; + if (entry->key.type != VAL_KWARGS) { + KrkValue name = entry->key; + KrkValue value = entry->value; + /* See if we can place it */ + for (int j = 0; j < (int)closure->function->requiredArgs; ++j) { + if (krk_valuesEqual(name, closure->function->requiredArgNames.values[j])) { + if (!IS_KWARGS(vm.stackTop[-argCount + j])) { + multipleDefs(closure,j); + goto _errorAfterPositionals; + } + vm.stackTop[-argCount + j] = value; + goto _finishKwarg; + } } - } - /* See if it's a keyword arg. */ - for (int j = 0; j < (int)closure->function->keywordArgs; ++j) { - if (krk_valuesEqual(name, closure->function->keywordArgNames.values[j])) { - krk_push(INTEGER_VAL(j + closure->function->requiredArgs)); - krk_push(value); - found++; - goto _finishArg; + /* See if it's a keyword arg. */ + for (int j = 0; j < (int)closure->function->keywordArgs; ++j) { + if (krk_valuesEqual(name, closure->function->keywordArgNames.values[j])) { + if (!IS_KWARGS(vm.stackTop[-argCount + j + closure->function->requiredArgs])) { + multipleDefs(closure, j + closure->function->requiredArgs); + goto _errorAfterPositionals; + } + vm.stackTop[-argCount + j + closure->function->requiredArgs] = value; + goto _finishKwarg; + } } - } - /* If we got to this point, it's not a recognized argument for this function. */ - if (closure->function->collectsKeywords) { - krk_push(name); - krk_push(value); - found++; - extraKwargs++; + if (!closure->function->collectsKeywords) { + krk_runtimeError(vm.exceptions.typeError, "%s() got an unexpected keyword argument '%s'", + closure->function->name ? closure->function->name->chars : "", + AS_CSTRING(name)); + goto _errorAfterPositionals; + } + continue; +_finishKwarg: + entry->key = KWARGS_VAL(0); + entry->value = BOOLEAN_VAL(1); continue; } - krk_runtimeError(vm.exceptions.typeError, "%s() got an unexpected keyword argument '%s'", - closure->function->name ? closure->function->name->chars : "", - AS_CSTRING(name)); - return 0; -_finishArg: - continue; } - size_t destination = existingPositionalArgs; - for (long i = 0; i < found; ++i) { - /* Check for specials */ - KrkValue name = startOfExtras[i*2]; - KrkValue value = startOfExtras[i*2+1]; - if (IS_KWARGS(name)) { - if (AS_INTEGER(name) == LONG_MAX-1) { - if (!IS_INSTANCE(value) || !AS_INSTANCE(value)->_internal || !((KrkObj*)(AS_INSTANCE(value)->_internal))->type == OBJ_FUNCTION) { - krk_runtimeError(vm.exceptions.typeError, "*expresssion value is not a list."); - return 0; - } - KrkValue _list_internal = OBJECT_VAL(AS_INSTANCE(value)->_internal); - for (size_t i = 0; i < AS_LIST(_list_internal)->count; ++i) { - startOfPositionals[destination] = AS_LIST(_list_internal)->values[i]; - destination++; - } - startOfExtras[i*2] = KWARGS_VAL(LONG_MAX-3); - } else if (AS_INTEGER(name) == LONG_MAX) { - startOfPositionals[destination] = value; - destination++; - startOfExtras[i*2] = KWARGS_VAL(LONG_MAX-3); - } - } + /* If this function takes a **kwargs, we need to provide it as a dict */ + if (closure->function->collectsKeywords) { + krk_push(krk_dict_of(0,NULL)); + argCount++; + KrkValue _dict_internal; + krk_tableGet(&AS_INSTANCE(krk_peek(0))->fields, vm.specialMethodNames[METHOD_DICT_INT], &_dict_internal); + krk_tableAddAll(&keywords, AS_DICT(_dict_internal)); } - if (destination > potentialPositionalArgs) { - if (!closure->function->collectsArguments) { - checkArgumentCount(closure,destination); - return 0; - } - krk_push(NONE_VAL()); krk_push(NONE_VAL()); krk_pop(); krk_pop(); - startOfPositionals[offsetOfExtraArgs] = krk_list_of(destination - potentialPositionalArgs, - &startOfPositionals[potentialPositionalArgs]); - destination = potentialPositionalArgs + 1; - } + krk_freeTable(&keywords); - for (long clearSlots = destination; clearSlots < startOfExtras - startOfPositionals; ++clearSlots) { - startOfPositionals[clearSlots] = KWARGS_VAL(0); - } - - for (int i = 0; i < found; ++i) { - if (IS_INTEGER(startOfExtras[i*2])) { - int destination = AS_INTEGER(startOfExtras[i*2]); - if (!IS_KWARGS(startOfPositionals[destination])) { - multipleDefs(closure, destination); - return 0; - } - startOfPositionals[destination] = startOfExtras[i*2+1]; - } else if (IS_STRING(startOfExtras[i*2])) { - krk_push(startOfExtras[i*2]); - krk_push(startOfExtras[i*2+1]); - } else if (IS_KWARGS(startOfExtras[i*2])) { - if (AS_INTEGER(startOfExtras[i*2]) == LONG_MAX-2) { - KrkValue _dict_internal; - if (!IS_INSTANCE(startOfExtras[i*2+1]) || !krk_tableGet(&AS_INSTANCE(startOfExtras[i*2+1])->fields, vm.specialMethodNames[METHOD_DICT_INT], &_dict_internal)) { - krk_runtimeError(vm.exceptions.typeError, "**expresssion value is not a dict."); - return 0; - } - for (size_t j = 0; j < AS_DICT(_dict_internal)->capacity; ++j) { - KrkTableEntry entry = AS_DICT(_dict_internal)->entries[j]; - if (entry.key.type == VAL_NONE) continue; - KrkValue name = entry.key; - KrkValue value = entry.value; - for (int j = 0; j < (int)closure->function->requiredArgNames.count; ++j) { - if (krk_valuesEqual(name, closure->function->requiredArgNames.values[j])) { - int destination = j; - if (!IS_KWARGS(startOfPositionals[destination])) { - multipleDefs(closure, destination); - } - startOfPositionals[destination] = value; - goto _finishDictEntry; - } - } - /* See if it's a keyword arg. */ - for (int j = 0; j < (int)closure->function->keywordArgNames.count; ++j) { - if (krk_valuesEqual(name, closure->function->keywordArgNames.values[j])) { - int destination = j + closure->function->requiredArgs; - if (!IS_KWARGS(startOfPositionals[destination])) { - multipleDefs(closure, destination); - } - startOfPositionals[destination] = value; - goto _finishDictEntry; - } - } - krk_push(name); - krk_push(value); - extraKwargs++; - _finishDictEntry: continue; - } - } - } else { -#ifdef ENABLE_TRACING - dumpStack(&vm.frames[vm.frameCount-1]); - krk_runtimeError(vm.exceptions.typeError, "Internal error? Item at index %d from %d found is %s", i*2, found, krk_typeName(startOfExtras[i*2])); -#endif - return 0; - } - } - if (extraKwargs) { - if (!closure->function->collectsKeywords) { - krk_runtimeError(vm.exceptions.typeError, "%s() got an unexpected keyword argument '%s'", - closure->function->name ? closure->function->name->chars : "", - AS_CSTRING(startOfExtras[found*2])); - } - krk_push(NONE_VAL()); krk_push(NONE_VAL()); krk_pop(); krk_pop(); - startOfPositionals[offsetOfExtraKeys] = krk_dict_of(extraKwargs*2,&startOfExtras[found*2]); - } - long clearSlots; - for (clearSlots = destination; clearSlots < closure->function->requiredArgs; ++clearSlots) { - if (IS_KWARGS(startOfPositionals[clearSlots])) { + for (size_t i = 0; i < (size_t)closure->function->requiredArgs; ++i) { + if (IS_KWARGS(vm.stackTop[-argCount + i])) { krk_runtimeError(vm.exceptions.typeError, "%s() missing required positional argument: '%s'", closure->function->name ? closure->function->name->chars : "", - AS_CSTRING(closure->function->requiredArgNames.values[clearSlots])); - return 0; + AS_CSTRING(closure->function->requiredArgNames.values[i])); + goto _errorAfterKeywords; } } - argCount = totalArguments; + + KRK_RESUME_GC(); argCountX = argCount - (closure->function->collectsArguments + closure->function->collectsKeywords); - while (vm.stackTop > startOfPositionals + argCount) krk_pop(); } else { /* We can't have had any kwargs. */ if ((size_t)argCount > potentialPositionalArgs && closure->function->collectsArguments) { @@ -1101,6 +1071,14 @@ _finishArg: frame->outSlots = (vm.stackTop - argCount - extra) - vm.stack; frame->globals = &closure->function->globalsContext->fields; return 1; + +_errorDuringPositionals: + krk_freeValueArray(&positionals); +_errorAfterPositionals: + krk_freeTable(&keywords); +_errorAfterKeywords: + KRK_RESUME_GC(); + return 0; } /**