mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Compare commits
778 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 22464fe5a0 | |||
| 547a29d2ca | |||
| 41c3d2fb70 | |||
| 8454e9006e | |||
| acdfcfe256 | |||
| acf2fb29cd | |||
| 27ee7cfbde | |||
| e8d8796988 | |||
| fd5e341855 | |||
| e2e23c66d2 | |||
| ad21e5e6d8 | |||
| dd57cb7112 | |||
| 4440566b95 | |||
| 1dfe38bea0 | |||
| 6ce31f334e | |||
| 6f43e95163 | |||
| ed6f3a0735 | |||
| cd1a566002 | |||
| 31a8743d66 | |||
| 916630be1a | |||
| 98285e6b16 | |||
| 85b5af6154 | |||
| fa86026a99 | |||
| 1fc90746a6 | |||
| 4e63ea9649 | |||
| 66a839eb54 | |||
| bf5f83ffda | |||
| 9c108002bf | |||
| 27146dca16 | |||
| 0c4218b704 | |||
| 1238739997 | |||
| 7090b5f07a | |||
| b65bd3778d | |||
| d6e1762346 | |||
| d3b323cf2f | |||
| d109e5b4e1 | |||
| bb141e5532 | |||
| e18e2a44f0 | |||
| 8bad1954a4 | |||
| 614927447a | |||
| 57e30b3be3 | |||
| 1e3da80923 | |||
| 727f2485c9 | |||
| d4238494eb | |||
| 25c8e95365 | |||
| e5fbf9dfa2 | |||
| 73fa6486c6 | |||
| 48771a357c | |||
| 7278fd1f1b | |||
| f6c58616a2 | |||
| b41f1180c8 | |||
| 6b67590fda | |||
| 0d8012f513 | |||
| 68ba386213 | |||
| 13b552538a | |||
| f0e9974221 | |||
| 45e70e4dd6 | |||
| 5cdcce8dbd | |||
| 84b70886cd | |||
| fe1275a6af | |||
| e871b77f41 | |||
| 1c6b1d0155 | |||
| fc4f0b9be7 | |||
| 2b39d87fe8 | |||
| 2f8b0f66bc | |||
| 5c093ed22b | |||
| 3ab2f9371e | |||
| f07ee20260 | |||
| 91444aec4b | |||
| 12c24e0e89 | |||
| d16912681a | |||
| 83922d0bbb | |||
| fd8634d26b | |||
| d890645964 | |||
| 622e68e535 | |||
| 2df9786f33 | |||
| d702b7fdf0 | |||
| a5b416e2ce | |||
| 6b122c6b2a | |||
| 089e2a1677 | |||
| 1e2381f870 | |||
| e48596e9e6 | |||
| 6b58d58a64 | |||
| af3aecd94f | |||
| 8ab39865d0 | |||
| ae926e0802 | |||
| 6276227e70 | |||
| 1a59721c69 | |||
| 7b65f394e6 | |||
| 61e4d1e6f0 | |||
| a2a5c34c56 | |||
| ad8a895af5 | |||
| 210f86f95c | |||
| a106e5dc5a | |||
| 2482642e09 | |||
| f5bc0cea20 | |||
| 4a07b84d2c | |||
| c0d30ab6cd | |||
| 07c35de3a6 | |||
| c38a27185e | |||
| ad89fe63ae | |||
| 1ac5d35753 | |||
| 3458a83e89 | |||
| b493c6bfde | |||
| abaad5c0d6 | |||
| 61a188a38a | |||
| 86f710cf0c | |||
| c022357ed5 | |||
| 3ae425e3f0 | |||
| a2966734aa | |||
| cd9733933e | |||
| 5830e2a655 | |||
| 8d6ba96430 | |||
| f1610a98c5 | |||
| 7c6f237468 | |||
| c87c409a1d | |||
| f377753b16 | |||
| 02a6d866ba | |||
| 0050bfe586 | |||
| 87e0840e9d | |||
| ef73ec560e | |||
| 11fb10a21a | |||
| 5dfdd53bcc | |||
| e441fdaad8 | |||
| 649901b75c | |||
| 4dc9869700 | |||
| 657d069582 | |||
| 249226730f | |||
| facc4bf428 | |||
| a0fe0c40b1 | |||
| 554406b987 | |||
| 76f24d2182 | |||
| 6c0dc1a720 | |||
| 2bec248a19 | |||
| deb349d729 | |||
| 2d29d140f5 | |||
| d6665fc402 | |||
| 98762c5a5d | |||
| 445ba44a56 | |||
| 79c4618754 | |||
| 49bfaca6c7 | |||
| e1ec2b02be | |||
| 3f508d90da | |||
| fafe86d364 | |||
| d12926da8a | |||
| a41b61ea58 | |||
| 6c78589163 | |||
| 6b3fd18262 | |||
| 0a94c69cc3 | |||
| cb76ed8ec4 | |||
| 744578687d | |||
| bcd10c710c | |||
| 545d649eff | |||
| 7ad75a4a19 | |||
| 81ec5f5dc0 | |||
| df2af60cfe | |||
| f654a567e1 | |||
| d5f145076c | |||
| a9b78063aa | |||
| 2eb2f5b408 | |||
| f70634b542 | |||
| df83d42935 | |||
| 074c6e2678 | |||
| 0aa83c503d | |||
| c717bbb77a | |||
| 570c261555 | |||
| f187fdd996 | |||
| 524a038876 | |||
| c069e5ff40 | |||
| 798ec3aff4 | |||
| 101ec5eb0a | |||
| 20a4e9ade6 | |||
| ad1087f5ed | |||
| 6a06a3e48d | |||
| 418eec2c7d | |||
| 2cb6c27781 | |||
| e47f0fc0c2 | |||
| 4c8205db1f | |||
| 88f9770f83 | |||
| 0e5b815399 | |||
| 73dc32c670 | |||
| dd925578c6 | |||
| 40bf7bde78 | |||
| c127614638 | |||
| f36944f551 | |||
| 7505bad677 | |||
| 386a2b8aa1 | |||
| ce6297aa04 | |||
| 6d55e770d3 | |||
| 9586aaa889 | |||
| dd1fa91a66 | |||
| 4bd98671bc | |||
| e6d9b450ba | |||
| 070e04ea22 | |||
| f1c23a0f75 | |||
| 08f9a3ed04 | |||
| b88ca625ab | |||
| e91b7d640c | |||
| e8f88daa9c | |||
| a085c04e37 | |||
| eb9bec19dc | |||
| 8277e950ee | |||
| 3ed8e7fbb2 | |||
| 291265ec86 | |||
| 698b3c925d | |||
| 543ac88eae | |||
| 8256d77c7f | |||
| 44eb1492be | |||
| 803f11e001 | |||
| 1c8576dcc2 | |||
| 9d0c49f05e | |||
| 1cbbb7e11c | |||
| 2550edd570 | |||
| 2f1a031fcd | |||
| 47795d0636 | |||
| 6ced9c3752 | |||
| c6860bc0c4 | |||
| fb3883e57e | |||
| 8bb7962eb8 | |||
| 743432d4ec | |||
| 8a09515c6c | |||
| e1beb502ab | |||
| 93aaa06736 | |||
| 230db2ca85 | |||
| 7967c76e14 | |||
| bacb826868 | |||
| 402890d571 | |||
| 79aa0866ce | |||
| 1bd5c48596 | |||
| 6beae5ec71 | |||
| da0dc6937d | |||
| cc0b28373a | |||
| 7b5f8b0728 | |||
| c6aa87c837 | |||
| e35c3aff83 | |||
| 3a462fe468 | |||
| 87564dc98f | |||
| 74696ffd96 | |||
| 6ddd79fd0e | |||
| a8c5df2442 | |||
| 6b32fa676f | |||
| 14f0e4a4e4 | |||
| 7ce5b21c1d | |||
| c0ff5b475f | |||
| 5ed13da7d6 | |||
| 80598f40bf | |||
| 63d2d192a1 | |||
| 8ad8c547dd | |||
| 64d7dec457 | |||
| e9b4cb11cf | |||
| a2385c05f5 | |||
| 87f1281cec | |||
| 9257ee6433 | |||
| d78d001734 | |||
| b432f12fdd | |||
| 00dd2dfa39 | |||
| a2f6152be8 | |||
| 0f2b3643ba | |||
| 43b93126e7 | |||
| 69e835cd0f | |||
| 1a45447b8b | |||
| 133d57cb0d | |||
| c7d0f8ebcb | |||
| 383a7d24d3 | |||
| 87e11676b3 | |||
| fd2f2f28de | |||
| 0d055559f1 | |||
| 85f0dd7da0 | |||
| 931a7223e6 | |||
| 11524f6f67 | |||
| cb870de2b5 | |||
| cf588bd5cb | |||
| 71f2975a5b | |||
| c326f065e1 | |||
| 05625cd658 | |||
| 15f2787033 | |||
| eec00ccf60 | |||
| ad50a6c410 | |||
| 8e72558bac | |||
| a1731254be | |||
| c7fad5aa33 | |||
| 1fd9dca510 | |||
| 96c948d812 | |||
| 2574adab48 | |||
| e4f32ad9ad | |||
| dfaff83eba | |||
| b34ee9a4b4 | |||
| 5af770cd59 | |||
| 0c7d29dff6 | |||
| 4fdf492219 | |||
| 6f745e211f | |||
| bfcc55fbf9 | |||
| e3361fbc2a | |||
| fca9522af3 | |||
| dd612950b4 | |||
| 996d0c0345 | |||
| 65066f1799 | |||
| 95412aeb50 | |||
| 5c055d670a | |||
| 52a9712c26 | |||
| f0040b5371 | |||
| 89ebb0c4f1 | |||
| 5b11d519d8 | |||
| 1a98512831 | |||
| ca49936468 | |||
| 0da057d99c | |||
| 8f3f731589 | |||
| 923e04cf50 | |||
| 1a8843d3de | |||
| 578db292fd | |||
| 54c853ff4a | |||
| c9168341bf | |||
| 007d26f168 | |||
| 156dd27f88 | |||
| f01704477f | |||
| 0f5386db2e | |||
| 18a0900a82 | |||
| 4ebe94725c | |||
| 6619dc4d75 | |||
| f282d94793 | |||
| 78a40fce88 | |||
| 34fc856a45 | |||
| 08c12ab7bf | |||
| 26bee4a16b | |||
| ae1ece7228 | |||
| 6c94b2d963 | |||
| 4f37adfd5e | |||
| 31d085e795 | |||
| 67e187f0f8 | |||
| 0f284091d1 | |||
| 938ed044f4 | |||
| 667f7788db | |||
| 207577f0af | |||
| 1085167fef | |||
| c0bf76d0a1 | |||
| f6b5a82972 | |||
| cdd72d9c37 | |||
| 2e4bc2de88 | |||
| dbbf2e2623 | |||
| eb172c28d7 | |||
| f0e920baf0 | |||
| 69a2c5cc73 | |||
| e92da7b76c | |||
| 510e53d89f | |||
| 53a81da0fa | |||
| 4e7050fe0c | |||
| a075498613 | |||
| 78462c9181 | |||
| 8c4da7accd | |||
| 8c13e2b7c6 | |||
| b0fb9ccfd8 | |||
| 11cb41770d | |||
| 81a2b3431c | |||
| 199a808e36 | |||
| 1f678a4ace | |||
| 668153092f | |||
| 11dad71578 | |||
| a725cb9093 | |||
| 47264bf289 | |||
| 319553f0ef | |||
| 99aff17075 | |||
| d4b009b394 | |||
| 40f48034d5 | |||
| ce66727177 | |||
| 005cacf18b | |||
| 97529c2a9a | |||
| 2e617e37e1 | |||
| ad9f32c5a8 | |||
| d046814d8b | |||
| f962890a92 | |||
| d0e67aada7 | |||
| 02474daa14 | |||
| 9c311ddc93 | |||
| 4dac03cb2d | |||
| dd558a108d | |||
| bdbd696c48 | |||
| 39dd182244 | |||
| 1167fd1ae4 | |||
| 82380780db | |||
| 2523ed473a | |||
| 40252169fc | |||
| 5cfc0d0dc0 | |||
| 5daabc9407 | |||
| f1c6d6c866 | |||
| 0b50b4a500 | |||
| 03ae38df4e | |||
| e690e1e877 | |||
| 1dbb2b74d3 | |||
| b071dcd4fb | |||
| 7206a8c4f9 | |||
| 24583a7a18 | |||
| 43df1d7e39 | |||
| 6a74b8bf0d | |||
| a4f63caa79 | |||
| ff49cf95fc | |||
| 18c82d5359 | |||
| d6865a9cc7 | |||
| 1c2fc94c20 | |||
| 52db92de53 | |||
| b0ec992d41 | |||
| 96d6e45acd | |||
| a41a649e83 | |||
| d671f57305 | |||
| 0e0773c683 | |||
| a41f5eb23f | |||
| 4e4929bc72 | |||
| c69d1201e1 | |||
| fa4b88b893 | |||
| 449ec101f6 | |||
| 427cc64de0 | |||
| f39a31a623 | |||
| db7e02cd41 | |||
| a15e99d2b6 | |||
| 2588507285 | |||
| 5161909cd7 | |||
| e88e7dc8db | |||
| 36e010cd75 | |||
| fb5af4de2c | |||
| acb504fa0d | |||
| 0006a8cd4a | |||
| 6ed64e2367 | |||
| e90f0d51a3 | |||
| 18337266f8 | |||
| 9781580c71 | |||
| 1001be2e99 | |||
| 0b720ffa61 | |||
| 29a7226d8e | |||
| 66a352c836 | |||
| 937b5b5462 | |||
| 9ad632559e | |||
| cfcca2a727 | |||
| 264a059aef | |||
| 9553e20d34 | |||
| 338ca305ae | |||
| 7e087d7191 | |||
| 69b4c1648a | |||
| f0eaf9eaf5 | |||
| e344c6ab6d | |||
| c8229dbd19 | |||
| 078d24d4d3 | |||
| 0c8fa845e4 | |||
| 8d54977d25 | |||
| 7cf94bac10 | |||
| 111602319b | |||
| 8a5b0433ab | |||
| a219e8b717 | |||
| dcc316d3b8 | |||
| d1e6d647bd | |||
| 6a796cb4cc | |||
| 6dcc3e7383 | |||
| 47c61cf502 | |||
| 95fa22a65c | |||
| 97a18ff4d9 | |||
| 5e8d2a4b84 | |||
| d2433a7723 | |||
| 2f4f36b334 | |||
| 95cb416852 | |||
| be2c156876 | |||
| 5c6de6858e | |||
| 5dd2b8e16f | |||
| a041162678 | |||
| e1b638376f | |||
| 3bcf570a17 | |||
| 0f93d9b7db | |||
| e1795cb72d | |||
| a3a18cd7a6 | |||
| 12b307396a | |||
| 88342b2709 | |||
| b9716c59c7 | |||
| 8a14073207 | |||
| e63962c0a4 | |||
| d768dcc42c | |||
| 5d63350a3b | |||
| b735c0d9df | |||
| cd38bcf074 | |||
| 630c2c5853 | |||
| ebbc7d0e82 | |||
| 059da2ad56 | |||
| ef0fc90cd0 | |||
| 599d141cc8 | |||
| b721d449e6 | |||
| 2f635f56cb | |||
| 6460ef77bc | |||
| 214bc3c95a | |||
| ddab53e66f | |||
| 3739299823 | |||
| b6121adc7d | |||
| 7e8fb15457 | |||
| dc0e335664 | |||
| b357a6320d | |||
| f8b1de0ab4 | |||
| 1d90018cfa | |||
| 297b6fe6e6 | |||
| 1400c6e88b | |||
| d90ccd7e6d | |||
| 4959e4958a | |||
| 7284d1d295 | |||
| bd2686d82d | |||
| c80f500c68 | |||
| 5cd877be7f | |||
| 6a1978c7e1 | |||
| 9ef4bbb10d | |||
| 8dd6b0fd09 | |||
| b720cb635a | |||
| d9f191cf97 | |||
| 59ea323976 | |||
| ba3a0c22a5 | |||
| 2554fd9c94 | |||
| b05d736b49 | |||
| 13a2cc3e5d | |||
| 55fed387a9 | |||
| ce31272dba | |||
| 2ee84eb3df | |||
| 85075bef75 | |||
| cd4cc3bd9d | |||
| b1871cf446 | |||
| 6498d90f1b | |||
| f709054910 | |||
| f0424ff308 | |||
| 4a791701bc | |||
| 46e50492eb | |||
| b97c6d10a2 | |||
| a94ff9666e | |||
| 3e911a8e14 | |||
| a797d45e90 | |||
| 4f6bae61eb | |||
| 4308f3c686 | |||
| b7049b3945 | |||
| bce3843456 | |||
| 4996e88602 | |||
| 2e838250a4 | |||
| 486870e353 | |||
| 48b63b1c7a | |||
| 64ab781266 | |||
| b5eb6602b7 | |||
| 505c6961dc | |||
| dc479392ef | |||
| 4ba9c3b733 | |||
| 4c868a9562 | |||
| 5fa01f4ca3 | |||
| cf070b64f1 | |||
| 0cae5eaf94 | |||
| 579ba2d9e4 | |||
| 406fb9c809 | |||
| 2106d4d446 | |||
| 02fffb02d2 | |||
| ab565f16bc | |||
| bc8308ba8d | |||
| 1e51517615 | |||
| dd3a292a27 | |||
| 7fe853c216 | |||
| 91ba9ba77b | |||
| 99a00cf417 | |||
| 0628778306 | |||
| 691997a447 | |||
| d979172b3e | |||
| 2aa59393ba | |||
| 4bafd62844 | |||
| d9e37bd729 | |||
| 5e5e129014 | |||
| 3cd80a520a | |||
| 2fe556d9c0 | |||
| b09f1712af | |||
| 5d0c8a70e9 | |||
| 8d1f9a6ece | |||
| 1fefa046cd | |||
| c579ab1c8b | |||
| aaf2615ed6 | |||
| 4a82b9391a | |||
| c18212573c | |||
| 8789a5d520 | |||
| 091ce867c1 | |||
| 0518ab22c4 | |||
| 41e6931987 | |||
| c261c01598 | |||
| 5c25a9a6a9 | |||
| f1164487e1 | |||
| bdb9d4d19c | |||
| b3b6fe3c07 | |||
| ed3a253372 | |||
| ed03b17bb4 | |||
| 6110b385a7 | |||
| 105f1f38a9 | |||
| 00518e0a4b | |||
| bb1951a8b6 | |||
| 01ee28d89d | |||
| 8f5ec1a60f | |||
| 465d7a23c8 | |||
| 96d66f6d24 | |||
| a96b871c46 | |||
| 6246483f12 | |||
| 0f31f16015 | |||
| 09419874c8 | |||
| 058dc7bd41 | |||
| 08c877699a | |||
| e79afd4c74 | |||
| eb3af3752f | |||
| ee59f8b8b2 | |||
| a21d3f627e | |||
| fa824e324b | |||
| d77249f006 | |||
| cb3e1433a4 | |||
| 06435f5bc7 | |||
| 18fdf7e03f | |||
| 6424569a63 | |||
| 0573306f51 | |||
| 2249afce25 | |||
| 7985f75dfa | |||
| c47cc0c3bb | |||
| 17b7745593 | |||
| 4cf9b2fd1c | |||
| dc757f70fd | |||
| f6f70c86db | |||
| 0e218f5356 | |||
| 52f35b83e2 | |||
| f6dc516319 | |||
| f32393a820 | |||
| 16b5986d14 | |||
| 7d67c573d7 | |||
| 42359d6241 | |||
| 414678d61a | |||
| 3cba701672 | |||
| 3df3216179 | |||
| 893f937922 | |||
| a1d4992187 | |||
| 3fefe52ffb | |||
| a2a272ca8e | |||
| 4b4ddd5a28 | |||
| 68f60714dc | |||
| d0bc006a73 | |||
| 584d6de3c2 | |||
| 42d23084b7 | |||
| 44d8a40bac | |||
| 0609abb3f7 | |||
| 80c343aec9 | |||
| 9248cdd6cc | |||
| a88a20d51f | |||
| 6f893b5183 | |||
| 1fa081a646 | |||
| a32ec182dd | |||
| 40e4eb599c | |||
| a88cda8ac6 | |||
| 789177c8fe | |||
| ac131c9052 | |||
| 7dff6ab75a | |||
| 43881f6b97 | |||
| f5026f9b6c | |||
| 7367bf6ffe | |||
| 1346456c6c | |||
| df382dea73 | |||
| 8cb40fcda7 | |||
| 4957c85269 | |||
| b88c8b40d6 | |||
| bc9c47d518 | |||
| 089f1f6c75 | |||
| 02b54e5379 | |||
| f01882a8e0 | |||
| d63e45a014 | |||
| 23e69edd2d | |||
| cc11ee15b4 | |||
| 8af688e2c9 | |||
| a99fb39dc1 | |||
| 8aba34301b | |||
| d764632f86 | |||
| 1c48be7822 | |||
| 959a5cff60 | |||
| 7137ee88b5 | |||
| f9e43724bf | |||
| af51a4ac9d | |||
| c0f5be7858 | |||
| 16884b87af | |||
| bcceeba09b | |||
| d405eb5541 | |||
| e998094297 | |||
| 4aef1ad209 | |||
| 1ab79ac414 | |||
| 1b606025ed | |||
| 9dff0aedb1 | |||
| 53da1fb5a1 | |||
| 70851aaf57 | |||
| edf7729d89 | |||
| 432afa2c42 | |||
| dc39d2290a | |||
| 5fac7a73cb | |||
| 3c41ad4018 | |||
| dae42ffe54 | |||
| 2b753167ca | |||
| 465ce1e528 | |||
| df5f83cb84 | |||
| 2c4b0eeff8 | |||
| a3111f144c | |||
| 71548aabb7 | |||
| 3dea108857 | |||
| 1aef549971 | |||
| 7d4b516ca3 | |||
| 606095f2fe | |||
| 4046368ef3 | |||
| baa0ee4133 | |||
| 3a21c9b6d7 | |||
| 093560e7d1 | |||
| ef3bbd2e64 | |||
| 6eeaef705d | |||
| bb3447173b | |||
| 7f630d41ab | |||
| 79f703ecba | |||
| 5ec676aa37 | |||
| e618438882 | |||
| 80a742df51 | |||
| 10e9a1a167 | |||
| 358dd61107 | |||
| 5014bfb50d | |||
| 9a0fb6f91b | |||
| 2732879f3e | |||
| 545c5eecc0 | |||
| 4319eaaa45 | |||
| 05b00a14c5 | |||
| 5b203ead1e | |||
| ed56d56dab | |||
| a19a6edb7c | |||
| 0c4d053a94 | |||
| 7ea38ce473 | |||
| ab72410456 | |||
| fcbb7ec49d | |||
| 05e6513fb4 | |||
| 45a442a9d7 | |||
| f1481105b7 | |||
| fe01ce5b02 | |||
| 96d02b1268 | |||
| 4078670bca | |||
| 9723d6e4ba | |||
| 77c6bfe287 | |||
| 44c29e88ae | |||
| 4eff93632f | |||
| b48514bdcb | |||
| 5f68be7190 | |||
| ea828944ef | |||
| 64d1d10492 | |||
| f6d15cfc38 | |||
| 4c70b5c644 | |||
| 260cad689a | |||
| 39b4caea81 | |||
| 09c6ca936c | |||
| bcf8ad87e6 | |||
| e4ca706530 | |||
| 1248e2ba8a | |||
| dd14973697 | |||
| bbab89e730 | |||
| 1365151dcb | |||
| bf0875d2bb | |||
| e1a7fa925e | |||
| 0133d9ac70 | |||
| 2de7c5073c | |||
| 28bd33297a | |||
| c424892c5e | |||
| 553b9df306 | |||
| 1cc6eaca2a | |||
| c5f480ebfd | |||
| 251dbca8e2 | |||
| 0a8e8bd046 | |||
| 94f1ad6cc1 | |||
| 5f1e90fc58 | |||
| 87ce13f91d | |||
| 6d00974a98 | |||
| 0a0afa7c6a | |||
| 9ec00ef182 | |||
| 2c04f4029f | |||
| bce75e2746 | |||
| 48a04ff1b4 | |||
| b28ec1bc88 | |||
| c9c0f9a79b | |||
| c2bc44e131 | |||
| 337395c1ee | |||
| 6619fd338a | |||
| a232dc6084 | |||
| 83c48ff966 | |||
| 88195a7c99 | |||
| 4eabf7d91c | |||
| 820f6d147f |
+6
-1
@@ -2,6 +2,9 @@
|
||||
*.bak
|
||||
*.d
|
||||
*.o
|
||||
/benchmark/**/*.dat
|
||||
/benchmark/*.pdf
|
||||
/benchmark/*.png
|
||||
*.orig
|
||||
*.pdb
|
||||
*.rej
|
||||
@@ -17,4 +20,6 @@ cscope.out
|
||||
/src/y.tab.c
|
||||
/bin
|
||||
/build
|
||||
/lib
|
||||
/mruby-source-*.gem
|
||||
doc/api
|
||||
.yardoc
|
||||
|
||||
+14
-3
@@ -1,7 +1,18 @@
|
||||
# no installation...
|
||||
language: c
|
||||
|
||||
install:
|
||||
- sudo apt-get -q install gperf
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
sudo: 9000
|
||||
- os: osx
|
||||
osx_image: xcod6.4
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gperf
|
||||
|
||||
env: MRUBY_CONFIG=travis_config.rb
|
||||
script: "./minirake all test"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
--markup markdown
|
||||
--plugin mruby
|
||||
--plugin coderay
|
||||
--output-dir doc/api
|
||||
|
||||
src/**/*.c
|
||||
mrblib/**/*.rb
|
||||
include/**/*.h
|
||||
|
||||
mrbgems/*/src/**/*.c
|
||||
mrbgems/*/mrblib/**/*.rb
|
||||
mrbgems/*/include/**/*.h
|
||||
-
|
||||
AUTHORS
|
||||
MITL
|
||||
CONTRIBUTING.md
|
||||
doc/guides/*.md
|
||||
@@ -1,6 +1,6 @@
|
||||
Original Authors "mruby developers" are:
|
||||
Yukihiro Matsumoto
|
||||
FUKUOKA CSK CORPORATION
|
||||
SCSK KYUSHU CORPORATION
|
||||
Kyushu Institute of Technology
|
||||
Network Applied Communication Laboratory, Inc.
|
||||
Daniel Bovensiepen
|
||||
@@ -26,8 +26,11 @@ Original Authors "mruby developers" are:
|
||||
Hiroshi Mimaki
|
||||
Satoshi Odawara
|
||||
Mitsubishi Electric Micro-Computer Application Software Co.,Ltd.
|
||||
Ralph Desir(Mav7)
|
||||
Hiroyuki Matsuzaki
|
||||
Yuhei Okazaki
|
||||
Manycolors, Inc.
|
||||
Shota Nakano
|
||||
Yuichi Osawa
|
||||
Terence Lee
|
||||
Zachary Scott
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ on-demand.
|
||||
|
||||
#### Don't use C++ style comments
|
||||
|
||||
/* This is the prefered comment style */
|
||||
/* This is the preferred comment style */
|
||||
|
||||
Use C++ style comments only for temporary comment e.g. commenting out some code lines.
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
* Prerequisites
|
||||
|
||||
1. Make sure you have bison (http://www.gnu.org/software/bison/) installed in
|
||||
your system.
|
||||
2. Make sure you have ruby installed in your system (required to build).
|
||||
|
||||
|
||||
* Compilation and Installation
|
||||
|
||||
1. Run make in the top directory.
|
||||
|
||||
This command will create a build directory with a directory for the host
|
||||
environment and one for each crossbuild environment based on the settings
|
||||
in the build_config.rb file.
|
||||
|
||||
Assuming a default build, each of the environment directories will have
|
||||
the following important directories:
|
||||
|
||||
* bin - The binary executables for this environment
|
||||
* lib - The libraries for this environment
|
||||
|
||||
You can find the header files in the include directory at the root of the
|
||||
project.
|
||||
|
||||
You can directly invoke 'minirake' with the following command:
|
||||
|
||||
$ ruby ./minirake
|
||||
|
||||
If an error occurs when compiling mruby, it will be helpful for others if you
|
||||
send a detailed report to the developers that includes the error log, machine,
|
||||
and OS type.
|
||||
|
||||
|
||||
* Adding existing gems
|
||||
|
||||
Gems from the [list of mruby gems](http://www.mruby.org/libraries/) can be
|
||||
added by adding their respective GitHub URLs to build_config.rb. For example,
|
||||
to add implementations of the File and IO Ruby core classes to mruby, insert
|
||||
the following in build_config.rb under the comment section `Use mrbgems`:
|
||||
|
||||
conf.gem :git => 'git@github.com:iij/mruby-io.git', :branch => 'master'
|
||||
|
||||
Afterwards, re-run:
|
||||
|
||||
ruby ./minirake
|
||||
|
||||
|
||||
* Porting to other platforms
|
||||
|
||||
That's all.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2014 mruby developers
|
||||
Copyright (c) 2015 mruby developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[![Build Status][build-status-img]][travis-ci]
|
||||
|
||||
## What's mruby
|
||||
## What is mruby
|
||||
|
||||
mruby is the lightweight implementation of the Ruby language complying to (part
|
||||
of) the [ISO standard][ISO-standard]. Its syntax is Ruby 1.9 compatible.
|
||||
of) the [ISO standard][ISO-standard]. Its syntax is Ruby 1.9 compatible.
|
||||
|
||||
mruby can be linked and embedded within your application. We provide the
|
||||
interpreter program "mruby" and the interactive mruby shell "mirb" as examples.
|
||||
@@ -15,39 +15,28 @@ program under the "test" directory for an example.
|
||||
This achievement was sponsored by the Regional Innovation Creation R&D Programs
|
||||
of the Ministry of Economy, Trade and Industry of Japan.
|
||||
|
||||
|
||||
## How to get mruby
|
||||
|
||||
The stable version 1.0.0 of mruby can be downloaded via the following URL:
|
||||
The stable version 1.2.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/1.2.0.zip](https://github.com/mruby/mruby/archive/1.2.0.zip)
|
||||
|
||||
https://github.com/mruby/mruby/archive/1.0.0.zip
|
||||
|
||||
The latest development version of mruby can be downloaded via the following URL:
|
||||
|
||||
https://github.com/mruby/mruby/zipball/master
|
||||
The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master)
|
||||
|
||||
The trunk of the mruby source tree can be checked out with the
|
||||
following command:
|
||||
|
||||
$ git clone https://github.com/mruby/mruby.git
|
||||
|
||||
|
||||
## mruby home-page
|
||||
|
||||
The URL of the mruby home-page is:
|
||||
|
||||
http://www.mruby.org/
|
||||
|
||||
The URL of the mruby home-page is: [http://www.mruby.org](http://www.mruby.org).
|
||||
|
||||
## Mailing list
|
||||
|
||||
We don't have mailing list, use GitHub forum <http://github.com/mruby/mruby>.
|
||||
|
||||
We don't have mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby).
|
||||
|
||||
## How to compile and install (mruby and gems)
|
||||
|
||||
See the INSTALL file.
|
||||
|
||||
See the [doc/guides/compile.md](doc/guides/compile.md) file.
|
||||
|
||||
## Running Tests
|
||||
|
||||
@@ -59,36 +48,16 @@ Or
|
||||
|
||||
$ ruby ./minirake test
|
||||
|
||||
|
||||
## Customization
|
||||
## How to customize mruby (mrbgems)
|
||||
|
||||
mruby contains a package manager called *mrbgems*. To create extensions
|
||||
in C and/or Ruby you should create a *GEM*. You will find a complete
|
||||
documentation with examples under *examples/mrbgems*.
|
||||
|
||||
in C and/or Ruby you should create a *GEM*. For a documentation of how to
|
||||
use mrbgems consult the file [doc/mrbgems/README.md](doc/mrbgems/README.md). For example code of
|
||||
how to use mrbgems look into the folder *examples/mrbgems/*.
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2014 mruby developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
mruby is released under the [MIT License](MITL).
|
||||
|
||||
## Note for License
|
||||
|
||||
@@ -107,17 +76,15 @@ file.)
|
||||
|
||||
Please ask us if you want to distribute your code under another license.
|
||||
|
||||
|
||||
## How to Contribute
|
||||
|
||||
See the [contribution guidelines][contribution-guidelines] then send a pull
|
||||
See the [contribution guidelines][contribution-guidelines], and then send a pull
|
||||
request to <http://github.com/mruby/mruby>. We consider you have granted
|
||||
non-exclusive right to your contributed code under MIT license. If you want to
|
||||
be named as one of mruby developers, please include an update to the AUTHORS
|
||||
file in your pull request.
|
||||
|
||||
[ISO-standard]: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579
|
||||
[build-status-img]: https://travis-ci.org/mruby/mruby.png?branch=master
|
||||
[contribution-guidelines]: https://github.com/mruby/mruby/blob/master/CONTRIBUTING.md
|
||||
[build-status-img]: https://travis-ci.org/mruby/mruby.svg?branch=master
|
||||
[contribution-guidelines]: CONTRIBUTING.md
|
||||
[travis-ci]: https://travis-ci.org/mruby/mruby
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# basic build file for mruby
|
||||
MRUBY_ROOT = File.dirname(File.expand_path(__FILE__))
|
||||
MRUBY_BUILD_HOST_IS_CYGWIN = RUBY_PLATFORM.include?('cygwin')
|
||||
MRUBY_BUILD_HOST_IS_OPENBSD = RUBY_PLATFORM.include?('openbsd')
|
||||
|
||||
# load build systems
|
||||
load "#{MRUBY_ROOT}/tasks/ruby_ext.rake"
|
||||
@@ -21,19 +22,17 @@ end
|
||||
# load custom rules
|
||||
load "#{MRUBY_ROOT}/src/mruby_core.rake"
|
||||
load "#{MRUBY_ROOT}/mrblib/mrblib.rake"
|
||||
load "#{MRUBY_ROOT}/tools/mrbc/mrbc.rake"
|
||||
|
||||
load "#{MRUBY_ROOT}/tasks/mrbgems.rake"
|
||||
load "#{MRUBY_ROOT}/tasks/libmruby.rake"
|
||||
|
||||
load "#{MRUBY_ROOT}/tasks/mrbgems_test.rake"
|
||||
load "#{MRUBY_ROOT}/test/mrbtest.rake"
|
||||
load "#{MRUBY_ROOT}/tasks/benchmark.rake"
|
||||
|
||||
##############################
|
||||
# generic build targets, rules
|
||||
task :default => :all
|
||||
|
||||
bin_path = "#{MRUBY_ROOT}/bin"
|
||||
bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin"
|
||||
FileUtils.mkdir_p bin_path, { :verbose => $verbose }
|
||||
|
||||
depfiles = MRuby.targets['host'].bins.map do |bin|
|
||||
@@ -52,7 +51,11 @@ MRuby.each_target do |target|
|
||||
gems.map do |gem|
|
||||
current_dir = gem.dir.relative_path_from(Dir.pwd)
|
||||
relative_from_root = gem.dir.relative_path_from(MRUBY_ROOT)
|
||||
current_build_dir = "#{build_dir}/#{relative_from_root}"
|
||||
current_build_dir = File.expand_path "#{build_dir}/#{relative_from_root}"
|
||||
|
||||
if current_build_dir !~ /^#{build_dir}/
|
||||
current_build_dir = "#{build_dir}/mrbgems/#{gem.name}"
|
||||
end
|
||||
|
||||
gem.bins.each do |bin|
|
||||
exec = exefile("#{build_dir}/bin/#{bin}")
|
||||
@@ -68,7 +71,7 @@ MRuby.each_target do |target|
|
||||
end
|
||||
|
||||
if target == MRuby.targets['host']
|
||||
install_path = MRuby.targets['host'].exefile("#{MRUBY_ROOT}/bin/#{bin}")
|
||||
install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}")
|
||||
|
||||
file install_path => exec do |t|
|
||||
FileUtils.rm_f t.name, { :verbose => $verbose }
|
||||
@@ -77,7 +80,7 @@ MRuby.each_target do |target|
|
||||
depfiles += [ install_path ]
|
||||
elsif target == MRuby.targets['host-debug']
|
||||
unless MRuby.targets['host'].gems.map {|g| g.bins}.include?([bin])
|
||||
install_path = MRuby.targets['host-debug'].exefile("#{MRUBY_ROOT}/bin/#{bin}")
|
||||
install_path = MRuby.targets['host-debug'].exefile("#{bin_path}/#{bin}")
|
||||
|
||||
file install_path => exec do |t|
|
||||
FileUtils.rm_f t.name, { :verbose => $verbose }
|
||||
@@ -111,9 +114,9 @@ task :all => depfiles do
|
||||
end
|
||||
|
||||
desc "run all mruby tests"
|
||||
task :test => ["all"] + MRuby.targets.values.map { |t| t.build_mrbtest_lib_only? ? t.libfile("#{t.build_dir}/test/mrbtest") : t.exefile("#{t.build_dir}/test/mrbtest") } do
|
||||
task :test => ["all"] do
|
||||
MRuby.each_target do
|
||||
run_test unless build_mrbtest_lib_only?
|
||||
run_test if test_enabled?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -136,5 +139,10 @@ end
|
||||
|
||||
desc 'generate document'
|
||||
task :doc do
|
||||
load "#{MRUBY_ROOT}/doc/language/generator.rb"
|
||||
begin
|
||||
sh "mrbdoc"
|
||||
rescue
|
||||
puts "ERROR: To generate documents, you should install yard-mruby gem."
|
||||
puts " $ gem install yard-mruby"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
Things to do (Things that are not done yet)
|
||||
|
||||
* Special variables ($1,$2..)
|
||||
* special variables ($1,$2..)
|
||||
* super in aliased methods
|
||||
* multi-assignment decomposing
|
||||
* keyword arguments in def statement
|
||||
|
||||
Things to improve (Done but things to fix)
|
||||
|
||||
* Hash (Reduce size. Use khash or save the order)
|
||||
* stringEx (Delete encoding、delete CODERANGE、delete everything except UTF-8 or ASCII)
|
||||
* Make additions as they are noticed.
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
# mruby version by Hideki Miura
|
||||
#
|
||||
|
||||
IMAGE_WIDTH = 256
|
||||
IMAGE_HEIGHT = 256
|
||||
IMAGE_WIDTH = 64
|
||||
IMAGE_HEIGHT = 64
|
||||
NSUBSAMPLES = 2
|
||||
NAO_SAMPLES = 8
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# Fib 39
|
||||
|
||||
def fib n
|
||||
return n if n < 2
|
||||
fib(n-2) + fib(n-1)
|
||||
end
|
||||
|
||||
puts fib(39)
|
||||
puts fib(37)
|
||||
@@ -40,7 +40,7 @@ end
|
||||
|
||||
i = 0
|
||||
while i<NUM
|
||||
i+=1
|
||||
i += 1
|
||||
result = test_lists()
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
MRuby::Build.new do |conf|
|
||||
toolchain :gcc
|
||||
end
|
||||
|
||||
MRuby::Build.new('no_boxing') do |conf|
|
||||
toolchain :gcc
|
||||
|
||||
conf.gembox 'default'
|
||||
end
|
||||
|
||||
MRuby::Build.new('word_boxing') do |conf|
|
||||
toolchain :gcc
|
||||
|
||||
conf.gembox 'default'
|
||||
conf.compilers.each do |c|
|
||||
c.defines += %w(MRB_WORD_BOXING)
|
||||
end
|
||||
end
|
||||
|
||||
MRuby::Build.new('nan_boxing') do |conf|
|
||||
toolchain :gcc
|
||||
|
||||
conf.gembox 'default'
|
||||
conf.compilers.each do |c|
|
||||
c.defines += %w(MRB_NAN_BOXING)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
MRuby::Build.new do |conf|
|
||||
toolchain :gcc
|
||||
end
|
||||
|
||||
MRuby::Build.new('gcc') do |conf|
|
||||
toolchain :gcc
|
||||
conf.gembox 'default'
|
||||
end
|
||||
|
||||
MRuby::Build.new('clang') do |conf|
|
||||
toolchain :clang
|
||||
conf.gembox 'default'
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
set yrange [0:]
|
||||
set terminal pngcairo font 'Sans, 8' lw 1 size 1400,1024
|
||||
set xtics rotate by -45
|
||||
set style histogram errorbars gap 2 lw 1
|
||||
set style fill solid border -1
|
||||
+16
-2
@@ -21,7 +21,6 @@ MRuby::Build.new do |conf|
|
||||
|
||||
# include the default GEMs
|
||||
conf.gembox 'default'
|
||||
|
||||
# C compiler settings
|
||||
# conf.cc do |cc|
|
||||
# cc.command = ENV['CC'] || 'gcc'
|
||||
@@ -99,7 +98,7 @@ MRuby::Build.new('host-debug') do |conf|
|
||||
conf.gembox 'default'
|
||||
|
||||
# C compiler settings
|
||||
conf.cc.defines = %w(ENABLE_DEBUG)
|
||||
conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
|
||||
|
||||
# Generate mruby debugger command (require mruby-eval)
|
||||
conf.gem :core => "mruby-bin-debugger"
|
||||
@@ -108,6 +107,21 @@ MRuby::Build.new('host-debug') do |conf|
|
||||
# conf.enable_bintest
|
||||
end
|
||||
|
||||
MRuby::Build.new('test') do |conf|
|
||||
# Gets set by the VS command prompts.
|
||||
if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
|
||||
toolchain :visualcpp
|
||||
else
|
||||
toolchain :gcc
|
||||
end
|
||||
|
||||
enable_debug
|
||||
conf.enable_bintest
|
||||
conf.enable_test
|
||||
|
||||
conf.gembox 'default'
|
||||
end
|
||||
|
||||
# Define cross build settings
|
||||
# MRuby::CrossBuild.new('32bit') do |conf|
|
||||
# toolchain :gcc
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# C API Reference
|
||||
|
||||
This is a C API Reference.
|
||||
The structure of this document will follow the directory structure of `include/` directory.
|
||||
|
||||
## Headers list
|
||||
Header name|Features
|
||||
-----------|--------
|
||||
[mrbconf.h](../mrbconf/README.md)|Defines macros for mruby configurations.
|
||||
[mruby.h](./mruby.h.md)|Main header of mruby C API. Include this first.
|
||||
[mruby/array.h](./mruby.array.h.md)|`Array` class.
|
||||
[mruby/class.h](./mruby.class.h.md)|`Class` class.
|
||||
[mruby/compile.h](./mruby.compile.h.md)|mruby compiler.
|
||||
[mruby/data.h](./mruby.data.h.md)|User defined object.
|
||||
[mruby/debug.h](./mruby.debug.h.md)|Debugging.
|
||||
[mruby/dump.h](./mruby.dump.h.md)|Dumping compiled mruby script.
|
||||
[mruby/error.h](./mruby.error.h.md)|Error handling.
|
||||
[mruby/gc.h](./mruby.gc.h.md)|Uncommon memory management stuffs.
|
||||
[mruby/hash.h](./mruby.hash.h.md)|`Hash` class.
|
||||
[mruby/irep.h](./mruby.irep.h.md)|Compiled mruby script.
|
||||
[mruby/khash.h](./mruby.khash.h.md)|Defines of khash which is used in hash table of mruby.
|
||||
[mruby/numeric.h](./mruby.numeric.h.md)|`Numeric` class and sub-classes of it.
|
||||
[mruby/opode.h](./mruby.opcode.h.md)|Operation codes used in mruby VM.
|
||||
[mruby/proc.h](./mruby.proc.h.md)|`Proc` class.
|
||||
[mruby/range.h](./mruby.range.h.md)|`Range` class.
|
||||
[mruby/re.h](./mruby.re.h.md)|`Regexp` class.
|
||||
[mruby/string.h](./mruby.string.h.md)|`String` class.
|
||||
[mruby/value.h](./mruby.value.h.md)|`mrb_value` functions and macros.
|
||||
[mruby/variable.h](./mruby.variable.h.md)|Functions to access to mruby variables.
|
||||
[mruby/version.h](./mruby.version.h.md)|Macros of mruby version.
|
||||
@@ -1,69 +0,0 @@
|
||||
# mruby.h
|
||||
|
||||
Basic header of mruby.
|
||||
It includes **mrbconf.h**, **mruby/value.h**, **mruby/version.h** internally.
|
||||
|
||||
## `mrb_state` management
|
||||
|
||||
### mrb_open
|
||||
```C
|
||||
mrb_state* mrb_open();
|
||||
```
|
||||
Creates new `mrb_state`.
|
||||
|
||||
### mrb_allocf
|
||||
```C
|
||||
typedef void* (*mrb_allocf) (struct mrb_state *mrb, void *ptr, size_t s, void *ud);
|
||||
```
|
||||
Function pointer type of custom allocator used in `mrb_open_allocf`.
|
||||
|
||||
The function pointing it must behave similarly as `realloc` except:
|
||||
* If `ptr` is `NULL` it must allocate new space.
|
||||
* If `s` is `NULL`, `ptr` must be freed.
|
||||
|
||||
### mrb_open_allocf
|
||||
```C
|
||||
mrb_state* mrb_open_allocf(mrb_allocf f, void *ud);
|
||||
```
|
||||
Create new `mrb_state` with custom allocator.
|
||||
`ud` will be passed to custom allocator `f`.
|
||||
If user data isn't required just pass `NULL`.
|
||||
Function pointer `f` must satisfy requirements of its type.
|
||||
|
||||
### mrb_close
|
||||
```C
|
||||
void mrb_close(mrb_state *mrb);
|
||||
```
|
||||
Deletes `mrb_state`.
|
||||
|
||||
## Method
|
||||
|
||||
### mrb_get_args
|
||||
```C
|
||||
int mrb_get_args(mrb_state *mrb, const char *format, ...);
|
||||
```
|
||||
Retrieve arguments from `mrb_state`.
|
||||
Use it inside a function pointed by `mrb_func_t`.
|
||||
It returns number of function retrieved.
|
||||
`format` is a list of following format specifier:
|
||||
|
||||
char|mruby type|retrieve types|note
|
||||
:---:|----------|--------------|---
|
||||
`o`|`Object`|`mrb_value`|Could be used to retreive any type of argument
|
||||
`C`|`Class`/`Module`|`mrb_value`|
|
||||
`S`|`String`|`mrb_value`|
|
||||
`A`|`Array`|`mrb_value`|
|
||||
`H`|`Hash`|`mrb_value`|
|
||||
`s`|`String`|`char*`, `mrb_int`|
|
||||
`z`|`String`|`char*`|
|
||||
`a`|`Array`|`mrb_value*`, `mrb_int`|
|
||||
`f`|`Float`|`mrb_float`|
|
||||
`i`|`Integer`|`mrb_int`|
|
||||
`b`|boolean|`mrb_bool`|
|
||||
`n`|`Symbol`|`mrb_sym`|
|
||||
`&`|block|`mrb_value`|
|
||||
`*`|rest arguments|`mrb_value*`, `mrb_int`|Receive the rest of arguments as an array.
|
||||
<code>|</code>|optional||After this spec following specs would be optional.
|
||||
`?`|optional given|`mrb_bool`|True if preceding argument is given. Used to check optional argument is given.
|
||||
|
||||
The passing variadic arguments must be a pointer of retrieving type.
|
||||
@@ -1,341 +0,0 @@
|
||||
# How to use mruby debugger mrdb
|
||||
|
||||
copyright (c) 2014 Specified Non-Profit Coorporation mruby Forum
|
||||
|
||||
## 1.Summary
|
||||
This file documents the method for using the mruby debugger 'mrdb'
|
||||
|
||||
## 2 debugging with mrdb
|
||||
|
||||
## 2.1 Building mrdb
|
||||
|
||||
The trunk of the mruby source tree can be checked out with following command/
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/Kumikomi-Ruby/forum-mruby.git mruby
|
||||
```
|
||||
|
||||
Run make command
|
||||
```bash
|
||||
$ cd mruby
|
||||
$ make
|
||||
```
|
||||
|
||||
By default, make command will install debugger files into mruby/bin.
|
||||
|
||||
You can add the path for mrdb on your host environment with following command
|
||||
|
||||
```bash
|
||||
$ echo "export PATH=\$PATH:MRUBY_ROOT/bin" >> ~/.bashrc
|
||||
$ source ~/.bashrc
|
||||
```
|
||||
|
||||
*MRUBY_ROOT is the directory in which mruby source cords will be installed.
|
||||
|
||||
To confirm mrdb was instaleed properly,run mrdb with --version option
|
||||
|
||||
```bash
|
||||
$ mrdb --version
|
||||
mruby 1.1.0 (2014-11-19)
|
||||
```
|
||||
|
||||
## 2.2 Bassic Operation
|
||||
|
||||
### 2.2.1 debugging mruby script file(rb file) with mrdb
|
||||
|
||||
To invoke mruby debugger, just type mrdb.
|
||||
|
||||
To specify the script file ,
|
||||
|
||||
```bash
|
||||
$ mrdb [option] file name
|
||||
```
|
||||
|
||||
For example : Debugging sample.rb
|
||||
|
||||
```bash
|
||||
$ mrdb sample.rb
|
||||
```
|
||||
|
||||
You can excute shell commands listed below
|
||||
|
||||
|command|description|
|
||||
|:-:|:--|
|
||||
|run|execute programs|
|
||||
|step|execute stepping|
|
||||
|continue|execute continuing program|
|
||||
|break|configure the breaking point|
|
||||
|delete|deleting the breaking points|
|
||||
|disable|disabling the breaking points|
|
||||
|enable|enabling the breaking points|
|
||||
|info breakpoints|showing list of the breaking points|
|
||||
|print|eavaluating and printing the values of the mruby expressions in the script|
|
||||
|list|displaying the source cords|
|
||||
|help|showing help|
|
||||
|quit|terminating the mruby debugger|
|
||||
|
||||
### 2.2.2 debugging mruby binary file(mrb file) with mrdb
|
||||
|
||||
You can debugg the mruby binary files
|
||||
|
||||
#### 2.2.2.1 debuggg the binary files
|
||||
|
||||
* notice
|
||||
To debugg mruby binary files, you need to compile mruby files with option -g.
|
||||
|
||||
```bash
|
||||
$ mrbc -g sample.rb
|
||||
```
|
||||
|
||||
You can debugg the mruby binary files with following command and the option -b.
|
||||
|
||||
```bash
|
||||
$ mrdb -b sample.mrb
|
||||
```
|
||||
|
||||
Then you can execute all debugger shell commands.
|
||||
|
||||
#### break command
|
||||
you can give any breakpoint to stop the program by specifiyng the line number and method name.
|
||||
And the breakpoint list will be displayed after you finished to set the breakpoint succesfully.
|
||||
|
||||
Usage:
|
||||
```
|
||||
break [file:]lineno
|
||||
b [file:]lineno
|
||||
break [class:]method
|
||||
b [class:]method
|
||||
```
|
||||
|
||||
The breakpoint will be numbered in serial order from 1.The number which was given to deleted breakpoint will not be given to another breakpoint again.
|
||||
|
||||
You can give multiple breakpoints to specified the line number and method.
|
||||
Be ware that breakpoint command will not check the validity of the class name and method name.
|
||||
|
||||
You can see the current breakpoint information by following options.
|
||||
|
||||
breakpoint breakpoint number : file name. line number
|
||||
|
||||
breakpoint breakpoint number : [class name,] method name
|
||||
|
||||
#### continue command
|
||||
|
||||
Usage:
|
||||
```
|
||||
continue [N]
|
||||
c [N]
|
||||
```
|
||||
|
||||
N: the next breakpoint number
|
||||
|
||||
Resuming the program and will stop the program at breakpoint at N (N-1 breakpoint will be ignored)
|
||||
|
||||
When you run continue command without any specifying N ,Program will be stopped at next breakpoint.
|
||||
|
||||
Example:
|
||||
```
|
||||
(foo.rb:1) continue 3
|
||||
```
|
||||
Resuming the program and stopping the program at the third breakpoint.
|
||||
|
||||
#### delete command
|
||||
|
||||
Deleting specified breakpoint
|
||||
|
||||
Usage:
|
||||
```
|
||||
delete [breakpointno]
|
||||
d [breakpointno]
|
||||
```
|
||||
|
||||
breakpointno: breakpoint number
|
||||
|
||||
Example:
|
||||
```
|
||||
(foo.rb:1) delete
|
||||
```
|
||||
|
||||
Deleting all brealpoint
|
||||
```
|
||||
(foo.rb:1) delete 1 3
|
||||
```
|
||||
|
||||
Deleting the breakpoint 1 and 3
|
||||
|
||||
#### diable command
|
||||
|
||||
Disabling the specified breakpoint
|
||||
|
||||
Usage:
|
||||
```
|
||||
disable [breakpointno]
|
||||
dis [breakpointno]
|
||||
```
|
||||
|
||||
brealpointno: breakpoint number
|
||||
|
||||
Example:
|
||||
```
|
||||
(foo.rb:1) disable
|
||||
```
|
||||
|
||||
Desabling all brealpoint
|
||||
```
|
||||
(foo.rb:1) disable 1 3
|
||||
```
|
||||
|
||||
Disabling the breakpoint 1 and 3
|
||||
|
||||
#### enable command
|
||||
|
||||
Enababling the specified breakpoint
|
||||
|
||||
Usage:
|
||||
```
|
||||
enable [breakpointno]
|
||||
e [breakpointno]
|
||||
```
|
||||
|
||||
brealpointno: breakpoint number
|
||||
|
||||
Example:
|
||||
```
|
||||
(foo.rb:1) enable
|
||||
```
|
||||
|
||||
Enabling all brealpoint
|
||||
```
|
||||
(foo.rb:1) enable 1 3
|
||||
```
|
||||
|
||||
Enabling the breakpoint 1 and 3
|
||||
|
||||
#### eval command
|
||||
|
||||
Evaluating the string as source code and printing the value.
|
||||
|
||||
Same as print command, please see print command.
|
||||
|
||||
#### help command
|
||||
|
||||
Displaying the help message.
|
||||
|
||||
Usage:
|
||||
```
|
||||
help [comand]
|
||||
h [command]
|
||||
```
|
||||
Typing help without any option will displays the command list.
|
||||
|
||||
#### info breakpoints command
|
||||
|
||||
Displaying the specified breakpoint information.
|
||||
|
||||
Usage:
|
||||
```
|
||||
info breakpoints [breakpointno]
|
||||
i b [breakpointno]
|
||||
```
|
||||
|
||||
breakpointno: breakpoint number
|
||||
|
||||
Typing "info breakpoints" without ant option will display all breakpoint information.
|
||||
Example
|
||||
```
|
||||
(sample.rb:1) info breakpoints
|
||||
Num Type Enb What
|
||||
1 breakpoint y at sample.rb:3 -> file name,line number
|
||||
2 breakpoint n in Sample_class:sample_class_method -> [class:]method name
|
||||
3 breakpoint y in sample_global_method
|
||||
```
|
||||
|
||||
Displaying specified the breakpoint number
|
||||
```
|
||||
(foo.rb:1) info breakpoints 1 3
|
||||
Num Type Enb What
|
||||
1 breakpoint y at sample.rb:3
|
||||
3 breakpoint y in sample_global_method
|
||||
```
|
||||
|
||||
#### list command
|
||||
|
||||
Displaying the cords of the source file.
|
||||
|
||||
Usage:
|
||||
```
|
||||
list [filename:]first[,last]
|
||||
l [filename]:first[,last]
|
||||
```
|
||||
|
||||
first: the opening row number
|
||||
last : the closing row number
|
||||
|
||||
When you specify first , but not specify option "last" , you will get 10 rows.
|
||||
When you don not specify both of first and last, you will next 10 rows.
|
||||
|
||||
Example:
|
||||
```
|
||||
Specifying file name and first row number
|
||||
sample.rb:1) list sample2.rb:5
|
||||
```
|
||||
|
||||
Specifying file name and first and last row number
|
||||
```
|
||||
(sample.rb:1) list sample2.rb:6,7
|
||||
```
|
||||
|
||||
#### print command
|
||||
Evaluating the string as source code and printing the value.
|
||||
|
||||
Usage:
|
||||
```
|
||||
print [expr]
|
||||
p [expr]
|
||||
```
|
||||
|
||||
expr: expression
|
||||
|
||||
To specify the expression is indispensableness.
|
||||
The displayed expressions will be numbered in serial order from 1.
|
||||
If an exception occurs, the exception information will be displayed and the debugging will be continued.
|
||||
|
||||
Example:
|
||||
```
|
||||
(sample.rb:1) print 1+2
|
||||
$1 = 3
|
||||
(sample.rb:1) print self
|
||||
$2 = main
|
||||
```
|
||||
|
||||
below is the case of the exception:
|
||||
```
|
||||
(sample.rb:1) print (1+2
|
||||
$1 = SyntaxError: line 1: syntax error, unexpected $end, expecting ')'
|
||||
```
|
||||
|
||||
#### quit command
|
||||
Quitting the debugger.
|
||||
|
||||
Usage:
|
||||
```
|
||||
quit
|
||||
q
|
||||
```
|
||||
|
||||
#### run command
|
||||
|
||||
Running the program and stopping at the first breakpoint.
|
||||
|
||||
Usage:
|
||||
```
|
||||
run
|
||||
r
|
||||
```
|
||||
|
||||
#### step command
|
||||
|
||||
Running the program step by step.
|
||||
When the method and the block will be invoked, the program will be stop at the first row.
|
||||
The program which is developed by C language will be ignored.
|
||||
|
||||
period
|
||||
@@ -75,7 +75,7 @@ toolchain :visualcpp
|
||||
|
||||
Toolchain configuration for Android.
|
||||
```ruby
|
||||
toolchain :androideabi
|
||||
toolchain :android
|
||||
```
|
||||
|
||||
Requires the custom standalone Android NDK and the toolchain path
|
||||
@@ -245,7 +245,7 @@ mruby can use C++ exception to raise exception internally.
|
||||
It is called C++ ABI mode.
|
||||
By using C++ exception it can release C++ stack object correctly.
|
||||
Whenever you mix C++ code C++ ABI mode would be enabled automatically.
|
||||
If you need to enable C++ ABI mode explicity add the following:
|
||||
If you need to enable C++ ABI mode explicitly add the following:
|
||||
```ruby
|
||||
conf.enable_cxx_abi
|
||||
```
|
||||
@@ -409,7 +409,7 @@ like this:
|
||||
|
||||
An extra directory is created for the target platform. In case you
|
||||
compile for *i386* a directory called *i386* is created under the
|
||||
build direcotry.
|
||||
build directory.
|
||||
|
||||
The cross compilation workflow starts in the same way as the normal
|
||||
compilation by compiling all *native* libraries and binaries.
|
||||
@@ -463,7 +463,7 @@ can't be disabled for the main build.
|
||||
MRuby::CrossBuild.new('Minimal') do |conf|
|
||||
toolchain :gcc
|
||||
|
||||
conf.cc.defines = %w(DISABLE_STDIO)
|
||||
conf.cc.defines = %w(MRB_DISABLE_STDIO)
|
||||
conf.bins = []
|
||||
end
|
||||
```
|
||||
@@ -0,0 +1,370 @@
|
||||
# How to Use the mruby Debugger
|
||||
|
||||
copyright (c) 2014 Specified Non-Profit Corporation mruby Forum
|
||||
|
||||
## 1. Summary
|
||||
|
||||
This file documents the mruby debugger ('mrdb') methods.
|
||||
|
||||
## 2 Debugging with mrdb
|
||||
|
||||
## 2.1 Building mrdb
|
||||
|
||||
The trunk of the mruby source tree, with the most recent mrdb, can be checked out with the following command:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/mruby/mruby.git
|
||||
```
|
||||
|
||||
To run the `make` command:
|
||||
|
||||
```bash
|
||||
$ cd mruby
|
||||
$ make
|
||||
```
|
||||
|
||||
By default, the `make` command will install the debugger files into mruby/bin.
|
||||
|
||||
You can add the path for mrdb on your host environment with the following command:
|
||||
|
||||
```bash
|
||||
$ echo "export PATH=\$PATH:MRUBY_ROOT/bin" >> ~/.bashrc
|
||||
$ source ~/.bashrc
|
||||
```
|
||||
|
||||
`*MRUBY_ROOT` is the directory in which mruby source code will be installed.
|
||||
|
||||
To confirm mrdb was installed properly, run mrdb with the `--version` option:
|
||||
|
||||
```bash
|
||||
$ mrdb --version
|
||||
mruby 1.2.0 (2014-11-17)
|
||||
```
|
||||
|
||||
## 2.2 Basic Operation
|
||||
|
||||
### 2.2.1 Debugging mruby Script Files (rb file) with mrdb
|
||||
|
||||
To invoke the mruby debugger, just type `mrdb`.
|
||||
|
||||
To specify the script file:
|
||||
|
||||
```bash
|
||||
$ mrdb [option] file name
|
||||
```
|
||||
|
||||
For example: Debugging sample.rb
|
||||
|
||||
```bash
|
||||
$ mrdb sample.rb
|
||||
```
|
||||
|
||||
You can execute the shell commands listed below:
|
||||
|
||||
|command|description|
|
||||
|:-:|:--|
|
||||
|run|execute programs|
|
||||
|step|execute stepping|
|
||||
|continue|execute continuing program|
|
||||
|break|configure the breaking point|
|
||||
|delete|deleting the breaking points|
|
||||
|disable|disabling the breaking points|
|
||||
|enable|enabling the breaking points|
|
||||
|info breakpoints|showing list of the breaking points|
|
||||
|print|evaluating and printing the values of the mruby expressions in the script|
|
||||
|list|displaying the source cords|
|
||||
|help|showing help|
|
||||
|quit|terminating the mruby debugger|
|
||||
|
||||
### 2.2.2 Debugging mruby Binary Files (mrb file) with mrdb
|
||||
|
||||
You can debug the mruby binary files.
|
||||
|
||||
#### 2.2.2.1 Debugging the binary files
|
||||
|
||||
* notice
|
||||
To debug mruby binary files, you need to compile mruby files with option `-g`.
|
||||
|
||||
```bash
|
||||
$ mrbc -g sample.rb
|
||||
```
|
||||
|
||||
You can debug the mruby binary files with following command and the option `-b`.
|
||||
|
||||
```bash
|
||||
$ mrdb -b sample.mrb
|
||||
```
|
||||
|
||||
Then you can execute all debugger shell commands.
|
||||
|
||||
#### Break Command
|
||||
|
||||
You can use any breakpoint to stop the program by specifying the line number and method name.
|
||||
The breakpoint list will be displayed after you have set the breakpoint successfully.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
break [file:]linenum
|
||||
b [file:]linenum
|
||||
break [class:]method
|
||||
b [class:]method
|
||||
```
|
||||
|
||||
The breakpoint will be ordered in serial from 1.
|
||||
The number, which was given to the deleted breakpoint, will never be given to another breakpoint again.
|
||||
|
||||
You can give multiple breakpoints to specified the line number and method.
|
||||
Be ware that breakpoint command will not check the validity of the class name and method name.
|
||||
|
||||
You can get the current breakpoint information by the following options.
|
||||
|
||||
breakpoint breakpoint number : file name. line number
|
||||
|
||||
breakpoint breakpoint number : [class name,] method name
|
||||
|
||||
#### Continue Command
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
continue [N]
|
||||
c [N]
|
||||
```
|
||||
|
||||
N: the next breakpoint number
|
||||
|
||||
When resuming the program, it will stop at breakpoint N (N-1 breakpoint will be ignored).
|
||||
|
||||
When you run the `continue` command without specifying N, the program will be stopped at the next breakpoint.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
(foo.rb:1) continue 3
|
||||
```
|
||||
|
||||
This will resume the program and stop it at the third breakpoint.
|
||||
|
||||
#### Delete Command
|
||||
|
||||
This will delete the specified breakpoint.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
delete [breakpoint-no]
|
||||
d [breakpoint-no]
|
||||
```
|
||||
|
||||
breakpoint-no: breakpoint number
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
(foo.rb:1) delete
|
||||
```
|
||||
|
||||
This will delete all of the breakpoints.
|
||||
|
||||
```
|
||||
(foo.rb:1) delete 1 3
|
||||
```
|
||||
|
||||
This will delete the breakpoint at 1 and 3.
|
||||
|
||||
#### Disable Command
|
||||
|
||||
This will disable the specified breakpoint.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
disable [breakpoint-no]
|
||||
dis [breakpoint-no]
|
||||
```
|
||||
|
||||
reappointing: breakpoint number
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
(foo.rb:1) disable
|
||||
```
|
||||
|
||||
Use `disable` if you would like to disable all of the breakpoints.
|
||||
|
||||
```
|
||||
(foo.rb:1) disable 1 3
|
||||
```
|
||||
|
||||
This will disable the breakpoints at 1 and 3.
|
||||
|
||||
#### Enable Command
|
||||
|
||||
This will enable the specified breakpoints.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
enable [breakpoint-no]
|
||||
e [breakpoint-no]
|
||||
```
|
||||
|
||||
breakpoint-no: breakpoint number
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
(foo.rb:1) enable
|
||||
```
|
||||
|
||||
Enabling all breakpoints
|
||||
```
|
||||
(foo.rb:1) enable 1 3
|
||||
```
|
||||
|
||||
Enabling the breakpoint 1 and 3
|
||||
|
||||
#### eval command
|
||||
|
||||
Evaluating the string as source code and printing the value.
|
||||
|
||||
Same as print command, please see print command.
|
||||
|
||||
#### help command
|
||||
|
||||
Displaying the help message.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
help [command]
|
||||
h [command]
|
||||
```
|
||||
|
||||
Typing `help` without any options will display the command list.
|
||||
|
||||
#### Info Breakpoints Command
|
||||
|
||||
Displaying the specified breakpoint information.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
info breakpoints [breakpoint-no]
|
||||
i b [breakpoint-no]
|
||||
```
|
||||
|
||||
breakpoint-no: breakpoint number
|
||||
|
||||
Typing "info breakpoints" without ant option will display all breakpoint information.
|
||||
Example:
|
||||
|
||||
```
|
||||
(sample.rb:1) info breakpoints
|
||||
Num Type Enb What
|
||||
1 breakpoint y at sample.rb:3 -> file name,line number
|
||||
2 breakpoint n in Sample_class:sample_class_method -> [class:]method name
|
||||
3 breakpoint y in sample_global_method
|
||||
```
|
||||
|
||||
Displaying the specified breakpoint number:
|
||||
|
||||
```
|
||||
(foo.rb:1) info breakpoints 1 3
|
||||
Num Type Enb What
|
||||
1 breakpoint y at sample.rb:3
|
||||
3 breakpoint y in sample_global_method
|
||||
```
|
||||
|
||||
#### List Command
|
||||
|
||||
To display the code of the source file.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
list [filename:]first[,last]
|
||||
l [filename]:first[,last]
|
||||
```
|
||||
|
||||
first: the opening row number
|
||||
last : the closing row number
|
||||
|
||||
When you specify the `first`, but not the `last` option, you will receive 10 rows.
|
||||
When you do not specify both the `first` and `last` options, you will receive the next 10 rows.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
Specifying file name and first row number
|
||||
sample.rb:1) list sample2.rb:5
|
||||
```
|
||||
|
||||
Specifying the file name and the first and last row number:
|
||||
|
||||
```
|
||||
(sample.rb:1) list sample2.rb:6,7
|
||||
```
|
||||
|
||||
#### Print Command
|
||||
|
||||
Evaluating the string as source code and printing the value.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
print [expr]
|
||||
p [expr]
|
||||
```
|
||||
|
||||
expr: expression
|
||||
|
||||
The expression is mandatory.
|
||||
The displayed expressions will be serially ordered from 1.
|
||||
If an exception occurs, the exception information will be displayed and the debugging will be continued.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
(sample.rb:1) print 1+2
|
||||
$1 = 3
|
||||
(sample.rb:1) print self
|
||||
$2 = main
|
||||
```
|
||||
|
||||
Below is the case of the exception:
|
||||
|
||||
```
|
||||
(sample.rb:1) print (1+2
|
||||
$1 = SyntaxError: line 1: syntax error, unexpected $end, expecting ')'
|
||||
```
|
||||
|
||||
#### Quit Command
|
||||
|
||||
Quitting the debugger.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
quit
|
||||
q
|
||||
```
|
||||
|
||||
#### Run Command
|
||||
|
||||
Running the program and stopping at the first breakpoint.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
run
|
||||
r
|
||||
```
|
||||
|
||||
#### Step Command
|
||||
|
||||
This will run the program step by step.
|
||||
When the method and the block are invoked, the program will be stop at the first row.
|
||||
The program, which is developed in C, will be ignored.
|
||||
@@ -0,0 +1,171 @@
|
||||
# How to use `mrb_gc_arena_save()`/`mrb_gc_arena_restore()`
|
||||
|
||||
This is basically English translation of [Matz's blog post](http://www.rubyist.net/~matz/20130731.html) written in Japanese.
|
||||
Some parts are updated to reflect recent changes.
|
||||
|
||||
When you are extending mruby using C language, you may encounter
|
||||
mysterious "arena overflow error" or memory leak or very slow
|
||||
execution speed. This is an error indicating overflow of "GC arena"
|
||||
implementing "conservative GC".
|
||||
|
||||
GC (garbage collector) must ensure that object is "alive", in other
|
||||
words, that it is referenced by somewhere from program. This can be
|
||||
determined by checking that that object can be directly or indirectly
|
||||
referenced by root. The local variables, global variables and
|
||||
constants etc are root.
|
||||
|
||||
If program execution is performed inside mruby VM, there is nothing to
|
||||
worry about because GC can access all roots owned by VM.
|
||||
|
||||
The problem arises when executing C functions. The object referenced
|
||||
by C variable is also "alive", but mruby GC cannot aware of this, so
|
||||
it might mistakenly recognize the objects referenced by only C
|
||||
variables as dead.
|
||||
|
||||
It is a fatal bug for GC to collect live objects.
|
||||
|
||||
In CRuby, we scan C stack area, and use C variable as root to check
|
||||
whether object is alive or not. Of course, because we are accessing C
|
||||
stack just as memory region, we never know it is an integer or a
|
||||
pointer. We workaround this by assuming that if it looks like a
|
||||
pointer, then assume it as a pointer. We call it "conservative".
|
||||
|
||||
By the way, CRuby's "conservative GC" has some problems.
|
||||
|
||||
Its biggest problem is we have no way to access to the stack area in
|
||||
portable way. Therefore, we cannot use this method if we'd like to
|
||||
implement highly portable runtime, like mruby.
|
||||
|
||||
So we came up an another plan to implement "conservative GC" in mruby.
|
||||
|
||||
Again, the problem is that there is an object which was created in C
|
||||
function, and is not referenced by Ruby world, and cannot be treated
|
||||
as garbage.
|
||||
|
||||
In mruby, we recognize all objects created in C function are alive.
|
||||
Then we have no problem such as recognizing live object as dead.
|
||||
|
||||
This means that because we cannot collect truly dead object, we may
|
||||
get a little bit less efficiency, but GC itself is highly portable.
|
||||
We can say goodbye to the problem that GC deletes live objects due to
|
||||
optimization which sometimes occurs in CRuby.
|
||||
|
||||
According to this idea, we have a table, called "GC arena", which
|
||||
remembers objects created in C function. The arena is stack
|
||||
structure, when C function execution is returned to mruby VM, all
|
||||
objects registered in the arena are popped.
|
||||
|
||||
This works very well, but GC arena causes another problem. "arena
|
||||
overflow error" or memory leak.
|
||||
|
||||
As of this writing, mruby automatically extend arena to remember
|
||||
objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in
|
||||
doc/mrbconf/README.md). If you keep creating objects in C functions,
|
||||
it increases memory usage, since GC never kick in. This memory usage
|
||||
may look like memory leak, and also makes execution slower.
|
||||
|
||||
With the build time configuration, you can limit the maximum size of
|
||||
arena (e.g., 100). Then if you create many objects, arena overflows,
|
||||
thus you will get "arena overflow error".
|
||||
|
||||
To workaround these problems, we have `mrb_gc_arena_save()` and
|
||||
`mrb_gc_arena_restore()` functions.
|
||||
|
||||
`int mrb_gc_arena_save(mrb)` returns the current position of the stack
|
||||
top of GC arena, and `void mrb_gc_arena_restore(mrb, idx)` sets the
|
||||
stack top position to back to given idx. We uses them like so:
|
||||
|
||||
```c
|
||||
int arena_idx = mrb_gc_arena_save(mrb);
|
||||
|
||||
...create objects...
|
||||
mrb_gc_arena_restore(mrb, arena_idx);
|
||||
|
||||
```
|
||||
|
||||
In mruby, C function call are surrounded by this save/restore, but we
|
||||
can further optimize memory usage by surrounding save/restore, and can
|
||||
avoid arena overflow.
|
||||
|
||||
Let's take a real example. Here is the source code of `Array#inspect`:
|
||||
|
||||
```c
|
||||
static mrb_value
|
||||
inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
|
||||
{
|
||||
mrb_int i;
|
||||
mrb_value s, arystr;
|
||||
char head[] = { '[' };
|
||||
char sep[] = { ',', ' ' };
|
||||
char tail[] = { ']' };
|
||||
|
||||
/* check recursive */
|
||||
for(i=0; i<RARRAY_LEN(list); i++) {
|
||||
if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) {
|
||||
return mrb_str_new(mrb, "[...]", 5);
|
||||
}
|
||||
}
|
||||
|
||||
mrb_ary_push(mrb, list, ary);
|
||||
|
||||
arystr = mrb_str_buf_new(mrb, 64);
|
||||
mrb_str_buf_cat(mrb, arystr, head, sizeof(head));
|
||||
|
||||
for(i=0; i<RARRAY_LEN(ary); i++) {
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
|
||||
if (i > 0) {
|
||||
mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep));
|
||||
}
|
||||
if (mrb_array_p(RARRAY_PTR(ary)[i])) {
|
||||
s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list);
|
||||
}
|
||||
else {
|
||||
s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]);
|
||||
}
|
||||
mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s));
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
}
|
||||
|
||||
mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail));
|
||||
mrb_ary_pop(mrb, list);
|
||||
|
||||
return arystr;
|
||||
}
|
||||
```
|
||||
|
||||
This is a real example, so a little bit complicated, so bear with me.
|
||||
The essence of `Array#inspect` is that after stringifying each element
|
||||
of array using `inspect` method, we join them together so that we can
|
||||
get `inspect` representation of entire array.
|
||||
|
||||
After the `inspect` representation of entire array is created, we no
|
||||
longer require the individual string representation. That means that
|
||||
we don't have to register these temporal objects into GC arena.
|
||||
|
||||
Therefore, in `ary_inspect()` function, we do:
|
||||
|
||||
* save the position of the stack top using `mrb_gc_arena_save()`.
|
||||
* get `inspect` representation of each element.
|
||||
* append it to the constructing entire `inspect` representation of array.
|
||||
* restore stack top position using `mrb_gc_arena_restore()`.
|
||||
|
||||
to keep the arena size small.
|
||||
|
||||
Please note that the final `inspect` representation of entire array
|
||||
was created before the call of `mrb_gc_arena_restore()`. Otherwise,
|
||||
required temporal object may be deleted by GC.
|
||||
|
||||
We may have a usecase that after creating many temporal objects, we'd
|
||||
like to keep some of them. In this case, we cannot use the same idea
|
||||
in `ary_inspect()` like appending objects to existing one. Instead,
|
||||
after `mrb_gc_arena_restore()`, we register back the objects we'd like
|
||||
to keep to the arena using `mrb_gc_protect(mrb, obj)`. Use
|
||||
`mrb_gc_protect()` with caution because its usage could lead to arena
|
||||
overflow error.
|
||||
|
||||
We also have to mention that when `mrb_funcall` is called in top
|
||||
level, its return value is also registered to GC arena, so calling
|
||||
them repeatedly eventually lead to arena overflow error. Use
|
||||
`mrb_gc_arena_save()` and `mrb_gc_arena_restore()` or possible use of
|
||||
`mrb_gc_protect()` to workaround this.
|
||||
@@ -3,7 +3,7 @@
|
||||
## How to use these macros.
|
||||
You can use mrbconfs with following ways:
|
||||
* Write them in `mrbconf.h`.
|
||||
* Using compiler flags is prefered when building a cross binaries or multiple mruby binaries
|
||||
* Using compiler flags is preferred when building a cross binaries or multiple mruby binaries
|
||||
since it's easier to use different mrbconf per each `MRuby::Build`.
|
||||
* Most flags can be enabled by just commenting in.
|
||||
* Pass them as compiler flags.
|
||||
@@ -11,11 +11,7 @@ You can use mrbconfs with following ways:
|
||||
changes `struct` layout and cause memory access error when C and other language(e.g., C++) is mixed.
|
||||
|
||||
## stdio setting.
|
||||
`ENABLE_STDIO`
|
||||
* Will be defined automatically if `DISABLE_STDIO` isn't defined.
|
||||
* Uses `<stdio.h>` functions.
|
||||
|
||||
`DISABLE_STDIO`
|
||||
`MRB_DISABLE_STDIO`
|
||||
* When defined `<stdio.h>` functions won't be used.
|
||||
* Some features will be disabled when this is enabled:
|
||||
* `mrb_irep` load/dump from/to file.
|
||||
@@ -23,15 +19,12 @@ You can use mrbconfs with following ways:
|
||||
* Printing features in **src/print.c**.
|
||||
|
||||
## Debug macros.
|
||||
`ENABLE_DEBUG`
|
||||
`MRB_ENABLE_DEBUG_HOOK`
|
||||
* When defined code fetch hook and debug OP hook will be enabled.
|
||||
* When using any of the hook set function pointer `code_fetch_hook` and/or `debug_op_hook` of `mrb_state`.
|
||||
* Fetch hook will be called before any OP.
|
||||
* Debug OP hook will be called when dispatching `OP_DEBUG`.
|
||||
|
||||
`DISABLE_DEBUG`
|
||||
* Will be define automatically if `ENABLE_DEBUG` isn't defined.
|
||||
|
||||
`MRB_DEBUG`
|
||||
* When defined `mrb_assert*` macro will be defined with macros from `<assert.h>`.
|
||||
* Could be enabled via `enable_debug` method of `MRuby::Build`.
|
||||
@@ -145,6 +138,10 @@ largest value of required alignment.
|
||||
* Ignored when `MRB_USE_IV_SEGLIST` is defined.
|
||||
|
||||
## Other configuration.
|
||||
`MRB_UTF8_STRING`
|
||||
* Adds UTF-8 encoding support to character-oriented String instance methods.
|
||||
* If it isn't defined, they only support the US-ASCII encoding.
|
||||
|
||||
`MRB_FUNCALL_ARGC_MAX`
|
||||
* Default value is `16`.
|
||||
* Specifies 4th argument(`argc`) max value of `mrb_funcall`.
|
||||
@@ -26,6 +26,15 @@ conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master'
|
||||
conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master'
|
||||
```
|
||||
|
||||
To use mrbgem from [mgem-list](https://github.com/mruby/mgem-list) use `:mgem` option:
|
||||
```ruby
|
||||
conf.gem :mgem => 'mruby-yaml'
|
||||
conf.gem :mgem => 'yaml' # 'mruby-' prefix could be omitted
|
||||
```
|
||||
|
||||
If there is missing dependencies, mrbgem dependencies solver will reference
|
||||
mrbgem from core or mgem-list.
|
||||
|
||||
To pull all gems from remote GIT repository on build, call ```./minirake -p```,
|
||||
or ```./minirake --pull-gems```.
|
||||
|
||||
@@ -142,7 +151,7 @@ MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
|
||||
# Use any version of mruby-uv from github.
|
||||
spec.add_dependency('mruby-uv', '>= 0.0.0', :github => 'mattn/mruby-uv')
|
||||
|
||||
# Use latest mruby-onig-regexp from github. (version requirements can be ignored)
|
||||
# Use latest mruby-onig-regexp from github. (version requirements can be omitted)
|
||||
spec.add_dependency('mruby-onig-regexp', :github => 'mattn/mruby-onig-regexp')
|
||||
end
|
||||
```
|
||||
@@ -189,18 +198,22 @@ end
|
||||
In case your GEM has more complex build requirements you can use
|
||||
the following options additionally inside of your GEM specification:
|
||||
|
||||
* `spec.cflags` (C compiler flags)
|
||||
* `spec.mruby_cflags` (global C compiler flags for everything)
|
||||
* `spec.mruby_ldflags` (global linker flags for everything)
|
||||
* `spec.mruby_libs` (global libraries for everything)
|
||||
* `spec.mruby_includes` (global includes for everything)
|
||||
* `spec.cc.flags` (C compiler flags)
|
||||
* `spec.cc.defines` (C compiler defines)
|
||||
* `spec.cc.include_paths` (C compiler include paths)
|
||||
* `spec.linker.flags` (Linker flags)
|
||||
* `spec.linker.libraries` (Linker libraries)
|
||||
* `spec.linker.library_paths` (Linker additional library path)
|
||||
* `spec.bins` (Generate binary file)
|
||||
* `spec.rbfiles` (Ruby files to compile)
|
||||
* `spec.objs` (Object files to compile)
|
||||
* `spec.test_rbfiles` (Ruby test files for integration into mrbtest)
|
||||
* `spec.test_objs` (Object test files for integration into mrbtest)
|
||||
* `spec.test_preload` (Initialization files for mrbtest)
|
||||
|
||||
### include_paths and depencency
|
||||
You also can use `spec.mruby.cc` and `spec.mruby.linker` to add extra global parameters for compiler and linker.
|
||||
|
||||
### include_paths and dependency
|
||||
|
||||
Your GEM can export include paths to another GEMs that depends on your GEM.
|
||||
By default, `/...absolute path.../{GEM_NAME}/include` will be exported.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +0,0 @@
|
||||
# Language
|
||||
|
||||
mruby is an implementation of the Ruby programming language.
|
||||
These documents are describing the language features and libraries
|
||||
which are provided together with mruby.
|
||||
|
||||
## Built-In Class and Modules
|
||||
|
||||
see *doc/language/Core.md*
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'pty'
|
||||
|
||||
c_dir = File.dirname(__FILE__)
|
||||
MRUBY_ROOT = File.expand_path("#{c_dir}/../..")
|
||||
DOC_DIR = File.expand_path(c_dir)
|
||||
|
||||
cmd = "ruby #{DOC_DIR}/mrbdoc/mrbdoc.rb #{MRUBY_ROOT} #{DOC_DIR} false"
|
||||
IO.popen(cmd, "r+") do |io|
|
||||
io.close_write
|
||||
while line = io.gets
|
||||
puts line
|
||||
end
|
||||
end
|
||||
@@ -1,231 +0,0 @@
|
||||
class MRBDoc
|
||||
SRC_DIR = 'src'
|
||||
MRBLIB_DIR = 'mrblib'
|
||||
|
||||
def analyze_code dir, &block
|
||||
@mrb_files = {}
|
||||
@dir = File.expand_path(dir)
|
||||
|
||||
block.call "MRBDOC\tanalyze #{@dir}"
|
||||
|
||||
analyze(dir) do |progress|
|
||||
block.call progress
|
||||
end
|
||||
end
|
||||
|
||||
def each_file(&block); @mrb_files.each {|k,v| block.call k,v}; end
|
||||
|
||||
def find_c_func(c_func_name)
|
||||
each_file do |file_name, file|
|
||||
c_func = file.c_funcs(c_func_name)
|
||||
return c_func unless c_func.nil?
|
||||
end
|
||||
{}
|
||||
end
|
||||
|
||||
def find_c_file(rb_obj_name, c_func_name)
|
||||
last_file_name_match = ''
|
||||
each_file do |file_name, file|
|
||||
c_func = file.c_funcs(c_func_name)
|
||||
if c_func and file.rb_class(rb_obj_name) or file.rb_module(rb_obj_name)
|
||||
return file_name
|
||||
elsif c_func
|
||||
last_file_name_match = file_name
|
||||
end
|
||||
end
|
||||
last_file_name_match
|
||||
end
|
||||
|
||||
def find_c_file_by_class(name)
|
||||
each_file do |file_name, file|
|
||||
rb_class = file.rb_class(name)
|
||||
return file_name unless rb_class.nil?
|
||||
end
|
||||
'nil'
|
||||
end
|
||||
|
||||
def find_c_file_by_module(name)
|
||||
each_file do |file_name, file|
|
||||
rb_module = file.rb_module(name)
|
||||
return file_name unless rb_module.nil?
|
||||
end
|
||||
'nil'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def analyze dir, &block
|
||||
collect_all_files dir, &block
|
||||
end
|
||||
|
||||
def collect_all_files dir, &block
|
||||
l = lambda {|f| block.call " - #{f.name}"}
|
||||
collect_files(src_code_dir(dir), /\.c$/, &l)
|
||||
collect_files(mrb_code_dir(dir), /\.rb$/, &l)
|
||||
end
|
||||
|
||||
def collect_files dir, rxp, &block
|
||||
Dir.foreach(dir) do |file|
|
||||
next unless file =~ rxp
|
||||
|
||||
file_path = "#{dir}/#{file}"
|
||||
mrb_file = MRBFile.new "#{file_path}"
|
||||
@mrb_files["#{file_path}"] = mrb_file
|
||||
|
||||
block.call mrb_file
|
||||
end
|
||||
end
|
||||
|
||||
def src_code_dir dir; File.expand_path SRC_DIR, dir; end
|
||||
def mrb_code_dir dir; File.expand_path MRBLIB_DIR, dir; end
|
||||
end
|
||||
|
||||
class MRBFile
|
||||
attr_reader :name
|
||||
attr_reader :file
|
||||
|
||||
def initialize mrb_file
|
||||
@file = mrb_file
|
||||
@name = File.basename file
|
||||
@c_funcs = {}
|
||||
@rb_class_c_def = {}
|
||||
@rb_method_c_def = {}
|
||||
@rb_class_method_c_def = {}
|
||||
@rb_module_c_def = {}
|
||||
@last_line = nil
|
||||
@assignments = {}
|
||||
|
||||
@assignments['mrb->object_class'] = 'Object'
|
||||
@assignments['mrb->kernel_module'] = 'Kernel'
|
||||
@assignments['mrb->module_class'] = 'Module'
|
||||
@assignments['mrb->nil_class'] = 'NilClass'
|
||||
@assignments['mrb->true_class'] = 'TrueClass'
|
||||
@assignments['mrb->class_class'] = 'Class'
|
||||
|
||||
analyze
|
||||
end
|
||||
|
||||
def each_class &block
|
||||
@rb_class_c_def.each do |class_name, class_hsh|
|
||||
block.call class_name, class_hsh
|
||||
end
|
||||
end
|
||||
|
||||
def each_method name, &block
|
||||
@rb_method_c_def.each do |met_name, met_hsh|
|
||||
met_name_tmp = met_name.sub /^#{name}_/, ''
|
||||
block.call met_name_tmp, met_hsh if met_hsh[:rb_class] == name
|
||||
end
|
||||
end
|
||||
|
||||
def each_class_method name, &block
|
||||
@rb_class_method_c_def.each do |met_name, met_hsh|
|
||||
met_name_tmp = met_name.sub /^#{name}_/, ''
|
||||
block.call met_name_tmp, met_hsh if met_hsh[:rb_class] == name
|
||||
end
|
||||
end
|
||||
|
||||
def each_module &block
|
||||
@rb_module_c_def.each do |module_name, module_hsh|
|
||||
block.call module_name, module_hsh
|
||||
end
|
||||
end
|
||||
|
||||
def each_core_object &block
|
||||
each_class {|n| block.call n}
|
||||
each_module {|n| block.call n}
|
||||
end
|
||||
|
||||
def c_funcs c_func_name; @c_funcs[c_func_name]; end
|
||||
def rb_class rb_class_name; @rb_class_c_def[rb_class_name]; end
|
||||
def rb_module rb_module_name; @rb_module_c_def[rb_module_name]; end
|
||||
|
||||
private
|
||||
|
||||
def analyze
|
||||
File.open(file).each_line.each_with_index do |line, idx|
|
||||
line_no = idx.succ
|
||||
if c_file?
|
||||
analyze_c_line line, line_no
|
||||
elsif rb_file?
|
||||
analyze_rb_line line, line_no
|
||||
else
|
||||
raise ArgumentError.new "#{file} is a not supported file type"
|
||||
end
|
||||
@last_line = line.strip
|
||||
end
|
||||
end
|
||||
|
||||
def c_file?; (name =~ /\.c$/); end
|
||||
def rb_file?; (name =~ /\.rb$/); end
|
||||
|
||||
RXP_C_VAR = /\s*([^\s]*?)\s*?/
|
||||
RXP_C_STR = /\s*?\"(.*?)\"\s*?/
|
||||
#RXP_C_ISO = /\s*\;\s*[\/\*]*\s*.*?([15\.]{0,3}[0-9\.]*)\s*[\\\\\*]*/
|
||||
RXP_C_ISO = /\s*;\s*[\/\*]*[\sa-zA-Z]*([\d\.]*)[\sa-zA-Z]*[\*\/]*/
|
||||
|
||||
def analyze_c_line line, line_no
|
||||
case line.strip
|
||||
when /^([a-zA-Z\_][a-zA-Z\_0-9]*?)\((.*?)\)\s*?$/
|
||||
# assuming c method definition
|
||||
@c_funcs[$1] = {:line_no => line_no, :args => $2, :return => @last_line}
|
||||
when /mrb_define_class\(.*?\,#{RXP_C_STR}\,#{RXP_C_VAR}\)#{RXP_C_ISO}/
|
||||
# assuming ruby class definition in c
|
||||
class_name = $1.clone
|
||||
iso = $3.clone
|
||||
iso.strip!
|
||||
@rb_class_c_def[class_name] = {:c_object => $2, :iso => iso}
|
||||
assigns = line.split '='
|
||||
if assigns.size > 1
|
||||
assigns[0..-2].each do |v|
|
||||
@assignments[v.strip] = class_name
|
||||
end
|
||||
end
|
||||
when /mrb_define_module\(.*?\,#{RXP_C_STR}\)#{RXP_C_ISO}/
|
||||
# assuming ruby class definition in c
|
||||
module_name = $1.clone
|
||||
iso = $2.clone
|
||||
iso.strip!
|
||||
@rb_module_c_def[module_name] = {:iso => iso}
|
||||
assigns = line.split '='
|
||||
if assigns.size > 1
|
||||
assigns[0..-2].each do |v|
|
||||
@assignments[v.strip] = module_name
|
||||
end
|
||||
end
|
||||
when /mrb_define_method\(.*?\,#{RXP_C_VAR}\,#{RXP_C_STR}\,#{RXP_C_VAR}\,#{RXP_C_VAR}\)#{RXP_C_ISO}/
|
||||
# assuming ruby method definition in c
|
||||
name = $1.clone
|
||||
name = resolve_obj(name)
|
||||
iso = $5.clone
|
||||
iso.strip!
|
||||
@rb_method_c_def["#{name}_#{$2}"] = {:c_func => $3, :args => $4, :rb_class => name, :iso => iso}
|
||||
when /mrb_define_class_method\(.*?\,#{RXP_C_VAR}\,#{RXP_C_STR}\,#{RXP_C_VAR}\,#{RXP_C_VAR}\)#{RXP_C_ISO}/
|
||||
# assuming ruby class method definition in c
|
||||
class_name = $1.clone
|
||||
class_name = resolve_obj(class_name)
|
||||
iso = $5.clone
|
||||
iso.strip!
|
||||
@rb_class_method_c_def["#{class_name}_#{$2}"] = {:c_func => $3, :args => $4, :rb_class => class_name, :iso => iso}
|
||||
when /mrb_name_class\(.*?\,#{RXP_C_VAR}\,\s*mrb_intern\(.*?,#{RXP_C_STR}\)\)#{RXP_C_ISO}/
|
||||
class_name = $2.clone
|
||||
iso = $3.clone
|
||||
iso.strip!
|
||||
@rb_class_c_def[class_name] = {:c_object => $1, :iso => iso}
|
||||
@assignments[$1] = class_name
|
||||
when /mrb_include_module\(.*?\,#{RXP_C_VAR}\,\s*mrb_class_get\(.*?\,#{RXP_C_STR}\)\)/
|
||||
class_name = resolve_obj($1)
|
||||
mod = $2.clone
|
||||
@rb_class_c_def[class_name][:include] = [] unless @rb_class_c_def[class_name].has_key? :include
|
||||
@rb_class_c_def[class_name][:include] << mod
|
||||
end
|
||||
end
|
||||
|
||||
def analyze_rb_line line, line_no
|
||||
|
||||
end
|
||||
|
||||
def resolve_obj c_var
|
||||
@assignments[c_var]
|
||||
end
|
||||
end
|
||||
@@ -1,118 +0,0 @@
|
||||
class MRBDoc
|
||||
def write_documentation dir, cfg, &block
|
||||
block.call "MRBDOC\twrite to #{File.expand_path(dir)}"
|
||||
|
||||
write(dir, cfg) do |progress|
|
||||
block.call progress
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def write dir, cfg
|
||||
File.open(File.expand_path('Core.md', dir), 'wb+') do |io|
|
||||
print_core_classes(io, cfg)
|
||||
print_core_modules(io, cfg)
|
||||
end
|
||||
end
|
||||
|
||||
def get_core_list id
|
||||
core_list = {}
|
||||
each_file do |file_path, mrb_file|
|
||||
mrb_file.send(id) do |name, cls_hsh|
|
||||
core_list[name] = {:data => cls_hsh, :methods => {}, :class_methods => {}}
|
||||
mrb_file.each_method name do |met_name, met_hsh|
|
||||
core_list[name][:methods][met_name] = met_hsh
|
||||
end
|
||||
mrb_file.each_class_method name do |met_name, met_hsh|
|
||||
core_list[name][:class_methods][met_name] = met_hsh
|
||||
end
|
||||
end
|
||||
end
|
||||
core_list
|
||||
end
|
||||
|
||||
def print_core_classes(io, cfg)
|
||||
core_list = get_core_list :each_class
|
||||
io.puts "# Core Classes\n\n"
|
||||
core_list.sort.each do |name, hsh|
|
||||
file = find_c_file_by_class(name)
|
||||
file = file.split("#{@dir}/")[1]
|
||||
iso = hsh[:data][:iso]
|
||||
iso = 'n/a' if iso.nil? or iso == ''
|
||||
mixins = hsh[:data][:include].join(', ') unless hsh[:data][:include].nil?
|
||||
mixins = 'n/a' if mixins.nil? or mixins == ''
|
||||
|
||||
io.puts <<CLASS
|
||||
## #{name}
|
||||
|
||||
ISO Code | Mixins | Source File
|
||||
--- | --- | ---
|
||||
#{iso} | #{mixins} | #{file}
|
||||
|
||||
CLASS
|
||||
print_class_methods(io, hsh, cfg)
|
||||
print_methods(io, hsh, cfg)
|
||||
end
|
||||
end
|
||||
|
||||
def print_core_modules(io, cfg)
|
||||
core_list = get_core_list :each_module
|
||||
io.puts "# Core Modules\n\n"
|
||||
core_list.sort.each do |name, hsh|
|
||||
file = find_c_file_by_module(name)
|
||||
file = file.split("#{@dir}/")[1]
|
||||
iso = hsh[:data][:iso]
|
||||
iso = 'n/a' if iso.nil? or iso == ''
|
||||
|
||||
io.puts <<CLASS
|
||||
## #{name}
|
||||
|
||||
ISO Code | Source File
|
||||
--- | ---
|
||||
#{iso} | #{file}
|
||||
|
||||
CLASS
|
||||
print_class_methods(io, hsh, cfg)
|
||||
print_methods(io, hsh, cfg)
|
||||
end
|
||||
end
|
||||
|
||||
def print_methods(io, hsh, cfg)
|
||||
return unless hsh[:methods].size > 0
|
||||
io.puts "### Methods\n\n"
|
||||
hsh[:methods].sort.each do |met_name, met_hsh|
|
||||
print_method(io, met_name, met_hsh, cfg)
|
||||
end
|
||||
end
|
||||
|
||||
def print_class_methods(io, hsh, cfg)
|
||||
return unless hsh[:class_methods].size > 0
|
||||
io.puts "### Class Methods\n\n"
|
||||
hsh[:class_methods].sort.each do |met_name, met_hsh|
|
||||
print_method(io, met_name, met_hsh, cfg)
|
||||
end
|
||||
end
|
||||
|
||||
def print_method(io, met_name, met_hsh, cfg)
|
||||
if cfg[:print_line_no]
|
||||
line_no_head = ' | Line'
|
||||
line_no = " | #{find_c_func(met_hsh[:c_func])[:line_no]}"
|
||||
else
|
||||
line_no, line_no_head = '', ''
|
||||
end
|
||||
file = find_c_file(met_hsh[:rb_class], met_hsh[:c_func])
|
||||
file = file.split("#{@dir}/")[1]
|
||||
iso = met_hsh[:iso]
|
||||
iso = 'n/a' if iso.nil? or iso == ''
|
||||
|
||||
io.puts <<METHOD
|
||||
#### #{met_name}
|
||||
|
||||
ISO Code | Source File | C Function#{line_no_head}
|
||||
--- | --- | ---
|
||||
#{iso} | #{file} | #{met_hsh[:c_func]}#{line_no}
|
||||
|
||||
METHOD
|
||||
end
|
||||
end
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
$: << File.dirname(__FILE__) + '/lib'
|
||||
|
||||
require 'mrbdoc_analyze'
|
||||
require 'mrbdoc_docu'
|
||||
|
||||
MRUBY_ROOT = ARGV[0]
|
||||
DOC_ROOT = ARGV[1]
|
||||
_WRITE_LINE_NO = ARGV[2]
|
||||
STDOUT.sync = true
|
||||
|
||||
raise ArgumentError.new 'mruby root missing!' if MRUBY_ROOT.nil?
|
||||
raise ArgumentError.new 'doc root missing!' if DOC_ROOT.nil?
|
||||
|
||||
if _WRITE_LINE_NO.nil?
|
||||
WRITE_LINE_NO = true
|
||||
else
|
||||
case _WRITE_LINE_NO
|
||||
when 'true'
|
||||
WRITE_LINE_NO = true
|
||||
when 'false'
|
||||
WRITE_LINE_NO = false
|
||||
else
|
||||
raise ArgumentError.new 'Line no parameter has to be false or true!'
|
||||
end
|
||||
end
|
||||
|
||||
mrbdoc = MRBDoc.new
|
||||
|
||||
mrbdoc.analyze_code MRUBY_ROOT do |progress|
|
||||
puts progress
|
||||
end
|
||||
|
||||
cfg = {:print_line_no => WRITE_LINE_NO}
|
||||
mrbdoc.write_documentation DOC_ROOT, cfg do |progress|
|
||||
puts progress
|
||||
end
|
||||
@@ -50,7 +50,7 @@ MRuby::CrossBuild.new("ArduinoDue") do |conf|
|
||||
cc.defines << %w(KHASH_DEFAULT_SIZE=8)
|
||||
cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
|
||||
cc.defines << %w(MRB_GC_STRESS)
|
||||
#cc.defines << %w(DISABLE_STDIO) #if you dont need stdio.
|
||||
#cc.defines << %w(MRB_DISABLE_STDIO) #if you dont need stdio.
|
||||
#cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval
|
||||
end
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ MRuby::CrossBuild.new("chipKITMax32") do |conf|
|
||||
cc.defines << %w(KHASH_DEFAULT_SIZE=8)
|
||||
cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
|
||||
cc.defines << %w(MRB_GC_STRESS)
|
||||
#cc.defines << %w(DISABLE_STDIO) #if you dont need stdio.
|
||||
#cc.defines << %w(MRB_DISABLE_STDIO) #if you dont need stdio.
|
||||
#cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval
|
||||
end
|
||||
|
||||
|
||||
+16
-22
@@ -26,6 +26,9 @@
|
||||
/* represent mrb_value as a word (natural unit of data for the processor) */
|
||||
//#define MRB_WORD_BOXING
|
||||
|
||||
/* string class to handle UTF-8 encoding */
|
||||
//#define MRB_UTF8_STRING
|
||||
|
||||
/* argv max size in mrb_funcall */
|
||||
//#define MRB_FUNCALL_ARGC_MAX 16
|
||||
|
||||
@@ -72,23 +75,25 @@
|
||||
/* fixed size state atexit stack */
|
||||
//#define MRB_FIXED_STATE_ATEXIT_STACK
|
||||
|
||||
/* -DDISABLE_XXXX to drop following features */
|
||||
//#define DISABLE_STDIO /* use of stdio */
|
||||
/* -DMRB_DISABLE_XXXX to drop following features */
|
||||
//#define MRB_DISABLE_STDIO /* use of stdio */
|
||||
|
||||
/* -DENABLE_XXXX to enable following features */
|
||||
//#define ENABLE_DEBUG /* hooks for debugger */
|
||||
/* -DMRB_ENABLE_XXXX to enable following features */
|
||||
//#define MRB_ENABLE_DEBUG_HOOK /* hooks for debugger */
|
||||
|
||||
/* end of configuration */
|
||||
|
||||
/* define ENABLE_XXXX from DISABLE_XXX */
|
||||
#ifndef DISABLE_STDIO
|
||||
#define ENABLE_STDIO
|
||||
#endif
|
||||
#ifndef ENABLE_DEBUG
|
||||
#define DISABLE_DEBUG
|
||||
/* define MRB_DISABLE_XXXX from DISABLE_XXX (for compatibility) */
|
||||
#ifdef DISABLE_STDIO
|
||||
#define MRB_DISABLE_STDIO
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
/* define MRB_ENABLE_XXXX from ENABLE_XXX (for compatibility) */
|
||||
#ifdef ENABLE_DEBUG
|
||||
#define MRB_ENABLE_DEBUG_HOOK
|
||||
#endif
|
||||
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
@@ -100,15 +105,4 @@
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#if defined(MRB_BUILD_AS_DLL)
|
||||
|
||||
#if defined(MRB_CORE) || defined(MRB_LIB)
|
||||
#define MRB_API __declspec(dllexport)
|
||||
#else
|
||||
#define MRB_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define MRB_API extern
|
||||
#endif
|
||||
|
||||
#endif /* MRUBYCONF_H */
|
||||
|
||||
+703
-95
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
** mruby - An embeddable Ruby implementation
|
||||
**
|
||||
** Copyright (c) mruby developers 2010-2014
|
||||
** Copyright (c) mruby developers 2010-2015
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
@@ -28,30 +28,43 @@
|
||||
#ifndef MRUBY_H
|
||||
#define MRUBY_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "mrbconf.h"
|
||||
#include "mruby/common.h"
|
||||
#include "mruby/value.h"
|
||||
#include "mruby/gc.h"
|
||||
#include "mruby/version.h"
|
||||
|
||||
/**
|
||||
* MRuby C API entry point
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
typedef uint32_t mrb_code;
|
||||
|
||||
/**
|
||||
* Required arguments signature type.
|
||||
*/
|
||||
typedef uint32_t mrb_aspec;
|
||||
|
||||
|
||||
struct mrb_irep;
|
||||
struct mrb_state;
|
||||
|
||||
/**
|
||||
* Function pointer type of custom allocator used in @see mrb_open_allocf.
|
||||
*
|
||||
* The function pointing it must behave similarly as realloc except:
|
||||
* - If ptr is NULL it must allocate new space.
|
||||
* - If s is NULL, ptr must be freed.
|
||||
*
|
||||
* See @see mrb_default_allocf for the default implementation.
|
||||
*/
|
||||
typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud);
|
||||
|
||||
#ifndef MRB_GC_ARENA_SIZE
|
||||
#define MRB_GC_ARENA_SIZE 100
|
||||
#endif
|
||||
|
||||
#ifndef MRB_FIXED_STATE_ATEXIT_STACK_SIZE
|
||||
#define MRB_FIXED_STATE_ATEXIT_STACK_SIZE 5
|
||||
#endif
|
||||
@@ -98,12 +111,6 @@ struct mrb_context {
|
||||
struct RFiber *fib;
|
||||
};
|
||||
|
||||
enum gc_state {
|
||||
GC_STATE_ROOT = 0,
|
||||
GC_STATE_MARK,
|
||||
GC_STATE_SWEEP
|
||||
};
|
||||
|
||||
struct mrb_jmpbuf;
|
||||
|
||||
typedef void (*mrb_atexit_func)(struct mrb_state*);
|
||||
@@ -137,39 +144,15 @@ typedef struct mrb_state {
|
||||
struct RClass *symbol_class;
|
||||
struct RClass *kernel_module;
|
||||
|
||||
struct heap_page *heaps; /* heaps for GC */
|
||||
struct heap_page *sweeps;
|
||||
struct heap_page *free_heaps;
|
||||
size_t live; /* count of live objects */
|
||||
#ifdef MRB_GC_FIXED_ARENA
|
||||
struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */
|
||||
#else
|
||||
struct RBasic **arena; /* GC protection array */
|
||||
int arena_capa;
|
||||
#endif
|
||||
int arena_idx;
|
||||
|
||||
enum gc_state gc_state; /* state of gc */
|
||||
int current_white_part; /* make white object by white_part */
|
||||
struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */
|
||||
struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */
|
||||
size_t gc_live_after_mark;
|
||||
size_t gc_threshold;
|
||||
int gc_interval_ratio;
|
||||
int gc_step_ratio;
|
||||
mrb_bool gc_disabled:1;
|
||||
mrb_bool gc_full:1;
|
||||
mrb_bool is_generational_gc_mode:1;
|
||||
mrb_bool out_of_memory:1;
|
||||
size_t majorgc_old_threshold;
|
||||
struct alloca_header *mems;
|
||||
mrb_gc gc;
|
||||
|
||||
mrb_sym symidx;
|
||||
struct kh_n2s *name2sym; /* symbol hash */
|
||||
struct symbol_name *symtbl; /* symbol table */
|
||||
size_t symcapa;
|
||||
|
||||
#ifdef ENABLE_DEBUG
|
||||
#ifdef MRB_ENABLE_DEBUG_HOOK
|
||||
void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
|
||||
void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
|
||||
#endif
|
||||
@@ -188,79 +171,618 @@ typedef struct mrb_state {
|
||||
mrb_int atexit_stack_len;
|
||||
} mrb_state;
|
||||
|
||||
#if __STDC_VERSION__ >= 201112L
|
||||
# define mrb_noreturn _Noreturn
|
||||
#elif defined __GNUC__ && !defined __STRICT_ANSI__
|
||||
# define mrb_noreturn __attribute__((noreturn))
|
||||
#elif defined _MSC_VER
|
||||
# define mrb_noreturn __declspec(noreturn)
|
||||
#else
|
||||
# define mrb_noreturn
|
||||
#endif
|
||||
|
||||
typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
|
||||
MRB_API struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass*);
|
||||
|
||||
/**
|
||||
* Defines a new class.
|
||||
*
|
||||
* If you're creating a gem it may look something like this:
|
||||
*
|
||||
* !!!c
|
||||
* void mrb_example_gem_init(mrb_state* mrb) {
|
||||
* struct RClass *example_class;
|
||||
* example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class);
|
||||
* }
|
||||
*
|
||||
* void mrb_example_gem_final(mrb_state* mrb) {
|
||||
* //free(TheAnimals);
|
||||
* }
|
||||
*
|
||||
* @param [mrb_state *] mrb The current mruby state.
|
||||
* @param [const char *] name The name of the defined class.
|
||||
* @param [struct RClass *] super The new class parent.
|
||||
* @return [struct RClass *] Reference to the newly defined class.
|
||||
* @see mrb_define_class_under
|
||||
*/
|
||||
MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super);
|
||||
|
||||
/**
|
||||
* Defines a new module.
|
||||
* @param [mrb_state *] mrb_state* The current mruby state.
|
||||
* @param [const char *] char* The name of the module.
|
||||
* @return [struct RClass *] Reference to the newly defined module.
|
||||
*/
|
||||
MRB_API struct RClass *mrb_define_module(mrb_state *, const char*);
|
||||
MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value);
|
||||
|
||||
/**
|
||||
* Include a module in another class or module.
|
||||
* Equivalent to:
|
||||
*
|
||||
* module B
|
||||
* include A
|
||||
* end
|
||||
* @param [mrb_state *] mrb_state* The current mruby state.
|
||||
* @param [struct RClass *] RClass* A reference to module or a class.
|
||||
* @param [struct RClass *] RClass* A reference to the module to be included.
|
||||
*/
|
||||
MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*);
|
||||
|
||||
MRB_API void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
|
||||
/**
|
||||
* Prepends a module in another class or module.
|
||||
*
|
||||
* Equivalent to:
|
||||
* module B
|
||||
* prepend A
|
||||
* end
|
||||
* @param [mrb_state *] mrb_state* The current mruby state.
|
||||
* @param [struct RClass *] RClass* A reference to module or a class.
|
||||
* @param [struct RClass *] RClass* A reference to the module to be prepended.
|
||||
*/
|
||||
MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*);
|
||||
|
||||
/**
|
||||
* Defines a global function in ruby.
|
||||
*
|
||||
* If you're creating a gem it may look something like this
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* !!!c
|
||||
* mrb_value example_method(mrb_state* mrb, mrb_value self)
|
||||
* {
|
||||
* puts("Executing example command!");
|
||||
* return self;
|
||||
* }
|
||||
*
|
||||
* void mrb_example_gem_init(mrb_state* mrb)
|
||||
* {
|
||||
* mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE());
|
||||
* }
|
||||
*
|
||||
* @param [mrb_state *] mrb The MRuby state reference.
|
||||
* @param [struct RClass *] cla The class pointer where the method will be defined.
|
||||
* @param [const char *] name The name of the method being defined.
|
||||
* @param [mrb_func_t] func The function pointer to the method definition.
|
||||
* @param [mrb_aspec] aspec The method parameters declaration.
|
||||
*/
|
||||
MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t func, mrb_aspec aspec);
|
||||
|
||||
/**
|
||||
* Defines a class method.
|
||||
*
|
||||
* Example:
|
||||
* # Ruby style
|
||||
* class Foo
|
||||
*
|
||||
* def Foo.bar
|
||||
* end
|
||||
*
|
||||
* end
|
||||
* // C style
|
||||
* mrb_value bar_method(mrb_state* mrb, mrb_value self){
|
||||
*
|
||||
* return mrb_nil_value();
|
||||
*
|
||||
* }
|
||||
* void mrb_example_gem_init(mrb_state* mrb){
|
||||
*
|
||||
* struct RClass *foo;
|
||||
*
|
||||
* foo = mrb_define_class(mrb, "Foo", mrb->object_class);
|
||||
*
|
||||
* mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
|
||||
*
|
||||
* }
|
||||
* @param [mrb_state *] mrb_state* The MRuby state reference.
|
||||
* @param [struct RClass *] RClass* The class where the class method will be defined.
|
||||
* @param [const char *] char* The name of the class method being defined.
|
||||
* @param [mrb_func_t] mrb_func_t The function pointer to the class method definition.
|
||||
* @param [mrb_aspec] mrb_aspec The method parameters declaration.
|
||||
*/
|
||||
MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec);
|
||||
MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t, mrb_aspec);
|
||||
|
||||
/**
|
||||
* Defines a module fuction.
|
||||
*
|
||||
* Example:
|
||||
* # Ruby style
|
||||
* module Foo
|
||||
*
|
||||
* def Foo.bar * end
|
||||
*
|
||||
* end
|
||||
* // C style
|
||||
* mrb_value bar_method(mrb_state* mrb, mrb_value self){
|
||||
*
|
||||
* return mrb_nil_value(); *
|
||||
* }
|
||||
* void mrb_example_gem_init(mrb_state* mrb){
|
||||
*
|
||||
* struct RClass *foo;
|
||||
*
|
||||
* foo = mrb_define_module(mrb, "Foo");
|
||||
*
|
||||
* mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
|
||||
*
|
||||
* }
|
||||
* @param [mrb_state *] mrb_state* The MRuby state reference.
|
||||
* @param [struct RClass *] RClass* The module where the module function will be defined.
|
||||
* @param [const char *] char* The name of the module function being defined.
|
||||
* @param [mrb_func_t] mrb_func_t The function pointer to the module function definition.
|
||||
* @param [mrb_aspec] mrb_aspec The method parameters declaration.
|
||||
*/
|
||||
MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
|
||||
|
||||
/**
|
||||
* Defines a constant.
|
||||
*
|
||||
* Example:
|
||||
* # Ruby style
|
||||
*
|
||||
* class ExampleClass
|
||||
*
|
||||
* AGE = 22
|
||||
*
|
||||
* end
|
||||
*
|
||||
* // C style
|
||||
* #include <stdio.h>
|
||||
* #include <mruby.h>
|
||||
*
|
||||
* void
|
||||
* mrb_example_gem_init(mrb_state* mrb){
|
||||
*
|
||||
* mrb_define_const(mrb, mrb->kernel_module, "AGE", mrb_fixnum_value(22));
|
||||
*
|
||||
* }
|
||||
*
|
||||
* mrb_value
|
||||
* mrb_example_gem_final(mrb_state* mrb){
|
||||
*
|
||||
* }
|
||||
* @param [mrb_state *] mrb_state* The MRuby state reference.
|
||||
* @param [struct RClass *] RClass* A class or module the constant is defined in.
|
||||
* @param [const char *] name The name of the constant being defined.
|
||||
* @param [mrb_value] mrb_value The value for the constant.
|
||||
*/
|
||||
MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
|
||||
|
||||
/**
|
||||
* Undefines a method.
|
||||
*
|
||||
* Example:
|
||||
* # Ruby style
|
||||
*
|
||||
* class ExampleClassA
|
||||
*
|
||||
* def example_method
|
||||
* "example"
|
||||
* end
|
||||
*
|
||||
* end
|
||||
*
|
||||
* ExampleClassA.new.example_method # => example
|
||||
*
|
||||
* class ExampleClassB < ExampleClassA
|
||||
*
|
||||
* undef_method :example_method
|
||||
*
|
||||
* end
|
||||
*
|
||||
* ExampleClassB.new.example_method # => undefined method 'example_method' for ExampleClassB (NoMethodError)
|
||||
*
|
||||
* // C style
|
||||
* #include <stdio.h>
|
||||
* #include <mruby.h>
|
||||
*
|
||||
* mrb_value
|
||||
* mrb_example_method(mrb_state *mrb){
|
||||
*
|
||||
* return mrb_str_new_cstr(mrb, "example");
|
||||
*
|
||||
* }
|
||||
*
|
||||
* void
|
||||
* mrb_example_gem_init(mrb_state* mrb){
|
||||
* struct RClass *example_class_a;
|
||||
* struct RClass *example_class_b;
|
||||
* struct RClass *example_class_c;
|
||||
*
|
||||
* example_class_a = mrb_define_class(mrb, "ExampleClassA", mrb->object_class);
|
||||
*
|
||||
* mrb_define_method(mrb, example_class_a, "example_method", mrb_example_method, MRB_ARGS_NONE());
|
||||
*
|
||||
* example_class_b = mrb_define_class(mrb, "ExampleClassB", example_class_a);
|
||||
*
|
||||
* example_class_c = mrb_define_class(mrb, "ExampleClassC", example_class_b);
|
||||
*
|
||||
* mrb_undef_method(mrb, example_class_c, "example_method");
|
||||
*
|
||||
* }
|
||||
*
|
||||
* mrb_example_gem_final(mrb_state* mrb){
|
||||
*
|
||||
* }
|
||||
*
|
||||
* @param [mrb_state*] mrb_state* The mruby state reference.
|
||||
* @param [struct RClass*] RClass* A class the method will be undefined from.
|
||||
* @param [const char*] constchar* The name of the method to be undefined.
|
||||
*/
|
||||
MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*);
|
||||
|
||||
/**
|
||||
* Undefine a class method.
|
||||
*
|
||||
* Example:
|
||||
* # Ruby style
|
||||
*
|
||||
* class ExampleClass
|
||||
* def self.example_method
|
||||
* "example"
|
||||
* end
|
||||
*
|
||||
* end
|
||||
*
|
||||
* ExampleClass.example_method
|
||||
*
|
||||
* // C style
|
||||
* #include <stdio.h>
|
||||
* #include <mruby.h>
|
||||
*
|
||||
* mrb_value
|
||||
* mrb_example_method(mrb_state *mrb){
|
||||
*
|
||||
* return mrb_str_new_cstr(mrb, "example");
|
||||
*
|
||||
* }
|
||||
*
|
||||
* void
|
||||
* mrb_example_gem_init(mrb_state* mrb){
|
||||
*
|
||||
* struct RClass *example_class;
|
||||
*
|
||||
* example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class);
|
||||
*
|
||||
* mrb_define_class_method(mrb, example_class, "example_method", mrb_example_method, MRB_ARGS_NONE());
|
||||
*
|
||||
* mrb_undef_class_method(mrb, example_class, "example_method");
|
||||
*
|
||||
* }
|
||||
*
|
||||
* void
|
||||
* mrb_example_gem_final(mrb_state* mrb){
|
||||
*
|
||||
* }
|
||||
* @param [mrb_state*] mrb_state* The mruby state reference.
|
||||
* @param [RClass*] RClass* A class the class method will be undefined from.
|
||||
* @param [constchar*] constchar* The name of the class method to be undefined.
|
||||
*/
|
||||
MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
|
||||
|
||||
/**
|
||||
* Initialize a new object instace of c class.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* # Ruby style
|
||||
* class ExampleClass
|
||||
* end
|
||||
*
|
||||
* p ExampleClass # => #<ExampleClass:0x9958588>
|
||||
* // C style
|
||||
* #include <stdio.h>
|
||||
* #include <mruby.h>
|
||||
*
|
||||
* void
|
||||
* mrb_example_gem_init(mrb_state* mrb) {
|
||||
* struct RClass *example_class;
|
||||
* mrb_value obj;
|
||||
*
|
||||
* example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); # => class ExampleClass; end
|
||||
* obj = mrb_obj_new(mrb, example_class, 0, NULL); # => ExampleClass.new
|
||||
* mrb_p(mrb, obj); // => Kernel#p
|
||||
* }
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [RClass*] c Reference to the class of the new object.
|
||||
* @param [mrb_int] argc Number of arguments in argv
|
||||
* @param [const mrb_value *] argv Array of mrb_value to initialize the object
|
||||
* @return [mrb_value] The newly initialized object
|
||||
*/
|
||||
MRB_API mrb_value mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv);
|
||||
#define mrb_class_new_instance(mrb,argc,argv,c) mrb_obj_new(mrb,c,argc,argv)
|
||||
|
||||
/** @see mrb_obj_new */
|
||||
MRB_INLINE mrb_value mrb_class_new_instance(mrb_state *mrb, mrb_int argc, const mrb_value *argv, struct RClass *c)
|
||||
{
|
||||
return mrb_obj_new(mrb,c,argc,argv);
|
||||
}
|
||||
|
||||
MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
|
||||
|
||||
/**
|
||||
* Creates a new instance of Class, Class.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* void
|
||||
* mrb_example_gem_init(mrb_state* mrb) {
|
||||
* struct RClass *example_class;
|
||||
* mrb_value obj;
|
||||
*
|
||||
* example_class = mrb_class_new(mrb, mrb->object_class);
|
||||
* obj = mrb_obj_new(mrb, example_class, 0, NULL); // => #<#<Class:0x9a945b8>:0x9a94588>
|
||||
* mrb_p(mrb, obj); // => Kernel#p
|
||||
* }
|
||||
*
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [struct RClass *] super The super class or parent.
|
||||
* @return [struct RClass *] Reference to the new class.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
|
||||
|
||||
/**
|
||||
* Creates a new module, Module.
|
||||
*
|
||||
* Example:
|
||||
* void
|
||||
* mrb_example_gem_init(mrb_state* mrb) {
|
||||
* struct RClass *example_module;
|
||||
*
|
||||
* example_module = mrb_module_new(mrb);
|
||||
* }
|
||||
*
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @return [struct RClass *] Reference to the new module.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_module_new(mrb_state *mrb);
|
||||
|
||||
/**
|
||||
* Returns an mrb_bool. True if class was defined, and false if the class was not defined.
|
||||
*
|
||||
* Example:
|
||||
* void
|
||||
* mrb_example_gem_init(mrb_state* mrb) {
|
||||
* struct RClass *example_class;
|
||||
* mrb_bool cd;
|
||||
*
|
||||
* example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class);
|
||||
* cd = mrb_class_defined(mrb, "ExampleClass");
|
||||
*
|
||||
* // If mrb_class_defined returns 1 then puts "True"
|
||||
* // If mrb_class_defined returns 0 then puts "False"
|
||||
* if (cd == 1){
|
||||
* puts("True");
|
||||
* }
|
||||
* else {
|
||||
* puts("False");
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [const char *] name A string representing the name of the class.
|
||||
* @return [mrb_bool] A boolean value.
|
||||
*/
|
||||
MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name);
|
||||
|
||||
/**
|
||||
* Gets a class.
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [const char *] name The name of the class.
|
||||
* @return [struct RClass *] A reference to the class.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name);
|
||||
|
||||
/**
|
||||
* Gets a child class.
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [struct RClass *] outer The name of the parent class.
|
||||
* @param [const char *] name The name of the class.
|
||||
* @return [struct RClass *] A reference to the class.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
|
||||
/**
|
||||
* Gets a module.
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [const char *] name The name of the module.
|
||||
* @return [struct RClass *] A reference to the module.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_module_get(mrb_state *mrb, const char *name);
|
||||
|
||||
/**
|
||||
* Gets a module defined under another module.
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [struct RClass *] outer The name of the outer module.
|
||||
* @param [const char *] name The name of the module.
|
||||
* @return [struct RClass *] A reference to the module.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value);
|
||||
|
||||
/**
|
||||
* Duplicate an object.
|
||||
*
|
||||
* Equivalent to:
|
||||
* Object#dup
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [mrb_value] obj Object to be duplicate.
|
||||
* @return [mrb_value] The newly duplicated object.
|
||||
*/
|
||||
MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj);
|
||||
MRB_API mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method);
|
||||
|
||||
/**
|
||||
* Returns true if obj responds to the given method. If the method was defined for that
|
||||
* class it returns true, it returns false otherwise.
|
||||
*
|
||||
* Example:
|
||||
* # Ruby style
|
||||
* class ExampleClass
|
||||
* def example_method
|
||||
* end
|
||||
* end
|
||||
*
|
||||
* ExampleClass.new.respond_to?(:example_method) # => true
|
||||
*
|
||||
* // C style
|
||||
* void
|
||||
* mrb_example_gem_init(mrb_state* mrb) {
|
||||
* struct RClass *example_class;
|
||||
* mrb_sym mid;
|
||||
* mrb_bool obj_resp;
|
||||
*
|
||||
* example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class);
|
||||
* mrb_define_method(mrb, example_class, "example_method", exampleMethod, MRB_ARGS_NONE());
|
||||
* mid = mrb_intern_str(mrb, mrb_str_new_cstr(mrb, "example_method" ));
|
||||
* obj_resp = mrb_obj_respond_to(mrb, example_class, mid); // => 1(true in Ruby world)
|
||||
*
|
||||
* // If mrb_obj_respond_to returns 1 then puts "True"
|
||||
* // If mrb_obj_respond_to returns 0 then puts "False"
|
||||
* if (obj_resp == 1) {
|
||||
* puts("True");
|
||||
* }
|
||||
* else if (obj_resp == 0) {
|
||||
* puts("False");
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [struct RClass *] c A reference to a class.
|
||||
* @param [mrb_sym] mid A symbol referencing a method id.
|
||||
* @return [mrb_bool] A boolean value.
|
||||
*/
|
||||
MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid);
|
||||
|
||||
/**
|
||||
* Defines a new class under a given module
|
||||
*
|
||||
* @param [mrb_state*] mrb The current mruby state.
|
||||
* @param [struct RClass *] outer Reference to the module under which the new class will be defined
|
||||
* @param [const char *] name The name of the defined class
|
||||
* @param [struct RClass *] super The new class parent
|
||||
* @return [struct RClass *] Reference to the newly defined class
|
||||
* @see mrb_define_class
|
||||
*/
|
||||
MRB_API struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super);
|
||||
|
||||
MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
|
||||
/* required arguments */
|
||||
/**
|
||||
* Function requires n arguments.
|
||||
*
|
||||
* @param n
|
||||
* The number of required arguments.
|
||||
*/
|
||||
#define MRB_ARGS_REQ(n) ((mrb_aspec)((n)&0x1f) << 18)
|
||||
/* optional arguments */
|
||||
|
||||
/**
|
||||
* Funtion takes n optional arguments
|
||||
*
|
||||
* @param n
|
||||
* The number of optional arguments.
|
||||
*/
|
||||
#define MRB_ARGS_OPT(n) ((mrb_aspec)((n)&0x1f) << 13)
|
||||
/* mandatory and optinal arguments */
|
||||
|
||||
/**
|
||||
* Funtion takes n1 mandatory arguments and n2 optional arguments
|
||||
*
|
||||
* @param n1
|
||||
* The number of required arguments.
|
||||
* @param n2
|
||||
* The number of optional arguments.
|
||||
*/
|
||||
#define MRB_ARGS_ARG(n1,n2) (MRB_ARGS_REQ(n1)|MRB_ARGS_OPT(n2))
|
||||
|
||||
/* rest argument */
|
||||
/** rest argument */
|
||||
#define MRB_ARGS_REST() ((mrb_aspec)(1 << 12))
|
||||
/* required arguments after rest */
|
||||
|
||||
/** required arguments after rest */
|
||||
#define MRB_ARGS_POST(n) ((mrb_aspec)((n)&0x1f) << 7)
|
||||
/* keyword arguments (n of keys, kdict) */
|
||||
|
||||
/** keyword arguments (n of keys, kdict) */
|
||||
#define MRB_ARGS_KEY(n1,n2) ((mrb_aspec)((((n1)&0x1f) << 2) | ((n2)?(1<<1):0)))
|
||||
/* block argument */
|
||||
|
||||
/**
|
||||
* Function takes a block argument
|
||||
*/
|
||||
#define MRB_ARGS_BLOCK() ((mrb_aspec)1)
|
||||
|
||||
/* accept any number of arguments */
|
||||
/**
|
||||
* Function accepts any number of arguments
|
||||
*/
|
||||
#define MRB_ARGS_ANY() MRB_ARGS_REST()
|
||||
/* accept no arguments */
|
||||
|
||||
/**
|
||||
* Function accepts no arguments
|
||||
*/
|
||||
#define MRB_ARGS_NONE() ((mrb_aspec)0)
|
||||
|
||||
/* compatibility macros; will be removed */
|
||||
#define ARGS_REQ(n) MRB_ARGS_REQ(n)
|
||||
#define ARGS_OPT(n) MRB_ARGS_OPT(n)
|
||||
#define ARGS_REST() MRB_ARGS_REST()
|
||||
#define ARGS_POST(n) MRB_ARGS_POST()
|
||||
#define ARGS_KEY(n1,n2) MRB_ARGS_KEY(n1,n2)
|
||||
#define ARGS_BLOCK() MRB_ARGS_BLOCK()
|
||||
#define ARGS_ANY() MRB_ARGS_ANY()
|
||||
#define ARGS_NONE() MRB_ARGS_NONE()
|
||||
/**
|
||||
* Format specifiers for {mrb_get_args} function
|
||||
*
|
||||
* Must be a C string composed of the following format specifiers:
|
||||
*
|
||||
* | char | Ruby type | C types | Notes |
|
||||
* |:----:|----------------|-------------------|----------------------------------------------------|
|
||||
* | `o` | {Object} | {mrb_value} | Could be used to retrieve any type of argument |
|
||||
* | `C` | {Class}/{Module} | {mrb_value} | |
|
||||
* | `S` | {String} | {mrb_value} | when `!` follows, the value may be `nil` |
|
||||
* | `A` | {Array} | {mrb_value} | when `!` follows, the value may be `nil` |
|
||||
* | `H` | {Hash} | {mrb_value} | when `!` follows, the value may be `nil` |
|
||||
* | `s` | {String} | char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` |
|
||||
* | `z` | {String} | char * | `NULL` terminated string; `z!` gives `NULL` for `nil` |
|
||||
* | `a` | {Array} | {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` |
|
||||
* | `f` | {Float} | {mrb_float} | |
|
||||
* | `i` | {Integer} | {mrb_int} | |
|
||||
* | `b` | boolean | {mrb_bool} | |
|
||||
* | `n` | {Symbol} | {mrb_sym} | |
|
||||
* | `&` | block | {mrb_value} | |
|
||||
* | `*` | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array. |
|
||||
* | | | optional | | After this spec following specs would be optional. |
|
||||
* | `?` | optional given | {mrb_bool} | `TRUE` if preceding argument is given. Used to check optional argument is given. |
|
||||
*
|
||||
* @see mrb_get_args
|
||||
*/
|
||||
typedef const char *mrb_args_format;
|
||||
|
||||
MRB_API mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...);
|
||||
/**
|
||||
* Retrieve arguments from mrb_state.
|
||||
*
|
||||
* When applicable, implicit conversions (such as `to_str`, `to_ary`, `to_hash`) are
|
||||
* applied to received arguments.
|
||||
* Used inside a function of mrb_func_t type.
|
||||
*
|
||||
* @param mrb The current MRuby state.
|
||||
* @param format [mrb_args_format] is a list of format specifiers
|
||||
* @param ... The passing variadic arguments must be a pointer of retrieving type.
|
||||
* @return the number of arguments retrieved.
|
||||
* @see mrb_args_format
|
||||
*/
|
||||
MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...);
|
||||
|
||||
static inline mrb_sym
|
||||
mrb_get_mid(mrb_state *mrb) /* get method symbol */
|
||||
{
|
||||
return mrb->c->ci->mid;
|
||||
}
|
||||
|
||||
static inline int
|
||||
mrb_get_argc(mrb_state *mrb) /* get argc */
|
||||
{
|
||||
return mrb->c->ci->argc;
|
||||
}
|
||||
|
||||
/* `strlen` for character string literals (use with caution or `strlen` instead)
|
||||
Adjacent string literals are concatenated in C/C++ in translation phase 6.
|
||||
@@ -270,6 +792,9 @@ MRB_API mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...);
|
||||
*/
|
||||
#define mrb_strlen_lit(lit) (sizeof(lit "") - 1)
|
||||
|
||||
/**
|
||||
* Call existing ruby functions.
|
||||
*/
|
||||
MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...);
|
||||
MRB_API mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*);
|
||||
MRB_API mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*, mrb_value);
|
||||
@@ -294,15 +819,74 @@ MRB_API struct RBasic *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*)
|
||||
MRB_API void mrb_free(mrb_state*, void*);
|
||||
|
||||
MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len);
|
||||
|
||||
/**
|
||||
* Turns a C string into a Ruby string value.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*);
|
||||
MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len);
|
||||
#define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
|
||||
|
||||
MRB_API mrb_state* mrb_open(void);
|
||||
MRB_API mrb_state* mrb_open_allocf(mrb_allocf, void *ud);
|
||||
MRB_API mrb_state* mrb_open_core(mrb_allocf, void *ud);
|
||||
MRB_API void mrb_close(mrb_state*);
|
||||
#ifdef _WIN32
|
||||
char* mrb_utf8_from_locale(const char *p, size_t len);
|
||||
char* mrb_locale_from_utf8(const char *p, size_t len);
|
||||
#define mrb_locale_free(p) free(p)
|
||||
#define mrb_utf8_free(p) free(p)
|
||||
#else
|
||||
#define mrb_utf8_from_locale(p, l) (p)
|
||||
#define mrb_locale_from_utf8(p, l) (p)
|
||||
#define mrb_locale_free(p)
|
||||
#define mrb_utf8_free(p)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates new mrb_state.
|
||||
*
|
||||
* @return
|
||||
* Pointer to the newly created mrb_state.
|
||||
*/
|
||||
MRB_API mrb_state* mrb_open(void);
|
||||
|
||||
/**
|
||||
* Create new mrb_state with custom allocators.
|
||||
*
|
||||
* @param f
|
||||
* Reference to the allocation function.
|
||||
* @param ud
|
||||
* User data will be passed to custom allocator f.
|
||||
* If user data isn't required just pass NULL.
|
||||
* @return
|
||||
* Pointer to the newly created mrb_state.
|
||||
*/
|
||||
MRB_API mrb_state* mrb_open_allocf(mrb_allocf f, void *ud);
|
||||
|
||||
/**
|
||||
* Create new mrb_state with just the MRuby core
|
||||
*
|
||||
* @param f
|
||||
* Reference to the allocation function.
|
||||
* Use mrb_default_allocf for the default
|
||||
* @param ud
|
||||
* User data will be passed to custom allocator f.
|
||||
* If user data isn't required just pass NULL.
|
||||
* @return
|
||||
* Pointer to the newly created mrb_state.
|
||||
*/
|
||||
MRB_API mrb_state* mrb_open_core(mrb_allocf f, void *ud);
|
||||
|
||||
/**
|
||||
* Closes and frees a mrb_state.
|
||||
*
|
||||
* @param mrb
|
||||
* Pointer to the mrb_state to be closed.
|
||||
*/
|
||||
MRB_API void mrb_close(mrb_state *mrb);
|
||||
|
||||
/**
|
||||
* The default allocation function.
|
||||
*
|
||||
* @see mrb_allocf
|
||||
*/
|
||||
MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*);
|
||||
|
||||
MRB_API mrb_value mrb_top_self(mrb_state *);
|
||||
@@ -348,24 +932,23 @@ MRB_API mrb_bool mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass
|
||||
MRB_API mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value self);
|
||||
MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self);
|
||||
|
||||
/* need to include <ctype.h> to use these macros */
|
||||
#ifndef ISPRINT
|
||||
#define ISASCII(c) (!(((int)(unsigned char)(c)) & ~0x7f))
|
||||
#define ISPRINT(c) (ISASCII(c) && isprint((int)(unsigned char)(c)))
|
||||
#define ISSPACE(c) (ISASCII(c) && isspace((int)(unsigned char)(c)))
|
||||
#define ISUPPER(c) (ISASCII(c) && isupper((int)(unsigned char)(c)))
|
||||
#define ISLOWER(c) (ISASCII(c) && islower((int)(unsigned char)(c)))
|
||||
#define ISALNUM(c) (ISASCII(c) && isalnum((int)(unsigned char)(c)))
|
||||
#define ISALPHA(c) (ISASCII(c) && isalpha((int)(unsigned char)(c)))
|
||||
#define ISDIGIT(c) (ISASCII(c) && isdigit((int)(unsigned char)(c)))
|
||||
#define ISXDIGIT(c) (ISASCII(c) && isxdigit((int)(unsigned char)(c)))
|
||||
#define ISBLANK(c) (ISASCII(c) && isblank((int)(unsigned char)(c)))
|
||||
#define ISCNTRL(c) (ISASCII(c) && iscntrl((int)(unsigned char)(c)))
|
||||
#define TOUPPER(c) (ISASCII(c) ? toupper((int)(unsigned char)(c)) : (c))
|
||||
#define TOLOWER(c) (ISASCII(c) ? tolower((int)(unsigned char)(c)) : (c))
|
||||
#define ISASCII(c) ((unsigned)(c) <= 0x7f)
|
||||
#define ISPRINT(c) (((unsigned)(c) - 0x20) < 0x5f)
|
||||
#define ISSPACE(c) ((c) == ' ' || (unsigned)(c) - '\t' < 5)
|
||||
#define ISUPPER(c) (((unsigned)(c) - 'A') < 26)
|
||||
#define ISLOWER(c) (((unsigned)(c) - 'a') < 26)
|
||||
#define ISALPHA(c) ((((unsigned)(c) | 0x20) - 'a') < 26)
|
||||
#define ISDIGIT(c) (((unsigned)(c) - '0') < 10)
|
||||
#define ISXDIGIT(c) (ISDIGIT(c) || ((unsigned)(c) | 0x20) - 'a' < 6)
|
||||
#define ISALNUM(c) (ISALPHA(c) || ISDIGIT(c))
|
||||
#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
|
||||
#define ISCNTRL(c) ((unsigned)(c) < 0x20 || (c) == 0x7f)
|
||||
#define TOUPPER(c) (ISLOWER(c) ? ((c) & 0x5f) : (c))
|
||||
#define TOLOWER(c) (ISUPPER(c) ? ((c) | 0x20) : (c))
|
||||
#endif
|
||||
|
||||
MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len);
|
||||
MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len);
|
||||
MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc);
|
||||
|
||||
MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg);
|
||||
@@ -403,7 +986,13 @@ MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg);
|
||||
MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv);
|
||||
MRB_API mrb_value mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c);
|
||||
|
||||
/* mrb_gc_protect() leaves the object in the arena */
|
||||
MRB_API void mrb_gc_protect(mrb_state *mrb, mrb_value obj);
|
||||
/* mrb_gc_register() keeps the object from GC. */
|
||||
MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj);
|
||||
/* mrb_gc_unregister() removes the object from GC root. */
|
||||
MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj);
|
||||
|
||||
MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
|
||||
#define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val))
|
||||
MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
|
||||
@@ -424,8 +1013,26 @@ MRB_API mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id);
|
||||
MRB_API mrb_bool mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid);
|
||||
MRB_API mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c);
|
||||
|
||||
/* fiber functions (you need to link mruby-fiber mrbgem to use) */
|
||||
|
||||
/*
|
||||
* Resume a Fiber
|
||||
*
|
||||
* @mrbgem mruby-fiber
|
||||
*/
|
||||
MRB_API mrb_value mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int argc, const mrb_value *argv);
|
||||
|
||||
/*
|
||||
* Yield a Fiber
|
||||
*
|
||||
* @mrbgem mruby-fiber
|
||||
*/
|
||||
MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
|
||||
|
||||
/*
|
||||
* FiberError reference
|
||||
*
|
||||
* @mrbgem mruby-fiber
|
||||
*/
|
||||
#define E_FIBER_ERROR (mrb_class_get(mrb, "FiberError"))
|
||||
|
||||
/* memory pool implementation */
|
||||
@@ -439,6 +1046,9 @@ MRB_API void* mrb_alloca(mrb_state *mrb, size_t);
|
||||
|
||||
MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func);
|
||||
|
||||
MRB_API void mrb_show_version(mrb_state *mrb);
|
||||
MRB_API void mrb_show_copyright(mrb_state *mrb);
|
||||
|
||||
#ifdef MRB_DEBUG
|
||||
#include <assert.h>
|
||||
#define mrb_assert(p) assert(p)
|
||||
@@ -456,8 +1066,6 @@ MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func);
|
||||
|
||||
MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_H */
|
||||
|
||||
+72
-7
@@ -7,9 +7,13 @@
|
||||
#ifndef MRUBY_ARRAY_H
|
||||
#define MRUBY_ARRAY_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/*
|
||||
* Array class
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
|
||||
typedef struct mrb_shared_array {
|
||||
int refcnt;
|
||||
@@ -41,15 +45,78 @@ struct RArray {
|
||||
void mrb_ary_decref(mrb_state*, mrb_shared_array*);
|
||||
MRB_API void mrb_ary_modify(mrb_state*, struct RArray*);
|
||||
MRB_API mrb_value mrb_ary_new_capa(mrb_state*, mrb_int);
|
||||
|
||||
/*
|
||||
* Initializes a new array.
|
||||
*
|
||||
* Equivalent to:
|
||||
*
|
||||
* Array.new
|
||||
*
|
||||
* @param mrb The mruby state reference.
|
||||
* @return The initialized array
|
||||
*/
|
||||
MRB_API mrb_value mrb_ary_new(mrb_state *mrb);
|
||||
|
||||
MRB_API mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals);
|
||||
MRB_API mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
|
||||
MRB_API void mrb_ary_concat(mrb_state*, mrb_value, mrb_value);
|
||||
MRB_API mrb_value mrb_ary_splat(mrb_state*, mrb_value);
|
||||
MRB_API void mrb_ary_push(mrb_state*, mrb_value, mrb_value);
|
||||
|
||||
/*
|
||||
* Pushes value into array.
|
||||
*
|
||||
* Equivalent to:
|
||||
*
|
||||
* ary << value
|
||||
*
|
||||
* @param mrb The mruby state reference.
|
||||
* @param ary The array in which the value will be pushed
|
||||
* @param value The value to be pushed into array
|
||||
*/
|
||||
MRB_API void mrb_ary_push(mrb_state *mrb, mrb_value array, mrb_value value);
|
||||
|
||||
/*
|
||||
* Pops the last element from the array.
|
||||
*
|
||||
* Equivalent to:
|
||||
*
|
||||
* ary.pop
|
||||
*
|
||||
* @param mrb The mruby state reference.
|
||||
* @param ary The array from which the value will be poped.
|
||||
* @return The poped value.
|
||||
*/
|
||||
MRB_API mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary);
|
||||
|
||||
/*
|
||||
* Returns a reference to an element of the array on the given index.
|
||||
*
|
||||
* Equivalent to:
|
||||
*
|
||||
* ary[n]
|
||||
*
|
||||
* @param mrb The mruby state reference.
|
||||
* @param ary The target array.
|
||||
* @param n The array index being referenced
|
||||
* @return The referenced value.
|
||||
*/
|
||||
MRB_API mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n);
|
||||
|
||||
/*
|
||||
* Sets a value on an array at the given index
|
||||
*
|
||||
* Equivalent to:
|
||||
*
|
||||
* ary[n] = val
|
||||
*
|
||||
* @param mrb The mruby state reference.
|
||||
* @param ary The target array.
|
||||
* @param n The array index being referenced.
|
||||
* @param val The value being setted.
|
||||
*/
|
||||
MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val);
|
||||
|
||||
MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value a, mrb_value b);
|
||||
MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
|
||||
MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item);
|
||||
@@ -67,8 +134,6 @@ mrb_ary_len(mrb_state *mrb, mrb_value ary)
|
||||
return RARRAY_LEN(ary);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_ARRAY_H */
|
||||
|
||||
@@ -61,7 +61,6 @@ typedef struct mrb_value {
|
||||
#define mrb_symbol(o) (o).value.sym
|
||||
|
||||
#define BOXNAN_SET_VALUE(o, tt, attr, v) do {\
|
||||
(o).value.ttt = (0xfff00000|(((tt)+1)<<14));\
|
||||
switch (tt) {\
|
||||
case MRB_TT_FALSE:\
|
||||
case MRB_TT_TRUE:\
|
||||
@@ -70,6 +69,7 @@ typedef struct mrb_value {
|
||||
case MRB_TT_SYMBOL: (o).attr = (v); break;\
|
||||
default: (o).value.i = 0; (o).value.p = (void*)((uintptr_t)(o).value.p | (((uintptr_t)(v))>>2)); break;\
|
||||
}\
|
||||
(o).value.ttt = (0xfff00000|(((tt)+1)<<14));\
|
||||
} while (0)
|
||||
|
||||
#define SET_FLOAT_VALUE(mrb,r,v) do { \
|
||||
@@ -87,7 +87,6 @@ typedef struct mrb_value {
|
||||
#define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
|
||||
#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
|
||||
#define SET_OBJ_VALUE(r,v) BOXNAN_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
|
||||
#define SET_PROC_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_PROC, value.p, v)
|
||||
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
|
||||
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ typedef struct mrb_value {
|
||||
#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
|
||||
#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
|
||||
#define SET_OBJ_VALUE(r,v) BOXNIX_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
|
||||
#define SET_PROC_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_PROC, value.p, v)
|
||||
#define SET_CPTR_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
|
||||
#define SET_UNDEF_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
|
||||
|
||||
|
||||
@@ -92,15 +92,13 @@ mrb_type(mrb_value o)
|
||||
#define mrb_nil_p(o) ((o).w == MRB_Qnil)
|
||||
|
||||
#define BOXWORD_SET_VALUE(o, ttt, attr, v) do {\
|
||||
(o).w = 0;\
|
||||
(o).attr = (v);\
|
||||
switch (ttt) {\
|
||||
case MRB_TT_FALSE: (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\
|
||||
case MRB_TT_TRUE: (o).w = MRB_Qtrue; break;\
|
||||
case MRB_TT_UNDEF: (o).w = MRB_Qundef; break;\
|
||||
case MRB_TT_FIXNUM: (o).value.i_flag = MRB_FIXNUM_FLAG; break;\
|
||||
case MRB_TT_SYMBOL: (o).value.sym_flag = MRB_SYMBOL_FLAG; break;\
|
||||
default: if ((o).value.bp) (o).value.bp->tt = ttt; break;\
|
||||
case MRB_TT_FIXNUM: (o).value.i_flag = MRB_FIXNUM_FLAG; (o).attr = (v); break;\
|
||||
case MRB_TT_SYMBOL: (o).value.sym_flag = MRB_SYMBOL_FLAG; (o).attr = (v); break;\
|
||||
default: (o).w = 0; (o).attr = (v); if ((o).value.bp) (o).value.bp->tt = ttt; break;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
@@ -113,7 +111,6 @@ mrb_type(mrb_value o)
|
||||
#define SET_INT_VALUE(r,n) BOXWORD_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
|
||||
#define SET_SYM_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
|
||||
#define SET_OBJ_VALUE(r,v) BOXWORD_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
|
||||
#define SET_PROC_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_PROC, value.p, v)
|
||||
#define SET_UNDEF_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
|
||||
|
||||
#endif /* MRUBY_BOXING_WORD_H */
|
||||
|
||||
+21
-9
@@ -7,9 +7,12 @@
|
||||
#ifndef MRUBY_CLASS_H
|
||||
#define MRUBY_CLASS_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* Class class
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
struct RClass {
|
||||
MRB_OBJECT_HEADER;
|
||||
@@ -48,14 +51,25 @@ mrb_class(mrb_state *mrb, mrb_value v)
|
||||
}
|
||||
}
|
||||
|
||||
#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~0xff) | (char)tt)
|
||||
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & 0xff)
|
||||
// TODO: figure out where to put user flags
|
||||
#define MRB_FLAG_IS_PREPENDED (1 << 19)
|
||||
#define MRB_FLAG_IS_ORIGIN (1 << 20)
|
||||
#define MRB_CLASS_ORIGIN(c) do {\
|
||||
if (c->flags & MRB_FLAG_IS_PREPENDED) {\
|
||||
c = c->super;\
|
||||
while (!(c->flags & MRB_FLAG_IS_ORIGIN)) {\
|
||||
c = c->super;\
|
||||
}\
|
||||
}\
|
||||
} while (0)
|
||||
#define MRB_INSTANCE_TT_MASK (0xFF)
|
||||
#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_INSTANCE_TT_MASK) | (char)tt)
|
||||
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_INSTANCE_TT_MASK)
|
||||
|
||||
MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
|
||||
MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
|
||||
MRB_API struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
|
||||
MRB_API struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
|
||||
MRB_API void mrb_define_method_vm(mrb_state*, struct RClass*, mrb_sym, mrb_value);
|
||||
MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, struct RProc *);
|
||||
MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec);
|
||||
MRB_API void mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b);
|
||||
@@ -70,8 +84,6 @@ void mrb_gc_mark_mt(mrb_state*, struct RClass*);
|
||||
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
|
||||
void mrb_gc_free_mt(mrb_state*, struct RClass*);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_CLASS_H */
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
** mruby/common.h - mruby common platform definitions
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
|
||||
#ifndef MRUBY_COMMON_H
|
||||
#define MRUBY_COMMON_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define MRB_BEGIN_DECL extern "C" {
|
||||
# define MRB_END_DECL }
|
||||
#else
|
||||
/** Start declarations in C mode */
|
||||
# define MRB_BEGIN_DECL
|
||||
/** End declarations in C mode */
|
||||
# define MRB_END_DECL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Shared compiler macros
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
/** Declare a function that never returns. */
|
||||
#if __STDC_VERSION__ >= 201112L
|
||||
# define mrb_noreturn _Noreturn
|
||||
#elif defined __GNUC__ && !defined __STRICT_ANSI__
|
||||
# define mrb_noreturn __attribute__((noreturn))
|
||||
#elif defined _MSC_VER
|
||||
# define mrb_noreturn __declspec(noreturn)
|
||||
#else
|
||||
# define mrb_noreturn
|
||||
#endif
|
||||
|
||||
/** Mark a function as deprecated. */
|
||||
#if defined __GNUC__ && !defined __STRICT_ANSI__
|
||||
# define mrb_deprecated __attribute__((deprecated))
|
||||
#elif defined _MSC_VER
|
||||
# define mrb_deprecated __declspec(deprecated)
|
||||
#else
|
||||
# define mrb_deprecated
|
||||
#endif
|
||||
|
||||
/** Declare a function as always inlined. */
|
||||
#if defined(_MSC_VER)
|
||||
# define MRB_INLINE static __inline
|
||||
#else
|
||||
# define MRB_INLINE static inline
|
||||
#endif
|
||||
|
||||
|
||||
/** Declare a public MRuby API function. */
|
||||
#if defined(MRB_BUILD_AS_DLL)
|
||||
#if defined(MRB_CORE) || defined(MRB_LIB)
|
||||
# define MRB_API __declspec(dllexport)
|
||||
#else
|
||||
# define MRB_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
# define MRB_API extern
|
||||
#endif
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_COMMON_H */
|
||||
+14
-14
@@ -7,9 +7,12 @@
|
||||
#ifndef MRUBY_COMPILE_H
|
||||
#define MRUBY_COMPILE_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* MRuby Compiler
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
#include "mruby.h"
|
||||
|
||||
@@ -55,8 +58,8 @@ enum mrb_lex_state_enum {
|
||||
EXPR_CMDARG, /* newline significant, +/- is an operator. */
|
||||
EXPR_MID, /* newline significant, +/- is an operator. */
|
||||
EXPR_FNAME, /* ignore newline, no reserved words. */
|
||||
EXPR_DOT, /* right after `.' or `::', no reserved words. */
|
||||
EXPR_CLASS, /* immediate after `class', no here document. */
|
||||
EXPR_DOT, /* right after '.' or '::', no reserved words. */
|
||||
EXPR_CLASS, /* immediate after 'class', no here document. */
|
||||
EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */
|
||||
EXPR_MAX_STATE
|
||||
};
|
||||
@@ -109,7 +112,7 @@ struct mrb_parser_state {
|
||||
struct mrb_pool *pool;
|
||||
mrb_ast_node *cells;
|
||||
const char *s, *send;
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
FILE *f;
|
||||
#endif
|
||||
mrbc_context *cxt;
|
||||
@@ -164,7 +167,7 @@ MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*);
|
||||
MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx);
|
||||
|
||||
/* utility functions */
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
MRB_API struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*);
|
||||
#endif
|
||||
MRB_API struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
|
||||
@@ -172,19 +175,16 @@ MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int,mr
|
||||
MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
|
||||
|
||||
/* program load functions */
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
MRB_API mrb_value mrb_load_file(mrb_state*,FILE*);
|
||||
MRB_API mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
|
||||
#endif
|
||||
MRB_API mrb_value mrb_load_string(mrb_state *mrb, const char *s);
|
||||
MRB_API mrb_value mrb_load_nstring(mrb_state *mrb, const char *s, int len);
|
||||
#ifdef ENABLE_STDIO
|
||||
MRB_API mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
|
||||
#endif
|
||||
MRB_API mrb_value mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *cxt);
|
||||
MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *cxt);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
/** @} */
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_COMPILE_H */
|
||||
|
||||
+15
-6
@@ -7,12 +7,23 @@
|
||||
#ifndef MRUBY_DATA_H
|
||||
#define MRUBY_DATA_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* Custom C wrapped data.
|
||||
*
|
||||
* Defining Ruby wrappers around native objects.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Custom data type description.
|
||||
*/
|
||||
typedef struct mrb_data_type {
|
||||
/** data type name */
|
||||
const char *struct_name;
|
||||
|
||||
/** data type release function pointer */
|
||||
void (*dfree)(mrb_state *mrb, void*);
|
||||
} mrb_data_type;
|
||||
|
||||
@@ -59,8 +70,6 @@ mrb_data_init(mrb_value v, void *ptr, const mrb_data_type *type)
|
||||
DATA_TYPE(v) = type;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_DATA_H */
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
#ifndef MRUBY_DEBUG_H
|
||||
#define MRUBY_DEBUG_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* MRuby Debugging.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
typedef enum mrb_debug_line_type {
|
||||
mrb_debug_line_ary = 0,
|
||||
@@ -58,8 +61,6 @@ MRB_API mrb_irep_debug_info_file *mrb_debug_info_append_file(
|
||||
MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep);
|
||||
MRB_API void mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_DEBUG_H */
|
||||
|
||||
+56
-19
@@ -7,17 +7,25 @@
|
||||
#ifndef MRUBY_DUMP_H
|
||||
#define MRUBY_DUMP_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mruby.h"
|
||||
#include "mruby/irep.h"
|
||||
#include "mruby/common.h"
|
||||
|
||||
int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size);
|
||||
#ifdef ENABLE_STDIO
|
||||
int mrb_dump_irep_binary(mrb_state*, mrb_irep*, int, FILE*);
|
||||
int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep*, int, FILE *f, const char *initname);
|
||||
/**
|
||||
* Dumping compiled mruby script.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
#define DUMP_DEBUG_INFO 1
|
||||
#define DUMP_ENDIAN_BIG 2
|
||||
#define DUMP_ENDIAN_LIL 4
|
||||
#define DUMP_ENDIAN_NAT 6
|
||||
#define DUMP_ENDIAN_MASK 6
|
||||
|
||||
int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
int mrb_dump_irep_binary(mrb_state*, mrb_irep*, uint8_t, FILE*);
|
||||
int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep*, uint8_t flags, FILE *f, const char *initname);
|
||||
mrb_irep *mrb_read_irep_file(mrb_state*, FILE*);
|
||||
MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*);
|
||||
MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*);
|
||||
@@ -42,7 +50,8 @@ MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
|
||||
#define MRB_DUMP_NULL_SYM_LEN 0xFFFF
|
||||
|
||||
/* Rite Binary File header */
|
||||
#define RITE_BINARY_IDENTIFIER "RITE"
|
||||
#define RITE_BINARY_IDENT "RITE"
|
||||
#define RITE_BINARY_IDENT_LIL "ETIR"
|
||||
#define RITE_BINARY_FORMAT_VER "0003"
|
||||
#define RITE_COMPILER_NAME "MATZ"
|
||||
#define RITE_COMPILER_VERSION "0000"
|
||||
@@ -50,17 +59,17 @@ MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
|
||||
#define RITE_VM_VER "0000"
|
||||
|
||||
#define RITE_BINARY_EOF "END\0"
|
||||
#define RITE_SECTION_IREP_IDENTIFIER "IREP"
|
||||
#define RITE_SECTION_LINENO_IDENTIFIER "LINE"
|
||||
#define RITE_SECTION_DEBUG_IDENTIFIER "DBG\0"
|
||||
#define RITE_SECTION_LV_IDENTIFIER "LVAR"
|
||||
#define RITE_SECTION_IREP_IDENT "IREP"
|
||||
#define RITE_SECTION_LINENO_IDENT "LINE"
|
||||
#define RITE_SECTION_DEBUG_IDENT "DBG\0"
|
||||
#define RITE_SECTION_LV_IDENT "LVAR"
|
||||
|
||||
#define MRB_DUMP_DEFAULT_STR_LEN 128
|
||||
#define MRB_DUMP_ALIGNMENT sizeof(uint32_t)
|
||||
|
||||
/* binary header */
|
||||
struct rite_binary_header {
|
||||
uint8_t binary_identify[4]; /* Binary Identifier */
|
||||
uint8_t binary_ident[4]; /* Binary Identifier */
|
||||
uint8_t binary_version[4]; /* Binary Format Version */
|
||||
uint8_t binary_crc[2]; /* Binary CRC */
|
||||
uint8_t binary_size[4]; /* Binary Size */
|
||||
@@ -70,7 +79,7 @@ struct rite_binary_header {
|
||||
|
||||
/* section header */
|
||||
#define RITE_SECTION_HEADER \
|
||||
uint8_t section_identify[4]; \
|
||||
uint8_t section_ident[4]; \
|
||||
uint8_t section_size[4]
|
||||
|
||||
struct rite_section_header {
|
||||
@@ -101,6 +110,17 @@ struct rite_binary_footer {
|
||||
RITE_SECTION_HEADER;
|
||||
};
|
||||
|
||||
static inline int
|
||||
bigendian_p()
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
i = 1;
|
||||
p = (char*)&i;
|
||||
return p[0]?0:1;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
uint8_to_bin(uint8_t s, uint8_t *bin)
|
||||
{
|
||||
@@ -126,6 +146,16 @@ uint32_to_bin(uint32_t l, uint8_t *bin)
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
uint32l_to_bin(uint32_t l, uint8_t *bin)
|
||||
{
|
||||
bin[3] = (l >> 24) & 0xff;
|
||||
bin[2] = (l >> 16) & 0xff;
|
||||
bin[1] = (l >> 8) & 0xff;
|
||||
bin[0] = l & 0xff;
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
bin_to_uint32(const uint8_t *bin)
|
||||
{
|
||||
@@ -135,6 +165,15 @@ bin_to_uint32(const uint8_t *bin)
|
||||
(uint32_t)bin[3];
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
bin_to_uint32l(const uint8_t *bin)
|
||||
{
|
||||
return (uint32_t)bin[3] << 24 |
|
||||
(uint32_t)bin[2] << 16 |
|
||||
(uint32_t)bin[1] << 8 |
|
||||
(uint32_t)bin[0];
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
bin_to_uint16(const uint8_t *bin)
|
||||
{
|
||||
@@ -148,11 +187,9 @@ bin_to_uint8(const uint8_t *bin)
|
||||
return (uint8_t)bin[0];
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
/* crc.c */
|
||||
/** @internal crc.c */
|
||||
uint16_t
|
||||
calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc);
|
||||
|
||||
|
||||
+40
-7
@@ -7,9 +7,12 @@
|
||||
#ifndef MRUBY_ERROR_H
|
||||
#define MRUBY_ERROR_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* MRuby error handling.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
struct RException {
|
||||
MRB_OBJECT_HEADER;
|
||||
@@ -24,13 +27,43 @@ MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value st
|
||||
MRB_API mrb_value mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv);
|
||||
MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
|
||||
MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb);
|
||||
MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, const char *fmt, ...);
|
||||
MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...);
|
||||
|
||||
/* declaration for fail method */
|
||||
MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
/**
|
||||
* Protect
|
||||
*
|
||||
* @mrbgem mruby-error
|
||||
*/
|
||||
MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state);
|
||||
|
||||
/**
|
||||
* Ensure
|
||||
*
|
||||
* @mrbgem mruby-error
|
||||
*/
|
||||
MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
|
||||
mrb_func_t ensure, mrb_value e_data);
|
||||
|
||||
/**
|
||||
* Rescue
|
||||
*
|
||||
* @mrbgem mruby-error
|
||||
*/
|
||||
MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
|
||||
mrb_func_t rescue, mrb_value r_data);
|
||||
|
||||
/**
|
||||
* Rescue exception
|
||||
*
|
||||
* @mrbgem mruby-error
|
||||
*/
|
||||
MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
|
||||
mrb_func_t rescue, mrb_value r_data,
|
||||
mrb_int len, struct RClass **classes);
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_ERROR_H */
|
||||
|
||||
+62
-7
@@ -7,16 +7,71 @@
|
||||
#ifndef MRUBY_GC_H
|
||||
#define MRUBY_GC_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* Uncommon memory management stuffs.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
|
||||
struct mrb_state;
|
||||
|
||||
typedef void (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data);
|
||||
void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data);
|
||||
MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c);
|
||||
|
||||
#ifndef MRB_GC_ARENA_SIZE
|
||||
#define MRB_GC_ARENA_SIZE 100
|
||||
#endif
|
||||
|
||||
typedef void (mrb_each_object_callback)(mrb_state *mrb, struct RBasic *obj, void *data);
|
||||
void mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data);
|
||||
MRB_API void mrb_free_context(mrb_state *mrb, struct mrb_context *c);
|
||||
typedef enum {
|
||||
MRB_GC_STATE_ROOT = 0,
|
||||
MRB_GC_STATE_MARK,
|
||||
MRB_GC_STATE_SWEEP
|
||||
} mrb_gc_state;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
typedef struct mrb_heap_page {
|
||||
struct RBasic *freelist;
|
||||
struct mrb_heap_page *prev;
|
||||
struct mrb_heap_page *next;
|
||||
struct mrb_heap_page *free_next;
|
||||
struct mrb_heap_page *free_prev;
|
||||
mrb_bool old:1;
|
||||
void *objects[];
|
||||
} mrb_heap_page;
|
||||
|
||||
typedef struct mrb_gc {
|
||||
mrb_heap_page *heaps; /* heaps for GC */
|
||||
mrb_heap_page *sweeps;
|
||||
mrb_heap_page *free_heaps;
|
||||
size_t live; /* count of live objects */
|
||||
#ifdef MRB_GC_FIXED_ARENA
|
||||
struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */
|
||||
#else
|
||||
struct RBasic **arena; /* GC protection array */
|
||||
int arena_capa;
|
||||
#endif
|
||||
int arena_idx;
|
||||
|
||||
mrb_gc_state state; /* state of gc */
|
||||
int current_white_part; /* make white object by white_part */
|
||||
struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */
|
||||
struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */
|
||||
size_t live_after_mark;
|
||||
size_t threshold;
|
||||
int interval_ratio;
|
||||
int step_ratio;
|
||||
mrb_bool disabled :1;
|
||||
mrb_bool full :1;
|
||||
mrb_bool generational :1;
|
||||
mrb_bool out_of_memory :1;
|
||||
size_t majorgc_old_threshold;
|
||||
} mrb_gc;
|
||||
|
||||
MRB_API mrb_bool
|
||||
mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object);
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_GC_H */
|
||||
|
||||
+31
-6
@@ -7,9 +7,12 @@
|
||||
#ifndef MRUBY_HASH_H
|
||||
#define MRUBY_HASH_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* Hash class
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
struct RHash {
|
||||
MRB_OBJECT_HEADER;
|
||||
@@ -21,15 +24,39 @@ struct RHash {
|
||||
#define mrb_hash_value(p) mrb_obj_value((void*)(p))
|
||||
|
||||
MRB_API mrb_value mrb_hash_new_capa(mrb_state*, int);
|
||||
|
||||
/*
|
||||
* Initializes a new hash.
|
||||
*/
|
||||
MRB_API mrb_value mrb_hash_new(mrb_state *mrb);
|
||||
|
||||
/*
|
||||
* Sets a keys and values to hashes.
|
||||
*/
|
||||
MRB_API void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val);
|
||||
|
||||
/*
|
||||
* Gets a value from a key.
|
||||
*/
|
||||
MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key);
|
||||
|
||||
MRB_API mrb_value mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def);
|
||||
|
||||
/*
|
||||
* Deletes hash key and value pair.
|
||||
*/
|
||||
MRB_API mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key);
|
||||
|
||||
/*
|
||||
* Gets an array of keys.
|
||||
*/
|
||||
MRB_API mrb_value mrb_hash_keys(mrb_state *mrb, mrb_value hash);
|
||||
MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
|
||||
MRB_API mrb_value mrb_hash_empty_p(mrb_state *mrb, mrb_value self);
|
||||
|
||||
/*
|
||||
* Clears the hash.
|
||||
*/
|
||||
MRB_API mrb_value mrb_hash_clear(mrb_state *mrb, mrb_value hash);
|
||||
|
||||
/* RHASH_TBL allocates st_table if not available. */
|
||||
@@ -47,8 +74,6 @@ void mrb_gc_mark_hash(mrb_state*, struct RHash*);
|
||||
size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*);
|
||||
void mrb_gc_free_hash(mrb_state*, struct RHash*);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_HASH_H */
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
#ifndef MRUBY_IREP_H
|
||||
#define MRUBY_IREP_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mruby/common.h"
|
||||
#include "mruby/compile.h"
|
||||
|
||||
/**
|
||||
* Compiled mruby scripts.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
enum irep_pool_type {
|
||||
IREP_TT_STRING,
|
||||
IREP_TT_FIXNUM,
|
||||
@@ -53,8 +55,6 @@ void mrb_irep_free(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_incref(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_decref(mrb_state*, struct mrb_irep*);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_IREP_H */
|
||||
|
||||
+15
-11
@@ -7,12 +7,15 @@
|
||||
#ifndef MRUBY_KHASH_H
|
||||
#define MRUBY_KHASH_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "mruby.h"
|
||||
#include <string.h>
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* khash definitions used in mruby's hash table.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
typedef uint32_t khint_t;
|
||||
typedef khint_t khiter_t;
|
||||
@@ -148,20 +151,23 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
new_n_buckets = KHASH_MIN_SIZE; \
|
||||
khash_power2(new_n_buckets); \
|
||||
{ \
|
||||
kh_##name##_t hh; \
|
||||
uint8_t *old_ed_flags = h->ed_flags; \
|
||||
khkey_t *old_keys = h->keys; \
|
||||
khval_t *old_vals = h->vals; \
|
||||
khint_t old_n_buckets = h->n_buckets; \
|
||||
khint_t i; \
|
||||
h->n_buckets = new_n_buckets; \
|
||||
kh_alloc_##name(mrb, h); \
|
||||
hh.n_buckets = new_n_buckets; \
|
||||
kh_alloc_##name(mrb, &hh); \
|
||||
/* relocate */ \
|
||||
for (i=0 ; i<old_n_buckets ; i++) { \
|
||||
if (!__ac_iseither(old_ed_flags, i)) { \
|
||||
khint_t k = kh_put_##name(mrb, h, old_keys[i], NULL); \
|
||||
if (kh_is_map) kh_value(h,k) = old_vals[i]; \
|
||||
khint_t k = kh_put_##name(mrb, &hh, old_keys[i], NULL); \
|
||||
if (kh_is_map) kh_value(&hh,k) = old_vals[i]; \
|
||||
} \
|
||||
} \
|
||||
/* copy hh to h */ \
|
||||
*h = hh; \
|
||||
mrb_free(mrb, old_keys); \
|
||||
} \
|
||||
} \
|
||||
@@ -263,8 +269,6 @@ static inline khint_t __ac_X31_hash_string(const char *s)
|
||||
|
||||
typedef const char *kh_cstr_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_KHASH_H */
|
||||
|
||||
+53
-9
@@ -7,9 +7,14 @@
|
||||
#ifndef MRUBY_NUMERIC_H
|
||||
#define MRUBY_NUMERIC_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* Numeric class and it's sub-classes.
|
||||
*
|
||||
* Integer, Float and Fixnum
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
#define POSFIXABLE(f) ((f) <= MRB_INT_MAX)
|
||||
#define NEGFIXABLE(f) ((f) >= MRB_INT_MIN)
|
||||
@@ -17,6 +22,8 @@ extern "C" {
|
||||
|
||||
MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val);
|
||||
MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base);
|
||||
/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
|
||||
MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
|
||||
MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
|
||||
|
||||
mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
@@ -28,11 +35,48 @@ mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
#define MRB_UINT_MAKE(n) MRB_UINT_MAKE2(n)
|
||||
#define mrb_uint MRB_UINT_MAKE(MRB_INT_BIT)
|
||||
|
||||
#ifdef MRB_WORD_BOXING
|
||||
# define MRB_INT_OVERFLOW_MASK ((mrb_uint)1 << (MRB_INT_BIT - 1 - MRB_FIXNUM_SHIFT))
|
||||
#define MRB_INT_OVERFLOW_MASK ((mrb_uint)1 << (MRB_INT_BIT - 1 - MRB_FIXNUM_SHIFT))
|
||||
|
||||
/* Idea from Potion: https://github.com/perl11/potion (MIT) */
|
||||
#if (defined(__clang__) && ((__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ >= 4))) \
|
||||
|| (defined(__GNUC__) && __GNUC__ >= 5)
|
||||
|
||||
static inline mrb_bool
|
||||
mrb_int_add_overflow(mrb_int augend, mrb_int addend, mrb_int *sum)
|
||||
{
|
||||
mrb_bool of;
|
||||
|
||||
#ifdef MRB_INT64
|
||||
long long val;
|
||||
of = __builtin_saddll_overflow(augend, addend, &val) ||
|
||||
#else
|
||||
# define MRB_INT_OVERFLOW_MASK ((mrb_uint)1 << (MRB_INT_BIT - 1))
|
||||
int val;
|
||||
of = __builtin_sadd_overflow(augend, addend, &val) ||
|
||||
#endif
|
||||
(val > MRB_INT_MAX) || (val < MRB_INT_MIN);
|
||||
|
||||
*sum = (mrb_int) val;
|
||||
return of;
|
||||
}
|
||||
|
||||
static inline mrb_bool
|
||||
mrb_int_sub_overflow(mrb_int minuend, mrb_int subtrahend, mrb_int *difference)
|
||||
{
|
||||
mrb_bool of;
|
||||
|
||||
#ifdef MRB_INT64
|
||||
long long val;
|
||||
of = __builtin_ssubll_overflow(minuend, subtrahend, &val) ||
|
||||
#else
|
||||
int val;
|
||||
of = __builtin_ssub_overflow(minuend, subtrahend, &val) ||
|
||||
#endif
|
||||
(val > MRB_INT_MAX) || (val < MRB_INT_MIN);
|
||||
|
||||
*difference = (mrb_int) val;
|
||||
return of;
|
||||
}
|
||||
#else
|
||||
|
||||
static inline mrb_bool
|
||||
mrb_int_add_overflow(mrb_int augend, mrb_int addend, mrb_int *sum)
|
||||
@@ -54,13 +98,13 @@ mrb_int_sub_overflow(mrb_int minuend, mrb_int subtrahend, mrb_int *difference)
|
||||
return !!(((x ^ z) & (~y ^ z)) & MRB_INT_OVERFLOW_MASK);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#undef MRB_INT_OVERFLOW_MASK
|
||||
#undef mrb_uint
|
||||
#undef MRB_UINT_MAKE
|
||||
#undef MRB_UINT_MAKE2
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_NUMERIC_H */
|
||||
|
||||
+1
-17
@@ -14,24 +14,8 @@
|
||||
struct RClass *c;\
|
||||
struct RBasic *gcnext
|
||||
|
||||
/* white: 011, black: 100, gray: 000 */
|
||||
#define MRB_GC_GRAY 0
|
||||
#define MRB_GC_WHITE_A 1
|
||||
#define MRB_GC_WHITE_B (1 << 1)
|
||||
#define MRB_GC_BLACK (1 << 2)
|
||||
#define MRB_GC_WHITES (MRB_GC_WHITE_A | MRB_GC_WHITE_B)
|
||||
#define MRB_GC_COLOR_MASK 7
|
||||
#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag)
|
||||
|
||||
#define paint_gray(o) ((o)->color = MRB_GC_GRAY)
|
||||
#define paint_black(o) ((o)->color = MRB_GC_BLACK)
|
||||
#define paint_white(o) ((o)->color = MRB_GC_WHITES)
|
||||
#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
|
||||
#define is_gray(o) ((o)->color == MRB_GC_GRAY)
|
||||
#define is_white(o) ((o)->color & MRB_GC_WHITES)
|
||||
#define is_black(o) ((o)->color & MRB_GC_BLACK)
|
||||
#define is_dead(s, o) (((o)->color & other_white_part(s) & MRB_GC_WHITES) || (o)->tt == MRB_TT_FREE)
|
||||
#define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
|
||||
#define other_white_part(s) ((s)->current_white_part ^ MRB_GC_WHITES)
|
||||
|
||||
struct RBasic {
|
||||
MRB_OBJECT_HEADER;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define MRUBY_OPCODE_H
|
||||
|
||||
#define MAXARG_Bx (0xffff)
|
||||
#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
|
||||
#define MAXARG_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */
|
||||
|
||||
/* instructions: packed 32 bit */
|
||||
/* ------------------------------- */
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
#ifndef MRUBY_PROC_H
|
||||
#define MRUBY_PROC_H
|
||||
|
||||
#include "mruby/common.h"
|
||||
#include "mruby/irep.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* Proc class
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
struct REnv {
|
||||
MRB_OBJECT_HEADER;
|
||||
@@ -69,8 +71,6 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state*, mrb_int);
|
||||
#include "mruby/khash.h"
|
||||
KHASH_DECLARE(mt, mrb_sym, struct RProc*, TRUE)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_PROC_H */
|
||||
|
||||
+19
-7
@@ -7,9 +7,12 @@
|
||||
#ifndef MRUBY_RANGE_H
|
||||
#define MRUBY_RANGE_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* Range class
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
typedef struct mrb_range_edges {
|
||||
mrb_value beg;
|
||||
@@ -25,12 +28,21 @@ struct RRange {
|
||||
#define mrb_range_ptr(v) ((struct RRange*)(mrb_ptr(v)))
|
||||
#define mrb_range_value(p) mrb_obj_value((void*)(p))
|
||||
|
||||
MRB_API mrb_value mrb_range_new(mrb_state*, mrb_value, mrb_value, mrb_bool);
|
||||
/*
|
||||
* Initializes a Range.
|
||||
*
|
||||
* If the third parameter is FALSE then it includes the last value in the range.
|
||||
* If the third parameter is TRUE then it excludes the last value in the range.
|
||||
*
|
||||
* @param start the beginning value.
|
||||
* @param end the ending value.
|
||||
* @param exclude represents the inclusion or exclusion of the last value.
|
||||
*/
|
||||
MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude);
|
||||
|
||||
MRB_API mrb_bool mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len);
|
||||
mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_RANGE_H */
|
||||
|
||||
+89
-10
@@ -7,9 +7,12 @@
|
||||
#ifndef MRUBY_STRING_H
|
||||
#define MRUBY_STRING_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* String class
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
extern const char mrb_digitmap[];
|
||||
|
||||
@@ -59,52 +62,130 @@ struct RString {
|
||||
#define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE)
|
||||
#define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE)
|
||||
|
||||
#define RSTR_FROZEN_P(s) ((s)->flags & MRB_STR_FROZEN)
|
||||
#define RSTR_SET_FROZEN_FLAG(s) ((s)->flags |= MRB_STR_FROZEN)
|
||||
#define RSTR_UNSET_FROZEN_FLAG(s) ((s)->flags &= ~MRB_STR_FROZEN)
|
||||
|
||||
/*
|
||||
* Returns a pointer from a Ruby string
|
||||
*/
|
||||
#define mrb_str_ptr(s) ((struct RString*)(mrb_ptr(s)))
|
||||
#define RSTRING(s) mrb_str_ptr(s)
|
||||
#define RSTRING_PTR(s) RSTR_PTR(RSTRING(s))
|
||||
#define RSTRING_EMBED_LEN(s) RSTR_ENBED_LEN(RSTRING(s))
|
||||
#define RSTRING_LEN(s) RSTR_LEN(RSTRING(s))
|
||||
#define RSTRING_LEN(s) RSTR_LEN(RSTRING(s))
|
||||
#define RSTRING_CAPA(s) RSTR_CAPA(RSTRING(s))
|
||||
#define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s))
|
||||
mrb_int mrb_str_strlen(mrb_state*, struct RString*);
|
||||
|
||||
#define MRB_STR_SHARED 1
|
||||
#define MRB_STR_NOFREE 2
|
||||
#define MRB_STR_EMBED 4
|
||||
#define MRB_STR_EMBED_LEN_MASK 0xf8
|
||||
#define MRB_STR_EMBED_LEN_SHIFT 3
|
||||
#define MRB_STR_FROZEN 4
|
||||
#define MRB_STR_EMBED 8
|
||||
#define MRB_STR_EMBED_LEN_MASK 0x1f0
|
||||
#define MRB_STR_EMBED_LEN_SHIFT 4
|
||||
|
||||
void mrb_gc_free_str(mrb_state*, struct RString*);
|
||||
MRB_API void mrb_str_modify(mrb_state*, struct RString*);
|
||||
MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value);
|
||||
|
||||
/*
|
||||
* Adds two strings together.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value);
|
||||
|
||||
/*
|
||||
* Converts pointer into a Ruby string.
|
||||
*/
|
||||
MRB_API mrb_value mrb_ptr_to_str(mrb_state *, void*);
|
||||
|
||||
/*
|
||||
* Returns an object as a Ruby string.
|
||||
*/
|
||||
MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
|
||||
|
||||
/*
|
||||
* Resizes the string's length.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
|
||||
|
||||
/*
|
||||
* Returns a sub string.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
|
||||
|
||||
/*
|
||||
* Returns a Ruby string type.
|
||||
*/
|
||||
MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str);
|
||||
|
||||
MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
|
||||
MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa);
|
||||
|
||||
MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr);
|
||||
MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr);
|
||||
|
||||
/*
|
||||
* Duplicates a string object.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str);
|
||||
|
||||
/*
|
||||
* Returns a symbol from a passed in string.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self);
|
||||
|
||||
MRB_API mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck);
|
||||
MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck);
|
||||
|
||||
/*
|
||||
* Returns a converted string type.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
|
||||
|
||||
/*
|
||||
* Returns true if the strings match and false if the strings don't match.
|
||||
*/
|
||||
MRB_API mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
|
||||
|
||||
/*
|
||||
* Returns a concated string comprised of a Ruby string and a C string.
|
||||
*
|
||||
* @see mrb_str_cat_cstr
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
|
||||
|
||||
/*
|
||||
* Returns a concated string comprised of a Ruby string and a C string.
|
||||
*
|
||||
* @see mrb_str_cat
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr);
|
||||
MRB_API mrb_value mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2);
|
||||
#define mrb_str_cat_lit(mrb, str, lit) mrb_str_cat(mrb, str, lit, mrb_strlen_lit(lit))
|
||||
|
||||
/*
|
||||
* Adds str2 to the end of str1.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
|
||||
|
||||
/*
|
||||
* Returns 0 if both Ruby strings are equal. Returns a value < 0 if Ruby str1 is less than Ruby str2. Returns a value > 0 if Ruby str2 is greater than Ruby str1.
|
||||
*/
|
||||
MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
|
||||
|
||||
/*
|
||||
* Returns a C string from a Ruby string.
|
||||
*/
|
||||
MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
|
||||
|
||||
mrb_value mrb_str_pool(mrb_state *mrb, mrb_value str);
|
||||
mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
|
||||
|
||||
/*
|
||||
* Returns a printable version of str, surrounded by quote marks, with special characters escaped.
|
||||
*/
|
||||
mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
|
||||
|
||||
void mrb_noregexp(mrb_state *mrb, mrb_value self);
|
||||
@@ -115,8 +196,6 @@ void mrb_regexp_check(mrb_state *mrb, mrb_value obj);
|
||||
#define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len)
|
||||
#define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_STRING_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** mrb_throw.h - mruby exception throwing handler
|
||||
** mruby/throw.h - mruby exception throwing handler
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
+53
-22
@@ -7,6 +7,13 @@
|
||||
#ifndef MRUBY_VALUE_H
|
||||
#define MRUBY_VALUE_H
|
||||
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* MRuby Value definition functions and macros.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
typedef uint32_t mrb_sym;
|
||||
typedef uint8_t mrb_bool;
|
||||
struct mrb_state;
|
||||
@@ -34,25 +41,21 @@ struct mrb_state;
|
||||
|
||||
#ifdef MRB_USE_FLOAT
|
||||
typedef float mrb_float;
|
||||
# define mrb_float_to_str(buf, i) sprintf(buf, "%.7e", i)
|
||||
# define str_to_mrb_float(buf) strtof(buf, NULL)
|
||||
#else
|
||||
typedef double mrb_float;
|
||||
# define mrb_float_to_str(buf, i) sprintf(buf, "%.16e", i)
|
||||
# define str_to_mrb_float(buf) strtod(buf, NULL)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined _MSC_VER && _MSC_VER < 1900
|
||||
# ifndef __cplusplus
|
||||
# define inline __inline
|
||||
# endif
|
||||
# if _MSC_VER < 1900
|
||||
# include <stdarg.h>
|
||||
# include <stdarg.h>
|
||||
MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg);
|
||||
MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
|
||||
# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
|
||||
# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
|
||||
# endif
|
||||
# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
|
||||
# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
|
||||
# if _MSC_VER < 1800
|
||||
# include <float.h>
|
||||
# define isfinite(n) _finite(n)
|
||||
@@ -63,11 +66,7 @@ MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
|
||||
static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
|
||||
# define INFINITY (*(float *)&IEEE754_INFINITY_BITS_SINGLE)
|
||||
# define NAN ((float)(INFINITY - INFINITY))
|
||||
# else
|
||||
# include <inttypes.h>
|
||||
# endif
|
||||
#else
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
enum mrb_vtype {
|
||||
@@ -99,6 +98,22 @@ enum mrb_vtype {
|
||||
|
||||
#include "mruby/object.h"
|
||||
|
||||
#ifdef MRB_DOCUMENTATION_BLOCK
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* MRuby value boxing.
|
||||
*
|
||||
* Actual implementation depends on configured boxing type.
|
||||
*
|
||||
* @see mruby/boxing_no.h Default boxing representation
|
||||
* @see mruby/boxing_word.h Word representation
|
||||
* @see mruby/boxing_nan.h Boxed double representation
|
||||
*/
|
||||
typedef void mrb_value;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MRB_NAN_BOXING)
|
||||
#include "boxing_nan.h"
|
||||
#elif defined(MRB_WORD_BOXING)
|
||||
@@ -129,8 +144,10 @@ enum mrb_vtype {
|
||||
#define mrb_test(o) mrb_bool(o)
|
||||
MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value);
|
||||
|
||||
static inline mrb_value
|
||||
mrb_float_value(struct mrb_state *mrb, mrb_float f)
|
||||
/*
|
||||
* Returns a float in Ruby.
|
||||
*/
|
||||
MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
|
||||
{
|
||||
mrb_value v;
|
||||
(void) mrb;
|
||||
@@ -147,8 +164,10 @@ mrb_cptr_value(struct mrb_state *mrb, void *p)
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_fixnum_value(mrb_int i)
|
||||
/*
|
||||
* Returns a fixnum in Ruby.
|
||||
*/
|
||||
MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
|
||||
{
|
||||
mrb_value v;
|
||||
SET_INT_VALUE(v, i);
|
||||
@@ -171,24 +190,34 @@ mrb_obj_value(void *p)
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_nil_value(void)
|
||||
|
||||
/*
|
||||
* Get a nil mrb_value object.
|
||||
*
|
||||
* @return
|
||||
* nil mrb_value object reference.
|
||||
*/
|
||||
MRB_INLINE mrb_value mrb_nil_value(void)
|
||||
{
|
||||
mrb_value v;
|
||||
SET_NIL_VALUE(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_false_value(void)
|
||||
/*
|
||||
* Returns false in Ruby.
|
||||
*/
|
||||
MRB_INLINE mrb_value mrb_false_value(void)
|
||||
{
|
||||
mrb_value v;
|
||||
SET_FALSE_VALUE(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_true_value(void)
|
||||
/*
|
||||
* Returns true in Ruby.
|
||||
*/
|
||||
MRB_INLINE mrb_value mrb_true_value(void)
|
||||
{
|
||||
mrb_value v;
|
||||
SET_TRUE_VALUE(v);
|
||||
@@ -234,4 +263,6 @@ mrb_ro_data_p(const char *p)
|
||||
# define mrb_ro_data_p(p) FALSE
|
||||
#endif
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_VALUE_H */
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
#ifndef MRUBY_VARIABLE_H
|
||||
#define MRUBY_VARIABLE_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mruby/common.h"
|
||||
|
||||
/**
|
||||
* Functions to access mruby variables.
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
typedef struct global_variable {
|
||||
int counter;
|
||||
@@ -74,8 +77,6 @@ void mrb_gc_mark_iv(mrb_state*, struct RObject*);
|
||||
size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*);
|
||||
void mrb_gc_free_iv(mrb_state*, struct RObject*);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_VARIABLE_H */
|
||||
|
||||
+85
-15
@@ -7,34 +7,104 @@
|
||||
#ifndef MRUBY_VERSION_H
|
||||
#define MRUBY_VERSION_H
|
||||
|
||||
#define MRUBY_RUBY_VERSION "1.9"
|
||||
#define MRUBY_RUBY_ENGINE "mruby"
|
||||
#include "mruby/common.h"
|
||||
|
||||
#define MRUBY_VERSION "1.1.0"
|
||||
#define MRUBY_RELEASE_MAJOR 1
|
||||
#define MRUBY_RELEASE_MINOR 1
|
||||
#define MRUBY_RELEASE_TEENY 1
|
||||
#define MRUBY_RELEASE_NO 10101
|
||||
#define MRUBY_RELEASE_DATE "2014-11-19"
|
||||
#define MRUBY_RELEASE_YEAR 2014
|
||||
#define MRUBY_RELEASE_MONTH 11
|
||||
#define MRUBY_RELEASE_DAY 19
|
||||
|
||||
#define MRUBY_BIRTH_YEAR 2010
|
||||
|
||||
#define MRUBY_AUTHOR "mruby developers"
|
||||
/**
|
||||
* mruby version definition macros
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
/*
|
||||
* A passed in expression.
|
||||
*/
|
||||
#define MRB_STRINGIZE0(expr) #expr
|
||||
|
||||
/*
|
||||
* Passes in an expression to MRB_STRINGIZE0.
|
||||
*/
|
||||
#define MRB_STRINGIZE(expr) MRB_STRINGIZE0(expr)
|
||||
|
||||
/*
|
||||
* The version of Ruby used by mruby.
|
||||
*/
|
||||
#define MRUBY_RUBY_VERSION "1.9"
|
||||
|
||||
/*
|
||||
* Ruby engine.
|
||||
*/
|
||||
#define MRUBY_RUBY_ENGINE "mruby"
|
||||
|
||||
/*
|
||||
* Major release version number.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MAJOR 1
|
||||
|
||||
/*
|
||||
* Minor release version number.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MINOR 2
|
||||
|
||||
/*
|
||||
* Tiny release version number.
|
||||
*/
|
||||
#define MRUBY_RELEASE_TEENY 0
|
||||
|
||||
/*
|
||||
* The mruby version.
|
||||
*/
|
||||
#define MRUBY_VERSION MRB_STRINGIZE(MRUBY_RELEASE_MAJOR) "." MRB_STRINGIZE(MRUBY_RELEASE_MINOR) "." MRB_STRINGIZE(MRUBY_RELEASE_TEENY)
|
||||
|
||||
/*
|
||||
* Release number.
|
||||
*/
|
||||
#define MRUBY_RELEASE_NO (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY)
|
||||
|
||||
/*
|
||||
* Release year.
|
||||
*/
|
||||
#define MRUBY_RELEASE_YEAR 2015
|
||||
|
||||
/*
|
||||
* Release month.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MONTH 11
|
||||
|
||||
/*
|
||||
* Release day.
|
||||
*/
|
||||
#define MRUBY_RELEASE_DAY 17
|
||||
|
||||
/*
|
||||
* Release date as a string.
|
||||
*/
|
||||
#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR) "-" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) "-" MRB_STRINGIZE(MRUBY_RELEASE_DAY)
|
||||
|
||||
/*
|
||||
* The year mruby was first created.
|
||||
*/
|
||||
#define MRUBY_BIRTH_YEAR 2010
|
||||
|
||||
/*
|
||||
* MRuby's authors.
|
||||
*/
|
||||
#define MRUBY_AUTHOR "mruby developers"
|
||||
|
||||
/*
|
||||
* mruby's version, and release date.
|
||||
*/
|
||||
#define MRUBY_DESCRIPTION \
|
||||
"mruby " MRUBY_VERSION \
|
||||
" (" MRUBY_RELEASE_DATE ") " \
|
||||
|
||||
/*
|
||||
* mruby's copyright information.
|
||||
*/
|
||||
#define MRUBY_COPYRIGHT \
|
||||
"mruby - Copyright (c) " \
|
||||
MRB_STRINGIZE(MRUBY_BIRTH_YEAR)"-" \
|
||||
MRB_STRINGIZE(MRUBY_RELEASE_YEAR)" " \
|
||||
MRUBY_AUTHOR \
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_VERSION_H */
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
require "pathname"
|
||||
|
||||
module MRuby
|
||||
module Source
|
||||
# MRuby's source root directory
|
||||
ROOT = Pathname.new(File.expand_path('../../../',__FILE__))
|
||||
|
||||
# Reads a constant defined at version.h
|
||||
MRUBY_READ_VERSION_CONSTANT = Proc.new { |name| ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?$/)[1] }
|
||||
|
||||
MRUBY_RUBY_VERSION = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_VERSION']
|
||||
MRUBY_RUBY_ENGINE = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_ENGINE']
|
||||
|
||||
MRUBY_RELEASE_MAJOR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MAJOR'])
|
||||
MRUBY_RELEASE_MINOR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MINOR'])
|
||||
MRUBY_RELEASE_TEENY = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_TEENY'])
|
||||
|
||||
MRUBY_VERSION = [MRUBY_RELEASE_MAJOR,MRUBY_RELEASE_MINOR,MRUBY_RELEASE_TEENY].join('.')
|
||||
MRUBY_RELEASE_NO = (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY)
|
||||
|
||||
MRUBY_RELEASE_YEAR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_YEAR'])
|
||||
MRUBY_RELEASE_MONTH = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MONTH'])
|
||||
MRUBY_RELEASE_DAY = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_DAY'])
|
||||
MRUBY_RELEASE_DATE = [MRUBY_RELEASE_YEAR,MRUBY_RELEASE_MONTH,MRUBY_RELEASE_DAY].join('.')
|
||||
|
||||
MRUBY_BIRTH_YEAR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_BIRTH_YEAR'])
|
||||
|
||||
MRUBY_AUTHOR = MRUBY_READ_VERSION_CONSTANT['MRUBY_AUTHOR']
|
||||
end
|
||||
end
|
||||
@@ -237,7 +237,8 @@ module MiniRake
|
||||
|
||||
# Time stamp for file task.
|
||||
def timestamp
|
||||
File::stat(name.to_s).mtime
|
||||
stat = File::stat(name.to_s)
|
||||
stat.directory? ? Time.at(0) : stat.mtime
|
||||
end
|
||||
end
|
||||
|
||||
@@ -254,12 +255,14 @@ module MiniRake
|
||||
|
||||
# Declare a set of files tasks to create the given directories on
|
||||
# demand.
|
||||
def directory(dir)
|
||||
path = []
|
||||
Sys.split_all(dir).each do |p|
|
||||
path << p
|
||||
FileTask.define_task(File.join(path)) do |t|
|
||||
Sys.makedirs(t.name)
|
||||
def directory(args, &block)
|
||||
MiniRake::FileTask.define_task(args) do |t|
|
||||
block.call(t) unless block.nil?
|
||||
dir = args.is_a?(Hash) ? args.keys.first : args
|
||||
(dir.split(File::SEPARATOR) + ['']).inject do |acc, part|
|
||||
(acc + File::SEPARATOR).tap do |d|
|
||||
Dir.mkdir(d) unless File.exists? d
|
||||
end + part
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+14
-11
@@ -14,34 +14,34 @@ MRuby::GemBox.new do |conf|
|
||||
# Use standard Struct class
|
||||
conf.gem :core => "mruby-struct"
|
||||
|
||||
# Use extensional Enumerable module
|
||||
# Use Enumerable module extension
|
||||
conf.gem :core => "mruby-enum-ext"
|
||||
|
||||
# Use extensional String class
|
||||
# Use String class extension
|
||||
conf.gem :core => "mruby-string-ext"
|
||||
|
||||
# Use extensional Numeric class
|
||||
# Use Numeric class extension
|
||||
conf.gem :core => "mruby-numeric-ext"
|
||||
|
||||
# Use extensional Array class
|
||||
# Use Array class extension
|
||||
conf.gem :core => "mruby-array-ext"
|
||||
|
||||
# Use extensional Hash class
|
||||
# Use Hash class extension
|
||||
conf.gem :core => "mruby-hash-ext"
|
||||
|
||||
# Use extensional Range class
|
||||
# Use Range class extension
|
||||
conf.gem :core => "mruby-range-ext"
|
||||
|
||||
# Use extensional Proc class
|
||||
# Use Proc class extension
|
||||
conf.gem :core => "mruby-proc-ext"
|
||||
|
||||
# Use extensional Symbol class
|
||||
# Use Symbol class extension
|
||||
conf.gem :core => "mruby-symbol-ext"
|
||||
|
||||
# Use Random class
|
||||
conf.gem :core => "mruby-random"
|
||||
|
||||
# Use extensional Object class
|
||||
# Use Object class extension
|
||||
conf.gem :core => "mruby-object-ext"
|
||||
|
||||
# Use ObjectSpace class
|
||||
@@ -56,7 +56,7 @@ MRuby::GemBox.new do |conf|
|
||||
# Use Enumerable::Lazy class (require mruby-enumerator)
|
||||
conf.gem :core => "mruby-enum-lazy"
|
||||
|
||||
# Use extended toplevel object (main) methods
|
||||
# Use toplevel object (main) methods extension
|
||||
conf.gem :core => "mruby-toplevel-ext"
|
||||
|
||||
# Generate mirb command
|
||||
@@ -68,6 +68,9 @@ MRuby::GemBox.new do |conf|
|
||||
# Generate mruby-strip command
|
||||
conf.gem :core => "mruby-bin-strip"
|
||||
|
||||
# Use extensional Kernel module
|
||||
# Use Kernel module extension
|
||||
conf.gem :core => "mruby-kernel-ext"
|
||||
|
||||
# Use mruby-compiler to build other mrbgems
|
||||
conf.gem :core => "mruby-compiler"
|
||||
end
|
||||
|
||||
@@ -4,6 +4,6 @@ MRuby::GemBox.new do |conf|
|
||||
|
||||
Dir.glob("#{root}/mrbgems/mruby-*/mrbgem.rake") do |x|
|
||||
g = File.basename File.dirname x
|
||||
conf.gem :core => g unless g =~ /^mruby-(print|sprintf|bin-debugger)$/
|
||||
conf.gem :core => g unless g =~ /^mruby-(print|sprintf|bin-debugger|test)$/
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MRuby::Gem::Specification.new('mruby-array-ext') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'extensional Array class'
|
||||
spec.summary = 'Array class extension'
|
||||
end
|
||||
|
||||
@@ -217,7 +217,7 @@ class Array
|
||||
# [ "a", "b", "c" ].compact! #=> nil
|
||||
#
|
||||
def compact!
|
||||
result = self.select { |e| e != nil }
|
||||
result = self.select { |e| !e.nil? }
|
||||
if result.size == self.size
|
||||
nil
|
||||
else
|
||||
@@ -262,7 +262,7 @@ class Array
|
||||
#
|
||||
|
||||
def fetch(n=nil, ifnone=NONE, &block)
|
||||
warn "block supersedes default value argument" if n != nil && ifnone != NONE && block
|
||||
warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block
|
||||
|
||||
idx = n
|
||||
if idx < 0
|
||||
@@ -312,51 +312,51 @@ class Array
|
||||
#
|
||||
|
||||
def fill(arg0=nil, arg1=nil, arg2=nil, &block)
|
||||
if arg0 == nil && arg1 == nil && arg2 == nil && !block
|
||||
if arg0.nil? && arg1.nil? && arg2.nil? && !block
|
||||
raise ArgumentError, "wrong number of arguments (0 for 1..3)"
|
||||
end
|
||||
|
||||
beg = len = 0
|
||||
ary = []
|
||||
if block
|
||||
if arg0 == nil && arg1 == nil && arg2 == nil
|
||||
if arg0.nil? && arg1.nil? && arg2.nil?
|
||||
# ary.fill { |index| block } -> ary
|
||||
beg = 0
|
||||
len = self.size
|
||||
elsif arg0 != nil && arg0.kind_of?(Range)
|
||||
elsif !arg0.nil? && arg0.kind_of?(Range)
|
||||
# ary.fill(range) { |index| block } -> ary
|
||||
beg = arg0.begin
|
||||
beg += self.size if beg < 0
|
||||
len = arg0.end
|
||||
len += self.size if len < 0
|
||||
len += 1 unless arg0.exclude_end?
|
||||
elsif arg0 != nil
|
||||
elsif !arg0.nil?
|
||||
# ary.fill(start [, length] ) { |index| block } -> ary
|
||||
beg = arg0
|
||||
beg += self.size if beg < 0
|
||||
if arg1 == nil
|
||||
if arg1.nil?
|
||||
len = self.size
|
||||
else
|
||||
len = arg0 + arg1
|
||||
end
|
||||
end
|
||||
else
|
||||
if arg0 != nil && arg1 == nil && arg2 == nil
|
||||
if !arg0.nil? && arg1.nil? && arg2.nil?
|
||||
# ary.fill(obj) -> ary
|
||||
beg = 0
|
||||
len = self.size
|
||||
elsif arg0 != nil && arg1 != nil && arg1.kind_of?(Range)
|
||||
elsif !arg0.nil? && !arg1.nil? && arg1.kind_of?(Range)
|
||||
# ary.fill(obj, range ) -> ary
|
||||
beg = arg1.begin
|
||||
beg += self.size if beg < 0
|
||||
len = arg1.end
|
||||
len += self.size if len < 0
|
||||
len += 1 unless arg1.exclude_end?
|
||||
elsif arg0 != nil && arg1 != nil
|
||||
elsif !arg0.nil? && !arg1.nil?
|
||||
# ary.fill(obj, start [, length]) -> ary
|
||||
beg = arg1
|
||||
beg += self.size if beg < 0
|
||||
if arg2 == nil
|
||||
if arg2.nil?
|
||||
len = self.size
|
||||
else
|
||||
len = beg + arg2
|
||||
@@ -582,7 +582,7 @@ class Array
|
||||
elsif v == true
|
||||
satisfied = true
|
||||
smaller = true
|
||||
elsif v == false || v == nil
|
||||
elsif v == false || v.nil?
|
||||
smaller = false
|
||||
end
|
||||
if smaller
|
||||
@@ -681,4 +681,32 @@ class Array
|
||||
return nil if self.size == result.size
|
||||
self.replace(result)
|
||||
end
|
||||
|
||||
##
|
||||
# call-seq:
|
||||
# ary.index(val) -> int or nil
|
||||
# ary.index {|item| block } -> int or nil
|
||||
#
|
||||
# Returns the _index_ of the first object in +ary+ such that the object is
|
||||
# <code>==</code> to +obj+.
|
||||
#
|
||||
# If a block is given instead of an argument, returns the _index_ of the
|
||||
# first object for which the block returns +true+. Returns +nil+ if no
|
||||
# match is found.
|
||||
#
|
||||
# ISO 15.2.12.5.14
|
||||
def index(val=NONE, &block)
|
||||
return to_enum(:find_index, val) if !block && val == NONE
|
||||
|
||||
if block
|
||||
idx = 0
|
||||
self.each do |*e|
|
||||
return idx if block.call(*e)
|
||||
idx += 1
|
||||
end
|
||||
else
|
||||
return self.__ary_index(val)
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -113,8 +113,9 @@ mrb_ary_values_at(mrb_state *mrb, mrb_value self)
|
||||
* Returns the result of interpreting <i>aray</i> as an array of
|
||||
* <tt>[key, value]</tt> paris.
|
||||
*
|
||||
* [[:foo, :bar], [1, 2]].to_h
|
||||
* # => {:foo => :bar, 1 => 2}
|
||||
* [[:foo, :bar], [1, 2]].to_h
|
||||
* # => {:foo => :bar, 1 => 2}
|
||||
*
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
|
||||
@@ -293,3 +293,8 @@ assert('Array#to_h') do
|
||||
assert_raise(TypeError) { [1].to_h }
|
||||
assert_raise(ArgumentError) { [[1]].to_h }
|
||||
end
|
||||
|
||||
assert("Array#index (block)") do
|
||||
assert_nil (1..10).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
|
||||
assert_equal 34, (1..100).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
MRuby::Gem::Specification.new('mruby-bin-debugger') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'mruby debuggeer command'
|
||||
spec.summary = 'mruby debugger command'
|
||||
|
||||
spec.add_dependency('mruby-eval', :core => 'mruby-eval')
|
||||
|
||||
|
||||
@@ -203,9 +203,6 @@ mrb_debug_set_break_line( mrb_state *mrb, mrb_debug_context *dbg, const char *fi
|
||||
}
|
||||
|
||||
set_file = mrb_malloc(mrb, strlen(file) + 1);
|
||||
if(set_file == NULL) {
|
||||
return MRB_DEBUG_NOBUF;
|
||||
}
|
||||
|
||||
index = dbg->bpnum;
|
||||
dbg->bp[index].bpno = dbg->next_bpno;
|
||||
@@ -243,10 +240,6 @@ mrb_debug_set_break_method( mrb_state *mrb, mrb_debug_context *dbg, const char *
|
||||
|
||||
if(class_name != NULL) {
|
||||
set_class = mrb_malloc(mrb, strlen(class_name) + 1);
|
||||
if(set_class == NULL) {
|
||||
return MRB_DEBUG_NOBUF;
|
||||
}
|
||||
|
||||
strncpy(set_class, class_name, strlen(class_name) + 1);
|
||||
}
|
||||
else {
|
||||
@@ -254,12 +247,6 @@ mrb_debug_set_break_method( mrb_state *mrb, mrb_debug_context *dbg, const char *
|
||||
}
|
||||
|
||||
set_method = mrb_malloc(mrb, strlen(method_name) + 1);
|
||||
if(set_method == NULL) {
|
||||
if(set_class != NULL) {
|
||||
mrb_free(mrb, (void*)set_class);
|
||||
}
|
||||
return MRB_DEBUG_NOBUF;
|
||||
}
|
||||
|
||||
strncpy(set_method, method_name, strlen(method_name) + 1);
|
||||
|
||||
@@ -346,7 +333,7 @@ mrb_debug_delete_break( mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno )
|
||||
free_breakpoint(mrb, &dbg->bp[index]);
|
||||
|
||||
for(i = index ; i < dbg->bpnum; i++) {
|
||||
if(dbg->bp[i + 1].type == MRB_DEBUG_BPTYPE_NONE) {
|
||||
if((i + 1) == dbg->bpnum) {
|
||||
memset(&dbg->bp[i], 0, sizeof(mrb_debug_breakpoint));
|
||||
}
|
||||
else {
|
||||
@@ -474,7 +461,7 @@ mrb_debug_check_breakpoint_line( mrb_state *mrb, mrb_debug_context *dbg, const c
|
||||
}
|
||||
|
||||
bp = dbg->bp;
|
||||
for(i=0; i<MAX_BREAKPOINT; i++) {
|
||||
for(i=0; i<dbg->bpnum; i++) {
|
||||
switch (bp->type) {
|
||||
case MRB_DEBUG_BPTYPE_LINE:
|
||||
if(bp->enable == TRUE) {
|
||||
@@ -508,7 +495,7 @@ mrb_debug_check_breakpoint_method( mrb_state *mrb, mrb_debug_context *dbg, struc
|
||||
}
|
||||
|
||||
bp = dbg->bp;
|
||||
for(i=0; i<MAX_BREAKPOINT; i++) {
|
||||
for(i=0; i<dbg->bpnum; i++) {
|
||||
if(bp->type == MRB_DEBUG_BPTYPE_METHOD) {
|
||||
if(bp->enable == TRUE) {
|
||||
bpno = compare_break_method(mrb, bp, class_obj, method_sym, isCfunc);
|
||||
|
||||
@@ -45,18 +45,18 @@ build_path(mrb_state *mrb, const char *dir, const char *base)
|
||||
len = strlen(base) + 1;
|
||||
|
||||
if (strcmp(dir, ".")) {
|
||||
len += strlen(dir) + strlen("/");
|
||||
len += strlen(dir) + sizeof("/") - 1;
|
||||
}
|
||||
|
||||
if ((path = mrb_malloc(mrb, len)) != NULL) {
|
||||
memset(path, 0, len);
|
||||
path = mrb_malloc(mrb, len);
|
||||
memset(path, 0, len);
|
||||
|
||||
if (strcmp(dir, ".")) {
|
||||
strcat(path, dir);
|
||||
strcat(path, "/");
|
||||
}
|
||||
strcat(path, base);
|
||||
if (strcmp(dir, ".")) {
|
||||
strcat(path, dir);
|
||||
strcat(path, "/");
|
||||
}
|
||||
strcat(path, base);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -73,9 +73,10 @@ dirname(mrb_state *mrb, const char *path)
|
||||
p = strrchr(path, '/');
|
||||
len = p != NULL ? p - path : strlen(path);
|
||||
|
||||
if ((dir = mrb_malloc(mrb, len + 1)) != NULL) {
|
||||
strncpy(dir, path, len);
|
||||
}
|
||||
dir = mrb_malloc(mrb, len + 1);
|
||||
strncpy(dir, path, len);
|
||||
dir[len] = '\0';
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
@@ -84,9 +85,7 @@ source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename)
|
||||
{
|
||||
source_file *file = NULL;
|
||||
|
||||
if ((file = mrb_malloc(mrb, sizeof(source_file))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
file = mrb_malloc(mrb, sizeof(source_file));
|
||||
|
||||
memset(file, '\0', sizeof(source_file));
|
||||
file->fp = fopen(filename, "rb");
|
||||
@@ -105,7 +104,8 @@ source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename)
|
||||
static mrb_bool
|
||||
remove_newlines(char *s, FILE *fp)
|
||||
{
|
||||
char c, *p;
|
||||
int c;
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
if ((len = strlen(s)) == 0) {
|
||||
@@ -120,7 +120,7 @@ remove_newlines(char *s, FILE *fp)
|
||||
|
||||
if (*p == '\r') {
|
||||
/* peek the next character and skip '\n' */
|
||||
if ((unsigned char)(c = fgetc(fp)) != '\n') {
|
||||
if ((c = fgetc(fp)) != '\n') {
|
||||
ungetc(c, fp);
|
||||
}
|
||||
}
|
||||
@@ -196,6 +196,9 @@ mrb_debug_get_source(mrb_state *mrb, mrdb_state *mrdb, const char *srcpath, cons
|
||||
fclose(fp);
|
||||
break;
|
||||
}
|
||||
|
||||
mrb_free(mrb, (void *)search_path[1]);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size
|
||||
mrb_value
|
||||
mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc)
|
||||
{
|
||||
void *tmp;
|
||||
void (*tmp)(struct mrb_state *, struct mrb_irep *, mrb_code *, mrb_value *);
|
||||
mrb_value ruby_code;
|
||||
mrb_value s;
|
||||
mrb_value v;
|
||||
@@ -56,9 +56,9 @@ mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t
|
||||
* e
|
||||
* end
|
||||
*/
|
||||
ruby_code = mrb_str_new_cstr(mrb, "begin\n");
|
||||
ruby_code = mrb_str_new_lit(mrb, "begin\n");
|
||||
ruby_code = mrb_str_cat(mrb, ruby_code, expr, len);
|
||||
ruby_code = mrb_str_cat_cstr(mrb, ruby_code, "\nrescue => e\ne\nend");
|
||||
ruby_code = mrb_str_cat_lit(mrb, ruby_code, "\nrescue => e\ne\nend");
|
||||
|
||||
recv = dbg->regs[0];
|
||||
|
||||
|
||||
@@ -58,9 +58,11 @@ print_api_common_error(int32_t error)
|
||||
}
|
||||
|
||||
#undef STRTOUL
|
||||
#define STRTOUL(ul,s) \
|
||||
#define STRTOUL(ul,s) { \
|
||||
int i; \
|
||||
ul = 0; \
|
||||
for(int i=0; ISDIGIT(s[i]); i++) ul = 10*ul + (s[i] -'0');
|
||||
for(i=0; ISDIGIT(s[i]); i++) ul = 10*ul + (s[i] -'0'); \
|
||||
}
|
||||
|
||||
static int32_t
|
||||
parse_breakpoint_no(char* args)
|
||||
@@ -154,7 +156,7 @@ check_bptype(char* args)
|
||||
static void
|
||||
print_breakpoint(mrb_debug_breakpoint *bp)
|
||||
{
|
||||
char* enable_letter[] = {BREAK_INFO_MSG_DISABLE, BREAK_INFO_MSG_ENABLE};
|
||||
const char* enable_letter[] = {BREAK_INFO_MSG_DISABLE, BREAK_INFO_MSG_ENABLE};
|
||||
|
||||
if(bp->type == MRB_DEBUG_BPTYPE_LINE) {
|
||||
printf(BREAK_INFO_MSG_LINEBREAK,
|
||||
@@ -254,7 +256,7 @@ parse_breakcommand(mrdb_state *mrdb, const char **file, uint32_t *line, char **c
|
||||
}
|
||||
|
||||
args = mrdb->words[1];
|
||||
if((body = strchr(args, ':')) == NULL) {
|
||||
if((body = strrchr(args, ':')) == NULL) {
|
||||
body = args;
|
||||
type = check_bptype(body);
|
||||
} else {
|
||||
|
||||
@@ -33,7 +33,7 @@ static help_msg help_msg_list[] = {
|
||||
"\n"
|
||||
"Continue program stopped by a breakpoint.\n"
|
||||
"If N, which is non negative value, is passed,\n"
|
||||
"proceed program until the N-th breakpoint is comming.\n"
|
||||
"proceed program until the N-th breakpoint is coming.\n"
|
||||
"If N is not passed, N is assumed 1.\n"
|
||||
},
|
||||
{
|
||||
@@ -255,11 +255,11 @@ replace_ext(mrb_state *mrb, const char *filename, const char *ext)
|
||||
len = strlen(filename);
|
||||
}
|
||||
|
||||
if ((s = mrb_malloc(mrb, len + strlen(ext) + 1)) != NULL) {
|
||||
memset(s, '\0', len + strlen(ext) + 1);
|
||||
strncpy(s, filename, len);
|
||||
strcat(s, ext);
|
||||
}
|
||||
s = mrb_malloc(mrb, len + strlen(ext) + 1);
|
||||
memset(s, '\0', len + strlen(ext) + 1);
|
||||
strncpy(s, filename, len);
|
||||
strcat(s, ext);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -411,11 +411,11 @@ dbgcmd_list(mrb_state *mrb, mrdb_state *mrdb)
|
||||
filename = st->filename;
|
||||
}
|
||||
mrb_debug_list(mrb, mrdb->dbg, filename, st->line_min, st->line_max);
|
||||
listcmd_parser_state_free(mrb, st);
|
||||
|
||||
if (filename != NULL && filename != st->filename) {
|
||||
mrb_free(mrb, filename);
|
||||
}
|
||||
listcmd_parser_state_free(mrb, st);
|
||||
}
|
||||
|
||||
return DBGST_PROMPT;
|
||||
@@ -466,6 +466,7 @@ dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb)
|
||||
int buf;
|
||||
|
||||
printf("The program is running. Exit anyway? (y or n) ");
|
||||
fflush(stdout);
|
||||
|
||||
if ((buf = getchar()) == EOF) {
|
||||
mrdb->dbg->xm = DBG_QUIT;
|
||||
|
||||
@@ -32,14 +32,14 @@ dbgcmd_print(mrb_state *mrb, mrdb_state *mrdb)
|
||||
/* eval expr */
|
||||
expr = mrb_str_new_cstr(mrb, NULL);
|
||||
for (wcnt=1; wcnt<mrdb->wcnt; wcnt++) {
|
||||
expr = mrb_str_cat_cstr(mrb, expr, " ");
|
||||
expr = mrb_str_cat_lit(mrb, expr, " ");
|
||||
expr = mrb_str_cat_cstr(mrb, expr, mrdb->words[wcnt]);
|
||||
}
|
||||
|
||||
result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL);
|
||||
|
||||
/* $print_no = result */
|
||||
s = mrb_str_cat_cstr(mrb, result, "\0");
|
||||
s = mrb_str_cat_lit(mrb, result, "\0");
|
||||
printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s));
|
||||
|
||||
if (mrdb->print_no == 0) {
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#include "apibreak.h"
|
||||
#include "apilist.h"
|
||||
|
||||
void mrb_show_version(mrb_state *);
|
||||
void mrb_show_copyright(mrb_state *);
|
||||
void mrdb_state_free(mrb_state *);
|
||||
|
||||
static mrb_debug_context *_debug_context = NULL;
|
||||
@@ -215,6 +213,7 @@ void
|
||||
mrb_debug_context_free(mrb_state *mrb)
|
||||
{
|
||||
if (_debug_context) {
|
||||
mrb_debug_delete_break_all(mrb, _debug_context);
|
||||
mrb_free(mrb, _debug_context);
|
||||
_debug_context = NULL;
|
||||
}
|
||||
@@ -223,9 +222,9 @@ mrb_debug_context_free(mrb_state *mrb)
|
||||
static mrdb_state*
|
||||
mrdb_state_new(mrb_state *mrb)
|
||||
{
|
||||
mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrb_state));
|
||||
mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrdb_state));
|
||||
|
||||
memset(mrdb, 0, sizeof(mrb_state));
|
||||
memset(mrdb, 0, sizeof(mrdb_state));
|
||||
|
||||
mrdb->dbg = mrb_debug_context_get(mrb);
|
||||
mrdb->command = mrb_malloc(mrb, MAX_COMMAND_LINE+1);
|
||||
@@ -274,7 +273,7 @@ get_command(mrb_state *mrb, mrdb_state *mrdb)
|
||||
if (i == 0 && feof(stdin)) {
|
||||
clearerr(stdin);
|
||||
strcpy(mrdb->command, "quit");
|
||||
i += strlen("quit");
|
||||
i += sizeof("quit") - 1;
|
||||
}
|
||||
|
||||
if (i == MAX_COMMAND_LINE) {
|
||||
@@ -479,6 +478,7 @@ get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb)
|
||||
while (!cmd) {
|
||||
for (p=NULL; !p || *p=='\0'; ) {
|
||||
printf("(%s:%d) ", mrdb->dbg->prvfile, mrdb->dbg->prvline);
|
||||
fflush(stdout);
|
||||
p = get_command(mrb, mrdb);
|
||||
}
|
||||
|
||||
@@ -502,7 +502,7 @@ get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static const int32_t
|
||||
static int32_t
|
||||
check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)
|
||||
{
|
||||
struct RClass* c;
|
||||
@@ -570,7 +570,7 @@ mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *reg
|
||||
switch (dbg->xm) {
|
||||
case DBG_STEP:
|
||||
case DBG_NEXT: // temporary
|
||||
if (dbg->prvfile == file && dbg->prvline == line) {
|
||||
if (!file || (dbg->prvfile == file && dbg->prvline == line)) {
|
||||
return;
|
||||
}
|
||||
dbg->method_bpno = 0;
|
||||
@@ -650,13 +650,13 @@ main(int argc, char **argv)
|
||||
mrb_debug_context* dbg_backup;
|
||||
debug_command *cmd;
|
||||
|
||||
l_restart:
|
||||
|
||||
if (mrb == NULL) {
|
||||
fputs("Invalid mrb_state, exiting mruby\n", stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
l_restart:
|
||||
|
||||
/* parse command parameters */
|
||||
n = parse_args(mrb, argc, argv, &args);
|
||||
if (n == EXIT_FAILURE || args.rfp == NULL) {
|
||||
|
||||
@@ -6,16 +6,28 @@ MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec|
|
||||
if spec.build.cc.search_header_path 'readline/readline.h'
|
||||
spec.cc.defines << "ENABLE_READLINE"
|
||||
if spec.build.cc.search_header_path 'termcap.h'
|
||||
if MRUBY_BUILD_HOST_IS_CYGWIN then
|
||||
spec.linker.libraries << 'ncurses'
|
||||
else
|
||||
spec.linker.libraries << 'termcap'
|
||||
if MRUBY_BUILD_HOST_IS_CYGWIN || MRUBY_BUILD_HOST_IS_OPENBSD
|
||||
if spec.build.cc.search_header_path 'termcap.h'
|
||||
if MRUBY_BUILD_HOST_IS_CYGWIN then
|
||||
spec.linker.libraries << 'ncurses'
|
||||
else
|
||||
spec.linker.libraries << 'termcap'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if RUBY_PLATFORM.include?('netbsd')
|
||||
spec.linker.libraries << 'edit'
|
||||
else
|
||||
spec.linker.libraries << 'readline'
|
||||
if spec.build.cc.search_header_path 'curses.h'
|
||||
spec.linker.libraries << 'ncurses'
|
||||
end
|
||||
end
|
||||
spec.linker.libraries << 'readline'
|
||||
elsif spec.build.cc.search_header_path 'linenoise.h'
|
||||
spec.cc.defines << "ENABLE_LINENOISE"
|
||||
end
|
||||
|
||||
spec.bins = %w(mirb)
|
||||
spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
|
||||
end
|
||||
|
||||
@@ -74,16 +74,21 @@ get_history_path(mrb_state *mrb)
|
||||
static void
|
||||
p(mrb_state *mrb, mrb_value obj, int prompt)
|
||||
{
|
||||
obj = mrb_funcall(mrb, obj, "inspect", 0);
|
||||
mrb_value val;
|
||||
|
||||
val = mrb_funcall(mrb, obj, "inspect", 0);
|
||||
if (prompt) {
|
||||
if (!mrb->exc) {
|
||||
fputs(" => ", stdout);
|
||||
}
|
||||
else {
|
||||
obj = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
|
||||
val = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
|
||||
}
|
||||
}
|
||||
fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
|
||||
if (!mrb_string_p(val)) {
|
||||
val = mrb_obj_as_string(mrb, obj);
|
||||
}
|
||||
fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
|
||||
putc('\n', stdout);
|
||||
}
|
||||
|
||||
@@ -188,9 +193,6 @@ is_code_block_open(struct mrb_parser_state *parser)
|
||||
return code_block_open;
|
||||
}
|
||||
|
||||
void mrb_show_version(mrb_state *);
|
||||
void mrb_show_copyright(mrb_state *);
|
||||
|
||||
struct _args {
|
||||
mrb_bool verbose : 1;
|
||||
int argc;
|
||||
@@ -276,6 +278,7 @@ print_cmdline(int code_block_open)
|
||||
else {
|
||||
printf("> ");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -363,6 +366,8 @@ main(int argc, char **argv)
|
||||
ai = mrb_gc_arena_save(mrb);
|
||||
|
||||
while (TRUE) {
|
||||
char *utf8;
|
||||
|
||||
#ifndef ENABLE_READLINE
|
||||
print_cmdline(code_block_open);
|
||||
|
||||
@@ -412,17 +417,21 @@ main(int argc, char **argv)
|
||||
strcpy(ruby_code, last_code_line);
|
||||
}
|
||||
|
||||
utf8 = mrb_utf8_from_locale(ruby_code, -1);
|
||||
if (!utf8) abort();
|
||||
|
||||
/* parse code */
|
||||
parser = mrb_parser_new(mrb);
|
||||
if (parser == NULL) {
|
||||
fputs("create parser state error\n", stderr);
|
||||
break;
|
||||
}
|
||||
parser->s = ruby_code;
|
||||
parser->send = ruby_code + strlen(ruby_code);
|
||||
parser->s = utf8;
|
||||
parser->send = utf8 + strlen(utf8);
|
||||
parser->lineno = cxt->lineno;
|
||||
mrb_parser_parse(parser, cxt);
|
||||
code_block_open = is_code_block_open(parser);
|
||||
mrb_utf8_free(utf8);
|
||||
|
||||
if (code_block_open) {
|
||||
/* no evaluation of code */
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
MRuby::Gem::Specification.new 'mruby-bin-mrbc' do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'mruby compiler executable'
|
||||
|
||||
spec.add_dependency 'mruby-compiler', :core => 'mruby-compiler'
|
||||
|
||||
exec = exefile("#{build.build_dir}/bin/mrbc")
|
||||
mrbc_objs = Dir.glob("#{spec.dir}/tools/mrbc/*.c").map { |f| objfile(f.pathmap("#{spec.build_dir}/tools/mrbc/%n")) }.flatten
|
||||
|
||||
file exec => mrbc_objs + [libfile("#{build.build_dir}/lib/libmruby_core")] do |t|
|
||||
build.linker.run t.name, t.prerequisites
|
||||
end
|
||||
|
||||
build.bins << 'mrbc' unless build.bins.find { |v| v == 'mrbc' }
|
||||
end
|
||||
@@ -9,16 +9,6 @@
|
||||
#define RITEBIN_EXT ".mrb"
|
||||
#define C_EXT ".c"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
void mrb_show_version(mrb_state *);
|
||||
void mrb_show_copyright(mrb_state *);
|
||||
}
|
||||
#else
|
||||
void mrb_show_version(mrb_state *);
|
||||
void mrb_show_copyright(mrb_state *);
|
||||
#endif
|
||||
|
||||
struct mrbc_args {
|
||||
int argc;
|
||||
char **argv;
|
||||
@@ -28,7 +18,7 @@ struct mrbc_args {
|
||||
const char *initname;
|
||||
mrb_bool check_syntax : 1;
|
||||
mrb_bool verbose : 1;
|
||||
mrb_bool debug_info : 1;
|
||||
unsigned int flags : 4;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -41,6 +31,8 @@ usage(const char *name)
|
||||
"-v print version number, then turn on verbose mode",
|
||||
"-g produce debugging information",
|
||||
"-B<symbol> binary <symbol> output in C language format",
|
||||
"-e generate little endian iseq data",
|
||||
"-E generate big endian iseq data",
|
||||
"--verbose run at verbose mode",
|
||||
"--version print the version",
|
||||
"--copyright print the copyright",
|
||||
@@ -124,7 +116,13 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
|
||||
args->verbose = TRUE;
|
||||
break;
|
||||
case 'g':
|
||||
args->debug_info = TRUE;
|
||||
args->flags |= DUMP_DEBUG_INFO;
|
||||
break;
|
||||
case 'E':
|
||||
args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK);
|
||||
break;
|
||||
case 'e':
|
||||
args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK);
|
||||
break;
|
||||
case 'h':
|
||||
return -1;
|
||||
@@ -153,14 +151,17 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) {
|
||||
fprintf(stderr, "%s: generating %s endian C file. specify -e/-E for cross compiling.\n",
|
||||
args->prog, bigendian_p() ? "big" : "little");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(mrb_state *mrb, struct mrbc_args *args)
|
||||
{
|
||||
if (args->outfile)
|
||||
mrb_free(mrb, (void*)args->outfile);
|
||||
mrb_free(mrb, (void*)args->outfile);
|
||||
mrb_close(mrb);
|
||||
}
|
||||
|
||||
@@ -232,13 +233,13 @@ dump_file(mrb_state *mrb, FILE *wfp, const char *outfile, struct RProc *proc, st
|
||||
mrb_irep *irep = proc->body.irep;
|
||||
|
||||
if (args->initname) {
|
||||
n = mrb_dump_irep_cfunc(mrb, irep, args->debug_info, wfp, args->initname);
|
||||
n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname);
|
||||
if (n == MRB_DUMP_INVALID_ARGUMENT) {
|
||||
fprintf(stderr, "%s: invalid C language symbol name\n", args->initname);
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = mrb_dump_irep_binary(mrb, irep, args->debug_info, wfp);
|
||||
n = mrb_dump_irep_binary(mrb, irep, args->flags, wfp);
|
||||
}
|
||||
if (n != MRB_DUMP_OK) {
|
||||
fprintf(stderr, "%s: error in mrb dump (%s) %d\n", args->prog, outfile, n);
|
||||
@@ -23,7 +23,7 @@ MRuby.each_target do
|
||||
FileUtils.copy "#{File.dirname(__FILE__)}/#{mruby_config}", t.name
|
||||
config = Hash[open("#{build_dir}/lib/libmruby.flags.mak").read.split("\n").map {|x| a = x.split(/\s*=\s*/, 2); [a[0], a[1].gsub('\\"', '"') ]}]
|
||||
IO.write(t.name, File.open(t.name) {|f|
|
||||
f.read.gsub (/echo (MRUBY_CFLAGS|MRUBY_LDFLAGS|MRUBY_LIBS)/) {|x| config[$1].empty? ? '' : "echo #{config[$1]}"}
|
||||
f.read.gsub (/echo (MRUBY_CFLAGS|MRUBY_LIBS|MRUBY_LDFLAGS_BEFORE_LIBS|MRUBY_LDFLAGS)/) {|x| config[$1].empty? ? '' : "echo #{config[$1]}"}
|
||||
})
|
||||
FileUtils.chmod(0755, t.name)
|
||||
end
|
||||
|
||||
@@ -4,12 +4,14 @@ while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--cflags) echo MRUBY_CFLAGS;;
|
||||
--ldflags) echo MRUBY_LDFLAGS;;
|
||||
--ldflags-before-libs) echo MRUBY_LDFLAGS_BEFORE_LIBS;;
|
||||
--libs) echo MRUBY_LIBS;;
|
||||
--help) echo "Usage: mruby-config [switches]"
|
||||
echo " switches:"
|
||||
echo " --cflags print flags passed to compiler"
|
||||
echo " --ldflags print flags passed to linker"
|
||||
echo " --libs print linked libraries"
|
||||
echo " --cflags print flags passed to compiler"
|
||||
echo " --ldflags print flags passed to linker"
|
||||
echo " --ldflags-before-libs print flags passwd to linker before linked libraries"
|
||||
echo " --libs print linked libraries"
|
||||
exit 0;;
|
||||
esac
|
||||
shift
|
||||
|
||||
@@ -5,6 +5,7 @@ shift
|
||||
if "%0" equ "" goto :eof
|
||||
if "%0" equ "--cflags" goto cflags
|
||||
if "%0" equ "--ldflags" goto ldflags
|
||||
if "%0" equ "--ldflags-before-libs" goto ldflagsbeforelibs
|
||||
if "%0" equ "--libs" goto libs
|
||||
if "%0" equ "--help" goto showhelp
|
||||
echo Invalid Option
|
||||
@@ -22,9 +23,14 @@ goto top
|
||||
echo MRUBY_LDFLAGS
|
||||
goto top
|
||||
|
||||
:ldflagsbeforelibs
|
||||
echo MRUBY_LDFLAGS_BEFORE_LIBS
|
||||
goto top
|
||||
|
||||
:showhelp
|
||||
echo Usage: mruby-config [switches]
|
||||
echo switches:
|
||||
echo --cflags print flags passed to compiler
|
||||
echo --ldflags print flags passed to linker
|
||||
echo --libs print linked libraries
|
||||
echo --cflags print flags passed to compiler
|
||||
echo --ldflags print flags passed to linker
|
||||
echo --ldflags-before-libs print flags passwd to linker before linked libraries
|
||||
echo --libs print linked libraries
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
require 'tempfile'
|
||||
|
||||
assert('regression for #1564') do
|
||||
o = `bin/mruby -e '<<' 2>&1`
|
||||
o = `#{cmd('mruby')} -e #{shellquote('<<')} 2>&1`
|
||||
assert_equal o, "-e:1:2: syntax error, unexpected tLSHFT\n"
|
||||
o = `bin/mruby -e '<<-' 2>&1`
|
||||
o = `#{cmd('mruby')} -e #{shellquote('<<-')} 2>&1`
|
||||
assert_equal o, "-e:1:3: syntax error, unexpected tLSHFT\n"
|
||||
end
|
||||
|
||||
assert('regression for #1572') do
|
||||
script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb')
|
||||
system "echo 'p \"ok\"' > #{script.path}"
|
||||
system "bin/mrbc -g -o #{bin.path} #{script.path}"
|
||||
o = `bin/mruby -b #{bin.path}`.strip
|
||||
File.write script.path, 'p "ok"'
|
||||
system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}"
|
||||
o = `#{cmd('mruby')} -b #{bin.path}`.strip
|
||||
assert_equal o, '"ok"'
|
||||
end
|
||||
|
||||
@@ -21,14 +21,14 @@ assert '$0 value' do
|
||||
# .rb script
|
||||
script.write "p $0\n"
|
||||
script.flush
|
||||
assert_equal "\"#{script.path}\"", `./bin/mruby "#{script.path}"`.chomp
|
||||
assert_equal "\"#{script.path}\"", `#{cmd('mruby')} "#{script.path}"`.chomp
|
||||
|
||||
# .mrb file
|
||||
`./bin/mrbc -o "#{bin.path}" "#{script.path}"`
|
||||
assert_equal "\"#{bin.path}\"", `./bin/mruby -b "#{bin.path}"`.chomp
|
||||
`#{cmd('mrbc')} -o "#{bin.path}" "#{script.path}"`
|
||||
assert_equal "\"#{bin.path}\"", `#{cmd('mruby')} -b "#{bin.path}"`.chomp
|
||||
|
||||
# one liner
|
||||
assert_equal '"-e"', `./bin/mruby -e 'p $0'`.chomp
|
||||
assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp
|
||||
end
|
||||
|
||||
assert '__END__', '8.6' do
|
||||
@@ -42,5 +42,5 @@ __END__
|
||||
p 'legend'
|
||||
EOS
|
||||
script.flush
|
||||
assert_equal "\"test\"\n\"fin\"\n", `./bin/mruby #{script.path}`
|
||||
assert_equal "\"test\"\n\"fin\"\n", `#{cmd('mruby')} #{script.path}`
|
||||
end
|
||||
|
||||
@@ -3,4 +3,5 @@ MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec|
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'mruby command'
|
||||
spec.bins = %w(mruby)
|
||||
spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
|
||||
end
|
||||
|
||||
@@ -7,21 +7,19 @@
|
||||
#include "mruby/dump.h"
|
||||
#include "mruby/variable.h"
|
||||
|
||||
#ifndef ENABLE_STDIO
|
||||
#ifdef MRB_DISABLE_STDIO
|
||||
static void
|
||||
p(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
obj = mrb_funcall(mrb, obj, "inspect", 0);
|
||||
fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
|
||||
mrb_value val = mrb_inspect(mrb, obj);
|
||||
|
||||
fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
|
||||
putc('\n', stdout);
|
||||
}
|
||||
#else
|
||||
#define p(mrb,obj) mrb_p(mrb,obj)
|
||||
#endif
|
||||
|
||||
void mrb_show_version(mrb_state *);
|
||||
void mrb_show_copyright(mrb_state *);
|
||||
|
||||
struct _args {
|
||||
FILE *rfp;
|
||||
char* cmdline;
|
||||
@@ -161,10 +159,9 @@ cleanup(mrb_state *mrb, struct _args *args)
|
||||
{
|
||||
if (args->rfp && args->rfp != stdin)
|
||||
fclose(args->rfp);
|
||||
if (args->cmdline && !args->fname)
|
||||
if (!args->fname)
|
||||
mrb_free(mrb, args->cmdline);
|
||||
if (args->argv)
|
||||
mrb_free(mrb, args->argv);
|
||||
mrb_free(mrb, args->argv);
|
||||
mrb_close(mrb);
|
||||
}
|
||||
|
||||
@@ -194,7 +191,11 @@ main(int argc, char **argv)
|
||||
|
||||
ARGV = mrb_ary_new_capa(mrb, args.argc);
|
||||
for (i = 0; i < args.argc; i++) {
|
||||
mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, args.argv[i]));
|
||||
char* utf8 = mrb_utf8_from_locale(args.argv[i], -1);
|
||||
if (utf8) {
|
||||
mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
|
||||
mrb_utf8_free(utf8);
|
||||
}
|
||||
}
|
||||
mrb_define_global_const(mrb, "ARGV", ARGV);
|
||||
|
||||
@@ -207,7 +208,7 @@ main(int argc, char **argv)
|
||||
/* Set $0 */
|
||||
zero_sym = mrb_intern_lit(mrb, "$0");
|
||||
if (args.rfp) {
|
||||
char *cmdline;
|
||||
const char *cmdline;
|
||||
cmdline = args.cmdline ? args.cmdline : "-";
|
||||
mrbc_filename(mrb, c, cmdline);
|
||||
mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline));
|
||||
@@ -225,7 +226,10 @@ main(int argc, char **argv)
|
||||
v = mrb_load_file_cxt(mrb, args.rfp, c);
|
||||
}
|
||||
else {
|
||||
v = mrb_load_string_cxt(mrb, args.cmdline, c);
|
||||
char* utf8 = mrb_utf8_from_locale(args.cmdline, -1);
|
||||
if (!utf8) abort();
|
||||
v = mrb_load_string_cxt(mrb, utf8, c);
|
||||
mrb_utf8_free(utf8);
|
||||
}
|
||||
|
||||
mrbc_context_free(mrb, c);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
require 'tempfile'
|
||||
|
||||
assert('no files') do
|
||||
o = `bin/mruby-strip 2>&1`
|
||||
o = `#{cmd('mruby-strip')} 2>&1`
|
||||
assert_equal 1, $?.exitstatus
|
||||
assert_equal "no files to strip", o.split("\n")[0]
|
||||
end
|
||||
|
||||
assert('file not found') do
|
||||
o = `bin/mruby-strip not_found.mrb 2>&1`
|
||||
o = `#{cmd('mruby-strip')} not_found.mrb 2>&1`
|
||||
assert_equal 1, $?.exitstatus
|
||||
assert_equal "can't open file for reading not_found.mrb\n", o
|
||||
end
|
||||
@@ -16,7 +16,7 @@ assert('not irep file') do
|
||||
t = Tempfile.new('script.rb')
|
||||
t.write 'p test\n'
|
||||
t.flush
|
||||
o = `bin/mruby-strip #{t.path} 2>&1`
|
||||
o = `#{cmd('mruby-strip')} #{t.path} 2>&1`
|
||||
assert_equal 1, $?.exitstatus
|
||||
assert_equal "can't read irep file #{t.path}\n", o
|
||||
end
|
||||
@@ -26,15 +26,15 @@ assert('success') do
|
||||
Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb')
|
||||
script_file.write "p 'test'\n"
|
||||
script_file.flush
|
||||
`bin/mrbc -g -o #{compiled1.path} #{script_file.path}`
|
||||
`bin/mrbc -g -o #{compiled2.path} #{script_file.path}`
|
||||
`#{cmd('mrbc')} -g -o #{compiled1.path} #{script_file.path}`
|
||||
`#{cmd('mrbc')} -g -o #{compiled2.path} #{script_file.path}`
|
||||
|
||||
o = `bin/mruby-strip #{compiled1.path}`
|
||||
o = `#{cmd('mruby-strip')} #{compiled1.path}`
|
||||
assert_equal 0, $?.exitstatus
|
||||
assert_equal "", o
|
||||
assert_equal `bin/mruby #{script_file.path}`, `bin/mruby -b #{compiled1.path}`
|
||||
assert_equal `#{cmd('mruby')} #{script_file.path}`, `#{cmd('mruby')} -b #{compiled1.path}`
|
||||
|
||||
o = `bin/mruby-strip #{compiled1.path} #{compiled2.path}`
|
||||
o = `#{cmd('mruby-strip')} #{compiled1.path} #{compiled2.path}`
|
||||
assert_equal 0, $?.exitstatus
|
||||
assert_equal "", o
|
||||
end
|
||||
@@ -44,12 +44,12 @@ assert('check debug section') do
|
||||
Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb')
|
||||
script_file.write "p 'test'\n"
|
||||
script_file.flush
|
||||
`bin/mrbc -o #{without_debug.path} #{script_file.path}`
|
||||
`bin/mrbc -g -o #{with_debug.path} #{script_file.path}`
|
||||
`#{cmd('mrbc')} -o #{without_debug.path} #{script_file.path}`
|
||||
`#{cmd('mrbc')} -g -o #{with_debug.path} #{script_file.path}`
|
||||
|
||||
assert_true with_debug.size >= without_debug.size
|
||||
|
||||
`bin/mruby-strip #{with_debug.path}`
|
||||
`#{cmd('mruby-strip')} #{with_debug.path}`
|
||||
assert_equal without_debug.size, with_debug.size
|
||||
end
|
||||
|
||||
@@ -62,12 +62,12 @@ a += b
|
||||
p Kernel.local_variables
|
||||
EOS
|
||||
script_file.flush
|
||||
`bin/mrbc -o #{with_lv.path} #{script_file.path}`
|
||||
`bin/mrbc -o #{without_lv.path} #{script_file.path}`
|
||||
`#{cmd('mrbc')} -o #{with_lv.path} #{script_file.path}`
|
||||
`#{cmd('mrbc')} -o #{without_lv.path} #{script_file.path}`
|
||||
|
||||
`bin/mruby-strip -l #{without_lv.path}`
|
||||
`#{cmd('mruby-strip')} -l #{without_lv.path}`
|
||||
assert_true without_lv.size < with_lv.size
|
||||
|
||||
assert_equal '[:a, :b]', `bin/mruby -b #{with_lv.path}`.chomp
|
||||
assert_equal '[]', `bin/mruby -b #{without_lv.path}`.chomp
|
||||
assert_equal '[:a, :b]', `#{cmd('mruby')} -b #{with_lv.path}`.chomp
|
||||
assert_equal '[]', `#{cmd('mruby')} -b #{without_lv.path}`.chomp
|
||||
end
|
||||
|
||||
@@ -31,8 +31,8 @@ irep_remove_lv(mrb_state *mrb, mrb_irep *irep)
|
||||
static void
|
||||
print_usage(const char *f)
|
||||
{
|
||||
printf("Usage: %s [options] irepfiles\n", f);
|
||||
printf("options:\n");
|
||||
printf("Usage: %s [switches] irepfiles\n", f);
|
||||
printf("switches:\n");
|
||||
printf(" -l, --lvar remove LVAR section too.\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ assert('Compiling multiple files without new line in last line. #2361') do
|
||||
a.flush
|
||||
b.write('module B; end')
|
||||
b.flush
|
||||
result = `bin/mrbc -c -o #{out.path} #{a.path} #{b.path} 2>&1`
|
||||
assert_equal "bin/mrbc:#{a.path}:Syntax OK", result.chomp
|
||||
result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} #{b.path} 2>&1`
|
||||
assert_equal "#{cmd('mrbc')}:#{a.path}:Syntax OK", result.chomp
|
||||
assert_equal 0, $?.exitstatus
|
||||
end
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "node.h"
|
||||
#include "mruby/opcode.h"
|
||||
#include "mruby/re.h"
|
||||
#include "mrb_throw.h"
|
||||
#include "mruby/throw.h"
|
||||
|
||||
typedef mrb_ast_node node;
|
||||
typedef struct mrb_parser_state parser_state;
|
||||
@@ -96,7 +96,7 @@ codegen_error(codegen_scope *s, const char *message)
|
||||
mrb_pool_close(s->mpool);
|
||||
s = tmp;
|
||||
}
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MBB_DISABLE_STDIO
|
||||
if (s->filename && s->lineno) {
|
||||
fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message);
|
||||
}
|
||||
@@ -188,6 +188,11 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
|
||||
if (val) break;
|
||||
switch (c0) {
|
||||
case OP_MOVE:
|
||||
if (GETARG_A(i) == GETARG_A(i0)) {
|
||||
/* skip overriden OP_MOVE */
|
||||
s->pc--;
|
||||
s->iseq[s->pc] = i;
|
||||
}
|
||||
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) {
|
||||
/* skip swapping OP_MOVE */
|
||||
return 0;
|
||||
@@ -370,7 +375,7 @@ dispatch(codegen_scope *s, int pc)
|
||||
case OP_ONERR:
|
||||
break;
|
||||
default:
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
fprintf(stderr, "bug: dispatch on non JMP op\n");
|
||||
#endif
|
||||
scope_error(s);
|
||||
@@ -406,7 +411,18 @@ push_(codegen_scope *s)
|
||||
nregs_update;
|
||||
}
|
||||
|
||||
static void
|
||||
push_n_(codegen_scope *s, size_t n)
|
||||
{
|
||||
if (s->sp+n > 511) {
|
||||
codegen_error(s, "too complex expression");
|
||||
}
|
||||
s->sp+=n;
|
||||
nregs_update;
|
||||
}
|
||||
|
||||
#define push() push_(s)
|
||||
#define push_n(n) push_n_(s,n)
|
||||
#define pop_(s) ((s)->sp--)
|
||||
#define pop() pop_(s)
|
||||
#define pop_n(n) (s->sp-=(n))
|
||||
@@ -953,8 +969,16 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_MASGN:
|
||||
gen_vmassignment(s, tree->car, sp, val);
|
||||
break;
|
||||
|
||||
/* splat without assignment */
|
||||
case NODE_NIL:
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
printf("unknown lhs %d\n", type);
|
||||
#endif
|
||||
break;
|
||||
@@ -989,9 +1013,12 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
|
||||
}
|
||||
if (val) {
|
||||
genop(s, MKOP_AB(OP_MOVE, cursp(), rhs));
|
||||
push();
|
||||
}
|
||||
pop();
|
||||
else {
|
||||
pop();
|
||||
}
|
||||
push_n(post);
|
||||
pop_n(post);
|
||||
genop(s, MKOP_ABC(OP_APOST, cursp(), n, post));
|
||||
n = 1;
|
||||
if (t->car) { /* rest */
|
||||
@@ -1005,9 +1032,7 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
pop();
|
||||
push();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,6 +1330,17 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
int pos1, pos2;
|
||||
node *e = tree->cdr->cdr->car;
|
||||
|
||||
switch ((intptr_t)tree->car->car) {
|
||||
case NODE_TRUE:
|
||||
case NODE_INT:
|
||||
case NODE_STR:
|
||||
codegen(s, tree->cdr->car, val);
|
||||
return;
|
||||
case NODE_FALSE:
|
||||
case NODE_NIL:
|
||||
codegen(s, e, val);
|
||||
return;
|
||||
}
|
||||
codegen(s, tree->car, VAL);
|
||||
pop();
|
||||
pos1 = genop_peep(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0), NOVAL);
|
||||
@@ -1447,12 +1483,17 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
int pos = cursp();
|
||||
genop(s, MKOP_A(OP_LOADNIL, cursp()));
|
||||
if (pos3) dispatch_linked(s, pos3);
|
||||
pop();
|
||||
if (head) pop();
|
||||
genop(s, MKOP_AB(OP_MOVE, cursp(), pos));
|
||||
push();
|
||||
}
|
||||
else if (pos3) {
|
||||
dispatch_linked(s, pos3);
|
||||
else {
|
||||
if (pos3) {
|
||||
dispatch_linked(s, pos3);
|
||||
}
|
||||
if (head) {
|
||||
pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1603,8 +1644,14 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
}
|
||||
if (t->car) { /* rest (len - pre - post) */
|
||||
int rn = len - post - n;
|
||||
int rn;
|
||||
|
||||
if (len < post + n) {
|
||||
rn = 0;
|
||||
}
|
||||
else {
|
||||
rn = len - post - n;
|
||||
}
|
||||
genop(s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn));
|
||||
gen_assignment(s, t->car, cursp(), NOVAL);
|
||||
n += rn;
|
||||
@@ -1628,6 +1675,9 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
/* variable rhs */
|
||||
codegen(s, t, VAL);
|
||||
gen_vmassignment(s, tree->car, rhs, val);
|
||||
if (!val) {
|
||||
pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1890,7 +1940,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
break;
|
||||
|
||||
case NODE_GVAR:
|
||||
{
|
||||
if (val) {
|
||||
int sym = new_sym(s, sym(tree));
|
||||
|
||||
genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
|
||||
@@ -1899,7 +1949,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
break;
|
||||
|
||||
case NODE_IVAR:
|
||||
{
|
||||
if (val) {
|
||||
int sym = new_sym(s, sym(tree));
|
||||
|
||||
genop(s, MKOP_ABx(OP_GETIV, cursp(), sym));
|
||||
@@ -1908,7 +1958,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
break;
|
||||
|
||||
case NODE_CVAR:
|
||||
{
|
||||
if (val) {
|
||||
int sym = new_sym(s, sym(tree));
|
||||
|
||||
genop(s, MKOP_ABx(OP_GETCV, cursp(), sym));
|
||||
@@ -1921,7 +1971,9 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
int sym = new_sym(s, sym(tree));
|
||||
|
||||
genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym));
|
||||
push();
|
||||
if (val) {
|
||||
push();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1930,7 +1982,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
break;
|
||||
|
||||
case NODE_BACK_REF:
|
||||
{
|
||||
if (val) {
|
||||
char buf[2] = { '$' };
|
||||
mrb_value str;
|
||||
int sym;
|
||||
@@ -1944,7 +1996,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
break;
|
||||
|
||||
case NODE_NTH_REF:
|
||||
{
|
||||
if (val) {
|
||||
int sym;
|
||||
mrb_state *mrb = s->mrb;
|
||||
mrb_value fix = mrb_fixnum_value((intptr_t)tree);
|
||||
@@ -2086,6 +2138,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if (val) {
|
||||
node *n = tree;
|
||||
|
||||
if (!n) break;
|
||||
codegen(s, n->car, VAL);
|
||||
n = n->cdr;
|
||||
while (n) {
|
||||
@@ -2174,7 +2227,8 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
case NODE_REGX:
|
||||
if (val) {
|
||||
char *p1 = (char*)tree->car;
|
||||
char *p2 = (char*)tree->cdr;
|
||||
char *p2 = (char*)tree->cdr->car;
|
||||
char *p3 = (char*)tree->cdr->cdr;
|
||||
int ai = mrb_gc_arena_save(s->mrb);
|
||||
int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS));
|
||||
int off = new_lit(s, mrb_str_new_cstr(s->mrb, p1));
|
||||
@@ -2184,11 +2238,22 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
|
||||
push();
|
||||
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
|
||||
if (p2) {
|
||||
if (p2 || p3) {
|
||||
push();
|
||||
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
|
||||
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
|
||||
if (p2) {
|
||||
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
|
||||
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
|
||||
} else {
|
||||
genop(s, MKOP_A(OP_LOADNIL, cursp()));
|
||||
}
|
||||
argc++;
|
||||
if (p3) {
|
||||
push();
|
||||
off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
|
||||
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
|
||||
argc++;
|
||||
pop();
|
||||
}
|
||||
pop();
|
||||
}
|
||||
pop();
|
||||
@@ -2628,13 +2693,17 @@ loop_break(codegen_scope *s, node *tree)
|
||||
}
|
||||
|
||||
loop = s->loop;
|
||||
while (loop->type == LOOP_BEGIN) {
|
||||
while (loop && loop->type == LOOP_BEGIN) {
|
||||
genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
|
||||
loop = loop->prev;
|
||||
}
|
||||
while (loop->type == LOOP_RESCUE) {
|
||||
while (loop && loop->type == LOOP_RESCUE) {
|
||||
loop = loop->prev;
|
||||
}
|
||||
if (!loop) {
|
||||
codegen_error(s, "unexpected break");
|
||||
}
|
||||
|
||||
if (loop->type == LOOP_NORMAL) {
|
||||
int tmp;
|
||||
|
||||
@@ -2664,453 +2733,6 @@ loop_pop(codegen_scope *s, int val)
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
static int
|
||||
print_r(mrb_state *mrb, mrb_irep *irep, size_t n, int pre)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (n == 0) return 0;
|
||||
|
||||
for (i=0; i+1<irep->nlocals; i++) {
|
||||
if (irep->lv[i].r == n) {
|
||||
mrb_sym sym = irep->lv[i].name;
|
||||
if (pre) printf(" ");
|
||||
printf("R%d:%s", (int)n, mrb_sym2name(mrb, sym));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RA 1
|
||||
#define RB 2
|
||||
#define RAB 3
|
||||
|
||||
static void
|
||||
print_lv(mrb_state *mrb, mrb_irep *irep, mrb_code c, int r)
|
||||
{
|
||||
int pre = 0;
|
||||
|
||||
if (!irep->lv
|
||||
|| ((!(r & RA) || GETARG_A(c) >= irep->nlocals)
|
||||
&& (!(r & RB) || GETARG_B(c) >= irep->nlocals))) {
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
printf("\t; ");
|
||||
if (r & RA) {
|
||||
pre = print_r(mrb, irep, GETARG_A(c), 0);
|
||||
}
|
||||
if (r & RB) {
|
||||
print_r(mrb, irep, GETARG_B(c), pre);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
codedump(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
#ifdef ENABLE_STDIO
|
||||
int i;
|
||||
int ai;
|
||||
mrb_code c;
|
||||
const char *file = NULL, *next_file;
|
||||
int32_t line;
|
||||
|
||||
if (!irep) return;
|
||||
printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", (void*)irep,
|
||||
irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen);
|
||||
|
||||
for (i = 0; i < (int)irep->ilen; i++) {
|
||||
ai = mrb_gc_arena_save(mrb);
|
||||
|
||||
next_file = mrb_debug_get_filename(irep, i);
|
||||
if (next_file && file != next_file) {
|
||||
printf("file: %s\n", next_file);
|
||||
file = next_file;
|
||||
}
|
||||
line = mrb_debug_get_line(irep, i);
|
||||
if (line < 0) {
|
||||
printf(" ");
|
||||
}
|
||||
else {
|
||||
printf("%5d ", line);
|
||||
}
|
||||
|
||||
printf("%03d ", i);
|
||||
c = irep->iseq[i];
|
||||
switch (GET_OPCODE(c)) {
|
||||
case OP_NOP:
|
||||
printf("OP_NOP\n");
|
||||
break;
|
||||
case OP_MOVE:
|
||||
printf("OP_MOVE\tR%d\tR%d", GETARG_A(c), GETARG_B(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_LOADL:
|
||||
{
|
||||
mrb_value v = irep->pool[GETARG_Bx(c)];
|
||||
mrb_value s = mrb_inspect(mrb, v);
|
||||
printf("OP_LOADL\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s));
|
||||
}
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_LOADI:
|
||||
printf("OP_LOADI\tR%d\t%d", GETARG_A(c), GETARG_sBx(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_LOADSYM:
|
||||
printf("OP_LOADSYM\tR%d\t:%s", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_LOADNIL:
|
||||
printf("OP_LOADNIL\tR%d\t", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_LOADSELF:
|
||||
printf("OP_LOADSELF\tR%d\t", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_LOADT:
|
||||
printf("OP_LOADT\tR%d\t", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_LOADF:
|
||||
printf("OP_LOADF\tR%d\t", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_GETGLOBAL:
|
||||
printf("OP_GETGLOBAL\tR%d\t:%s", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_SETGLOBAL:
|
||||
printf("OP_SETGLOBAL\t:%s\tR%d",
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
|
||||
GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_GETCONST:
|
||||
printf("OP_GETCONST\tR%d\t:%s", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_SETCONST:
|
||||
printf("OP_SETCONST\t:%s\tR%d",
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
|
||||
GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_GETMCNST:
|
||||
printf("OP_GETMCNST\tR%d\tR%d::%s", GETARG_A(c), GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_SETMCNST:
|
||||
printf("OP_SETMCNST\tR%d::%s\tR%d", GETARG_A(c)+1,
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
|
||||
GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_GETIV:
|
||||
printf("OP_GETIV\tR%d\t%s", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_SETIV:
|
||||
printf("OP_SETIV\t%s\tR%d",
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
|
||||
GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_GETUPVAR:
|
||||
printf("OP_GETUPVAR\tR%d\t%d\t%d",
|
||||
GETARG_A(c), GETARG_B(c), GETARG_C(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_SETUPVAR:
|
||||
printf("OP_SETUPVAR\tR%d\t%d\t%d",
|
||||
GETARG_A(c), GETARG_B(c), GETARG_C(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_GETCV:
|
||||
printf("OP_GETCV\tR%d\t%s", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_SETCV:
|
||||
printf("OP_SETCV\t%s\tR%d",
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
|
||||
GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_JMP:
|
||||
printf("OP_JMP\t\t%03d\n", i+GETARG_sBx(c));
|
||||
break;
|
||||
case OP_JMPIF:
|
||||
printf("OP_JMPIF\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
|
||||
break;
|
||||
case OP_JMPNOT:
|
||||
printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
|
||||
break;
|
||||
case OP_SEND:
|
||||
printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_SENDB:
|
||||
printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_TAILCALL:
|
||||
printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_SUPER:
|
||||
printf("OP_SUPER\tR%d\t%d\n", GETARG_A(c),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_ARGARY:
|
||||
printf("OP_ARGARY\tR%d\t%d:%d:%d:%d", GETARG_A(c),
|
||||
(GETARG_Bx(c)>>10)&0x3f,
|
||||
(GETARG_Bx(c)>>9)&0x1,
|
||||
(GETARG_Bx(c)>>4)&0x1f,
|
||||
(GETARG_Bx(c)>>0)&0xf);
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
|
||||
case OP_ENTER:
|
||||
printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
|
||||
(GETARG_Ax(c)>>18)&0x1f,
|
||||
(GETARG_Ax(c)>>13)&0x1f,
|
||||
(GETARG_Ax(c)>>12)&0x1,
|
||||
(GETARG_Ax(c)>>7)&0x1f,
|
||||
(GETARG_Ax(c)>>2)&0x1f,
|
||||
(GETARG_Ax(c)>>1)&0x1,
|
||||
GETARG_Ax(c) & 0x1);
|
||||
break;
|
||||
case OP_RETURN:
|
||||
printf("OP_RETURN\tR%d", GETARG_A(c));
|
||||
switch (GETARG_B(c)) {
|
||||
case OP_R_NORMAL:
|
||||
case OP_R_RETURN:
|
||||
printf("\treturn"); break;
|
||||
case OP_R_BREAK:
|
||||
printf("\tbreak"); break;
|
||||
default:
|
||||
printf("\tbroken"); break;
|
||||
break;
|
||||
}
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_BLKPUSH:
|
||||
printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d", GETARG_A(c),
|
||||
(GETARG_Bx(c)>>10)&0x3f,
|
||||
(GETARG_Bx(c)>>9)&0x1,
|
||||
(GETARG_Bx(c)>>4)&0x1f,
|
||||
(GETARG_Bx(c)>>0)&0xf);
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
|
||||
case OP_LAMBDA:
|
||||
printf("OP_LAMBDA\tR%d\tI(%+d)\t%d", GETARG_A(c), GETARG_b(c)+1, GETARG_c(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_RANGE:
|
||||
printf("OP_RANGE\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_METHOD:
|
||||
printf("OP_METHOD\tR%d\t:%s", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
|
||||
case OP_ADD:
|
||||
printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_ADDI:
|
||||
printf("OP_ADDI\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_SUB:
|
||||
printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_SUBI:
|
||||
printf("OP_SUBI\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_MUL:
|
||||
printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_DIV:
|
||||
printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_LT:
|
||||
printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_LE:
|
||||
printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_GT:
|
||||
printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_GE:
|
||||
printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
case OP_EQ:
|
||||
printf("OP_EQ\tR%d\t:%s\t%d\n", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
|
||||
GETARG_C(c));
|
||||
break;
|
||||
|
||||
case OP_STOP:
|
||||
printf("OP_STOP\n");
|
||||
break;
|
||||
|
||||
case OP_ARRAY:
|
||||
printf("OP_ARRAY\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_ARYCAT:
|
||||
printf("OP_ARYCAT\tR%d\tR%d", GETARG_A(c), GETARG_B(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_ARYPUSH:
|
||||
printf("OP_ARYPUSH\tR%d\tR%d", GETARG_A(c), GETARG_B(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_AREF:
|
||||
printf("OP_AREF\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_APOST:
|
||||
printf("OP_APOST\tR%d\t%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_STRING:
|
||||
{
|
||||
mrb_value v = irep->pool[GETARG_Bx(c)];
|
||||
mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
|
||||
printf("OP_STRING\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s));
|
||||
}
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_STRCAT:
|
||||
printf("OP_STRCAT\tR%d\tR%d", GETARG_A(c), GETARG_B(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_HASH:
|
||||
printf("OP_HASH\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
|
||||
case OP_OCLASS:
|
||||
printf("OP_OCLASS\tR%d", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_CLASS:
|
||||
printf("OP_CLASS\tR%d\t:%s", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_MODULE:
|
||||
printf("OP_MODULE\tR%d\t:%s", GETARG_A(c),
|
||||
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_EXEC:
|
||||
printf("OP_EXEC\tR%d\tI(%+d)", GETARG_A(c), GETARG_Bx(c)+1);
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_SCLASS:
|
||||
printf("OP_SCLASS\tR%d\tR%d", GETARG_A(c), GETARG_B(c));
|
||||
print_lv(mrb, irep, c, RAB);
|
||||
break;
|
||||
case OP_TCLASS:
|
||||
printf("OP_TCLASS\tR%d", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_ERR:
|
||||
{
|
||||
mrb_value v = irep->pool[GETARG_Bx(c)];
|
||||
mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
|
||||
printf("OP_ERR\t%s\n", RSTRING_PTR(s));
|
||||
}
|
||||
break;
|
||||
case OP_EPUSH:
|
||||
printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)+1);
|
||||
break;
|
||||
case OP_ONERR:
|
||||
printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c));
|
||||
break;
|
||||
case OP_RESCUE:
|
||||
printf("OP_RESCUE\tR%d", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_RAISE:
|
||||
printf("OP_RAISE\tR%d", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_POPERR:
|
||||
printf("OP_POPERR\t%d", GETARG_A(c));
|
||||
print_lv(mrb, irep, c, RA);
|
||||
break;
|
||||
case OP_EPOP:
|
||||
printf("OP_EPOP\t%d\n", GETARG_A(c));
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("OP_unknown %d\t%d\t%d\t%d\n", GET_OPCODE(c),
|
||||
GETARG_A(c), GETARG_B(c), GETARG_C(c));
|
||||
break;
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
codedump_recur(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
codedump(mrb, irep);
|
||||
for (i=0; i<irep->rlen; i++) {
|
||||
codedump_recur(mrb, irep->reps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mrb_codedump_all(mrb_state *mrb, struct RProc *proc)
|
||||
{
|
||||
codedump_recur(mrb, proc->body.irep);
|
||||
}
|
||||
|
||||
MRB_API struct RProc*
|
||||
mrb_generate_code(mrb_state *mrb, parser_state *p)
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
/* ANSI-C code produced by gperf version 3.0.3 */
|
||||
/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' src/keywords */
|
||||
/* ANSI-C code produced by gperf version 3.0.4 */
|
||||
/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords */
|
||||
|
||||
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
@@ -28,13 +28,13 @@
|
||||
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
|
||||
#endif
|
||||
|
||||
#line 1 "src/keywords"
|
||||
#line 1 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
|
||||
struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
|
||||
const struct kwtable *mrb_reserved_word(const char *, unsigned int);
|
||||
static const struct kwtable *reserved_word(const char *, unsigned int);
|
||||
#define mrb_reserved_word(str, len) reserved_word(str, len)
|
||||
#line 8 "src/keywords"
|
||||
#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
struct kwtable;
|
||||
|
||||
#define TOTAL_KEYWORDS 40
|
||||
@@ -100,7 +100,7 @@ hash (register const char *str, register unsigned int len)
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#ifdef __GNUC_STDC_INLINE__
|
||||
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
|
||||
__attribute__ ((__gnu_inline__))
|
||||
#endif
|
||||
#endif
|
||||
@@ -110,87 +110,87 @@ mrb_reserved_word (register const char *str, register unsigned int len)
|
||||
static const struct kwtable wordlist[] =
|
||||
{
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
#line 18 "src/keywords"
|
||||
#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"break", {keyword_break, keyword_break}, EXPR_MID},
|
||||
#line 23 "src/keywords"
|
||||
#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"else", {keyword_else, keyword_else}, EXPR_BEG},
|
||||
#line 33 "src/keywords"
|
||||
#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"nil", {keyword_nil, keyword_nil}, EXPR_END},
|
||||
#line 26 "src/keywords"
|
||||
#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG},
|
||||
#line 25 "src/keywords"
|
||||
#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"end", {keyword_end, keyword_end}, EXPR_END},
|
||||
#line 42 "src/keywords"
|
||||
#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"then", {keyword_then, keyword_then}, EXPR_BEG},
|
||||
#line 34 "src/keywords"
|
||||
#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"not", {keyword_not, keyword_not}, EXPR_ARG},
|
||||
#line 27 "src/keywords"
|
||||
#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"false", {keyword_false, keyword_false}, EXPR_END},
|
||||
#line 40 "src/keywords"
|
||||
#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"self", {keyword_self, keyword_self}, EXPR_END},
|
||||
#line 24 "src/keywords"
|
||||
#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE},
|
||||
#line 37 "src/keywords"
|
||||
#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID},
|
||||
#line 43 "src/keywords"
|
||||
#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"true", {keyword_true, keyword_true}, EXPR_END},
|
||||
#line 46 "src/keywords"
|
||||
#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"until", {keyword_until, modifier_until}, EXPR_VALUE},
|
||||
#line 45 "src/keywords"
|
||||
#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"unless", {keyword_unless, modifier_unless}, EXPR_VALUE},
|
||||
#line 39 "src/keywords"
|
||||
#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"return", {keyword_return, keyword_return}, EXPR_MID},
|
||||
#line 21 "src/keywords"
|
||||
#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"def", {keyword_def, keyword_def}, EXPR_FNAME},
|
||||
#line 16 "src/keywords"
|
||||
#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"and", {keyword_and, keyword_and}, EXPR_VALUE},
|
||||
#line 22 "src/keywords"
|
||||
#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"do", {keyword_do, keyword_do}, EXPR_BEG},
|
||||
#line 49 "src/keywords"
|
||||
#line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"yield", {keyword_yield, keyword_yield}, EXPR_ARG},
|
||||
#line 28 "src/keywords"
|
||||
#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"for", {keyword_for, keyword_for}, EXPR_VALUE},
|
||||
#line 44 "src/keywords"
|
||||
#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},
|
||||
#line 35 "src/keywords"
|
||||
#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"or", {keyword_or, keyword_or}, EXPR_VALUE},
|
||||
#line 30 "src/keywords"
|
||||
#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"in", {keyword_in, keyword_in}, EXPR_VALUE},
|
||||
#line 47 "src/keywords"
|
||||
#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"when", {keyword_when, keyword_when}, EXPR_VALUE},
|
||||
#line 38 "src/keywords"
|
||||
#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"retry", {keyword_retry, keyword_retry}, EXPR_END},
|
||||
#line 29 "src/keywords"
|
||||
#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"if", {keyword_if, modifier_if}, EXPR_VALUE},
|
||||
#line 19 "src/keywords"
|
||||
#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"case", {keyword_case, keyword_case}, EXPR_VALUE},
|
||||
#line 36 "src/keywords"
|
||||
#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"redo", {keyword_redo, keyword_redo}, EXPR_END},
|
||||
#line 32 "src/keywords"
|
||||
#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"next", {keyword_next, keyword_next}, EXPR_MID},
|
||||
#line 41 "src/keywords"
|
||||
#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"super", {keyword_super, keyword_super}, EXPR_ARG},
|
||||
#line 31 "src/keywords"
|
||||
#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"module", {keyword_module, keyword_module}, EXPR_VALUE},
|
||||
#line 17 "src/keywords"
|
||||
#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"begin", {keyword_begin, keyword_begin}, EXPR_BEG},
|
||||
#line 12 "src/keywords"
|
||||
#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END},
|
||||
#line 11 "src/keywords"
|
||||
#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END},
|
||||
#line 10 "src/keywords"
|
||||
#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
|
||||
#line 14 "src/keywords"
|
||||
#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"END", {keyword_END, keyword_END}, EXPR_END},
|
||||
#line 15 "src/keywords"
|
||||
#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},
|
||||
#line 13 "src/keywords"
|
||||
#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
|
||||
{""},
|
||||
#line 20 "src/keywords"
|
||||
#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"class", {keyword_class, keyword_class}, EXPR_CLASS},
|
||||
{""}, {""},
|
||||
#line 48 "src/keywords"
|
||||
#line 48 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
{"while", {keyword_while, modifier_while}, EXPR_VALUE}
|
||||
};
|
||||
|
||||
@@ -208,5 +208,5 @@ mrb_reserved_word (register const char *str, register unsigned int len)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#line 50 "src/keywords"
|
||||
#line 50 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
|
||||
%{
|
||||
#undef PARSER_DEBUG
|
||||
|
||||
#define YYDEBUG 1
|
||||
#ifdef PARSER_DEBUG
|
||||
# define YYDEBUG 1
|
||||
#endif
|
||||
#define YYERROR_VERBOSE 1
|
||||
/*
|
||||
* Force yacc to use our memory management. This is a little evil because
|
||||
@@ -26,7 +27,7 @@
|
||||
#include "mruby/proc.h"
|
||||
#include "mruby/error.h"
|
||||
#include "node.h"
|
||||
#include "mrb_throw.h"
|
||||
#include "mruby/throw.h"
|
||||
|
||||
#define YYLEX_PARAM p
|
||||
|
||||
@@ -201,6 +202,7 @@ parser_strndup(parser_state *p, const char *s, size_t len)
|
||||
b[len] = '\0';
|
||||
return b;
|
||||
}
|
||||
#undef strndup
|
||||
#define strndup(s,len) parser_strndup(p, s, len)
|
||||
|
||||
static char*
|
||||
@@ -237,7 +239,9 @@ local_nest(parser_state *p)
|
||||
static void
|
||||
local_unnest(parser_state *p)
|
||||
{
|
||||
p->locals = p->locals->cdr;
|
||||
if (p->locals) {
|
||||
p->locals = p->locals->cdr;
|
||||
}
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
@@ -259,7 +263,9 @@ local_var_p(parser_state *p, mrb_sym sym)
|
||||
static void
|
||||
local_add_f(parser_state *p, mrb_sym sym)
|
||||
{
|
||||
p->locals->car = push(p->locals->car, nsym(sym));
|
||||
if (p->locals) {
|
||||
p->locals->car = push(p->locals->car, nsym(sym));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -270,11 +276,17 @@ local_add(parser_state *p, mrb_sym sym)
|
||||
}
|
||||
}
|
||||
|
||||
static node*
|
||||
locals_node(parser_state *p)
|
||||
{
|
||||
return p->locals ? p->locals->car : NULL;
|
||||
}
|
||||
|
||||
/* (:scope (vars..) (prog...)) */
|
||||
static node*
|
||||
new_scope(parser_state *p, node *body)
|
||||
{
|
||||
return cons((node*)NODE_SCOPE, cons(p->locals->car, body));
|
||||
return cons((node*)NODE_SCOPE, cons(locals_node(p), body));
|
||||
}
|
||||
|
||||
/* (:begin prog...) */
|
||||
@@ -601,35 +613,35 @@ new_undef(parser_state *p, mrb_sym sym)
|
||||
static node*
|
||||
new_class(parser_state *p, node *c, node *s, node *b)
|
||||
{
|
||||
return list4((node*)NODE_CLASS, c, s, cons(p->locals->car, b));
|
||||
return list4((node*)NODE_CLASS, c, s, cons(locals_node(p), b));
|
||||
}
|
||||
|
||||
/* (:sclass obj body) */
|
||||
static node*
|
||||
new_sclass(parser_state *p, node *o, node *b)
|
||||
{
|
||||
return list3((node*)NODE_SCLASS, o, cons(p->locals->car, b));
|
||||
return list3((node*)NODE_SCLASS, o, cons(locals_node(p), b));
|
||||
}
|
||||
|
||||
/* (:module module body) */
|
||||
static node*
|
||||
new_module(parser_state *p, node *m, node *b)
|
||||
{
|
||||
return list3((node*)NODE_MODULE, m, cons(p->locals->car, b));
|
||||
return list3((node*)NODE_MODULE, m, cons(locals_node(p), b));
|
||||
}
|
||||
|
||||
/* (:def m lv (arg . body)) */
|
||||
static node*
|
||||
new_def(parser_state *p, mrb_sym m, node *a, node *b)
|
||||
{
|
||||
return list5((node*)NODE_DEF, nsym(m), p->locals->car, a, b);
|
||||
return list5((node*)NODE_DEF, nsym(m), locals_node(p), a, b);
|
||||
}
|
||||
|
||||
/* (:sdef obj m lv (arg . body)) */
|
||||
static node*
|
||||
new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b)
|
||||
{
|
||||
return list6((node*)NODE_SDEF, o, nsym(m), p->locals->car, a, b);
|
||||
return list6((node*)NODE_SDEF, o, nsym(m), locals_node(p), a, b);
|
||||
}
|
||||
|
||||
/* (:arg . sym) */
|
||||
@@ -667,14 +679,14 @@ new_block_arg(parser_state *p, node *a)
|
||||
static node*
|
||||
new_block(parser_state *p, node *a, node *b)
|
||||
{
|
||||
return list4((node*)NODE_BLOCK, p->locals->car, a, b);
|
||||
return list4((node*)NODE_BLOCK, locals_node(p), a, b);
|
||||
}
|
||||
|
||||
/* (:lambda arg body) */
|
||||
static node*
|
||||
new_lambda(parser_state *p, node *a, node *b)
|
||||
{
|
||||
return list4((node*)NODE_LAMBDA, p->locals->car, a, b);
|
||||
return list4((node*)NODE_LAMBDA, locals_node(p), a, b);
|
||||
}
|
||||
|
||||
/* (:asgn lhs rhs) */
|
||||
@@ -749,9 +761,9 @@ new_dsym(parser_state *p, node *a)
|
||||
|
||||
/* (:str . (a . a)) */
|
||||
static node*
|
||||
new_regx(parser_state *p, const char *p1, const char* p2)
|
||||
new_regx(parser_state *p, const char *p1, const char* p2, const char* p3)
|
||||
{
|
||||
return cons((node*)NODE_REGX, cons((node*)p1, (node*)p2));
|
||||
return cons((node*)NODE_REGX, cons((node*)p1, cons((node*)p2, (node*)p3)));
|
||||
}
|
||||
|
||||
/* (:dregx . a) */
|
||||
@@ -1149,17 +1161,6 @@ heredoc_end(parser_state *p)
|
||||
%right tPOW
|
||||
%right '!' '~' tUPLUS
|
||||
|
||||
%nonassoc idNULL
|
||||
%nonassoc idRespond_to
|
||||
%nonassoc idIFUNC
|
||||
%nonassoc idCFUNC
|
||||
%nonassoc id_core_set_method_alias
|
||||
%nonassoc id_core_set_variable_alias
|
||||
%nonassoc id_core_undef_method
|
||||
%nonassoc id_core_define_method
|
||||
%nonassoc id_core_define_singleton_method
|
||||
%nonassoc id_core_set_postexe
|
||||
|
||||
%token tLAST_TOKEN
|
||||
|
||||
%%
|
||||
@@ -1468,7 +1469,7 @@ mlhs : mlhs_basic
|
||||
mlhs_inner : mlhs_basic
|
||||
| tLPAREN mlhs_inner rparen
|
||||
{
|
||||
$$ = list1($2);
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
@@ -1517,7 +1518,7 @@ mlhs_basic : mlhs_list
|
||||
mlhs_item : mlhs_node
|
||||
| tLPAREN mlhs_inner rparen
|
||||
{
|
||||
$$ = $2;
|
||||
$$ = new_masgn(p, $2, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -2143,11 +2144,17 @@ primary : literal
|
||||
p->lpar_beg = ++p->paren_nest;
|
||||
}
|
||||
f_larglist
|
||||
{
|
||||
$<stack>$ = p->cmdarg_stack;
|
||||
p->cmdarg_stack = 0;
|
||||
}
|
||||
lambda_body
|
||||
{
|
||||
p->lpar_beg = $<num>2;
|
||||
$$ = new_lambda(p, $3, $4);
|
||||
$$ = new_lambda(p, $3, $5);
|
||||
local_unnest(p);
|
||||
p->cmdarg_stack = $<stack>4;
|
||||
CMDARG_LEXPOP();
|
||||
}
|
||||
| keyword_if expr_value then
|
||||
compstmt
|
||||
@@ -2935,7 +2942,7 @@ backref : tNTH_REF
|
||||
| tBACK_REF
|
||||
;
|
||||
|
||||
superclass : term
|
||||
superclass : /* term */
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
@@ -2947,12 +2954,12 @@ superclass : term
|
||||
expr_value term
|
||||
{
|
||||
$$ = $3;
|
||||
}
|
||||
} /*
|
||||
| error term
|
||||
{
|
||||
yyerrok;
|
||||
$$ = 0;
|
||||
}
|
||||
} */
|
||||
;
|
||||
|
||||
f_arglist : '(' f_args rparen
|
||||
@@ -3287,7 +3294,7 @@ yyerror(parser_state *p, const char *s)
|
||||
int n;
|
||||
|
||||
if (! p->capture_errors) {
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
if (p->filename) {
|
||||
fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s);
|
||||
}
|
||||
@@ -3323,7 +3330,7 @@ yywarn(parser_state *p, const char *s)
|
||||
int n;
|
||||
|
||||
if (! p->capture_errors) {
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
if (p->filename) {
|
||||
fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s);
|
||||
}
|
||||
@@ -3394,7 +3401,7 @@ nextc(parser_state *p)
|
||||
cons_free(tmp);
|
||||
}
|
||||
else {
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
if (p->f) {
|
||||
if (feof(p->f)) goto eof;
|
||||
c = fgetc(p->f);
|
||||
@@ -3484,7 +3491,7 @@ peeks(parser_state *p, const char *s)
|
||||
{
|
||||
int len = strlen(s);
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
if (p->f) {
|
||||
int n = 0;
|
||||
while (*s) {
|
||||
@@ -3598,10 +3605,13 @@ toklast(parser_state *p)
|
||||
static void
|
||||
tokfix(parser_state *p)
|
||||
{
|
||||
if (p->bidx >= MRB_PARSER_BUF_SIZE) {
|
||||
int i = p->bidx, imax = MRB_PARSER_BUF_SIZE - 1;
|
||||
|
||||
if (i > imax) {
|
||||
i = imax;
|
||||
yyerror(p, "string too long (truncated)");
|
||||
}
|
||||
p->buf[p->bidx] = '\0';
|
||||
p->buf[i] = '\0';
|
||||
}
|
||||
|
||||
static const char*
|
||||
@@ -3976,6 +3986,8 @@ parse_string(parser_state *p)
|
||||
char *s = strndup(tok(p), toklen(p));
|
||||
char flags[3];
|
||||
char *flag = flags;
|
||||
char enc = '\0';
|
||||
char *encp;
|
||||
char *dup;
|
||||
|
||||
newtok(p);
|
||||
@@ -3984,6 +3996,8 @@ parse_string(parser_state *p)
|
||||
case 'i': f |= 1; break;
|
||||
case 'x': f |= 2; break;
|
||||
case 'm': f |= 4; break;
|
||||
case 'u': f |= 16; break;
|
||||
case 'n': f |= 32; break;
|
||||
default: tokadd(p, re_opt); break;
|
||||
}
|
||||
}
|
||||
@@ -3999,12 +4013,20 @@ parse_string(parser_state *p)
|
||||
if (f & 1) *flag++ = 'i';
|
||||
if (f & 2) *flag++ = 'x';
|
||||
if (f & 4) *flag++ = 'm';
|
||||
dup = strndup(flags, (size_t)(flag - flags));
|
||||
if (f & 16) enc = 'u';
|
||||
if (f & 32) enc = 'n';
|
||||
}
|
||||
else {
|
||||
if (flag > flags) {
|
||||
dup = strndup(flags, (size_t)(flag - flags));
|
||||
} else {
|
||||
dup = NULL;
|
||||
}
|
||||
yylval.nd = new_regx(p, s, dup);
|
||||
if (enc) {
|
||||
encp = strndup(&enc, 1);
|
||||
} else {
|
||||
encp = NULL;
|
||||
}
|
||||
yylval.nd = new_regx(p, s, dup, encp);
|
||||
|
||||
return tREGEXP;
|
||||
}
|
||||
@@ -4114,10 +4136,9 @@ parser_yylex(parser_state *p)
|
||||
retry:
|
||||
last_state = p->lstate;
|
||||
switch (c = nextc(p)) {
|
||||
case '\0': /* NUL */
|
||||
case '\004': /* ^D */
|
||||
case '\032': /* ^Z */
|
||||
return 0;
|
||||
case '\0': /* NUL */
|
||||
case -1: /* end of script. */
|
||||
if (p->heredocs_from_nextline)
|
||||
goto maybe_heredoc;
|
||||
@@ -4145,7 +4166,9 @@ parser_yylex(parser_state *p)
|
||||
p->lineno++;
|
||||
p->column = 0;
|
||||
if (p->parsing_heredoc != NULL) {
|
||||
return parse_string(p);
|
||||
if (p->lex_strterm) {
|
||||
return parse_string(p);
|
||||
}
|
||||
}
|
||||
goto retry;
|
||||
default:
|
||||
@@ -4197,7 +4220,7 @@ parser_yylex(parser_state *p)
|
||||
}
|
||||
pushback(p, c);
|
||||
if (IS_SPCARG(c)) {
|
||||
yywarning(p, "`*' interpreted as argument prefix");
|
||||
yywarning(p, "'*' interpreted as argument prefix");
|
||||
c = tSTAR;
|
||||
}
|
||||
else if (IS_BEG()) {
|
||||
@@ -4448,7 +4471,7 @@ parser_yylex(parser_state *p)
|
||||
}
|
||||
pushback(p, c);
|
||||
if (IS_SPCARG(c)) {
|
||||
yywarning(p, "`&' interpreted as argument prefix");
|
||||
yywarning(p, "'&' interpreted as argument prefix");
|
||||
c = tAMPER;
|
||||
}
|
||||
else if (IS_BEG()) {
|
||||
@@ -4754,7 +4777,7 @@ parser_yylex(parser_state *p)
|
||||
nondigit = c;
|
||||
break;
|
||||
|
||||
case '_': /* `_' in number just ignored */
|
||||
case '_': /* '_' in number just ignored */
|
||||
if (nondigit) goto decode_num;
|
||||
nondigit = c;
|
||||
break;
|
||||
@@ -4769,7 +4792,7 @@ parser_yylex(parser_state *p)
|
||||
pushback(p, c);
|
||||
if (nondigit) {
|
||||
trailing_uc:
|
||||
yyerror_i(p, "trailing `%c' in number", nondigit);
|
||||
yyerror_i(p, "trailing '%c' in number", nondigit);
|
||||
}
|
||||
tokfix(p);
|
||||
if (is_float) {
|
||||
@@ -4795,6 +4818,7 @@ parser_yylex(parser_state *p)
|
||||
case ')':
|
||||
case ']':
|
||||
p->paren_nest--;
|
||||
/* fall through */
|
||||
case '}':
|
||||
COND_LEXPOP();
|
||||
CMDARG_LEXPOP();
|
||||
@@ -5111,7 +5135,14 @@ parser_yylex(parser_state *p)
|
||||
pushback(p, c);
|
||||
if (last_state == EXPR_FNAME) goto gvar;
|
||||
tokfix(p);
|
||||
yylval.nd = new_nth_ref(p, atoi(tok(p)));
|
||||
{
|
||||
unsigned long n = strtoul(tok(p), NULL, 10);
|
||||
if (n > INT_MAX) {
|
||||
yyerror_i(p, "capture group index must be <= %d", INT_MAX);
|
||||
return 0;
|
||||
}
|
||||
yylval.nd = new_nth_ref(p, (int)n);
|
||||
}
|
||||
return tNTH_REF;
|
||||
|
||||
default:
|
||||
@@ -5119,6 +5150,7 @@ parser_yylex(parser_state *p)
|
||||
pushback(p, c);
|
||||
return '$';
|
||||
}
|
||||
/* fall through */
|
||||
case '0':
|
||||
tokadd(p, '$');
|
||||
}
|
||||
@@ -5143,10 +5175,10 @@ parser_yylex(parser_state *p)
|
||||
}
|
||||
else if (isdigit(c)) {
|
||||
if (p->bidx == 1) {
|
||||
yyerror_i(p, "`@%c' is not allowed as an instance variable name", c);
|
||||
yyerror_i(p, "'@%c' is not allowed as an instance variable name", c);
|
||||
}
|
||||
else {
|
||||
yyerror_i(p, "`@@%c' is not allowed as a class variable name", c);
|
||||
yyerror_i(p, "'@@%c' is not allowed as a class variable name", c);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -5162,7 +5194,7 @@ parser_yylex(parser_state *p)
|
||||
|
||||
default:
|
||||
if (!identchar(c)) {
|
||||
yyerror_i(p, "Invalid char `\\x%02X' in expression", c);
|
||||
yyerror_i(p, "Invalid char '\\x%02X' in expression", c);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
@@ -5410,7 +5442,7 @@ mrb_parser_new(mrb_state *mrb)
|
||||
p->pool = pool;
|
||||
|
||||
p->s = p->send = NULL;
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISBLE_STDIO
|
||||
p->f = NULL;
|
||||
#endif
|
||||
|
||||
@@ -5509,7 +5541,7 @@ mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
MRB_API parser_state*
|
||||
mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
|
||||
{
|
||||
@@ -5601,7 +5633,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
MRB_API mrb_value
|
||||
mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c)
|
||||
{
|
||||
@@ -5639,7 +5671,7 @@ mrb_load_string(mrb_state *mrb, const char *s)
|
||||
return mrb_load_string_cxt(mrb, s, NULL);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
|
||||
static void
|
||||
dump_prefix(node *tree, int offset)
|
||||
@@ -5665,7 +5697,7 @@ dump_recur(mrb_state *mrb, node *tree, int offset)
|
||||
void
|
||||
mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
|
||||
{
|
||||
#ifdef ENABLE_STDIO
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
int nodetype;
|
||||
|
||||
if (!tree) return;
|
||||
@@ -5952,9 +5984,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
|
||||
break;
|
||||
|
||||
case NODE_COLON3:
|
||||
printf("NODE_COLON3:\n");
|
||||
dump_prefix(tree, offset+1);
|
||||
printf("::%s\n", mrb_sym2name(mrb, sym(tree)));
|
||||
printf("NODE_COLON3: ::%s\n", mrb_sym2name(mrb, sym(tree)));
|
||||
break;
|
||||
|
||||
case NODE_ARRAY:
|
||||
@@ -6329,10 +6359,9 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
|
||||
printf("post mandatory args:\n");
|
||||
dump_recur(mrb, n->car, offset+2);
|
||||
}
|
||||
n = n->cdr;
|
||||
if (n) {
|
||||
if (n->cdr) {
|
||||
dump_prefix(n, offset+1);
|
||||
printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
|
||||
printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr)));
|
||||
}
|
||||
}
|
||||
mrb_parser_dump(mrb, tree->cdr->car, offset+1);
|
||||
@@ -0,0 +1,40 @@
|
||||
MRuby::Gem::Specification.new 'mruby-compiler' do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'mruby compiler library'
|
||||
|
||||
current_dir = spec.dir
|
||||
current_build_dir = spec.build_dir
|
||||
|
||||
lex_def = "#{current_dir}/core/lex.def"
|
||||
core_objs = Dir.glob("#{current_dir}/core/*.c").map { |f|
|
||||
next nil if build.cxx_abi_enabled? and f =~ /(codegen).c$/
|
||||
objfile(f.pathmap("#{current_build_dir}/core/%n"))
|
||||
}.compact
|
||||
|
||||
if build.cxx_abi_enabled?
|
||||
core_objs <<
|
||||
build.compile_as_cxx("#{current_build_dir}/core/y.tab.c", "#{current_build_dir}/core/y.tab.cxx",
|
||||
objfile("#{current_build_dir}/y.tab"), ["#{current_dir}/core"]) <<
|
||||
build.compile_as_cxx("#{current_dir}/core/codegen.c", "#{current_build_dir}/core/codegen.cxx")
|
||||
else
|
||||
core_objs << objfile("#{current_build_dir}/core/y.tab")
|
||||
file objfile("#{current_build_dir}/core/y.tab") => "#{current_build_dir}/core/y.tab.c" do |t|
|
||||
cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"]
|
||||
end
|
||||
end
|
||||
file objfile("#{current_build_dir}/core/y.tab") => lex_def
|
||||
|
||||
# Parser
|
||||
file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y"] do |t|
|
||||
yacc.run t.name, t.prerequisites.first
|
||||
end
|
||||
|
||||
# Lexical analyzer
|
||||
file lex_def => "#{current_dir}/core/keywords" do |t|
|
||||
gperf.run t.name, t.prerequisites.first
|
||||
end
|
||||
|
||||
file libfile("#{build.build_dir}/lib/libmruby_core") => core_objs
|
||||
build.libmruby << core_objs
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
MRuby::Gem::Specification.new('mruby-enum-ext') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'extensional Enumerable module'
|
||||
spec.summary = 'Enumerable module extension'
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@ module Enumerable
|
||||
# a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0]
|
||||
|
||||
def drop_while(&block)
|
||||
return to_enum :drop_while unless block_given?
|
||||
return to_enum :drop_while unless block
|
||||
|
||||
ary, state = [], false
|
||||
self.each do |*val|
|
||||
@@ -77,13 +77,13 @@ module Enumerable
|
||||
# Passes elements to the block until the block returns +nil+ or +false+,
|
||||
# then stops iterating and returns an array of all prior elements.
|
||||
#
|
||||
# If no block is given, an enumerator is returned instead.
|
||||
# If no block is given, an enumerator is returned instead.
|
||||
#
|
||||
# a = [1, 2, 3, 4, 5, 0]
|
||||
# a.take_while {|i| i < 3 } #=> [1, 2]
|
||||
#
|
||||
# a = [1, 2, 3, 4, 5, 0]
|
||||
# a.take_while {|i| i < 3 } #=> [1, 2]
|
||||
|
||||
def take_while(&block)
|
||||
return to_enum :take_while unless block_given?
|
||||
return to_enum :take_while unless block
|
||||
|
||||
ary = []
|
||||
self.each do |*val|
|
||||
@@ -94,13 +94,12 @@ module Enumerable
|
||||
end
|
||||
|
||||
##
|
||||
# call-seq:
|
||||
# enum.each_cons(n) {...} -> nil
|
||||
#
|
||||
# Iterates the given block for each array of consecutive <n>
|
||||
# elements.
|
||||
#
|
||||
# e.g.:
|
||||
# @return [nil]
|
||||
#
|
||||
# @example
|
||||
# (1..10).each_cons(3) {|a| p a}
|
||||
# # outputs below
|
||||
# [1, 2, 3]
|
||||
@@ -116,6 +115,7 @@ module Enumerable
|
||||
raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
|
||||
raise ArgumentError, "invalid size" if n <= 0
|
||||
|
||||
return to_enum(:each_cons,n) unless block
|
||||
ary = []
|
||||
n = n.to_int
|
||||
self.each do |*val|
|
||||
@@ -126,12 +126,11 @@ module Enumerable
|
||||
end
|
||||
|
||||
##
|
||||
# call-seq:
|
||||
# enum.each_slice(n) {...} -> nil
|
||||
#
|
||||
# Iterates the given block for each slice of <n> elements.
|
||||
#
|
||||
# e.g.:
|
||||
# @return [nil]
|
||||
#
|
||||
# @example
|
||||
# (1..10).each_slice(3) {|a| p a}
|
||||
# # outputs below
|
||||
# [1, 2, 3]
|
||||
@@ -143,6 +142,7 @@ module Enumerable
|
||||
raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
|
||||
raise ArgumentError, "invalid slice size" if n <= 0
|
||||
|
||||
return to_enum(:each_slice,n) unless block
|
||||
ary = []
|
||||
n = n.to_int
|
||||
self.each do |*val|
|
||||
@@ -164,10 +164,10 @@ module Enumerable
|
||||
# block, and values are arrays of elements in <i>enum</i>
|
||||
# corresponding to the key.
|
||||
#
|
||||
# (1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
|
||||
|
||||
# (1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
|
||||
#
|
||||
def group_by(&block)
|
||||
return to_enum :group_by unless block_given?
|
||||
return to_enum :group_by unless block
|
||||
|
||||
h = {}
|
||||
self.each do |*val|
|
||||
@@ -189,7 +189,7 @@ module Enumerable
|
||||
# If no block is given, an enumerator is returned instead.
|
||||
|
||||
def sort_by(&block)
|
||||
return to_enum :sort_by unless block_given?
|
||||
return to_enum :sort_by unless block
|
||||
|
||||
ary = []
|
||||
orig = []
|
||||
@@ -275,7 +275,7 @@ module Enumerable
|
||||
# [1, 2, 3, 4].flat_map { |e| [e, -e] } #=> [1, -1, 2, -2, 3, -3, 4, -4]
|
||||
# [[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100]
|
||||
def flat_map(&block)
|
||||
return to_enum :flat_map unless block_given?
|
||||
return to_enum :flat_map unless block
|
||||
|
||||
ary = []
|
||||
self.each do |*e|
|
||||
@@ -303,7 +303,7 @@ module Enumerable
|
||||
# %w[albatross dog horse].max_by {|x| x.length } #=> "albatross"
|
||||
|
||||
def max_by(&block)
|
||||
return to_enum :max_by unless block_given?
|
||||
return to_enum :max_by unless block
|
||||
|
||||
first = true
|
||||
max = nil
|
||||
@@ -337,7 +337,7 @@ module Enumerable
|
||||
# %w[albatross dog horse].min_by {|x| x.length } #=> "dog"
|
||||
|
||||
def min_by(&block)
|
||||
return to_enum :min_by unless block_given?
|
||||
return to_enum :min_by unless block
|
||||
|
||||
first = true
|
||||
min = nil
|
||||
@@ -411,7 +411,7 @@ module Enumerable
|
||||
# %w(albatross dog horse).minmax_by { |x| x.length } #=> ["dog", "albatross"]
|
||||
|
||||
def minmax_by(&block)
|
||||
return to_enum :minmax_by unless block_given?
|
||||
return to_enum :minmax_by unless block
|
||||
|
||||
max = nil
|
||||
max_cmp = nil
|
||||
@@ -515,9 +515,9 @@ module Enumerable
|
||||
#
|
||||
|
||||
def each_with_object(obj=nil, &block)
|
||||
raise ArgumentError, "wrong number of arguments (0 for 1)" if obj == nil
|
||||
raise ArgumentError, "wrong number of arguments (0 for 1)" if obj.nil?
|
||||
|
||||
return to_enum(:each_with_object, obj) unless block_given?
|
||||
return to_enum(:each_with_object, obj) unless block
|
||||
|
||||
self.each {|*val| block.call(val.__svalue, obj) }
|
||||
obj
|
||||
@@ -542,7 +542,7 @@ module Enumerable
|
||||
#
|
||||
|
||||
def reverse_each(&block)
|
||||
return to_enum :reverse_each unless block_given?
|
||||
return to_enum :reverse_each unless block
|
||||
|
||||
ary = self.to_a
|
||||
i = ary.size - 1
|
||||
@@ -574,10 +574,10 @@ module Enumerable
|
||||
#
|
||||
|
||||
def cycle(n=nil, &block)
|
||||
return to_enum(:cycle, n) if !block_given? && n == nil
|
||||
return to_enum(:cycle, n) if !block && n.nil?
|
||||
|
||||
ary = []
|
||||
if n == nil
|
||||
if n.nil?
|
||||
self.each do|*val|
|
||||
ary.push val
|
||||
block.call(*val)
|
||||
@@ -623,7 +623,7 @@ module Enumerable
|
||||
#
|
||||
|
||||
def find_index(val=NONE, &block)
|
||||
return to_enum(:find_index, val) if !block_given? && val == NONE
|
||||
return to_enum(:find_index, val) if !block && val == NONE
|
||||
|
||||
idx = 0
|
||||
if block
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
# = Enumerable#lazy implementation
|
||||
#
|
||||
# Enumerable#lazy returns an instance of Enumerable::Lazy.
|
||||
# You can use it just like as normal Enumerable object,
|
||||
# except these methods act as 'lazy':
|
||||
#
|
||||
# - map collect
|
||||
# - select find_all
|
||||
# - reject
|
||||
# - grep
|
||||
# - drop
|
||||
# - drop_while
|
||||
# - take_while
|
||||
# - flat_map collect_concat
|
||||
# - zip
|
||||
#
|
||||
# == Acknowledgements
|
||||
#
|
||||
# Based on https://github.com/yhara/enumerable-lazy
|
||||
# Inspired by https://github.com/antimon2/enumerable_lz
|
||||
# http://jp.rubyist.net/magazine/?0034-Enumerable_lz (ja)
|
||||
|
||||
module Enumerable
|
||||
|
||||
# = Enumerable#lazy implementation
|
||||
#
|
||||
# Enumerable#lazy returns an instance of Enumerable::Lazy.
|
||||
# You can use it just like as normal Enumerable object,
|
||||
# except these methods act as 'lazy':
|
||||
#
|
||||
# - map collect
|
||||
# - select find_all
|
||||
# - reject
|
||||
# - grep
|
||||
# - drop
|
||||
# - drop_while
|
||||
# - take_while
|
||||
# - flat_map collect_concat
|
||||
# - zip
|
||||
def lazy
|
||||
Lazy.new(self)
|
||||
end
|
||||
|
||||
# == Acknowledgements
|
||||
#
|
||||
# Based on https://github.com/yhara/enumerable-lazy
|
||||
# Inspired by https://github.com/antimon2/enumerable_lz
|
||||
# http://jp.rubyist.net/magazine/?0034-Enumerable_lz (ja)
|
||||
class Lazy < Enumerator
|
||||
def initialize(obj, &block)
|
||||
super(){|yielder|
|
||||
|
||||
@@ -6,92 +6,91 @@
|
||||
# A class which allows both internal and external iteration.
|
||||
#
|
||||
# An Enumerator can be created by the following methods.
|
||||
# - Kernel#to_enum
|
||||
# - Kernel#enum_for
|
||||
# - Enumerator.new
|
||||
# - {Kernel#to_enum}
|
||||
# - {Kernel#enum_for}
|
||||
# - {Enumerator#initialize Enumerator.new}
|
||||
#
|
||||
# Most methods have two forms: a block form where the contents
|
||||
# are evaluated for each item in the enumeration, and a non-block form
|
||||
# which returns a new Enumerator wrapping the iteration.
|
||||
#
|
||||
# enumerator = %w(one two three).each
|
||||
# puts enumerator.class # => Enumerator
|
||||
# enumerator = %w(one two three).each
|
||||
# puts enumerator.class # => Enumerator
|
||||
#
|
||||
# enumerator.each_with_object("foo") do |item, obj|
|
||||
# puts "#{obj}: #{item}"
|
||||
# end
|
||||
# enumerator.each_with_object("foo") do |item, obj|
|
||||
# puts "#{obj}: #{item}"
|
||||
# end
|
||||
#
|
||||
# # foo: one
|
||||
# # foo: two
|
||||
# # foo: three
|
||||
# # foo: one
|
||||
# # foo: two
|
||||
# # foo: three
|
||||
#
|
||||
# enum_with_obj = enumerator.each_with_object("foo")
|
||||
# puts enum_with_obj.class # => Enumerator
|
||||
# enum_with_obj = enumerator.each_with_object("foo")
|
||||
# puts enum_with_obj.class # => Enumerator
|
||||
#
|
||||
# enum_with_obj.each do |item, obj|
|
||||
# puts "#{obj}: #{item}"
|
||||
# end
|
||||
# enum_with_obj.each do |item, obj|
|
||||
# puts "#{obj}: #{item}"
|
||||
# end
|
||||
#
|
||||
# # foo: one
|
||||
# # foo: two
|
||||
# # foo: three
|
||||
# # foo: one
|
||||
# # foo: two
|
||||
# # foo: three
|
||||
#
|
||||
# This allows you to chain Enumerators together. For example, you
|
||||
# can map a list's elements to strings containing the index
|
||||
# and the element as a string via:
|
||||
#
|
||||
# puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
|
||||
# # => ["0:foo", "1:bar", "2:baz"]
|
||||
# puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
|
||||
# # => ["0:foo", "1:bar", "2:baz"]
|
||||
#
|
||||
# An Enumerator can also be used as an external iterator.
|
||||
# For example, Enumerator#next returns the next value of the iterator
|
||||
# or raises StopIteration if the Enumerator is at the end.
|
||||
#
|
||||
# e = [1,2,3].each # returns an enumerator object.
|
||||
# puts e.next # => 1
|
||||
# puts e.next # => 2
|
||||
# puts e.next # => 3
|
||||
# puts e.next # raises StopIteration
|
||||
# e = [1,2,3].each # returns an enumerator object.
|
||||
# puts e.next # => 1
|
||||
# puts e.next # => 2
|
||||
# puts e.next # => 3
|
||||
# puts e.next # raises StopIteration
|
||||
#
|
||||
# You can use this to implement an internal iterator as follows:
|
||||
#
|
||||
# def ext_each(e)
|
||||
# while true
|
||||
# begin
|
||||
# vs = e.next_values
|
||||
# rescue StopIteration
|
||||
# return $!.result
|
||||
# def ext_each(e)
|
||||
# while true
|
||||
# begin
|
||||
# vs = e.next_values
|
||||
# rescue StopIteration
|
||||
# return $!.result
|
||||
# end
|
||||
# y = yield(*vs)
|
||||
# e.feed y
|
||||
# end
|
||||
# end
|
||||
# y = yield(*vs)
|
||||
# e.feed y
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# o = Object.new
|
||||
# o = Object.new
|
||||
#
|
||||
# def o.each
|
||||
# puts yield
|
||||
# puts yield(1)
|
||||
# puts yield(1, 2)
|
||||
# 3
|
||||
# end
|
||||
# def o.each
|
||||
# puts yield
|
||||
# puts yield(1)
|
||||
# puts yield(1, 2)
|
||||
# 3
|
||||
# end
|
||||
#
|
||||
# # use o.each as an internal iterator directly.
|
||||
# puts o.each {|*x| puts x; [:b, *x] }
|
||||
# # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
|
||||
# # use o.each as an internal iterator directly.
|
||||
# puts o.each {|*x| puts x; [:b, *x] }
|
||||
# # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
|
||||
#
|
||||
# # convert o.each to an external iterator for
|
||||
# # implementing an internal iterator.
|
||||
# puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
|
||||
# # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
|
||||
#
|
||||
# # convert o.each to an external iterator for
|
||||
# # implementing an internal iterator.
|
||||
# puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
|
||||
# # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
|
||||
|
||||
class Enumerator
|
||||
include Enumerable
|
||||
|
||||
##
|
||||
# call-seq:
|
||||
# Enumerator.new(size = nil) { |yielder| ... }
|
||||
# Enumerator.new(obj, method = :each, *args)
|
||||
# @overload initialize(size = nil, &block)
|
||||
# @overload initialize(obj, method = :each, *args)
|
||||
#
|
||||
# Creates a new Enumerator object, which can be used as an
|
||||
# Enumerable.
|
||||
@@ -100,15 +99,15 @@ class Enumerator
|
||||
# which a "yielder" object, given as block parameter, can be used to
|
||||
# yield a value by calling the +yield+ method (aliased as +<<+):
|
||||
#
|
||||
# fib = Enumerator.new do |y|
|
||||
# a = b = 1
|
||||
# loop do
|
||||
# y << a
|
||||
# a, b = b, a + b
|
||||
# fib = Enumerator.new do |y|
|
||||
# a = b = 1
|
||||
# loop do
|
||||
# y << a
|
||||
# a, b = b, a + b
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
||||
# p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
||||
#
|
||||
def initialize(obj=nil, meth=:each, *args, &block)
|
||||
if block_given?
|
||||
@@ -188,8 +187,7 @@ class Enumerator
|
||||
#
|
||||
# If no block is given, returns a new Enumerator.
|
||||
#
|
||||
# === Example
|
||||
#
|
||||
# @example
|
||||
# to_three = Enumerator.new do |y|
|
||||
# 3.times do |x|
|
||||
# y << x
|
||||
@@ -582,27 +580,27 @@ module Kernel
|
||||
#
|
||||
# Here is such an example, with parameter passing and a sizing block:
|
||||
#
|
||||
# module Enumerable
|
||||
# # a generic method to repeat the values of any enumerable
|
||||
# def repeat(n)
|
||||
# raise ArgumentError, "#{n} is negative!" if n < 0
|
||||
# unless block_given?
|
||||
# return to_enum(__method__, n) do # __method__ is :repeat here
|
||||
# sz = size # Call size and multiply by n...
|
||||
# sz * n if sz # but return nil if size itself is nil
|
||||
# module Enumerable
|
||||
# # a generic method to repeat the values of any enumerable
|
||||
# def repeat(n)
|
||||
# raise ArgumentError, "#{n} is negative!" if n < 0
|
||||
# unless block_given?
|
||||
# return to_enum(__method__, n) do # __method__ is :repeat here
|
||||
# sz = size # Call size and multiply by n...
|
||||
# sz * n if sz # but return nil if size itself is nil
|
||||
# end
|
||||
# end
|
||||
# each do |*val|
|
||||
# n.times { yield *val }
|
||||
# end
|
||||
# end
|
||||
# each do |*val|
|
||||
# n.times { yield *val }
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# %i[hello world].repeat(2) { |w| puts w }
|
||||
# # => Prints 'hello', 'hello', 'world', 'world'
|
||||
# enum = (1..14).repeat(3)
|
||||
# # => returns an Enumerator when called without a block
|
||||
# enum.first(4) # => [1, 1, 1, 2]
|
||||
# %i[hello world].repeat(2) { |w| puts w }
|
||||
# # => Prints 'hello', 'hello', 'world', 'world'
|
||||
# enum = (1..14).repeat(3)
|
||||
# # => returns an Enumerator when called without a block
|
||||
# enum.first(4) # => [1, 1, 1, 2]
|
||||
#
|
||||
def to_enum(meth=:each, *args)
|
||||
Enumerator.new self, meth, *args
|
||||
|
||||
@@ -427,7 +427,6 @@ assert 'modifying existing methods' do
|
||||
assert_equal i, e.next
|
||||
i += 1
|
||||
}
|
||||
assert_nil loop_ret
|
||||
end
|
||||
|
||||
assert 'Integral#times' do
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user