mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-15 22:17:39 +00:00
Compare commits
1265 Commits
v1.80pr1.1
...
v1.16.5-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2c64186965 | ||
![]() |
31ba17d085 | ||
![]() |
bcc7dd6991 | ||
![]() |
bd36185662 | ||
![]() |
045c4fc88c | ||
![]() |
e0fcc425c6 | ||
![]() |
e01895d719 | ||
![]() |
87b38f4249 | ||
![]() |
60d1d1bb18 | ||
![]() |
cdf8b77ffd | ||
![]() |
e2ce52fe81 | ||
![]() |
9cf70b10ef | ||
![]() |
9ac8f3aeea | ||
![]() |
e191b08eb5 | ||
![]() |
a1221b99e1 | ||
![]() |
85bced6b1d | ||
![]() |
fc4569e0cc | ||
![]() |
e7f08313d9 | ||
![]() |
79fc8237b6 | ||
![]() |
9d50d6414c | ||
![]() |
16df86224b | ||
![]() |
a9519f68a1 | ||
![]() |
f1a08a3362 | ||
![]() |
802949d888 | ||
![]() |
e558b31b2b | ||
![]() |
afd82fbf1f | ||
![]() |
f470478a0f | ||
![]() |
aa009df740 | ||
![]() |
0c6c0badde | ||
![]() |
bed2e0b658 | ||
![]() |
0f9ddac83c | ||
![]() |
932b77d7ee | ||
![]() |
5eedea1bbb | ||
![]() |
114261944a | ||
![]() |
4d10639efb | ||
![]() |
aa36b49c50 | ||
![]() |
8a1067940d | ||
![]() |
0477b2742c | ||
![]() |
b048b6666d | ||
![]() |
e16f66e128 | ||
![]() |
1cfad31a0d | ||
![]() |
92a0ef2b75 | ||
![]() |
1f6e0f287d | ||
![]() |
0e4b7a5a75 | ||
![]() |
47ad7a35dc | ||
![]() |
3eab2a9b57 | ||
![]() |
c4024a4c4c | ||
![]() |
f5fb82cd7d | ||
![]() |
e18ba8a2c2 | ||
![]() |
422bfdb60d | ||
![]() |
1851ed31cd | ||
![]() |
3929dba4a5 | ||
![]() |
5927e9bb10 | ||
![]() |
53811f8169 | ||
![]() |
298f339376 | ||
![]() |
9d44f1ca66 | ||
![]() |
306e06a79a | ||
![]() |
4f11549112 | ||
![]() |
7f3490591d | ||
![]() |
8ffd45c66e | ||
![]() |
e247bd823e | ||
![]() |
276956eed8 | ||
![]() |
18d66bd727 | ||
![]() |
d3563a3854 | ||
![]() |
c2dc8bf675 | ||
![]() |
603119e1e6 | ||
![]() |
d9b3f17b52 | ||
![]() |
993bccc51f | ||
![]() |
96d3b27064 | ||
![]() |
f33f57ea35 | ||
![]() |
070479d901 | ||
![]() |
2fe40f669d | ||
![]() |
1b39c9f470 | ||
![]() |
814d5cbcd1 | ||
![]() |
4d8862c78e | ||
![]() |
6cc2f035db | ||
![]() |
ea7a218f4a | ||
![]() |
544bcaa599 | ||
![]() |
ab6b861cd6 | ||
![]() |
72e8fc03d3 | ||
![]() |
482ae0d22e | ||
![]() |
6dd33f7099 | ||
![]() |
045472577a | ||
![]() |
9f539dbd59 | ||
![]() |
ca367e7cc7 | ||
![]() |
f6fd0ad172 | ||
![]() |
13779d6ad3 | ||
![]() |
d700f1f500 | ||
![]() |
06bf84f151 | ||
![]() |
8ba20985d7 | ||
![]() |
7bb7b5e638 | ||
![]() |
297426419b | ||
![]() |
eb61c5c5d7 | ||
![]() |
cf2bc667c1 | ||
![]() |
c8449086ee | ||
![]() |
662bead8be | ||
![]() |
acaa61a720 | ||
![]() |
5facbca2b3 | ||
![]() |
6c6b2c2ff3 | ||
![]() |
647902c019 | ||
![]() |
2aa70b49c1 | ||
![]() |
b17ab16e05 | ||
![]() |
94ad106272 | ||
![]() |
dc9edf26ec | ||
![]() |
048c7bda23 | ||
![]() |
c9397460a4 | ||
![]() |
9e82209aab | ||
![]() |
340ade170f | ||
![]() |
7cac8401e8 | ||
![]() |
0f899357c2 | ||
![]() |
3396fe2871 | ||
![]() |
9fbcbae5b3 | ||
![]() |
36a779dc18 | ||
![]() |
cd8b8bbc74 | ||
![]() |
d8319bb35c | ||
![]() |
afd6adbffa | ||
![]() |
d3a5d1e314 | ||
![]() |
56010382fb | ||
![]() |
0ff6b0ca70 | ||
![]() |
4b33306940 | ||
![]() |
4dea3dff36 | ||
![]() |
3e8c741170 | ||
![]() |
62baa72457 | ||
![]() |
5eb711da87 | ||
![]() |
79c5df1d92 | ||
![]() |
991ea6e829 | ||
![]() |
1d160641a4 | ||
![]() |
c2b3d914f7 | ||
![]() |
143b2bdbcd | ||
![]() |
8cb21ed4d1 | ||
![]() |
8aa7695fdd | ||
![]() |
fa78818069 | ||
![]() |
62172c6049 | ||
![]() |
39f3cf8cbe | ||
![]() |
5082947331 | ||
![]() |
01ddb2b4e4 | ||
![]() |
bdd38fb061 | ||
![]() |
06f35e4997 | ||
![]() |
2d95c32892 | ||
![]() |
6f4d4540b2 | ||
![]() |
96316cddaa | ||
![]() |
e84ddef877 | ||
![]() |
11b40bb6d5 | ||
![]() |
686c6a4c44 | ||
![]() |
a1821035d3 | ||
![]() |
7b8650bbc8 | ||
![]() |
0285260e97 | ||
![]() |
10a3a223a0 | ||
![]() |
2dc970a8bb | ||
![]() |
f74c4cc83c | ||
![]() |
7012ac7163 | ||
![]() |
227b444d81 | ||
![]() |
d50db8a6f3 | ||
![]() |
3a80b51a9f | ||
![]() |
03396cf07a | ||
![]() |
5b57f7509d | ||
![]() |
0568c86628 | ||
![]() |
b31e66686d | ||
![]() |
924b8ef30f | ||
![]() |
7bcc16bb40 | ||
![]() |
31e6746bdf | ||
![]() |
c39bf3eb4d | ||
![]() |
8b952e7e1e | ||
![]() |
04e97f7b86 | ||
![]() |
74752c561c | ||
![]() |
ee96458b56 | ||
![]() |
333410e4cd | ||
![]() |
999a39a3e6 | ||
![]() |
82ca19c296 | ||
![]() |
56d8a5d585 | ||
![]() |
aa5fbb2980 | ||
![]() |
db0bb071f5 | ||
![]() |
ab702e2ba1 | ||
![]() |
d4efacd40a | ||
![]() |
347affcc5c | ||
![]() |
8ebe34b8da | ||
![]() |
7086cb8a02 | ||
![]() |
8dbc930c2f | ||
![]() |
61eb67849d | ||
![]() |
c2316ef256 | ||
![]() |
0d22270f8b | ||
![]() |
abb9c14256 | ||
![]() |
815e534dc6 | ||
![]() |
51dde077fe | ||
![]() |
31d0b7afcd | ||
![]() |
95b0d950aa | ||
![]() |
efa2be2821 | ||
![]() |
670db97fc7 | ||
![]() |
1650b72edb | ||
![]() |
a5bca3f0df | ||
![]() |
88f41314c7 | ||
![]() |
5ef8d52c13 | ||
![]() |
0b65d56ab0 | ||
![]() |
a256b70685 | ||
![]() |
f16d1499fe | ||
![]() |
79ca851e4f | ||
![]() |
d5c54d64a6 | ||
![]() |
5cfdd2339f | ||
![]() |
3ab3213290 | ||
![]() |
46c9840d00 | ||
![]() |
b3f2f14e96 | ||
![]() |
3ace49d27f | ||
![]() |
9bd662d8dc | ||
![]() |
df7a40354e | ||
![]() |
c489d4bc4f | ||
![]() |
2b029bd506 | ||
![]() |
2227845658 | ||
![]() |
2d3e88ef59 | ||
![]() |
0bfe960cbd | ||
![]() |
a735f23e1f | ||
![]() |
de6f27ceaf | ||
![]() |
2fab1a3054 | ||
![]() |
d4745ae47e | ||
![]() |
dc21e2dbc9 | ||
![]() |
75dfa71275 | ||
![]() |
d71bf225cc | ||
![]() |
8644c4ebf6 | ||
![]() |
b323db30ee | ||
![]() |
53efd6b303 | ||
![]() |
97faa1b3bc | ||
![]() |
7404133d40 | ||
![]() |
e18e24407e | ||
![]() |
026afa7f73 | ||
![]() |
29cc5bb86b | ||
![]() |
aa9d3c8269 | ||
![]() |
f8074636bc | ||
![]() |
db2cde4a4c | ||
![]() |
5eec7d9172 | ||
![]() |
8b9735d72e | ||
![]() |
1866916cb8 | ||
![]() |
f38a6a9d43 | ||
![]() |
0f6db63020 | ||
![]() |
51fcd83b87 | ||
![]() |
c2190e1318 | ||
![]() |
c40a13558c | ||
![]() |
02695aea51 | ||
![]() |
d5be1aca0e | ||
![]() |
8ff8b78ed8 | ||
![]() |
7fc55aa9a0 | ||
![]() |
38335ca187 | ||
![]() |
e0e194099c | ||
![]() |
8063059764 | ||
![]() |
f96d923b2a | ||
![]() |
9142ccfc93 | ||
![]() |
9f7cc00fcb | ||
![]() |
b129ae627b | ||
![]() |
f9fb0619fa | ||
![]() |
7f9b86a78e | ||
![]() |
58ea7a275e | ||
![]() |
8487a13764 | ||
![]() |
f0ba1108d5 | ||
![]() |
5d0daf9b2d | ||
![]() |
8b8692ba53 | ||
![]() |
1f385f5b35 | ||
![]() |
34baa09b6c | ||
![]() |
b21866fbff | ||
![]() |
e0a288bcb9 | ||
![]() |
4592534a18 | ||
![]() |
28165bfcd6 | ||
![]() |
953b94fd08 | ||
![]() |
e10e30f82b | ||
![]() |
aeb1fa0e7e | ||
![]() |
349a7543b0 | ||
![]() |
3d589eda4a | ||
![]() |
de646b66b6 | ||
![]() |
4f0d311df7 | ||
![]() |
d6e3c9a7fa | ||
![]() |
a7a724f134 | ||
![]() |
b0e30fdce1 | ||
![]() |
4e15afa254 | ||
![]() |
84bac06178 | ||
![]() |
1fecb995c9 | ||
![]() |
99b719299c | ||
![]() |
fb9590467d | ||
![]() |
bc8e090873 | ||
![]() |
cf0f67265f | ||
![]() |
53dd15a213 | ||
![]() |
eb2d617ed8 | ||
![]() |
74dae4ec17 | ||
![]() |
abbc46877b | ||
![]() |
3cb25b3525 | ||
![]() |
f387730b88 | ||
![]() |
92b45b1868 | ||
![]() |
003c7ec2e8 | ||
![]() |
c45221a2d0 | ||
![]() |
8494ba8ce2 | ||
![]() |
058d63e77f | ||
![]() |
17b5bca443 | ||
![]() |
c3f5700494 | ||
![]() |
b17ff6daf0 | ||
![]() |
e8f5531a8c | ||
![]() |
51d3b091da | ||
![]() |
9708dd6786 | ||
![]() |
e48427dbbc | ||
![]() |
669b6d2d56 | ||
![]() |
32d956bbe7 | ||
![]() |
3a147c78a8 | ||
![]() |
8c56b6a7be | ||
![]() |
66e42e0817 | ||
![]() |
0ee3d10fda | ||
![]() |
ed0afc4068 | ||
![]() |
1f70ed6985 | ||
![]() |
8f3ea60c74 | ||
![]() |
eb722a74cd | ||
![]() |
1825f67eee | ||
![]() |
975a994581 | ||
![]() |
061514549d | ||
![]() |
5e52429c23 | ||
![]() |
396cf15a1f | ||
![]() |
7514cf7320 | ||
![]() |
1316d6a3c9 | ||
![]() |
e1cbbe3628 | ||
![]() |
6d367e08a3 | ||
![]() |
eaa7359c8c | ||
![]() |
657ceda3af | ||
![]() |
a934e42219 | ||
![]() |
1544749282 | ||
![]() |
763bab80fa | ||
![]() |
417fda3019 | ||
![]() |
444830cf2d | ||
![]() |
23bf33c454 | ||
![]() |
0be030c497 | ||
![]() |
ee27d8f081 | ||
![]() |
a3a9684505 | ||
![]() |
1381325813 | ||
![]() |
52b112fae6 | ||
![]() |
c83eeb16a8 | ||
![]() |
9d1ee6f61d | ||
![]() |
b90611b4b4 | ||
![]() |
e1e7ef59c6 | ||
![]() |
9ae0f4a993 | ||
![]() |
fd262a7995 | ||
![]() |
58054ad2d1 | ||
![]() |
1255bd00fd | ||
![]() |
1f84480a80 | ||
![]() |
b838efedd2 | ||
![]() |
f78e24f9a0 | ||
![]() |
88f5b20353 | ||
![]() |
331031be45 | ||
![]() |
c5694ea966 | ||
![]() |
34b5ede326 | ||
![]() |
7b476cb24b | ||
![]() |
7ca261d763 | ||
![]() |
c864576619 | ||
![]() |
247c05305d | ||
![]() |
2232f025b8 | ||
![]() |
b2e5401486 | ||
![]() |
41226371f3 | ||
![]() |
1edb7288b9 | ||
![]() |
cc5e972cfc | ||
![]() |
92be0126df | ||
![]() |
dd6f97622e | ||
![]() |
2c9f51db89 | ||
![]() |
72340defe4 | ||
![]() |
542b66c79a | ||
![]() |
e4b0a5b3ce | ||
![]() |
f7e3e72a6e | ||
![]() |
8b17ec76a8 | ||
![]() |
b8d5a89446 | ||
![]() |
4af5bcc0b0 | ||
![]() |
96c577482d | ||
![]() |
7f9a707f75 | ||
![]() |
ed3913c1f4 | ||
![]() |
16d74dd2e8 | ||
![]() |
24bb92007a | ||
![]() |
2f0cae0bc1 | ||
![]() |
e3a672099c | ||
![]() |
abf425dfb5 | ||
![]() |
663859d2e5 | ||
![]() |
f5eb6ce03e | ||
![]() |
4ae370b9db | ||
![]() |
b97e950d86 | ||
![]() |
5865e9c41a | ||
![]() |
85cf2d5ff1 | ||
![]() |
61f8e97f6b | ||
![]() |
c92f06cfd9 | ||
![]() |
05c3c8ad32 | ||
![]() |
bb8f4c624b | ||
![]() |
ea3a160367 | ||
![]() |
737b3cb576 | ||
![]() |
d83a68f3ff | ||
![]() |
24d3777722 | ||
![]() |
826797cbd5 | ||
![]() |
511eea39a1 | ||
![]() |
24af36743d | ||
![]() |
e2761bb315 | ||
![]() |
6734a0e112 | ||
![]() |
d4199064ae | ||
![]() |
04f9644ae7 | ||
![]() |
486f41f082 | ||
![]() |
fff8353451 | ||
![]() |
9a749642d2 | ||
![]() |
c35707725f | ||
![]() |
b0651082f4 | ||
![]() |
aab0cd34cd | ||
![]() |
d2a1a00dc4 | ||
![]() |
f194f4fa3a | ||
![]() |
c9f3d315c0 | ||
![]() |
7f90f2f7ca | ||
![]() |
9f57e77ed3 | ||
![]() |
ab39cb849d | ||
![]() |
a4c9e89370 | ||
![]() |
c8aeddedd4 | ||
![]() |
83df64e520 | ||
![]() |
74ac5bb3d1 | ||
![]() |
d13bd2cce8 | ||
![]() |
ab232bd689 | ||
![]() |
cc96e41d3e | ||
![]() |
741adfa7bb | ||
![]() |
666e83cf4f | ||
![]() |
e2a635b6e5 | ||
![]() |
c58441b29c | ||
![]() |
a6fcfb6af2 | ||
![]() |
17a9329207 | ||
![]() |
f6160bdc57 | ||
![]() |
6aae4e5766 | ||
![]() |
84a6bb1cf3 | ||
![]() |
c334423d42 | ||
![]() |
113b560a20 | ||
![]() |
5bf367af9f | ||
![]() |
61fb4caaad | ||
![]() |
6734af6e4a | ||
![]() |
bf6053906d | ||
![]() |
4766833cf2 | ||
![]() |
01d81cb91d | ||
![]() |
93068402a2 | ||
![]() |
34a2c835d4 | ||
![]() |
30d35883b8 | ||
![]() |
71563a52ff | ||
![]() |
0c6e7b5db5 | ||
![]() |
334ca65482 | ||
![]() |
8472112fc1 | ||
![]() |
84036d97d9 | ||
![]() |
0832974725 | ||
![]() |
6cee4efcd3 | ||
![]() |
6f868849ab | ||
![]() |
275ca58a82 | ||
![]() |
87393e8aef | ||
![]() |
86bf57e3cd | ||
![]() |
72c1d451fe | ||
![]() |
8b4a01df27 | ||
![]() |
d0a973fa46 | ||
![]() |
748ebbe66b | ||
![]() |
59de21eae2 | ||
![]() |
50473afea8 | ||
![]() |
37f925de0a | ||
![]() |
cefde3f003 | ||
![]() |
ae6124d1f4 | ||
![]() |
7e121ff72f | ||
![]() |
5155e18de2 | ||
![]() |
7365741088 | ||
![]() |
d5368d0719 | ||
![]() |
26c12ac1a9 | ||
![]() |
2c67849b35 | ||
![]() |
04509cefec | ||
![]() |
74b9f5dcb0 | ||
![]() |
7809a2eddd | ||
![]() |
183b342071 | ||
![]() |
0bb5515055 | ||
![]() |
e8e9294fdf | ||
![]() |
9acfc0316f | ||
![]() |
29fb0baa09 | ||
![]() |
d5de39ebd4 | ||
![]() |
0faf76e4bd | ||
![]() |
99581e1f40 | ||
![]() |
e8e2ed9fe5 | ||
![]() |
9f72448ecd | ||
![]() |
3da3f16deb | ||
![]() |
0e2ce3c634 | ||
![]() |
fe00e00537 | ||
![]() |
29646a7f61 | ||
![]() |
50d2712581 | ||
![]() |
3093f882d8 | ||
![]() |
e5cf0d1c61 | ||
![]() |
cd879b067f | ||
![]() |
053cb1b53c | ||
![]() |
6b102a8142 | ||
![]() |
ac7979fb46 | ||
![]() |
c8a6888a2f | ||
![]() |
9ce33f8a3f | ||
![]() |
d51851e763 | ||
![]() |
fb70a1a998 | ||
![]() |
a1dcd59d95 | ||
![]() |
2a17585702 | ||
![]() |
2f323f23d7 | ||
![]() |
087c305b0d | ||
![]() |
31764f6d65 | ||
![]() |
4efde2b294 | ||
![]() |
95554a53d1 | ||
![]() |
89c1b2771d | ||
![]() |
8f069a9b72 | ||
![]() |
2e9d6603e3 | ||
![]() |
46595e73df | ||
![]() |
a6a1b9b8e5 | ||
![]() |
3f277a7a7b | ||
![]() |
90c5d3f1e8 | ||
![]() |
a5f7cf8334 | ||
![]() |
3075f89797 | ||
![]() |
45297665c6 | ||
![]() |
ddbf3fc111 | ||
![]() |
da82b89676 | ||
![]() |
d5f1a2c817 | ||
![]() |
6020adef6b | ||
![]() |
d2a52a8b5d | ||
![]() |
9f8774960f | ||
![]() |
36bb8b67c9 | ||
![]() |
8f3a56dd32 | ||
![]() |
113d5d982f | ||
![]() |
37a447e745 | ||
![]() |
9e2232d240 | ||
![]() |
514db30fb1 | ||
![]() |
08181f72d4 | ||
![]() |
613a28a5af | ||
![]() |
e4c422d6f9 | ||
![]() |
478f992dea | ||
![]() |
b54519d0e6 | ||
![]() |
9499654757 | ||
![]() |
c5138c535c | ||
![]() |
5bd8d84d14 | ||
![]() |
ab0310e27c | ||
![]() |
607751da40 | ||
![]() |
1efabccd14 | ||
![]() |
029374e9aa | ||
![]() |
2a8efb3fd5 | ||
![]() |
48edcde4ef | ||
![]() |
58a2995bbc | ||
![]() |
a35dcb28ef | ||
![]() |
7b2d482387 | ||
![]() |
2b077554f7 | ||
![]() |
9134f243c1 | ||
![]() |
c0f3ca81fb | ||
![]() |
190ed4fd20 | ||
![]() |
b9ff9b7f90 | ||
![]() |
b9b8121be9 | ||
![]() |
014bf55cd4 | ||
![]() |
085ae2e74a | ||
![]() |
4ff33f165d | ||
![]() |
d929c02d2a | ||
![]() |
d50a08a549 | ||
![]() |
c493d668c8 | ||
![]() |
53477fd3a1 | ||
![]() |
87aa839b60 | ||
![]() |
e02ccdcb1a | ||
![]() |
f36f532c63 | ||
![]() |
5a816917d5 | ||
![]() |
7af63d052d | ||
![]() |
4f8217d1ab | ||
![]() |
5409d441b5 | ||
![]() |
d5f82fa458 | ||
![]() |
d0deab3519 | ||
![]() |
d5a8df753a | ||
![]() |
13de2c4dd0 | ||
![]() |
906280225e | ||
![]() |
161a5b4707 | ||
![]() |
c6b6b4479c | ||
![]() |
96e7b60285 | ||
![]() |
086fccd997 | ||
![]() |
5dfaf6eee9 | ||
![]() |
e251dd066c | ||
![]() |
9abcfe56ea | ||
![]() |
abbc641fd4 | ||
![]() |
c60dcb4f5a | ||
![]() |
4be0b15afa | ||
![]() |
a4ae36b6b3 | ||
![]() |
ac075d9f53 | ||
![]() |
05d7be0362 | ||
![]() |
9a71dc1a26 | ||
![]() |
156023b154 | ||
![]() |
6b3773a862 | ||
![]() |
376d628cf0 | ||
![]() |
44062ebd52 | ||
![]() |
5739285fc2 | ||
![]() |
70b457ed18 | ||
![]() |
ca2995ed38 | ||
![]() |
6816931659 | ||
![]() |
1547ecbeb3 | ||
![]() |
e918f55b58 | ||
![]() |
c28b468844 | ||
![]() |
052cf8ee7d | ||
![]() |
550ada2f9e | ||
![]() |
17b7727262 | ||
![]() |
4553e404b2 | ||
![]() |
a565a571f9 | ||
![]() |
fb64b6017b | ||
![]() |
ed4229ab70 | ||
![]() |
3fb906ef6c | ||
![]() |
e1663f3df0 | ||
![]() |
52c6584c81 | ||
![]() |
9f87eda5de | ||
![]() |
697e9449cf | ||
![]() |
76c3e4c155 | ||
![]() |
358289b5f9 | ||
![]() |
5eec24676f | ||
![]() |
f52b8fa2de | ||
![]() |
447c3ab125 | ||
![]() |
8fac68386e | ||
![]() |
a3021c4697 | ||
![]() |
b7c61f9c6d | ||
![]() |
08a0342618 | ||
![]() |
3d7a81696d | ||
![]() |
48cb032ddf | ||
![]() |
33260a7747 | ||
![]() |
a049502d12 | ||
![]() |
ae7ef66dfa | ||
![]() |
9748679484 | ||
![]() |
da419b24e7 | ||
![]() |
7f57a977a1 | ||
![]() |
2f42a4e85b | ||
![]() |
af40f5ae5c | ||
![]() |
759d02a249 | ||
![]() |
d7729337ac | ||
![]() |
ee391ae9ea | ||
![]() |
4ed4a6409b | ||
![]() |
e5cc345f49 | ||
![]() |
d847a4d9e0 | ||
![]() |
f106733d71 | ||
![]() |
f3de97d67f | ||
![]() |
544f276ff0 | ||
![]() |
463635a459 | ||
![]() |
3b7b845930 | ||
![]() |
1fc0214857 | ||
![]() |
11bf601db9 | ||
![]() |
7c1154ddfc | ||
![]() |
df557e03fa | ||
![]() |
524b6f1d8a | ||
![]() |
cea8be7efa | ||
![]() |
c5f918ad95 | ||
![]() |
b14c7842fc | ||
![]() |
eead8b5755 | ||
![]() |
10a27a7a25 | ||
![]() |
865fc239a0 | ||
![]() |
f9f94b8304 | ||
![]() |
cb8135a0d1 | ||
![]() |
ef4b0a5632 | ||
![]() |
6a6a87489c | ||
![]() |
2360a6e951 | ||
![]() |
f4f71185ae | ||
![]() |
062977336a | ||
![]() |
e52d98ad8b | ||
![]() |
ef8da8054f | ||
![]() |
1ccd687c00 | ||
![]() |
a8ce5a5b20 | ||
![]() |
68e6bc464b | ||
![]() |
68762fe84c | ||
![]() |
419f29321a | ||
![]() |
00b41d29c1 | ||
![]() |
0ffd5fcf85 | ||
![]() |
95fee95006 | ||
![]() |
239bd769df | ||
![]() |
b4e0e9984f | ||
![]() |
79f42e35ce | ||
![]() |
be89fc25f9 | ||
![]() |
8eae02c037 | ||
![]() |
930fd59298 | ||
![]() |
bf13bac152 | ||
![]() |
649acbae1c | ||
![]() |
05eada427b | ||
![]() |
03caf9d805 | ||
![]() |
d6ea3aab1c | ||
![]() |
f3a330e330 | ||
![]() |
044d2b2b06 | ||
![]() |
fb440b0d2e | ||
![]() |
0de5969ec1 | ||
![]() |
3f98b2785e | ||
![]() |
798868427e | ||
![]() |
c79f643ba7 | ||
![]() |
1db3a14c54 | ||
![]() |
bf6d017ad1 | ||
![]() |
8b1773dd60 | ||
![]() |
a706300598 | ||
![]() |
2541c3c5e6 | ||
![]() |
41a1b99f7d | ||
![]() |
1862a439e2 | ||
![]() |
018ecfbaa0 | ||
![]() |
4c8fd4fc35 | ||
![]() |
35c1b10224 | ||
![]() |
c1c01bef7c | ||
![]() |
a48c3d0ba8 | ||
![]() |
93a9ebc4f6 | ||
![]() |
7cc2bd43c6 | ||
![]() |
393e628721 | ||
![]() |
0bcd28e58c | ||
![]() |
42f5389fb8 | ||
![]() |
041cfe91b4 | ||
![]() |
0f82a4589b | ||
![]() |
4320a4f851 | ||
![]() |
037cbabb32 | ||
![]() |
0dde859582 | ||
![]() |
e59c043fb6 | ||
![]() |
ae928c4397 | ||
![]() |
da41c65128 | ||
![]() |
4d18234714 | ||
![]() |
d254c6464b | ||
![]() |
3a5d50e572 | ||
![]() |
03b6d2f1ab | ||
![]() |
b0397ed3c5 | ||
![]() |
fa70ebcac2 | ||
![]() |
86e0330100 | ||
![]() |
92567b4d7e | ||
![]() |
0ae70fed13 | ||
![]() |
3b7300543a | ||
![]() |
642351af1a | ||
![]() |
121802a683 | ||
![]() |
08cf55e55f | ||
![]() |
3c8c0d78ef | ||
![]() |
c4d18aa9ca | ||
![]() |
2d4a87adc9 | ||
![]() |
bedac71e3d | ||
![]() |
ee4e42e730 | ||
![]() |
0de75f05dd | ||
![]() |
be6dd21e54 | ||
![]() |
927ddb0bde | ||
![]() |
a8fadabaf1 | ||
![]() |
44d0f78c1b | ||
![]() |
38f9a015ca | ||
![]() |
c311cdc6f5 | ||
![]() |
a93e0f3284 | ||
![]() |
14b3065ba4 | ||
![]() |
3ea2d6a0a8 | ||
![]() |
c802290437 | ||
![]() |
f7781defe5 | ||
![]() |
418420523a | ||
![]() |
d342a1f368 | ||
![]() |
81f85361d5 | ||
![]() |
f1621b30ec | ||
![]() |
d4f6a594b6 | ||
![]() |
ff5ba5c131 | ||
![]() |
4243f30308 | ||
![]() |
813e91073d | ||
![]() |
7250f22ff6 | ||
![]() |
db31a53bba | ||
![]() |
3023f235a4 | ||
![]() |
79cd8b4da5 | ||
![]() |
8e4d311cd9 | ||
![]() |
9bd8c86a94 | ||
![]() |
cbc0c1d0b6 | ||
![]() |
49c37857d4 | ||
![]() |
b1139a4bf6 | ||
![]() |
7e8559278e | ||
![]() |
1e7f1c98fc | ||
![]() |
a802f25dd6 | ||
![]() |
f1d6d21d6d | ||
![]() |
a80302c513 | ||
![]() |
1c46949da7 | ||
![]() |
07a56454a0 | ||
![]() |
a0e72d02c8 | ||
![]() |
455a59ca85 | ||
![]() |
46d78af068 | ||
![]() |
08d22fd3df | ||
![]() |
e6c691a8f8 | ||
![]() |
4b0e5c445c | ||
![]() |
eb5cff1045 | ||
![]() |
35c7792aa2 | ||
![]() |
521688d630 | ||
![]() |
75e2845c01 | ||
![]() |
2f96283286 | ||
![]() |
cbe6e9b5f5 | ||
![]() |
2ab79cf474 | ||
![]() |
6ce34aba79 | ||
![]() |
5eeb320b60 | ||
![]() |
93310850d2 | ||
![]() |
a2880b12ca | ||
![]() |
cef2657048 | ||
![]() |
ccd85eb055 | ||
![]() |
303b57779a | ||
![]() |
6279816ecc | ||
![]() |
4ae77261fa | ||
![]() |
4b7d843b78 | ||
![]() |
1c28df65c3 | ||
![]() |
85b740f484 | ||
![]() |
f9929cb27d | ||
![]() |
bafab1ac07 | ||
![]() |
e05c262468 | ||
![]() |
acfb72246c | ||
![]() |
9d51c4c340 | ||
![]() |
18068effec | ||
![]() |
7a3f7d3bba | ||
![]() |
95aa48c456 | ||
![]() |
6ea8ca991b | ||
![]() |
f1e551b960 | ||
![]() |
772c54ec74 | ||
![]() |
13cb789c18 | ||
![]() |
42220c4268 | ||
![]() |
3052506e2e | ||
![]() |
0741daa7eb | ||
![]() |
b4aa554279 | ||
![]() |
8fe2abe0ae | ||
![]() |
5af789ae11 | ||
![]() |
904a168d5c | ||
![]() |
724441eddc | ||
![]() |
f68ab3edd1 | ||
![]() |
68542aca3a | ||
![]() |
594bc4203c | ||
![]() |
57318b022d | ||
![]() |
761159aa93 | ||
![]() |
29dce26bf6 | ||
![]() |
717ab69093 | ||
![]() |
138a2cf08f | ||
![]() |
81daf82647 | ||
![]() |
f3798bfb63 | ||
![]() |
bc07dfad2e | ||
![]() |
8dd1c2a6cc | ||
![]() |
d10b657a54 | ||
![]() |
f90da739eb | ||
![]() |
d9cadf64e8 | ||
![]() |
15d4a55cd8 | ||
![]() |
309cbdb8be | ||
![]() |
39a9ad0ce7 | ||
![]() |
0f3c44c926 | ||
![]() |
a0e7c4a74c | ||
![]() |
7d428030df | ||
![]() |
00c395f689 | ||
![]() |
d8e1c73d26 | ||
![]() |
ffa4cc241b | ||
![]() |
6f1b740c8f | ||
![]() |
3406ba3ebf | ||
![]() |
b6715bd812 | ||
![]() |
18aee02221 | ||
![]() |
401bbf2e6a | ||
![]() |
7467b7f88a | ||
![]() |
c82d8a7c2a | ||
![]() |
6b81bcf334 | ||
![]() |
3d67421d98 | ||
![]() |
acac70675d | ||
![]() |
56434259c1 | ||
![]() |
da7e4b9016 | ||
![]() |
d4b8650d21 | ||
![]() |
17645a79f0 | ||
![]() |
ce1f14a010 | ||
![]() |
43050426de | ||
![]() |
b05f60c98b | ||
![]() |
c44c560f96 | ||
![]() |
e839ef54af | ||
![]() |
0cb659d78c | ||
![]() |
9048deeb95 | ||
![]() |
5592ebae7d | ||
![]() |
b076c32fd1 | ||
![]() |
a48f1e310f | ||
![]() |
19aca001d7 | ||
![]() |
114f913bf8 | ||
![]() |
1c9810890a | ||
![]() |
b11beb508b | ||
![]() |
af8d4da594 | ||
![]() |
a81db2cda6 | ||
![]() |
99bdff0f92 | ||
![]() |
bb138326df | ||
![]() |
5b0ce7410d | ||
![]() |
d5ea22d1a0 | ||
![]() |
210f3fa9e2 | ||
![]() |
d661cfa88b | ||
![]() |
68bf3a71dc | ||
![]() |
3cdb12d293 | ||
![]() |
ad33acd7d1 | ||
![]() |
0ec3884e98 | ||
![]() |
7f2471d6b2 | ||
![]() |
e0660b1dab | ||
![]() |
2182cfbeb7 | ||
![]() |
8fafec4915 | ||
![]() |
b9fd690ecb | ||
![]() |
2f2ada4416 | ||
![]() |
9c951c58d9 | ||
![]() |
4b4b47e231 | ||
![]() |
2c027adb68 | ||
![]() |
4a25e7a178 | ||
![]() |
55d54fec63 | ||
![]() |
220e4bd660 | ||
![]() |
978c28a686 | ||
![]() |
b867ada5e5 | ||
![]() |
7071cc972b | ||
![]() |
6898f932a0 | ||
![]() |
2e0ef6385d | ||
![]() |
f93da7ea51 | ||
![]() |
1210bb8a4d | ||
![]() |
48a71e96eb | ||
![]() |
3bf47b5290 | ||
![]() |
9e9f199e55 | ||
![]() |
5a8a111857 | ||
![]() |
48ba247ab4 | ||
![]() |
362dbd97ac | ||
![]() |
aa0e1883d1 | ||
![]() |
9cdbcb4332 | ||
![]() |
23ddd4feb5 | ||
![]() |
fcaa777c95 | ||
![]() |
b195cab6a7 | ||
![]() |
63dc0daa09 | ||
![]() |
34602ec4be | ||
![]() |
f3ce44042f | ||
![]() |
4205f18f0c | ||
![]() |
6be330ae8d | ||
![]() |
4569af2130 | ||
![]() |
765c31315a | ||
![]() |
0e191e42a0 | ||
![]() |
ca34b2a1b8 | ||
![]() |
7afc3e5260 | ||
![]() |
f9e13ca67a | ||
![]() |
810258e9b8 | ||
![]() |
5e462adc5c | ||
![]() |
1fd0b40776 | ||
![]() |
2965fb666f | ||
![]() |
390575ab4d | ||
![]() |
e4ef92ca2d | ||
![]() |
9bf586b018 | ||
![]() |
173ea72001 | ||
![]() |
1230cabcb0 | ||
![]() |
6ed03e1fcd | ||
![]() |
c4b371b124 | ||
![]() |
a600213b00 | ||
![]() |
7799b8d4cb | ||
![]() |
245bf26480 | ||
![]() |
5d05205d69 | ||
![]() |
853e2622a1 | ||
![]() |
d0bf9e9cd7 | ||
![]() |
7a7951ae68 | ||
![]() |
bd28955c8e | ||
![]() |
e46f09a939 | ||
![]() |
71b1f8138d | ||
![]() |
1d82a1c98c | ||
![]() |
b5f60f3f11 | ||
![]() |
259665d9f1 | ||
![]() |
ba823bae13 | ||
![]() |
1290a4402c | ||
![]() |
379076a5e2 | ||
![]() |
d12bdf50d8 | ||
![]() |
cbfd5aeeee | ||
![]() |
41429bdc0b | ||
![]() |
54b9966feb | ||
![]() |
105c66127c | ||
![]() |
765ad0bd3f | ||
![]() |
dd05478483 | ||
![]() |
5d028dea39 | ||
![]() |
629c51d260 | ||
![]() |
9ea57961af | ||
![]() |
07b9b1c9c7 | ||
![]() |
5b942ff9c1 | ||
![]() |
7b5a918941 | ||
![]() |
47721bf76b | ||
![]() |
35ce0974cd | ||
![]() |
52e1906d42 | ||
![]() |
eaf24a3ceb | ||
![]() |
62760e371e | ||
![]() |
e154e11186 | ||
![]() |
72d079ef61 | ||
![]() |
0bfb7049b0 | ||
![]() |
f7cb526793 | ||
![]() |
e34e833d3d | ||
![]() |
a125a19728 | ||
![]() |
b3e6a53868 | ||
![]() |
218f8e53bb | ||
![]() |
d02575528b | ||
![]() |
c78adb2cdc | ||
![]() |
3e28f79ce9 | ||
![]() |
67af7a698b | ||
![]() |
06e76f9b15 | ||
![]() |
6d383d005c | ||
![]() |
c373583723 | ||
![]() |
f1d10809d5 | ||
![]() |
474f571798 | ||
![]() |
fb9c125ab8 | ||
![]() |
162fb37421 | ||
![]() |
d953f031f0 | ||
![]() |
7fde89ad95 | ||
![]() |
bd04a93ffb | ||
![]() |
e2bfaafe28 | ||
![]() |
1fb3d16b89 | ||
![]() |
35645b3d93 | ||
![]() |
a4cd1fe77d | ||
![]() |
4145914024 | ||
![]() |
6bd11a5e4a | ||
![]() |
46fa798797 | ||
![]() |
70a226207e | ||
![]() |
257a35f3ed | ||
![]() |
af01b9514b | ||
![]() |
070fd1f2ff | ||
![]() |
fb59da2b06 | ||
![]() |
11e4d0de82 | ||
![]() |
e46ab1e267 | ||
![]() |
d6e0f368df | ||
![]() |
9f2884bc0f | ||
![]() |
18d468e887 | ||
![]() |
63f6735bb8 | ||
![]() |
ab6f0ccd16 | ||
![]() |
ae0f093e73 | ||
![]() |
e5f988e3fe | ||
![]() |
12e82afad2 | ||
![]() |
6c2db93cbd | ||
![]() |
d5edbe700b | ||
![]() |
86ad43c3ab | ||
![]() |
f450c0156b | ||
![]() |
8abcfcb4ac | ||
![]() |
f3cace1d03 | ||
![]() |
e1e5e898ab | ||
![]() |
3aa3852ff6 | ||
![]() |
709a6329c7 | ||
![]() |
c9f05a2939 | ||
![]() |
e41377f862 | ||
![]() |
d173787a94 | ||
![]() |
d5aea26f3a | ||
![]() |
2681e578c4 | ||
![]() |
1f498dcc73 | ||
![]() |
83b01d35eb | ||
![]() |
8a7e651c99 | ||
![]() |
80a5759bae | ||
![]() |
e8a4fbb4e3 | ||
![]() |
0ce67afcc1 | ||
![]() |
a8dad23fa3 | ||
![]() |
443e0f8f76 | ||
![]() |
a838595e1e | ||
![]() |
61daab910e | ||
![]() |
7fd19c43e9 | ||
![]() |
ce0685c31f | ||
![]() |
e33f852baa | ||
![]() |
227d5e9e69 | ||
![]() |
1c648850ab | ||
![]() |
63691707fc | ||
![]() |
5d97b9c8f3 | ||
![]() |
77666d7399 | ||
![]() |
ed69495b03 | ||
![]() |
66b61d4e9e | ||
![]() |
8dd084ac5c | ||
![]() |
932f8a44fc | ||
![]() |
101b3500cc | ||
![]() |
a777801e15 | ||
![]() |
0d6787641a | ||
![]() |
744bba300e | ||
![]() |
34d43d8273 | ||
![]() |
7bc9745c7a | ||
![]() |
b414cba681 | ||
![]() |
1c9110b927 | ||
![]() |
325459e336 | ||
![]() |
ee3347afbd | ||
![]() |
27aaec9a82 | ||
![]() |
929f23fd2d | ||
![]() |
8422a40c69 | ||
![]() |
ca334e7e5c | ||
![]() |
54acf1d087 | ||
![]() |
42d3901ee3 | ||
![]() |
f8b328a048 | ||
![]() |
41a320e9a4 | ||
![]() |
57fb77d7fe | ||
![]() |
b59dcbfc0e | ||
![]() |
618c534d81 | ||
![]() |
26ba61097b | ||
![]() |
2c87e66db8 | ||
![]() |
f61f7df2d8 | ||
![]() |
364d31465e | ||
![]() |
4c7ac50dd8 | ||
![]() |
37e25136ed | ||
![]() |
d9f03f3ec7 | ||
![]() |
4d5c52bc63 | ||
![]() |
a1c4a9fb58 | ||
![]() |
031f17c98e | ||
![]() |
4ead319092 | ||
![]() |
dd6bab5413 | ||
![]() |
5b48a0fa5f | ||
![]() |
2032e7a83a | ||
![]() |
72b9d3d802 | ||
![]() |
70cb8ae16c | ||
![]() |
05a97a4f12 | ||
![]() |
8b86a954ee | ||
![]() |
741ee447ca | ||
![]() |
3537f49ced | ||
![]() |
c3e4a4de5e | ||
![]() |
86569533e9 | ||
![]() |
e6850ab644 | ||
![]() |
97c2421a22 | ||
![]() |
f765b6a487 | ||
![]() |
3e6f6467af | ||
![]() |
7e6eb62504 | ||
![]() |
949b71d40c | ||
![]() |
afdfcb21b7 | ||
![]() |
776a786e1b | ||
![]() |
8ae65d1bdd | ||
![]() |
0829506176 | ||
![]() |
71ee692da0 | ||
![]() |
acd0092ed5 | ||
![]() |
1160ffbf9e | ||
![]() |
93cb6547bd | ||
![]() |
f9c91f288f | ||
![]() |
62cf921cc6 | ||
![]() |
4bd7381827 | ||
![]() |
43459ec825 | ||
![]() |
5fa01f8b96 | ||
![]() |
67d5693d2a | ||
![]() |
c2a782afa4 | ||
![]() |
14c9558ee6 | ||
![]() |
d53a73e7e7 | ||
![]() |
7e334bd4a5 | ||
![]() |
51e787f631 | ||
![]() |
8080699030 | ||
![]() |
e555f9f7f0 | ||
![]() |
822db6e9b5 | ||
![]() |
ac1f30ef43 | ||
![]() |
0fc1b8c46b | ||
![]() |
e7c19bcf55 | ||
![]() |
63ca8aca4c | ||
![]() |
2caa9c57fc | ||
![]() |
33fad2da15 | ||
![]() |
518eefbe10 | ||
![]() |
1ba73454c1 | ||
![]() |
ee4735c17c | ||
![]() |
b008edae90 | ||
![]() |
c6bd88f3ad | ||
![]() |
efa57521c7 | ||
![]() |
4700f8831b | ||
![]() |
9428bee316 | ||
![]() |
89c7183a1d | ||
![]() |
d2a9e7e458 | ||
![]() |
1774f1a079 | ||
![]() |
de1307913b | ||
![]() |
093132533d | ||
![]() |
0685be6bfa | ||
![]() |
f40733e9a6 | ||
![]() |
a3d1cff298 | ||
![]() |
b8957cab5c | ||
![]() |
3ac8dde779 | ||
![]() |
17dace979a | ||
![]() |
d405316a4b | ||
![]() |
7e18f2cead | ||
![]() |
000786a1a7 | ||
![]() |
0bf13562b9 | ||
![]() |
45a189e834 | ||
![]() |
0ce6f34a09 | ||
![]() |
4d984dc5ee | ||
![]() |
984d358930 | ||
![]() |
a95893b823 | ||
![]() |
81aaead032 | ||
![]() |
a2083bcff1 | ||
![]() |
052f2a16dc | ||
![]() |
fd10ed6f62 | ||
![]() |
c0bdd4ff1d | ||
![]() |
5f0addbc3e | ||
![]() |
c9589ad0e7 | ||
![]() |
b21c495815 | ||
![]() |
18429c50f9 | ||
![]() |
7ec8ddcf7d | ||
![]() |
5bf9f9e3c5 | ||
![]() |
e4164ee9a1 | ||
![]() |
b522af3075 | ||
![]() |
8775052dee | ||
![]() |
c0c5d57e10 | ||
![]() |
4c2e97b1af | ||
![]() |
f17df15117 | ||
![]() |
bfbb18bdfc | ||
![]() |
cac65ef755 | ||
![]() |
a42793024b | ||
![]() |
7dbc4e6455 | ||
![]() |
a0d71cb3ad | ||
![]() |
83546d0acb | ||
![]() |
e2f9ddd534 | ||
![]() |
911e404bfa | ||
![]() |
bfeafe163f | ||
![]() |
6cf32f1f74 | ||
![]() |
04f162ef25 | ||
![]() |
b2aa390ae1 | ||
![]() |
6ca61f000f | ||
![]() |
20a47a7f88 | ||
![]() |
e2e6946c92 | ||
![]() |
abe917cd54 | ||
![]() |
a1d77ab8e7 | ||
![]() |
c8db671409 | ||
![]() |
52641b7bea | ||
![]() |
3e751ee94a | ||
![]() |
2b28cc3558 | ||
![]() |
f9761388b1 | ||
![]() |
d28694eb57 | ||
![]() |
d758895578 | ||
![]() |
043d5f00ca | ||
![]() |
36878e75b7 | ||
![]() |
ebb50cba48 | ||
![]() |
7c218361d9 | ||
![]() |
bb2eab0bed | ||
![]() |
e8c0cf3857 | ||
![]() |
db825a7aab | ||
![]() |
dbcae810f0 | ||
![]() |
914df8b0c7 | ||
![]() |
f753513289 | ||
![]() |
7bb8efed1d | ||
![]() |
0cec4aee8c | ||
![]() |
e0c9dc24e7 | ||
![]() |
244907a39a | ||
![]() |
9be61abd6b | ||
![]() |
922f424a78 | ||
![]() |
5c7828dd79 | ||
![]() |
74f5093d2a | ||
![]() |
4651e362c9 | ||
![]() |
a2e2a5cb37 | ||
![]() |
15a3882016 | ||
![]() |
d3ecd5214b | ||
![]() |
0a8a8a742e | ||
![]() |
ecff23d027 | ||
![]() |
20dcb32bae | ||
![]() |
678462d2db | ||
![]() |
61fdfec09b | ||
![]() |
5eadf5533d | ||
![]() |
2d3cd5dc80 | ||
![]() |
5208ad0b98 | ||
![]() |
662fb96beb | ||
![]() |
4c14431a3d | ||
![]() |
5ae38a3f18 | ||
![]() |
94e10d1f67 | ||
![]() |
0a50676884 | ||
![]() |
41cce78fcb | ||
![]() |
4c0fa1fabe | ||
![]() |
54e1dafa3f | ||
![]() |
3ac76bc05b | ||
![]() |
83030df3ee | ||
![]() |
07d15caf6f | ||
![]() |
3298efe652 | ||
![]() |
01d9919a3e | ||
![]() |
80b1170b63 | ||
![]() |
2e7302e654 | ||
![]() |
ca7fb8a0b4 | ||
![]() |
c9b0894f26 | ||
![]() |
c3454a195d | ||
![]() |
3b3dd8071b | ||
![]() |
0d28c67534 | ||
![]() |
d0af85754a | ||
![]() |
3e265c27ff | ||
![]() |
8d356f50c4 | ||
![]() |
f30c4f16c0 | ||
![]() |
8bb8caa315 | ||
![]() |
0f17a3d72e | ||
![]() |
7647369e2d | ||
![]() |
4b4208e724 | ||
![]() |
2a16a1df85 | ||
![]() |
25f7c58400 | ||
![]() |
c3db91f11f | ||
![]() |
8c66ce03d4 | ||
![]() |
2be2a0625e | ||
![]() |
c904d5041b | ||
![]() |
632762768e | ||
![]() |
c69ba205f8 | ||
![]() |
019f4dbea9 | ||
![]() |
259ea41ce3 | ||
![]() |
11290f7204 | ||
![]() |
abd06133fb | ||
![]() |
29a3a0c48f | ||
![]() |
2728c63512 | ||
![]() |
f3b11bc1c2 | ||
![]() |
04590befb3 | ||
![]() |
4e9034f910 | ||
![]() |
ba9cfa3764 | ||
![]() |
341e3e2f89 | ||
![]() |
3f70ca5192 | ||
![]() |
f11bfc53ee | ||
![]() |
61e3967b8e | ||
![]() |
add86ea100 | ||
![]() |
dd51c89278 | ||
![]() |
788d783745 | ||
![]() |
35da60543e | ||
![]() |
ce7923d248 | ||
![]() |
55847460c5 | ||
![]() |
893524b0a8 | ||
![]() |
8fb3ae405f | ||
![]() |
aa447ec101 | ||
![]() |
56b1cb4521 | ||
![]() |
90cc24614c | ||
![]() |
4fb0240a36 | ||
![]() |
f20a7afa7f | ||
![]() |
5be2202b2e | ||
![]() |
b8630f739a | ||
![]() |
1ef7c8e8db | ||
![]() |
1415dd0dae | ||
![]() |
5989d021c7 | ||
![]() |
90c4ebd208 |
@@ -11,5 +11,8 @@ insert_final_newline = true
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.properties]
|
||||
insert_final_newline = false
|
||||
[*.sexp]
|
||||
indent_size = 2
|
||||
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
|
16
.gitattributes
vendored
Normal file
16
.gitattributes
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Ignore changes in generated files
|
||||
src/generated/resources/data/** linguist-generated
|
||||
src/testMod/server-files/structures linguist-generated
|
||||
|
||||
* text=auto
|
||||
|
||||
*.gradle eol=lf diff=java
|
||||
*.java eol=lf diff=java
|
||||
*.kt eol=lf diff=java
|
||||
*.lua eol=lf
|
||||
*.md eol=lf diff=markdown
|
||||
*.txt eol=lf
|
||||
|
||||
*.png binary
|
||||
*.jar binary
|
||||
*.dfpwm binary
|
34
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
34
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: Bug report
|
||||
description: Report some misbehaviour in the mod
|
||||
labels: [ bug ]
|
||||
body:
|
||||
- type: dropdown
|
||||
id: mc-version
|
||||
attributes:
|
||||
label: Minecraft Version
|
||||
description: What version of Minecraft are you using?
|
||||
options:
|
||||
- 1.16.x
|
||||
- 1.17.x
|
||||
- 1.18.x
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: "What version of CC: Tweaked are you using?"
|
||||
placeholder: "e.g. 1.96.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: details
|
||||
attributes:
|
||||
label: Details
|
||||
description: |
|
||||
Description of the bug. Please include the following:
|
||||
- Logs: These will be located in the `logs/` directory of your Minecraft
|
||||
instance. Please upload them as a gist or directly into this editor.
|
||||
- Detailed reproduction steps: sometimes I can spot a bug pretty easily,
|
||||
but often it's much more obscure. The more information I have to help
|
||||
reproduce it, the quicker it'll get fixed.
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ComputerCraft Discord
|
||||
url: https://discord.computercraft.cc
|
||||
about: Get help on the ComputerCraft Discord.
|
||||
- name: GitHub Discussions
|
||||
url: https://github.com/cc-tweaked/CC-Tweaked/discussions
|
||||
about: Or ask questions on GitHub Discussions.
|
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea or improvement
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
<!--
|
||||
## Before reporting
|
||||
- Search for the suggestion here. It's possible someone's suggested it before!
|
||||
-->
|
||||
|
||||
## Useful information to include:
|
||||
- Explanation of how the feature/change should work.
|
||||
- Some rationale/use case for a feature. My general approach to designing new features is to ask yourself "what issue are we trying to solve" and _then_ "is this the best way to solve this issue?".
|
4
.github/ISSUE_TEMPLATE/something_else.md
vendored
Normal file
4
.github/ISSUE_TEMPLATE/something_else.md
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
name: Something else
|
||||
about: An issue about something else.
|
||||
---
|
17
.github/matchers/checkstyle.json
vendored
Normal file
17
.github/matchers/checkstyle.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "checkstyle",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([a-z]+) ([\\w./-]+):(\\d+):(\\d+): (.*)$",
|
||||
"severity": 1,
|
||||
"file": 2,
|
||||
"line": 3,
|
||||
"column": 4,
|
||||
"message": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
18
.github/matchers/illuaminate.json
vendored
Normal file
18
.github/matchers/illuaminate.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "illuaminate",
|
||||
"severity": "warning",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([\\w./-]+):\\[(\\d+):(\\d+)\\-(?:\\d+):(?:\\d+)\\]: (.*) \\[([a-z:-]+)\\]$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"message": 4,
|
||||
"code": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
15
.github/matchers/junit.json
vendored
Normal file
15
.github/matchers/junit.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "junit",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^## ([\\w./-]+):(\\d+): (.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"message": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
3
.github/pull_request_template.md
vendored
Normal file
3
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
## A quick checklist
|
||||
- If there's a existing issue, please link to it. If not, provide fill out the same information you would in a normal issue - reproduction steps for bugs, rationale for use-case.
|
||||
- If you're working on CraftOS, try to write a few test cases so we can ensure everything continues to work in the future. Tests live in `src/test/resources/test-rom/spec` and can be run with `./gradlew check`.
|
70
.github/workflows/main-ci.yml
vendored
Normal file
70
.github/workflows/main-ci.yml
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Java 8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 8
|
||||
|
||||
- name: Cache gradle dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- name: Disable Gradle daemon
|
||||
run: |
|
||||
mkdir -p ~/.gradle
|
||||
echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties
|
||||
|
||||
- name: Build with Gradle
|
||||
run: |
|
||||
./gradlew assemble || ./gradlew assemble
|
||||
./gradlew downloadAssets || ./gradlew downloadAssets
|
||||
xvfb-run ./gradlew build
|
||||
|
||||
- name: Upload Jar
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CC-Tweaked
|
||||
path: build/libs
|
||||
|
||||
- name: Upload Screnshots
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Screenshots
|
||||
path: test-files/client/screenshots
|
||||
if-no-files-found: ignore
|
||||
retention-days: 5
|
||||
if: failure()
|
||||
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v2
|
||||
|
||||
- name: Parse test reports
|
||||
run: ./tools/parse-reports.py
|
||||
if: ${{ failure() }}
|
||||
|
||||
- name: Cache pre-commit
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: ${{ runner.os }}-pre-commit-${{ hashFiles('config/pre-commit/config.yml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pre-commit-
|
||||
|
||||
- name: Run linters
|
||||
run: |
|
||||
pip install pre-commit
|
||||
pre-commit run --config config/pre-commit/config.yml --show-diff-on-failure --all --color=always
|
19
.github/workflows/make-doc.sh
vendored
Executable file
19
.github/workflows/make-doc.sh
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
|
||||
DEST="${GITHUB_REF#refs/*/}"
|
||||
echo "Uploading docs to https://tweaked.cc/$DEST"
|
||||
|
||||
# Setup ssh key
|
||||
mkdir -p "$HOME/.ssh/"
|
||||
echo "$SSH_KEY" > "$HOME/.ssh/key"
|
||||
chmod 600 "$HOME/.ssh/key"
|
||||
|
||||
# And upload
|
||||
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
|
||||
"$GITHUB_WORKSPACE/build/docs/lua/" \
|
||||
"$SSH_USER@$SSH_HOST:/$DEST"
|
||||
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
|
||||
"$GITHUB_WORKSPACE/build/docs/javadoc/" \
|
||||
"$SSH_USER@$SSH_HOST:/$DEST/javadoc"
|
50
.github/workflows/make-doc.yml
vendored
Normal file
50
.github/workflows/make-doc.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: Build documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- mc-1.16.x
|
||||
|
||||
jobs:
|
||||
make_doc:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Java 8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 8
|
||||
|
||||
- name: Cache gradle dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- name: Setup illuaminate
|
||||
run: |
|
||||
test -d bin || mkdir bin
|
||||
test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
|
||||
chmod +x bin/illuaminate
|
||||
|
||||
- name: Setup node
|
||||
run: npm ci
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew compileJava --no-daemon || ./gradlew compileJava --no-daemon
|
||||
|
||||
- name: Generate documentation
|
||||
run: ./gradlew docWebsite javadoc --no-daemon
|
||||
|
||||
- name: Upload documentation
|
||||
run: .github/workflows/make-doc.sh 2> /dev/null
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.SSH_KEY }}
|
||||
SSH_USER: ${{ secrets.SSH_USER }}
|
||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
||||
SSH_PORT: ${{ secrets.SSH_PORT }}
|
29
.gitignore
vendored
29
.gitignore
vendored
@@ -1,12 +1,29 @@
|
||||
build
|
||||
out
|
||||
run
|
||||
deploy
|
||||
# Build directories
|
||||
/classes
|
||||
/logs
|
||||
/build
|
||||
/out
|
||||
/doc/out/
|
||||
/node_modules
|
||||
|
||||
# Runtime directories
|
||||
/run
|
||||
/run-*
|
||||
/test-files
|
||||
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
.idea
|
||||
.gradle
|
||||
luaj-2.0.3/lib
|
||||
luaj-2.0.3/*.jar
|
||||
*.DS_Store
|
||||
|
||||
/.classpath
|
||||
/.project
|
||||
/.settings
|
||||
/.vscode
|
||||
bin/
|
||||
*.launch
|
||||
|
||||
/src/generated/resources/.cache
|
||||
/src/web/mount/*.d.ts
|
||||
|
22
.gitpod.yml
Normal file
22
.gitpod.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
image:
|
||||
file: config/gitpod/Dockerfile
|
||||
|
||||
ports:
|
||||
- port: 25565
|
||||
onOpen: notify
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- eamodio.gitlens
|
||||
- github.vscode-pull-request-github
|
||||
- ms-azuretools.vscode-docker
|
||||
- redhat.java
|
||||
- richardwillis.vscode-gradle
|
||||
- vscjava.vscode-java-debug
|
||||
- vscode.github
|
||||
|
||||
tasks:
|
||||
- name: Setup pre-commit hool
|
||||
init: pre-commit install --config config/pre-commit/config.yml --allow-missing-config
|
||||
- name: Install npm packages
|
||||
init: npm ci
|
14
.travis.yml
14
.travis.yml
@@ -1,14 +0,0 @@
|
||||
language: java
|
||||
|
||||
script: ./gradlew build --no-daemon
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/s
|
||||
|
||||
jdk:
|
||||
- oraclejdk8
|
115
CONTRIBUTING.md
Normal file
115
CONTRIBUTING.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Contributing to CC: Tweaked
|
||||
As with many open source projects, CC: Tweaked thrives on contributions from other people! This document (hopefully)
|
||||
provides an introduction as to how to get started in helping out.
|
||||
|
||||
If you've any other questions, [just ask the community][community] or [open an issue][new-issue].
|
||||
|
||||
## Reporting issues
|
||||
If you have a bug, suggestion, or other feedback, the best thing to do is [file an issue][new-issue]. When doing so,
|
||||
do use the issue templates - they provide a useful hint on what information to provide.
|
||||
|
||||
## Translations
|
||||
Translations are managed through [Weblate], an online interface for managing language strings. This is synced
|
||||
automatically with GitHub, so please don't submit PRs adding/changing translations!
|
||||
|
||||
## Developing
|
||||
In order to develop CC: Tweaked, you'll need to download the source code and then run it. This is a pretty simple
|
||||
process. When building on Windows, Use `gradlew.bat` instead of `./gradlew`.
|
||||
|
||||
- **Clone the repository:** `git clone https://github.com/cc-tweaked/CC-Tweaked.git && cd CC-Tweaked`
|
||||
- **Setup Forge:** `./gradlew build`
|
||||
- **Run Minecraft:** `./gradlew runClient` (or run the `GradleStart` class from your IDE).
|
||||
- **Optionally:** For small PRs (especially those only touching Lua code), it may be easier to use GitPod, which
|
||||
provides a pre-configured environment: [](https://gitpod.io/#https://github.com/cc-tweaked/CC-Tweaked/)
|
||||
|
||||
Do note you will need to download the mod after compiling to test.
|
||||
|
||||
If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` and copy the `.jar` from `build/libs`.
|
||||
These commands may take a few minutes to run the first time, as the environment is set up, but should be much faster
|
||||
afterwards.
|
||||
|
||||
The following sections describe the more niche sections of CC: Tweaked's build system. Some bits of these are
|
||||
quite-complex, and (dare I say) over-engineered, so you may wish to ignore them. Well tested/documented PRs are always
|
||||
preferred (and I'd definitely recommend setting up the tooling if you're doing serious development work), but for
|
||||
small changes it can be a lot.
|
||||
|
||||
### Code linters
|
||||
CC: Tweaked uses a couple of "linters" on its source code, to enforce a consistent style across the project. While these
|
||||
are run whenever you submit a PR, it's often useful to run this before committing.
|
||||
|
||||
- **[Checkstyle]:** Checks Java code to ensure it is consistently formatted. This can be run with `./gradlew build` or
|
||||
`./gradle check`.
|
||||
- **[illuaminate]:** Checks Lua code for semantic and styleistic issues. See [the usage section][illuaminate-usage] for
|
||||
how to download and run it. You may need to generate the Java documentation stubs (see "Documentation" below) for all
|
||||
lints to pass.
|
||||
|
||||
### Documentation
|
||||
When writing documentation for [CC: Tweaked's documentation website][docs], it may be useful to build the documentation
|
||||
and preview it yourself before submitting a PR.
|
||||
|
||||
Building all documentation is, sadly, a multi-stage process (though this is largely hidden by Gradle). First we need to
|
||||
convert Java doc-comments into Lua ones, we also generate some Javascript to embed. All of this is then finally fed into
|
||||
illuaminate, which spits out our HTML.
|
||||
|
||||
#### Setting up the tooling
|
||||
For various reasons, getting the environment set up to build documentation can be pretty complex. I'd quite like to
|
||||
automate this via Docker and/or nix in the future, but this needs to be done manually for now.
|
||||
|
||||
This tooling is only needed if you need to build the whole website. If you just want to generate the Lua stubs, you can
|
||||
skp this section.
|
||||
- Install Node/npm and install our Node packages with `npm ci`.
|
||||
- Install [illuaminate][illuaminate-usage] as described above.
|
||||
|
||||
#### Building documentation
|
||||
Gradle should be your entrypoint to building most documentation. There's two tasks which are of interest:
|
||||
|
||||
- `./gradlew luaJavadoc` - Generate documentation stubs for Java methods.
|
||||
- `./gradlew docWebsite` - Generate the whole website (including Javascript pages). The resulting HTML is stored at
|
||||
`./build/docs/lua/`.
|
||||
|
||||
#### Writing documentation
|
||||
illuaminate's documentation system is not currently documented (somewhat ironic), but is _largely_ the same as
|
||||
[ldoc][ldoc]. Documentation comments are written in Markdown,
|
||||
|
||||
Our markdown engine does _not_ support GitHub flavoured markdown, and so does not support all the features one might
|
||||
expect (such as tables). It is very much recommended that you build and preview the docs locally first.
|
||||
|
||||
### Testing
|
||||
Thankfully running tests is much simpler than running the documentation generator! `./gradlew check` will run the
|
||||
entire test suite (and some additional bits of verification).
|
||||
|
||||
Before we get into writing tests, it's worth mentioning the various test suites that CC: Tweaked has:
|
||||
- "Core" Java (`./src/test/java`): These test core bits of the mod which don't require any Minecraft interaction.
|
||||
This includes the `@LuaFunction` system, file system code, etc...
|
||||
|
||||
These tests are run by `./gradlew test`.
|
||||
|
||||
- CraftOS (`./src/test/resources/test-rom/`): These tests are written in Lua, and ensure the Lua environment, libraries
|
||||
and programs work as expected. These are (generally) written to be able to be run on emulators too, to provide some
|
||||
sort of compliance test.
|
||||
|
||||
These tests are run by the '"Core" Java' test suite, and so are also run with `./gradlew test`.
|
||||
|
||||
- In-game (`./src/testMod/java/dan200/computercraft/ingame/`): These tests are run on an actual Minecraft server and client,
|
||||
using [the same system Mojang do][mc-test]. The aim of these is to test in-game behaviour of blocks and peripherals.
|
||||
|
||||
These are run by `./gradlew testClient` and `./gradlew testServer`. You may want to run the client under `xvfb-run`
|
||||
or similar when running in a headless environment.
|
||||
|
||||
## CraftOS tests
|
||||
CraftOS's tests are written using a test system called "mcfly", heavily inspired by [busted] (and thus RSpec). Groups of
|
||||
tests go inside `describe` blocks, and a single test goes inside `it`.
|
||||
|
||||
Assertions are generally written using `expect` (inspired by Hamcrest and the like). For instance, `expect(foo):eq("bar")`
|
||||
asserts that your variable `foo` is equal to the expected value `"bar"`.
|
||||
|
||||
[new-issue]: https://github.com/cc-tweaked/CC-Tweaked/issues/new/choose "Create a new issue"
|
||||
[community]: README.md#Community "Get in touch with the community."
|
||||
[checkstyle]: https://checkstyle.org/
|
||||
[illuaminate]: https://github.com/SquidDev/illuaminate/ "Illuaminate on GitHub"
|
||||
[illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage "Installing Illuaminate"
|
||||
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/ "CC: Tweaked weblate instance"
|
||||
[docs]: https://tweaked.cc/ "CC: Tweaked documentation"
|
||||
[ldoc]: http://stevedonovan.github.io/ldoc/ "ldoc, a Lua documentation generator."
|
||||
[mc-test]: https://www.youtube.com/watch?v=vXaWOJTCYNg
|
||||
[busted]: https://github.com/Olivine-Labs/busted "busted: Elegant Lua unit testing."
|
14
LICENSE
14
LICENSE
@@ -19,14 +19,14 @@ Mod: The mod code designated by the present license, in source form, binary
|
||||
form, as obtained standalone, as part of a wider distribution or resulting from
|
||||
the compilation of the original or modified sources.
|
||||
|
||||
Dependency: Code required for the mod to work properly. This includes
|
||||
Dependency: Code required for the mod to work properly. This includes
|
||||
dependencies required to compile the code as well as any file or modification
|
||||
that is explicitly or implicitly required for the mod to be working.
|
||||
|
||||
1. Scope
|
||||
--------
|
||||
|
||||
The present license is granted to any user of the mod. As a prerequisite,
|
||||
The present license is granted to any user of the mod. As a prerequisite,
|
||||
a user must own a legally acquired copy of Minecraft
|
||||
|
||||
2. Liability
|
||||
@@ -41,13 +41,13 @@ or misuse of this mod fall on the user.
|
||||
3. Play rights
|
||||
--------------
|
||||
|
||||
The user is allowed to install this mod on a Minecraft client or server and to play
|
||||
The user is allowed to install this mod on a Minecraft client or server and to play
|
||||
without restriction.
|
||||
|
||||
4. Modification rights
|
||||
----------------------
|
||||
|
||||
The user has the right to decompile the source code, look at either the
|
||||
The user has the right to decompile the source code, look at either the
|
||||
decompiled version or the original source code, and to modify it.
|
||||
|
||||
5. Distribution of original or modified copy rights
|
||||
@@ -61,10 +61,10 @@ include:
|
||||
- patch to its source or binary files
|
||||
- any copy of a portion of its binary source files
|
||||
|
||||
The user is allowed to redistribute this mod partially, in totality, or
|
||||
The user is allowed to redistribute this mod partially, in totality, or
|
||||
included in a distribution.
|
||||
|
||||
When distributing binary files, the user must provide means to obtain its
|
||||
When distributing binary files, the user must provide means to obtain its
|
||||
entire set of sources or modified sources at no cost.
|
||||
|
||||
All distributions of this mod must remain licensed under the CCPL.
|
||||
@@ -92,7 +92,7 @@ must be made available at no cost and remain licensed under the CCPL.
|
||||
---------------
|
||||
|
||||
If you choose to contribute code or assets to be included in this mod, you
|
||||
agree that, if added to to the main repository at
|
||||
agree that, if added to to the main repository at
|
||||
https://github.com/dan200/ComputerCraft, your contributions will be covered by
|
||||
this license, and that Daniel Ratcliffe will retain the right to re-license the
|
||||
mod, including your contributions, in part or in whole, under other licenses.
|
||||
|
19
LICENSE-luaj
19
LICENSE-luaj
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2007 LuaJ. All rights reserved.
|
||||
|
||||
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.
|
72
README.md
72
README.md
@@ -1,31 +1,53 @@
|
||||
# CC: Tweaked
|
||||
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked)
|
||||
# 
|
||||
[](https://github.com/cc-tweaked/CC-Tweaked/actions "Current build status") [][CurseForge]
|
||||
|
||||
CC: Tweaked is a fork of ComputerCraft which aims to provide more earlier access to the more experimental and
|
||||
in-development features of the mod. For a more stable experience, I recommend checking out the
|
||||
[original mod](https://github.com/dan200/ComputerCraft).
|
||||
CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the
|
||||
much-beloved [ComputerCraft], it continues its legacy with better performance, stability, and a wealth of new features.
|
||||
|
||||
## What?
|
||||
CC: Tweaked does not aim to create a competing fork of ComputerCraft, nor am I planning to take it in in a vastly
|
||||
different direction to the original mod. In fact, CC: Tweaked aims to be a nurturing ground for various features, with
|
||||
a pull request against the original mod being the end goal.
|
||||
|
||||
CC: Tweaked also includes many pull requests from the community which have not yet been merged, offering a large number
|
||||
of additional bug fixes and features over the original mod.
|
||||
|
||||
## Relation to CCTweaks?
|
||||
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. However, I do plan
|
||||
to migrate some features of CCTweaks into CC: Tweaked.
|
||||
CC: Tweaked can be installed from [CurseForge] or [Modrinth]. It requires the [Minecraft Forge][forge] mod loader, but
|
||||
[versions are available for Fabric][ccrestitched].
|
||||
|
||||
## Contributing
|
||||
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you do wish to contribute
|
||||
code, do consider submitting it to the ComputerCraft repository instead.
|
||||
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you want to get started
|
||||
developing the mod, [check out the instructions here](CONTRIBUTING.md#developing).
|
||||
|
||||
That being said, in order to start helping develop CC: Tweaked, you'll need to follow these steps:
|
||||
## Community
|
||||
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about
|
||||
ComputerCraft we have a [forum](https://forums.computercraft.cc/) and [Discord guild](https://discord.computercraft.cc)!
|
||||
There's also a fairly populated, albeit quiet [IRC channel](http://webchat.esper.net/?channels=computercraft), if that's
|
||||
more your cup of tea.
|
||||
|
||||
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
|
||||
- **Setup Forge:** `./gradlew setupDecompWorkspace`
|
||||
- **Test your changes:** `./gradlew runClient` (or run the `GradleStart` class from your IDE).
|
||||
|
||||
If you want to run CC: Tweaked in a normal Minecraft instance, run `./gradlew build` and copy the `.jar` from
|
||||
`build/libs`.
|
||||
We also host fairly comprehensive documentation at [tweaked.cc](https://tweaked.cc/ "The CC: Tweaked website").
|
||||
|
||||
## Using
|
||||
CC: Tweaked is hosted on my maven repo, and so is relatively simple to depend on. You may wish to add a soft (or hard)
|
||||
dependency in your `mods.toml` file, with the appropriate version bounds, to ensure that API functionality you depend
|
||||
on is present.
|
||||
|
||||
```groovy
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://squiddev.cc/maven/'
|
||||
content {
|
||||
includeGroup 'org.squiddev'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fg.deobf("org.squiddev:cc-tweaked-${mc_version}:${cct_version}")
|
||||
}
|
||||
```
|
||||
|
||||
You should also be careful to only use classes within the `dan200.computercraft.api` package. Non-API classes are
|
||||
subject to change at any point. If you depend on functionality outside the API, file an issue, and we can look into
|
||||
exposing more features.
|
||||
|
||||
We bundle the API sources with the jar, so documentation should be easily viewable within your editor. Alternatively,
|
||||
the generated documentation [can be browsed online](https://tweaked.cc/javadoc/).
|
||||
|
||||
[computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
|
||||
[curseforge]: https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked from CurseForge"
|
||||
[modrinth]: https://modrinth.com/mod/gu7yAYhd "Download CC: Tweaked from Modrinth"
|
||||
[forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
|
||||
[ccrestitched]: https://www.curseforge.com/minecraft/mc-mods/cc-restitched "Download CC: Restitched from CurseForge"
|
||||
|
586
build.gradle
586
build.gradle
@@ -1,125 +1,573 @@
|
||||
|
||||
// For those who want the bleeding edge
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
name = "forge"
|
||||
url = "http://files.minecraftforge.net/maven"
|
||||
}
|
||||
mavenCentral()
|
||||
maven { url = "https://maven.minecraftforge.net" }
|
||||
maven { url = 'https://maven.parchmentmc.org' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||
classpath 'org.ajoberstar:gradle-git:1.6.0'
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:5.1.+'
|
||||
classpath "org.spongepowered:mixingradle:0.7.+"
|
||||
classpath 'org.parchmentmc:librarian:1.+'
|
||||
}
|
||||
}
|
||||
apply plugin: 'net.minecraftforge.gradle.forge'
|
||||
apply plugin: 'org.ajoberstar.grgit'
|
||||
|
||||
/*
|
||||
// for people who want stable - not yet functional for MC 1.8.8 - we require the forgegradle 2.1 snapshot
|
||||
plugins {
|
||||
id "net.minecraftforge.gradle.forge" version "2.0.2"
|
||||
id "checkstyle"
|
||||
id "jacoco"
|
||||
id "maven-publish"
|
||||
id "com.github.hierynomus.license" version "0.16.1"
|
||||
id "com.matthewprenger.cursegradle" version "1.4.0"
|
||||
id "com.github.breadmoirai.github-release" version "2.2.12"
|
||||
id "org.jetbrains.kotlin.jvm" version "1.6.0"
|
||||
id "com.modrinth.minotaur" version "1.2.1"
|
||||
}
|
||||
*/
|
||||
|
||||
version = "1.80pr1.1"
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
apply plugin: "org.spongepowered.mixin"
|
||||
apply plugin: 'org.parchmentmc.librarian.forgegradle'
|
||||
|
||||
version = mod_version
|
||||
|
||||
group = "org.squiddev"
|
||||
archivesBaseName = "cc-tweaked"
|
||||
archivesBaseName = "cc-tweaked-${mc_version}"
|
||||
|
||||
def javaVersion = JavaLanguageVersion.of(8)
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = javaVersion
|
||||
}
|
||||
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
tasks.withType(JavaExec).configureEach {
|
||||
javaLauncher = javaToolchains.launcherFor {
|
||||
languageVersion = javaVersion
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.resources {
|
||||
srcDir 'src/generated/resources'
|
||||
}
|
||||
|
||||
testMod {}
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = "1.12-14.21.1.2387"
|
||||
runDir = "run"
|
||||
replace '${version}', project.version
|
||||
runs {
|
||||
all {
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
// the mappings can be changed at any time, and must be in the following format.
|
||||
// snapshot_YYYYMMDD snapshot are built nightly.
|
||||
// stable_# stables are built at the discretion of the MCP team.
|
||||
// Use non-default mappings at your own risk. they may not allways work.
|
||||
// simply re-run your setup task after changing the mappings to update your workspace.
|
||||
mappings = "snapshot_20170629"
|
||||
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||
mods {
|
||||
computercraft {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
|
||||
arg "-mixin.config=computercraft.mixins.json"
|
||||
}
|
||||
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
}
|
||||
|
||||
server {
|
||||
workingDirectory project.file("run/server")
|
||||
arg "--nogui"
|
||||
}
|
||||
|
||||
data {
|
||||
workingDirectory project.file('run')
|
||||
args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
||||
}
|
||||
|
||||
testClient {
|
||||
workingDirectory project.file('test-files/client')
|
||||
parent runs.client
|
||||
|
||||
mods {
|
||||
cctest {
|
||||
source sourceSets.testMod
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testServer {
|
||||
workingDirectory project.file('test-files/server')
|
||||
parent runs.server
|
||||
|
||||
mods {
|
||||
cctest {
|
||||
source sourceSets.testMod
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
|
||||
|
||||
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
|
||||
}
|
||||
|
||||
mixin {
|
||||
add sourceSets.main, 'computercraft.mixins.refmap.json'
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "JEI"
|
||||
url = "http://dvs1.progwml6.com/files/maven"
|
||||
}
|
||||
maven {
|
||||
name = "squiddev"
|
||||
url = "https://dl.bintray.com/squiddev/maven"
|
||||
name "SquidDev"
|
||||
url "https://squiddev.cc/maven"
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
shade
|
||||
compile.extendsFrom shade
|
||||
implementation.extendsFrom shade
|
||||
cctJavadoc
|
||||
|
||||
testModImplementation.extendsFrom(implementation)
|
||||
testModImplementation.extendsFrom(testImplementation)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
deobfProvided "mezz.jei:jei_1.12:4.7.5.86:api"
|
||||
runtime "mezz.jei:jei_1.12:4.7.5.86"
|
||||
shade 'org.squiddev:Cobalt:0.3.0'
|
||||
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
|
||||
|
||||
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
||||
annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
|
||||
|
||||
compileOnly fg.deobf("mezz.jei:jei-1.16.5:7.7.0.104:api")
|
||||
compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.16.5:7.1.0.313")
|
||||
compileOnly fg.deobf("commoble.morered:morered-1.16.5:2.1.1.0")
|
||||
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-1.16.5:7.7.0.104")
|
||||
|
||||
shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT'
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
|
||||
testImplementation 'org.hamcrest:hamcrest:2.2'
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0'
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-reflect:1.6.0'
|
||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
|
||||
|
||||
testModImplementation sourceSets.main.output
|
||||
|
||||
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.5'
|
||||
}
|
||||
|
||||
// Compile tasks
|
||||
|
||||
compileTestModJava {
|
||||
dependsOn(compileJava)
|
||||
}
|
||||
|
||||
javadoc {
|
||||
include "dan200/computercraft/api/**/*.java"
|
||||
}
|
||||
|
||||
jar {
|
||||
dependsOn javadoc
|
||||
task luaJavadoc(type: Javadoc) {
|
||||
description "Generates documentation for Java-side Lua functions."
|
||||
group "documentation"
|
||||
|
||||
manifest {
|
||||
attributes('FMLAT': 'computercraft_at.cfg')
|
||||
source = sourceSets.main.allJava
|
||||
destinationDir = file("${project.docsDir}/luaJavadoc")
|
||||
classpath = sourceSets.main.compileClasspath
|
||||
|
||||
options.docletpath = configurations.cctJavadoc.files as List
|
||||
options.doclet = "cc.tweaked.javadoc.LuaDoclet"
|
||||
options.noTimestamp = false
|
||||
|
||||
javadocTool = javaToolchains.javadocToolFor {
|
||||
languageVersion = JavaLanguageVersion.of(11)
|
||||
}
|
||||
}
|
||||
|
||||
into("docs", { from (javadoc.destinationDir) })
|
||||
|
||||
into("api", { from (sourceSets.main.allSource) {
|
||||
include "dan200/computercraft/api/**/*.java"
|
||||
}})
|
||||
jar {
|
||||
manifest {
|
||||
attributes([
|
||||
"Specification-Title" : "computercraft",
|
||||
"Specification-Vendor" : "SquidDev",
|
||||
"Specification-Version" : "1",
|
||||
"Implementation-Title" : "CC: Tweaked",
|
||||
"Implementation-Version" : "${mod_version}",
|
||||
"Implementation-Vendor" : "SquidDev",
|
||||
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||
"MixinConfigs" : "computercraft.mixins.json",
|
||||
])
|
||||
}
|
||||
|
||||
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
|
||||
import org.ajoberstar.grgit.Grgit
|
||||
[compileJava, compileTestJava, compileTestModJava].forEach {
|
||||
it.configure {
|
||||
options.compilerArgs << "-Xlint" << "-Xlint:-processing"
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
inputs.property "mcversion", project.minecraft.version
|
||||
inputs.property "version", mod_version
|
||||
inputs.property "mcversion", mc_version
|
||||
|
||||
def grgit = Grgit.open(dir: '.')
|
||||
inputs.property "commithash", grgit.head().id
|
||||
|
||||
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
|
||||
def hash = 'none'
|
||||
Set<String> contributors = []
|
||||
try {
|
||||
hash = ["git", "-C", projectDir, "rev-parse", "HEAD"].execute().text.trim()
|
||||
|
||||
grgit.log().each {
|
||||
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
|
||||
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
|
||||
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
|
||||
["git", "-C", projectDir, "log", "--format=tformat:%an%n%cn"].execute().text.split('\n').each {
|
||||
if (!blacklist.contains(it)) contributors.add(it)
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
inputs.property "commithash", hash
|
||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'META-INF/mods.toml'
|
||||
include 'data/computercraft/lua/rom/help/credits.txt'
|
||||
|
||||
expand 'version': mod_version,
|
||||
'mcversion': mc_version,
|
||||
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
|
||||
}
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'mcmod.info'
|
||||
include 'assets/computercraft/lua/rom/help/credits.txt'
|
||||
|
||||
expand 'version':project.version,
|
||||
'mcversion':project.minecraft.version,
|
||||
'gitcontributors':contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
|
||||
exclude 'META-INF/mods.toml'
|
||||
exclude 'data/computercraft/lua/rom/help/credits.txt'
|
||||
}
|
||||
}
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
exclude 'assets/computercraft/lua/rom/help/credits.txt'
|
||||
sourcesJar {
|
||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||
}
|
||||
|
||||
// Web tasks
|
||||
|
||||
|
||||
import com.hierynomus.gradle.license.tasks.LicenseCheck
|
||||
import com.hierynomus.gradle.license.tasks.LicenseFormat
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
List<String> mkCommand(String command) {
|
||||
return Os.isFamily(Os.FAMILY_WINDOWS) ? ["cmd", "/c", command] : ["sh", "-c", command]
|
||||
}
|
||||
|
||||
task rollup(type: Exec) {
|
||||
group = "build"
|
||||
description = "Bundles JS into rollup"
|
||||
|
||||
inputs.files(fileTree("src/web")).withPropertyName("sources")
|
||||
inputs.file("package-lock.json").withPropertyName("package-lock.json")
|
||||
inputs.file("tsconfig.json").withPropertyName("Typescript config")
|
||||
inputs.file("rollup.config.js").withPropertyName("Rollup config")
|
||||
outputs.file("$buildDir/rollup/index.js").withPropertyName("output")
|
||||
|
||||
commandLine mkCommand('"node_modules/.bin/rollup" --config rollup.config.js')
|
||||
}
|
||||
|
||||
task illuaminateDocs(type: Exec, dependsOn: [rollup, luaJavadoc]) {
|
||||
group = "build"
|
||||
description = "Bundles JS into rollup"
|
||||
|
||||
inputs.files(fileTree("doc")).withPropertyName("docs")
|
||||
inputs.files(fileTree("src/main/resources/data/computercraft/lua/rom")).withPropertyName("lua rom")
|
||||
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
|
||||
inputs.dir("$buildDir/docs/luaJavadoc")
|
||||
inputs.file("$buildDir/rollup/index.js").withPropertyName("scripts")
|
||||
inputs.file("src/web/styles.css").withPropertyName("styles")
|
||||
outputs.dir("$buildDir/docs/lua")
|
||||
|
||||
commandLine mkCommand('"bin/illuaminate" doc-gen')
|
||||
}
|
||||
|
||||
task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
|
||||
from('doc') {
|
||||
include 'logo.png'
|
||||
include 'images/**'
|
||||
}
|
||||
from("$buildDir/rollup") {
|
||||
exclude 'index.js'
|
||||
}
|
||||
into "${project.docsDir}/lua"
|
||||
}
|
||||
|
||||
// Check tasks
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events "skipped", "failed"
|
||||
}
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
dependsOn('test')
|
||||
reports {
|
||||
xml.required = true
|
||||
html.required = true
|
||||
}
|
||||
}
|
||||
|
||||
check.dependsOn jacocoTestReport
|
||||
|
||||
license {
|
||||
mapping("java", "SLASHSTAR_STYLE")
|
||||
strictCheck true
|
||||
|
||||
ext.year = Calendar.getInstance().get(Calendar.YEAR)
|
||||
}
|
||||
|
||||
[licenseMain, licenseFormatMain].forEach {
|
||||
it.configure {
|
||||
include("**/*.java")
|
||||
exclude("dan200/computercraft/api/**")
|
||||
header file('config/license/main.txt')
|
||||
}
|
||||
}
|
||||
|
||||
[licenseTest, licenseFormatTest, licenseTestMod, licenseFormatTestMod].forEach {
|
||||
it.configure {
|
||||
include("**/*.java")
|
||||
header file('config/license/main.txt')
|
||||
}
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << "-Xlint"
|
||||
tasks.withType(LicenseFormat) {
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
}
|
||||
|
||||
runClient.outputs.upToDateWhen { false }
|
||||
runServer.outputs.upToDateWhen { false }
|
||||
|
||||
task licenseAPI(type: LicenseCheck)
|
||||
task licenseFormatAPI(type: LicenseFormat)
|
||||
[licenseAPI, licenseFormatAPI].forEach {
|
||||
it.configure {
|
||||
source = sourceSets.main.java
|
||||
include("dan200/computercraft/api/**")
|
||||
header file('config/license/api.txt')
|
||||
}
|
||||
}
|
||||
|
||||
task setupServer(type: Copy) {
|
||||
group "test server"
|
||||
description "Sets up the environment for the test server."
|
||||
|
||||
from("src/testMod/server-files") {
|
||||
include "eula.txt"
|
||||
include "server.properties"
|
||||
}
|
||||
into "test-files/server"
|
||||
}
|
||||
|
||||
["Client", "Server"].forEach { name ->
|
||||
tasks.register("test$name", JavaExec.class).configure {
|
||||
it.group('In-game tests')
|
||||
it.description("Runs tests on a temporary Minecraft instance.")
|
||||
it.dependsOn(setupServer, "prepareRunTest$name", "cleanTest$name", 'compileTestModJava')
|
||||
|
||||
// Copy from runTestServer. We do it in this slightly odd way as runTestServer
|
||||
// isn't created until the task is configured (which is no good for us).
|
||||
JavaExec exec = tasks.getByName("runTest$name")
|
||||
exec.copyTo(it)
|
||||
it.setClasspath(exec.getClasspath())
|
||||
it.mainClass = exec.mainClass
|
||||
it.setArgs(exec.getArgs())
|
||||
|
||||
it.systemProperty('forge.logging.console.level', 'info')
|
||||
it.systemProperty('cctest.run', 'true')
|
||||
|
||||
// Jacoco and modlauncher don't play well together as the classes loaded in-game don't
|
||||
// match up with those written to disk. We get Jacoco to dump all classes to disk, and
|
||||
// use that when generating the report.
|
||||
def coverageOut = new File(buildDir, "jacocoClassDump/test$name")
|
||||
jacoco.applyTo(it)
|
||||
it.jacoco.setIncludes(["dan200.computercraft.*"])
|
||||
it.jacoco.setClassDumpDir(coverageOut)
|
||||
it.outputs.dir(coverageOut)
|
||||
// Older versions of modlauncher don't include a protection domain (and thus no code
|
||||
// source). Jacoco skips such classes by default, so we need to explicitly include them.
|
||||
it.jacoco.setIncludeNoLocationClasses(true)
|
||||
}
|
||||
|
||||
tasks.register("jacocoTest${name}Report", JacocoReport.class).configure {
|
||||
it.group('In-game')
|
||||
it.description("Generate coverage reports for test$name")
|
||||
it.dependsOn("test$name")
|
||||
|
||||
it.executionData(new File(buildDir, "jacoco/test${name}.exec"))
|
||||
it.sourceDirectories.from(sourceSets.main.allJava.srcDirs)
|
||||
it.classDirectories.from(new File(buildDir, "jacocoClassDump/test$name"))
|
||||
|
||||
it.reports {
|
||||
xml.enabled true
|
||||
html.enabled true
|
||||
}
|
||||
}
|
||||
|
||||
if (name != "Client" || project.findProperty('cc.tweaked.clientTests') == 'true') {
|
||||
// Don't run client tests unless explicitly opted into them. They're a bit of a faff
|
||||
// to run and pretty flakey.
|
||||
check.dependsOn("jacocoTest${name}Report")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Upload tasks
|
||||
|
||||
task checkRelease {
|
||||
group "upload"
|
||||
description "Verifies that everything is ready for a release"
|
||||
|
||||
inputs.property "version", mod_version
|
||||
inputs.file("src/main/resources/data/computercraft/lua/rom/help/changelog.md")
|
||||
inputs.file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
|
||||
|
||||
doLast {
|
||||
def ok = true
|
||||
|
||||
// Check we're targetting the current version
|
||||
def whatsnew = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md").readLines()
|
||||
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
|
||||
ok = false
|
||||
project.logger.error("Expected `whatsnew.md' to target $mod_version.")
|
||||
}
|
||||
|
||||
// Check "read more" exists and trim it
|
||||
def idx = whatsnew.findIndexOf { it == 'Type "help changelog" to see the full version history.' }
|
||||
if (idx == -1) {
|
||||
ok = false
|
||||
project.logger.error("Must mention the changelog in whatsnew.md")
|
||||
} else {
|
||||
whatsnew = whatsnew.getAt(0..<idx)
|
||||
}
|
||||
|
||||
// Check whatsnew and changelog match.
|
||||
def versionChangelog = "# " + whatsnew.join("\n")
|
||||
def changelog = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/changelog.md").getText()
|
||||
if (!changelog.startsWith(versionChangelog)) {
|
||||
ok = false
|
||||
project.logger.error("whatsnew and changelog are not in sync")
|
||||
}
|
||||
|
||||
if (!ok) throw new IllegalStateException("Could not check release")
|
||||
}
|
||||
}
|
||||
check.dependsOn checkRelease
|
||||
|
||||
curseforge {
|
||||
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
||||
project {
|
||||
id = '282001'
|
||||
releaseType = 'release'
|
||||
changelog = "Release notes can be found on the GitHub repository (https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
|
||||
|
||||
addGameVersion "${mc_version}"
|
||||
}
|
||||
}
|
||||
|
||||
import com.modrinth.minotaur.TaskModrinthUpload
|
||||
tasks.register('publishModrinth', TaskModrinthUpload.class).configure {
|
||||
dependsOn('assemble', 'reobfJar')
|
||||
onlyIf {
|
||||
project.hasProperty('modrinthApiKey')
|
||||
}
|
||||
|
||||
token = project.hasProperty('modrinthApiKey') ? project.getProperty('modrinthApiKey') : ''
|
||||
projectId = 'gu7yAYhd'
|
||||
versionNumber = "${project.mc_version}-${project.mod_version}"
|
||||
uploadFile = jar
|
||||
addGameVersion(project.mc_version)
|
||||
changelog = "Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
|
||||
addLoader('forge')
|
||||
}
|
||||
|
||||
tasks.withType(GenerateModuleMetadata) {
|
||||
// We can't generate metadata as that includes Forge as a dependency.
|
||||
enabled = false
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
from components.java
|
||||
|
||||
pom {
|
||||
name = 'CC: Tweaked'
|
||||
description = 'CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.'
|
||||
url = 'https://github.com/cc-tweaked/CC-Tweaked'
|
||||
|
||||
scm {
|
||||
url = 'https://github.com/cc-tweaked/CC-Tweaked.git'
|
||||
}
|
||||
|
||||
issueManagement {
|
||||
system = 'github'
|
||||
url = 'https://github.com/cc-tweaked/CC-Tweaked/issues'
|
||||
}
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name = 'ComputerCraft Public License, Version 1.0'
|
||||
url = 'https://github.com/cc-tweaked/CC-Tweaked/blob/mc-1.15.x/LICENSE'
|
||||
}
|
||||
}
|
||||
|
||||
withXml { asNode().remove(asNode().get("dependencies")) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
if (project.hasProperty("mavenUser")) {
|
||||
maven {
|
||||
name = "SquidDev"
|
||||
url = "https://squiddev.cc/maven"
|
||||
credentials {
|
||||
username = project.property("mavenUser") as String
|
||||
password = project.property("mavenPass") as String
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
githubRelease {
|
||||
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
|
||||
owner 'cc-tweaked'
|
||||
repo 'CC-Tweaked'
|
||||
targetCommitish.set(project.provider({
|
||||
try {
|
||||
return ["git", "-C", projectDir, "rev-parse", "--abbrev-ref", "HEAD"].execute().text.trim()
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return "master"
|
||||
}))
|
||||
|
||||
tagName "v${mc_version}-${mod_version}"
|
||||
releaseName "[${mc_version}] ${mod_version}"
|
||||
body.set(project.provider({
|
||||
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
|
||||
.readLines()
|
||||
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
|
||||
.join("\n").trim()
|
||||
}))
|
||||
prerelease false
|
||||
}
|
||||
|
||||
def uploadTasks = ["publish", "curseforge", "publishModrinth", "githubRelease"]
|
||||
uploadTasks.forEach { tasks.getByName(it).dependsOn checkRelease }
|
||||
|
||||
task uploadAll(dependsOn: uploadTasks) {
|
||||
group "upload"
|
||||
description "Uploads to all repositories (Maven, Curse, Modrinth, GitHub release)"
|
||||
}
|
||||
|
@@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
cd luaj-2.0.3
|
||||
echo "Building LuaJ..."
|
||||
ant clean
|
||||
ant
|
||||
|
||||
echo "Copying output to libs..."
|
||||
rm ../libs/luaj-jse-2.0.3.jar
|
||||
cp luaj-jse-2.0.3.jar ../libs
|
||||
|
||||
echo "Done."
|
||||
cd ..
|
10
codesize.sh
10
codesize.sh
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
echo "Java code:"
|
||||
cat `find src | grep \\.java$` | wc
|
||||
|
||||
echo "Lua code:"
|
||||
cat `find src/main/resources/assets/computercraft/lua | grep \\.lua$` | wc
|
||||
|
||||
echo "JSON:"
|
||||
cat `find src/main/resources/assets/computercraft | grep \\.json$` | wc
|
||||
|
168
config/checkstyle/checkstyle.xml
Normal file
168
config/checkstyle/checkstyle.xml
Normal file
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
<module name="Checker">
|
||||
<property name="tabWidth" value="4"/>
|
||||
<property name="charset" value="UTF-8" />
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${config_loc}/suppressions.xml" />
|
||||
</module>
|
||||
|
||||
<module name="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value="render_old"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!-- Annotations -->
|
||||
<module name="AnnotationLocation" />
|
||||
<module name="AnnotationUseStyle" />
|
||||
<module name="MissingDeprecated" />
|
||||
<module name="MissingOverride" />
|
||||
|
||||
<!-- Blocks -->
|
||||
<module name="EmptyBlock" />
|
||||
<module name="EmptyCatchBlock">
|
||||
<property name="exceptionVariableName" value="ignored" />
|
||||
</module>
|
||||
<module name="LeftCurly">
|
||||
<property name="option" value="nl" />
|
||||
<!-- The defaults, minus lambdas. -->
|
||||
<property name="tokens" value="ANNOTATION_DEF,CLASS_DEF,CTOR_DEF,ENUM_CONSTANT_DEF,ENUM_DEF,INTERFACE_DEF,LITERAL_CASE,LITERAL_CATCH,LITERAL_DEFAULT,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,METHOD_DEF,OBJBLOCK,STATIC_INIT" />
|
||||
</module>
|
||||
<module name="NeedBraces">
|
||||
<property name="allowSingleLineStatement" value="true"/>
|
||||
</module>
|
||||
<module name="RightCurly">
|
||||
<property name="option" value="alone" />
|
||||
</module>
|
||||
|
||||
<!-- Class design. As if we've ever followed good practice here. -->
|
||||
<module name="FinalClass" />
|
||||
<module name="InterfaceIsType" />
|
||||
<module name="MutableException" />
|
||||
<module name="OneTopLevelClass" />
|
||||
|
||||
<!-- Coding -->
|
||||
<module name="ArrayTrailingComma" />
|
||||
<module name="EqualsHashCode" />
|
||||
<!-- FallThrough does not handle unreachable code well -->
|
||||
<module name="IllegalInstantiation" />
|
||||
<module name="IllegalThrows" />
|
||||
<module name="ModifiedControlVariable" />
|
||||
<module name="NoClone" />
|
||||
<module name="NoFinalizer" />
|
||||
<module name="OneStatementPerLine" />
|
||||
<module name="PackageDeclaration" />
|
||||
<module name="SimplifyBooleanExpression" />
|
||||
<module name="SimplifyBooleanReturn" />
|
||||
<module name="StringLiteralEquality" />
|
||||
<module name="UnnecessaryParentheses" />
|
||||
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
|
||||
<module name="UnnecessarySemicolonInTryWithResources" />
|
||||
<module name="UnnecessarySemicolonInEnumeration" />
|
||||
|
||||
<!-- Imports -->
|
||||
<module name="CustomImportOrder" />
|
||||
<module name="IllegalImport" />
|
||||
<module name="RedundantImport" />
|
||||
<module name="UnusedImports" />
|
||||
|
||||
<!-- Javadoc -->
|
||||
<!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
|
||||
<module name="AtclauseOrder" />
|
||||
<module name="InvalidJavadocPosition" />
|
||||
<module name="JavadocBlockTagLocation" />
|
||||
<module name="JavadocMethod"/>
|
||||
<module name="JavadocType"/>
|
||||
<module name="JavadocStyle" />
|
||||
<module name="NonEmptyAtclauseDescription" />
|
||||
<module name="SingleLineJavadoc" />
|
||||
<module name="SummaryJavadocCheck"/>
|
||||
|
||||
<!-- Misc -->
|
||||
<module name="ArrayTypeStyle" />
|
||||
<module name="CommentsIndentation" />
|
||||
<module name="Indentation" />
|
||||
<module name="OuterTypeFilename" />
|
||||
|
||||
<!-- Modifiers -->
|
||||
<module name="ModifierOrder" />
|
||||
<module name="RedundantModifier" />
|
||||
|
||||
<!-- Naming -->
|
||||
<module name="ClassTypeParameterName" />
|
||||
<module name="InterfaceTypeParameterName" />
|
||||
<module name="LambdaParameterName" />
|
||||
<module name="LocalFinalVariableName" />
|
||||
<module name="LocalVariableName" />
|
||||
<module name="MemberName" />
|
||||
<module name="MethodName" />
|
||||
<module name="MethodTypeParameterName" />
|
||||
<module name="PackageName">
|
||||
<property name="format" value="^dan200\.computercraft(\.[a-z][a-z0-9]*)*" />
|
||||
</module>
|
||||
<module name="ParameterName" />
|
||||
<module name="StaticVariableName">
|
||||
<property name="format" value="^[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z_]+)?$" />
|
||||
<property name="applyToPrivate" value="false" />
|
||||
</module>
|
||||
<module name="StaticVariableName">
|
||||
<property name="format" value="^(s_)?[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z_]+)?$" />
|
||||
<property name="applyToPrivate" value="true" />
|
||||
</module>
|
||||
<module name="TypeName" />
|
||||
|
||||
<!-- Whitespace -->
|
||||
<module name="EmptyForInitializerPad"/>
|
||||
<module name="EmptyForIteratorPad">
|
||||
<property name="option" value="space"/>
|
||||
</module>
|
||||
<module name="GenericWhitespace" />
|
||||
<module name="MethodParamPad" />
|
||||
<module name="NoLineWrap" />
|
||||
<module name="NoWhitespaceAfter">
|
||||
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP" />
|
||||
</module>
|
||||
<module name="NoWhitespaceBefore" />
|
||||
<!-- TODO: Decide on an OperatorWrap style. -->
|
||||
<module name="ParenPad">
|
||||
<property name="option" value="space" />
|
||||
<property name="tokens" value="ANNOTATION,ANNOTATION_FIELD_DEF,CTOR_CALL,CTOR_DEF,ENUM_CONSTANT_DEF,LITERAL_CATCH,LITERAL_DO,LITERAL_FOR,LITERAL_IF,LITERAL_NEW,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_WHILE,METHOD_CALL,METHOD_DEF,RESOURCE_SPECIFICATION,SUPER_CTOR_CALL,LAMBDA" />
|
||||
</module>
|
||||
<module name="ParenPad">
|
||||
<property name="option" value="nospace" />
|
||||
<property name="tokens" value="DOT,EXPR,QUESTION" />
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="option" value="eol" />
|
||||
<property name="tokens" value="COMMA,SEMI,ELLIPSIS,ARRAY_DECLARATOR,RBRACK,METHOD_REF" />
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="option" value="nl" />
|
||||
<property name="tokens" value="DOT,AT" />
|
||||
</module>
|
||||
<module name="SingleSpaceSeparator" />
|
||||
<module name="TypecastParenPad" />
|
||||
<module name="WhitespaceAfter">
|
||||
<property name="tokens" value="COMMA" />
|
||||
</module>
|
||||
<module name="WhitespaceAround">
|
||||
<property name="ignoreEnhancedForColon" value="false" />
|
||||
<!-- Allow empty functions -->
|
||||
<property name="allowEmptyLambdas" value="true" />
|
||||
<property name="allowEmptyMethods" value="true" />
|
||||
<property name="allowEmptyConstructors" value="true" />
|
||||
|
||||
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_RETURN,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND" />
|
||||
</module>
|
||||
</module>
|
||||
|
||||
<module name="FileTabCharacter" />
|
||||
<module name="NewlineAtEndOfFile" />
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="message" value="Trailing whitespace"/>
|
||||
</module>
|
||||
</module>
|
12
config/checkstyle/suppressions.xml
Normal file
12
config/checkstyle/suppressions.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
|
||||
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||
<suppressions>
|
||||
<!-- All the config options and method fields. -->
|
||||
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
|
||||
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />
|
||||
|
||||
<!-- The commands API is documented in Lua. -->
|
||||
<suppress checks="SummaryJavadocCheck" files=".*[\\/]CommandAPI.java" />
|
||||
</suppressions>
|
8
config/gitpod/Dockerfile
Normal file
8
config/gitpod/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM gitpod/workspace-base
|
||||
|
||||
USER gitpod
|
||||
|
||||
RUN sudo apt-get -q update \
|
||||
&& sudo apt-get install -yq openjdk-8-jdk openjdk-16-jdk python3-pip npm \
|
||||
&& sudo pip3 install pre-commit \
|
||||
&& sudo update-java-alternatives --set java-1.8.0-openjdk-amd64
|
2491
config/idea/codeInspectionSettings.xml
Normal file
2491
config/idea/codeInspectionSettings.xml
Normal file
File diff suppressed because it is too large
Load Diff
61
config/idea/codeStyleSettings.xml
Normal file
61
config/idea/codeStyleSettings.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<code_scheme name="Project" version="173">
|
||||
<JSON>
|
||||
<option name="OBJECT_WRAPPING" value="1" />
|
||||
<option name="ARRAY_WRAPPING" value="1" />
|
||||
</JSON>
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value />
|
||||
</option>
|
||||
<option name="JD_P_AT_EMPTY_LINES" value="false" />
|
||||
<option name="JD_PRESERVE_LINE_FEEDS" value="true" />
|
||||
</JavaCodeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
||||
<option name="BRACE_STYLE" value="2" />
|
||||
<option name="CLASS_BRACE_STYLE" value="2" />
|
||||
<option name="METHOD_BRACE_STYLE" value="2" />
|
||||
<option name="LAMBDA_BRACE_STYLE" value="5" />
|
||||
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||
<option name="SPACE_WITHIN_METHOD_CALL_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_METHOD_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_IF_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_WHILE_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_FOR_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_TRY_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_CATCH_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_SWITCH_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_SYNCHRONIZED_PARENTHESES" value="true" />
|
||||
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
|
||||
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
|
||||
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
|
||||
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
|
||||
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
|
||||
<option name="IF_BRACE_FORCE" value="1" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="1" />
|
||||
<option name="WHILE_BRACE_FORCE" value="1" />
|
||||
<option name="FOR_BRACE_FORCE" value="1" />
|
||||
<option name="SPACE_WITHIN_ANNOTATION_PARENTHESES" value="true" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="SPACE_WITHIN_BRACKETS" value="true" />
|
||||
<option name="SPACE_WITHIN_BRACES" value="true" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="4" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
3
config/license/api.txt
Normal file
3
config/license/api.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
Copyright Daniel Ratcliffe, 2011-${year}. This API may be redistributed unmodified and in full only.
|
||||
For help using the API, and posting your mods, visit the forums at computercraft.info.
|
3
config/license/main.txt
Normal file
3
config/license/main.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
This file is part of ComputerCraft - http://www.computercraft.info
|
||||
Copyright Daniel Ratcliffe, 2011-${year}. Do not distribute without permission.
|
||||
Send enquiries to dratcliffe@gmail.com
|
56
config/pre-commit/config.yml
Normal file
56
config/pre-commit/config.yml
Normal file
@@ -0,0 +1,56 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-merge-conflict
|
||||
|
||||
# Quick syntax checkers
|
||||
- id: check-xml
|
||||
- id: check-yaml
|
||||
- id: check-toml
|
||||
- id: check-json
|
||||
exclude: "tsconfig\\.json$"
|
||||
|
||||
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
|
||||
rev: 2.3.54
|
||||
hooks:
|
||||
- id: editorconfig-checker
|
||||
args: ['-disable-indentation']
|
||||
exclude: "^(.*\\.(bat)|LICENSE)$"
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: checkstyle
|
||||
name: Check Java codestyle
|
||||
files: ".*\\.java$"
|
||||
language: system
|
||||
entry: ./gradlew checkstyleMain checkstyleTest
|
||||
pass_filenames: false
|
||||
require_serial: true
|
||||
- id: license
|
||||
name: Check Java license headers
|
||||
files: ".*\\.java$"
|
||||
language: system
|
||||
entry: ./gradlew licenseFormat
|
||||
pass_filenames: false
|
||||
require_serial: true
|
||||
- id: illuaminate
|
||||
name: Check Lua code
|
||||
files: ".*\\.(lua|java|md)"
|
||||
language: script
|
||||
entry: config/pre-commit/illuaminate-lint.sh
|
||||
pass_filenames: false
|
||||
require_serial: true
|
||||
|
||||
exclude: |
|
||||
(?x)^(
|
||||
src/generated|
|
||||
src/test/resources/test-rom/data/json-parsing/|
|
||||
src/testMod/server-files/|
|
||||
config/idea/|
|
||||
.*\.dfpwm
|
||||
)
|
16
config/pre-commit/illuaminate-lint.sh
Executable file
16
config/pre-commit/illuaminate-lint.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
test -d bin || mkdir bin
|
||||
test -f bin/illuaminate || curl -s -obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
|
||||
chmod +x bin/illuaminate
|
||||
|
||||
if [ -n ${GITHUB_ACTIONS+x} ]; then
|
||||
# Register a problem matcher (see https://github.com/actions/toolkit/blob/master/docs/problem-matchers.md)
|
||||
# for illuaminate.
|
||||
echo "::add-matcher::.github/matchers/illuaminate.json"
|
||||
trap 'echo "::remove-matcher owner=illuaminate::"' EXIT
|
||||
fi
|
||||
|
||||
./gradlew luaJavadoc
|
||||
bin/illuaminate lint
|
21
deploy.sh
21
deploy.sh
@@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "Building with gradle..."
|
||||
rm -rf build/libs
|
||||
rm -rf build/resources
|
||||
rm -rf build/classes
|
||||
chmod -R +rw src/main/resources
|
||||
chmod +x gradlew
|
||||
./gradlew build
|
||||
|
||||
echo "Deleting old deployment..."
|
||||
rm -rf deploy
|
||||
mkdir deploy
|
||||
|
||||
echo "Making new deployment..."
|
||||
INPUTJAR=`ls -1 build/libs | grep -v sources`
|
||||
OUTPUTJAR=`ls -1 build/libs | grep -v sources | sed s/\-//g`
|
||||
FRIENDLYNAME=`ls -1 build/libs | grep -v sources | sed s/\-/\ /g | sed s/\.jar//g`
|
||||
cp build/libs/$INPUTJAR deploy/$OUTPUTJAR
|
||||
|
||||
echo "Done."
|
21
doc/events/alarm.md
Normal file
21
doc/events/alarm.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
module: [kind=event] alarm
|
||||
see: os.setAlarm To start an alarm.
|
||||
---
|
||||
|
||||
The @{timer} event is fired when an alarm started with @{os.setAlarm} completes.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The ID of the alarm that finished.
|
||||
|
||||
## Example
|
||||
Starts a timer and then prints its ID:
|
||||
```lua
|
||||
local alarmID = os.setAlarm(os.time() + 0.05)
|
||||
local event, id
|
||||
repeat
|
||||
event, id = os.pullEvent("alarm")
|
||||
until id == alarmID
|
||||
print("Alarm with ID " .. id .. " was fired")
|
||||
```
|
24
doc/events/char.md
Normal file
24
doc/events/char.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
module: [kind=event] char
|
||||
see: key To listen to any key press.
|
||||
---
|
||||
|
||||
The @{char} event is fired when a character is _typed_ on the keyboard.
|
||||
|
||||
The @{char} event is different to a key press. Sometimes multiple key presses may result in one character being
|
||||
typed (for instance, on some European keyboards). Similarly, some keys (e.g. <kbd>Ctrl</kbd>) do not have any
|
||||
corresponding character. The @{key} should be used if you want to listen to key presses themselves.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The string representing the character that was pressed.
|
||||
|
||||
|
||||
## Example
|
||||
Prints each character the user presses:
|
||||
```lua
|
||||
while true do
|
||||
local event, character = os.pullEvent("char")
|
||||
print(character .. " was pressed.")
|
||||
end
|
||||
```
|
18
doc/events/computer_command.md
Normal file
18
doc/events/computer_command.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
module: [kind=event] computer_command
|
||||
---
|
||||
|
||||
The @{computer_command} event is fired when the `/computercraft queue` command is run for the current computer.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
... @{string}: The arguments passed to the command.
|
||||
|
||||
## Example
|
||||
Prints the contents of messages sent:
|
||||
```lua
|
||||
while true do
|
||||
local event = {os.pullEvent("computer_command")}
|
||||
print("Received message:", table.unpack(event, 2))
|
||||
end
|
||||
```
|
19
doc/events/disk.md
Normal file
19
doc/events/disk.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
module: [kind=event] disk
|
||||
see: disk_eject For the event sent when a disk is removed.
|
||||
---
|
||||
|
||||
The @{disk} event is fired when a disk is inserted into an adjacent or networked disk drive.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The side of the disk drive that had a disk inserted.
|
||||
|
||||
## Example
|
||||
Prints a message when a disk is inserted:
|
||||
```lua
|
||||
while true do
|
||||
local event, side = os.pullEvent("disk")
|
||||
print("Inserted a disk on side " .. side)
|
||||
end
|
||||
```
|
19
doc/events/disk_eject.md
Normal file
19
doc/events/disk_eject.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
module: [kind=event] disk_eject
|
||||
see: disk For the event sent when a disk is inserted.
|
||||
---
|
||||
|
||||
The @{disk_eject} event is fired when a disk is removed from an adjacent or networked disk drive.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The side of the disk drive that had a disk removed.
|
||||
|
||||
## Example
|
||||
Prints a message when a disk is removed:
|
||||
```lua
|
||||
while true do
|
||||
local event, side = os.pullEvent("disk_eject")
|
||||
print("Removed a disk on side " .. side)
|
||||
end
|
||||
```
|
14
doc/events/http_check.md
Normal file
14
doc/events/http_check.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
module: [kind=event] http_check
|
||||
see: http.checkURLAsync To check a URL asynchronously.
|
||||
---
|
||||
|
||||
The @{http_check} event is fired when a URL check finishes.
|
||||
|
||||
This event is normally handled inside @{http.checkURL}, but it can still be seen when using @{http.checkURLAsync}.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The URL requested to be checked.
|
||||
3. @{boolean}: Whether the check succeeded.
|
||||
4. @{string|nil}: If the check failed, a reason explaining why the check failed.
|
39
doc/events/http_failure.md
Normal file
39
doc/events/http_failure.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
module: [kind=event] http_failure
|
||||
see: http.request To send an HTTP request.
|
||||
---
|
||||
|
||||
The @{http_failure} event is fired when an HTTP request fails.
|
||||
|
||||
This event is normally handled inside @{http.get} and @{http.post}, but it can still be seen when using @{http.request}.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The URL of the site requested.
|
||||
3. @{string}: An error describing the failure.
|
||||
4. @{http.Response|nil}: A response handle if the connection succeeded, but the server's response indicated failure.
|
||||
|
||||
## Example
|
||||
Prints an error why the website cannot be contacted:
|
||||
```lua
|
||||
local myURL = "https://does.not.exist.tweaked.cc"
|
||||
http.request(myURL)
|
||||
local event, url, err
|
||||
repeat
|
||||
event, url, err = os.pullEvent("http_failure")
|
||||
until url == myURL
|
||||
print("The URL " .. url .. " could not be reached: " .. err)
|
||||
```
|
||||
|
||||
Prints the contents of a webpage that does not exist:
|
||||
```lua
|
||||
local myURL = "https://tweaked.cc/this/does/not/exist"
|
||||
http.request(myURL)
|
||||
local event, url, err, handle
|
||||
repeat
|
||||
event, url, err, handle = os.pullEvent("http_failure")
|
||||
until url == myURL
|
||||
print("The URL " .. url .. " could not be reached: " .. err)
|
||||
print(handle.getResponseCode())
|
||||
handle.close()
|
||||
```
|
27
doc/events/http_success.md
Normal file
27
doc/events/http_success.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
module: [kind=event] http_success
|
||||
see: http.request To make an HTTP request.
|
||||
---
|
||||
|
||||
The @{http_success} event is fired when an HTTP request returns successfully.
|
||||
|
||||
This event is normally handled inside @{http.get} and @{http.post}, but it can still be seen when using @{http.request}.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The URL of the site requested.
|
||||
3. @{http.Response}: The handle for the response text.
|
||||
|
||||
## Example
|
||||
Prints the content of a website (this may fail if the request fails):
|
||||
```lua
|
||||
local myURL = "https://tweaked.cc/"
|
||||
http.request(myURL)
|
||||
local event, url, handle
|
||||
repeat
|
||||
event, url, handle = os.pullEvent("http_success")
|
||||
until url == myURL
|
||||
print("Contents of " .. url .. ":")
|
||||
print(handle.readAll())
|
||||
handle.close()
|
||||
```
|
26
doc/events/key.md
Normal file
26
doc/events/key.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
module: [kind=event] key
|
||||
---
|
||||
|
||||
This event is fired when any key is pressed while the terminal is focused.
|
||||
|
||||
This event returns a numerical "key code" (for instance, <kbd>F1</kbd> is 290). This value may vary between versions and
|
||||
so it is recommended to use the constants in the @{keys} API rather than hard coding numeric values.
|
||||
|
||||
If the button pressed represented a printable character, then the @{key} event will be followed immediately by a @{char}
|
||||
event. If you are consuming text input, use a @{char} event instead!
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The numerical key value of the key pressed.
|
||||
3. @{boolean}: Whether the key event was generated while holding the key (@{true}), rather than pressing it the first time (@{false}).
|
||||
|
||||
## Example
|
||||
Prints each key when the user presses it, and if the key is being held.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, key, is_held = os.pullEvent("key")
|
||||
print(("%s held=%s"):format(keys.getName(key), is_held))
|
||||
end
|
||||
```
|
24
doc/events/key_up.md
Normal file
24
doc/events/key_up.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
module: [kind=event] key_up
|
||||
see: keys For a lookup table of the given keys.
|
||||
---
|
||||
|
||||
Fired whenever a key is released (or the terminal is closed while a key was being pressed).
|
||||
|
||||
This event returns a numerical "key code" (for instance, <kbd>F1</kbd> is 290). This value may vary between versions and
|
||||
so it is recommended to use the constants in the @{keys} API rather than hard coding numeric values.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The numerical key value of the key pressed.
|
||||
|
||||
## Example
|
||||
Prints each key released on the keyboard whenever a @{key_up} event is fired.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, key = os.pullEvent("key_up")
|
||||
local name = keys.getName(key) or "unknown key"
|
||||
print(name .. " was released.")
|
||||
end
|
||||
```
|
26
doc/events/modem_message.md
Normal file
26
doc/events/modem_message.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
module: [kind=event] modem_message
|
||||
---
|
||||
|
||||
The @{modem_message} event is fired when a message is received on an open channel on any @{modem}.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The side of the modem that received the message.
|
||||
3. @{number}: The channel that the message was sent on.
|
||||
4. @{number}: The reply channel set by the sender.
|
||||
5. @{any}: The message as sent by the sender.
|
||||
6. @{number}: The distance between the sender and the receiver, in blocks.
|
||||
|
||||
## Example
|
||||
Wraps a @{modem} peripheral, opens channel 0 for listening, and prints all received messages.
|
||||
|
||||
```lua
|
||||
local modem = peripheral.find("modem") or error("No modem attached", 0)
|
||||
modem.open(0)
|
||||
|
||||
while true do
|
||||
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
|
||||
print(("Message received on side %s on channel %d (reply to %d) from %f blocks away with message %s"):format(side, channel, replyChannel, distance, tostring(message)))
|
||||
end
|
||||
```
|
18
doc/events/monitor_resize.md
Normal file
18
doc/events/monitor_resize.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
module: [kind=event] monitor_resize
|
||||
---
|
||||
|
||||
The @{monitor_resize} event is fired when an adjacent or networked monitor's size is changed.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The side or network ID of the monitor that resized.
|
||||
|
||||
## Example
|
||||
Prints a message when a monitor is resized:
|
||||
```lua
|
||||
while true do
|
||||
local event, side = os.pullEvent("monitor_resize")
|
||||
print("The monitor on side " .. side .. " was resized.")
|
||||
end
|
||||
```
|
20
doc/events/monitor_touch.md
Normal file
20
doc/events/monitor_touch.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
module: [kind=event] monitor_touch
|
||||
---
|
||||
|
||||
The @{monitor_touch} event is fired when an adjacent or networked Advanced Monitor is right-clicked.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The side or network ID of the monitor that was touched.
|
||||
3. @{number}: The X coordinate of the touch, in characters.
|
||||
4. @{number}: The Y coordinate of the touch, in characters.
|
||||
|
||||
## Example
|
||||
Prints a message when a monitor is touched:
|
||||
```lua
|
||||
while true do
|
||||
local event, side, x, y = os.pullEvent("monitor_touch")
|
||||
print("The monitor on side " .. side .. " was touched at (" .. x .. ", " .. y .. ")")
|
||||
end
|
||||
```
|
34
doc/events/mouse_click.md
Normal file
34
doc/events/mouse_click.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
module: [kind=event] mouse_click
|
||||
---
|
||||
|
||||
This event is fired when the terminal is clicked with a mouse. This event is only fired on advanced computers (including
|
||||
advanced turtles and pocket computers).
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The mouse button that was clicked.
|
||||
3. @{number}: The X-coordinate of the click.
|
||||
4. @{number}: The Y-coordinate of the click.
|
||||
|
||||
## Mouse buttons
|
||||
Several mouse events (@{mouse_click}, @{mouse_up}, @{mouse_scroll}) contain a "mouse button" code. This takes a
|
||||
numerical value depending on which button on your mouse was last pressed when this event occurred.
|
||||
|
||||
<table class="pretty-table">
|
||||
<!-- Our markdown parser doesn't work on tables!? Guess I'll have to roll my own soonish :/. -->
|
||||
<tr><th>Button code</th><th>Mouse button</th></tr>
|
||||
<tr><td align="right">1</td><td>Left button</td></tr>
|
||||
<tr><td align="right">2</td><td>Right button</td></tr>
|
||||
<tr><td align="right">3</td><td>Middle button</td></tr>
|
||||
</table>
|
||||
|
||||
## Example
|
||||
Print the button and the coordinates whenever the mouse is clicked.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, button, x, y = os.pullEvent("mouse_click")
|
||||
print(("The mouse button %s was pressed at %d, %d"):format(button, x, y))
|
||||
end
|
||||
```
|
22
doc/events/mouse_drag.md
Normal file
22
doc/events/mouse_drag.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
module: [kind=event] mouse_drag
|
||||
see: mouse_click For when a mouse button is initially pressed.
|
||||
---
|
||||
|
||||
This event is fired every time the mouse is moved while a mouse button is being held.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The [mouse button](mouse_click.html#Mouse_buttons) that is being pressed.
|
||||
3. @{number}: The X-coordinate of the mouse.
|
||||
4. @{number}: The Y-coordinate of the mouse.
|
||||
|
||||
## Example
|
||||
Print the button and the coordinates whenever the mouse is dragged.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, button, x, y = os.pullEvent("mouse_drag")
|
||||
print(("The mouse button %s was dragged at %d, %d"):format(button, x, y))
|
||||
end
|
||||
```
|
21
doc/events/mouse_scroll.md
Normal file
21
doc/events/mouse_scroll.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
module: [kind=event] mouse_scroll
|
||||
---
|
||||
|
||||
This event is fired when a mouse wheel is scrolled in the terminal.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The direction of the scroll. (-1 = up, 1 = down)
|
||||
3. @{number}: The X-coordinate of the mouse when scrolling.
|
||||
4. @{number}: The Y-coordinate of the mouse when scrolling.
|
||||
|
||||
## Example
|
||||
Prints the direction of each scroll, and the position of the mouse at the time.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, dir, x, y = os.pullEvent("mouse_scroll")
|
||||
print(("The mouse was scrolled in direction %s at %d, %d"):format(dir, x, y))
|
||||
end
|
||||
```
|
21
doc/events/mouse_up.md
Normal file
21
doc/events/mouse_up.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
module: [kind=event] mouse_up
|
||||
---
|
||||
|
||||
This event is fired when a mouse button is released or a held mouse leaves the computer's terminal.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The [mouse button](mouse_click.html#Mouse_buttons) that was released.
|
||||
3. @{number}: The X-coordinate of the mouse.
|
||||
4. @{number}: The Y-coordinate of the mouse.
|
||||
|
||||
## Example
|
||||
Prints the coordinates and button number whenever the mouse is released.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, button, x, y = os.pullEvent("mouse_up")
|
||||
print(("The mouse button %s was released at %d, %d"):format(button, x, y))
|
||||
end
|
||||
```
|
18
doc/events/paste.md
Normal file
18
doc/events/paste.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
module: [kind=event] paste
|
||||
---
|
||||
|
||||
The @{paste} event is fired when text is pasted into the computer through Ctrl-V (or ⌘V on Mac).
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{string} The text that was pasted.
|
||||
|
||||
## Example
|
||||
Prints pasted text:
|
||||
```lua
|
||||
while true do
|
||||
local event, text = os.pullEvent("paste")
|
||||
print('"' .. text .. '" was pasted')
|
||||
end
|
||||
```
|
19
doc/events/peripheral.md
Normal file
19
doc/events/peripheral.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
module: [kind=event] peripheral
|
||||
see: peripheral_detach For the event fired when a peripheral is detached.
|
||||
---
|
||||
|
||||
The @{peripheral} event is fired when a peripheral is attached on a side or to a modem.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The side the peripheral was attached to.
|
||||
|
||||
## Example
|
||||
Prints a message when a peripheral is attached:
|
||||
```lua
|
||||
while true do
|
||||
local event, side = os.pullEvent("peripheral")
|
||||
print("A peripheral was attached on side " .. side)
|
||||
end
|
||||
```
|
19
doc/events/peripheral_detach.md
Normal file
19
doc/events/peripheral_detach.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
module: [kind=event] peripheral_detach
|
||||
see: peripheral For the event fired when a peripheral is attached.
|
||||
---
|
||||
|
||||
The @{peripheral_detach} event is fired when a peripheral is detached from a side or from a modem.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The side the peripheral was detached from.
|
||||
|
||||
## Example
|
||||
Prints a message when a peripheral is detached:
|
||||
```lua
|
||||
while true do
|
||||
local event, side = os.pullEvent("peripheral_detach")
|
||||
print("A peripheral was detached on side " .. side)
|
||||
end
|
||||
```
|
30
doc/events/rednet_message.md
Normal file
30
doc/events/rednet_message.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
module: [kind=event] rednet_message
|
||||
see: modem_message For raw modem messages sent outside of Rednet.
|
||||
see: rednet.receive To wait for a Rednet message with an optional timeout and protocol filter.
|
||||
---
|
||||
|
||||
The @{rednet_message} event is fired when a message is sent over Rednet.
|
||||
|
||||
This event is usually handled by @{rednet.receive}, but it can also be pulled manually.
|
||||
|
||||
@{rednet_message} events are sent by @{rednet.run} in the top-level coroutine in response to @{modem_message} events. A @{rednet_message} event is always preceded by a @{modem_message} event. They are generated inside CraftOS rather than being sent by the ComputerCraft machine.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The ID of the sending computer.
|
||||
3. @{any}: The message sent.
|
||||
4. @{string|nil}: The protocol of the message, if provided.
|
||||
|
||||
## Example
|
||||
Prints a message when one is sent:
|
||||
```lua
|
||||
while true do
|
||||
local event, sender, message, protocol = os.pullEvent("rednet_message")
|
||||
if protocol ~= nil then
|
||||
print("Received message from " .. sender .. " with protocol " .. protocol .. " and message " .. tostring(message))
|
||||
else
|
||||
print("Received message from " .. sender .. " with message " .. tostring(message))
|
||||
end
|
||||
end
|
||||
```
|
14
doc/events/redstone.md
Normal file
14
doc/events/redstone.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
module: [kind=event] redstone
|
||||
---
|
||||
|
||||
The @{event!redstone} event is fired whenever any redstone inputs on the computer change.
|
||||
|
||||
## Example
|
||||
Prints a message when a redstone input changes:
|
||||
```lua
|
||||
while true do
|
||||
os.pullEvent("redstone")
|
||||
print("A redstone input has changed!")
|
||||
end
|
||||
```
|
27
doc/events/speaker_audio_empty.md
Normal file
27
doc/events/speaker_audio_empty.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
module: [kind=event] speaker_audio_empty
|
||||
see: speaker.playAudio To play audio using the speaker
|
||||
---
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The name of the speaker which is available to play more audio.
|
||||
|
||||
|
||||
## Example
|
||||
This uses @{io.lines} to read audio data in blocks of 16KiB from "example_song.dfpwm", and then attempts to play it
|
||||
using @{speaker.playAudio}. If the speaker's buffer is full, it waits for an event and tries again.
|
||||
|
||||
```lua {data-peripheral=speaker}
|
||||
local dfpwm = require("cc.audio.dfpwm")
|
||||
local speaker = peripheral.find("speaker")
|
||||
|
||||
local decoder = dfpwm.make_decoder()
|
||||
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
|
||||
local buffer = decoder(chunk)
|
||||
|
||||
while not speaker.playAudio(buffer) do
|
||||
os.pullEvent("speaker_audio_empty")
|
||||
end
|
||||
end
|
||||
```
|
28
doc/events/task_complete.md
Normal file
28
doc/events/task_complete.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
module: [kind=event] task_complete
|
||||
see: commands.execAsync To run a command which fires a task_complete event.
|
||||
---
|
||||
|
||||
The @{task_complete} event is fired when an asynchronous task completes. This is usually handled inside the function call that queued the task; however, functions such as @{commands.execAsync} return immediately so the user can wait for completion.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The ID of the task that completed.
|
||||
3. @{boolean}: Whether the command succeeded.
|
||||
4. @{string}: If the command failed, an error message explaining the failure. (This is not present if the command succeeded.)
|
||||
...: Any parameters returned from the command.
|
||||
|
||||
## Example
|
||||
Prints the results of an asynchronous command:
|
||||
```lua
|
||||
local taskID = commands.execAsync("say Hello")
|
||||
local event
|
||||
repeat
|
||||
event = {os.pullEvent("task_complete")}
|
||||
until event[2] == taskID
|
||||
if event[3] == true then
|
||||
print("Task " .. event[2] .. " succeeded:", table.unpack(event, 4))
|
||||
else
|
||||
print("Task " .. event[2] .. " failed: " .. event[4])
|
||||
end
|
||||
```
|
20
doc/events/term_resize.md
Normal file
20
doc/events/term_resize.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
module: [kind=event] term_resize
|
||||
---
|
||||
|
||||
The @{term_resize} event is fired when the main terminal is resized. For instance:
|
||||
- When a the tab bar is shown or hidden in @{multishell}.
|
||||
- When the terminal is redirected to a monitor via the "monitor" program and the monitor is resized.
|
||||
|
||||
When this event fires, some parts of the terminal may have been moved or deleted. Simple terminal programs (those
|
||||
not using @{term.setCursorPos}) can ignore this event, but more complex GUI programs should redraw the entire screen.
|
||||
|
||||
## Example
|
||||
Prints :
|
||||
```lua
|
||||
while true do
|
||||
os.pullEvent("term_resize")
|
||||
local w, h = term.getSize()
|
||||
print("The term was resized to (" .. w .. ", " .. h .. ")")
|
||||
end
|
||||
```
|
25
doc/events/terminate.md
Normal file
25
doc/events/terminate.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
module: [kind=event] terminate
|
||||
---
|
||||
|
||||
The @{terminate} event is fired when <kbd>Ctrl-T</kbd> is held down.
|
||||
|
||||
This event is normally handled by @{os.pullEvent}, and will not be returned. However, @{os.pullEventRaw} will return this event when fired.
|
||||
|
||||
@{terminate} will be sent even when a filter is provided to @{os.pullEventRaw}. When using @{os.pullEventRaw} with a filter, make sure to check that the event is not @{terminate}.
|
||||
|
||||
## Example
|
||||
Prints a message when Ctrl-T is held:
|
||||
```lua
|
||||
while true do
|
||||
local event = os.pullEventRaw("terminate")
|
||||
if event == "terminate" then print("Terminate requested!") end
|
||||
end
|
||||
```
|
||||
|
||||
Exits when Ctrl-T is held:
|
||||
```lua
|
||||
while true do
|
||||
os.pullEvent()
|
||||
end
|
||||
```
|
21
doc/events/timer.md
Normal file
21
doc/events/timer.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
module: [kind=event] timer
|
||||
see: os.startTimer To start a timer.
|
||||
---
|
||||
|
||||
The @{timer} event is fired when a timer started with @{os.startTimer} completes.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The ID of the timer that finished.
|
||||
|
||||
## Example
|
||||
Starts a timer and then prints its ID:
|
||||
```lua
|
||||
local timerID = os.startTimer(2)
|
||||
local event, id
|
||||
repeat
|
||||
event, id = os.pullEvent("timer")
|
||||
until id == timerID
|
||||
print("Timer with ID " .. id .. " was fired")
|
||||
```
|
14
doc/events/turtle_inventory.md
Normal file
14
doc/events/turtle_inventory.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
module: [kind=event] turtle_inventory
|
||||
---
|
||||
|
||||
The @{turtle_inventory} event is fired when a turtle's inventory is changed.
|
||||
|
||||
## Example
|
||||
Prints a message when the inventory is changed:
|
||||
```lua
|
||||
while true do
|
||||
os.pullEvent("turtle_inventory")
|
||||
print("The inventory was changed.")
|
||||
end
|
||||
```
|
21
doc/events/websocket_closed.md
Normal file
21
doc/events/websocket_closed.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
module: [kind=event] websocket_closed
|
||||
---
|
||||
|
||||
The @{websocket_closed} event is fired when an open WebSocket connection is closed.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The URL of the WebSocket that was closed.
|
||||
|
||||
## Example
|
||||
Prints a message when a WebSocket is closed (this may take a minute):
|
||||
```lua
|
||||
local myURL = "wss://example.tweaked.cc/echo"
|
||||
local ws = http.websocket(myURL)
|
||||
local event, url
|
||||
repeat
|
||||
event, url = os.pullEvent("websocket_closed")
|
||||
until url == myURL
|
||||
print("The WebSocket at " .. url .. " was closed.")
|
||||
```
|
25
doc/events/websocket_failure.md
Normal file
25
doc/events/websocket_failure.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
module: [kind=event] websocket_failure
|
||||
see: http.websocketAsync To send an HTTP request.
|
||||
---
|
||||
|
||||
The @{websocket_failure} event is fired when a WebSocket connection request fails.
|
||||
|
||||
This event is normally handled inside @{http.websocket}, but it can still be seen when using @{http.websocketAsync}.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The URL of the site requested.
|
||||
3. @{string}: An error describing the failure.
|
||||
|
||||
## Example
|
||||
Prints an error why the website cannot be contacted:
|
||||
```lua
|
||||
local myURL = "wss://example.tweaked.cc/not-a-websocket"
|
||||
http.websocketAsync(myURL)
|
||||
local event, url, err
|
||||
repeat
|
||||
event, url, err = os.pullEvent("websocket_failure")
|
||||
until url == myURL
|
||||
print("The URL " .. url .. " could not be reached: " .. err)
|
||||
```
|
27
doc/events/websocket_message.md
Normal file
27
doc/events/websocket_message.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
module: [kind=event] websocket_message
|
||||
---
|
||||
|
||||
The @{websocket_message} event is fired when a message is received on an open WebSocket connection.
|
||||
|
||||
This event is normally handled by @{http.Websocket.receive}, but it can also be pulled manually.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The URL of the WebSocket.
|
||||
3. @{string}: The contents of the message.
|
||||
4. @{boolean}: Whether this is a binary message.
|
||||
|
||||
## Example
|
||||
Prints a message sent by a WebSocket:
|
||||
```lua
|
||||
local myURL = "wss://example.tweaked.cc/echo"
|
||||
local ws = http.websocket(myURL)
|
||||
ws.send("Hello!")
|
||||
local event, url, message
|
||||
repeat
|
||||
event, url, message = os.pullEvent("websocket_message")
|
||||
until url == myURL
|
||||
print("Received message from " .. url .. " with contents " .. message)
|
||||
ws.close()
|
||||
```
|
28
doc/events/websocket_success.md
Normal file
28
doc/events/websocket_success.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
module: [kind=event] websocket_success
|
||||
see: http.websocketAsync To open a WebSocket asynchronously.
|
||||
---
|
||||
|
||||
The @{websocket_success} event is fired when a WebSocket connection request returns successfully.
|
||||
|
||||
This event is normally handled inside @{http.websocket}, but it can still be seen when using @{http.websocketAsync}.
|
||||
|
||||
## Return Values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The URL of the site.
|
||||
3. @{http.Websocket}: The handle for the WebSocket.
|
||||
|
||||
## Example
|
||||
Prints the content of a website (this may fail if the request fails):
|
||||
```lua
|
||||
local myURL = "wss://example.tweaked.cc/echo"
|
||||
http.websocketAsync(myURL)
|
||||
local event, url, handle
|
||||
repeat
|
||||
event, url, handle = os.pullEvent("websocket_success")
|
||||
until url == myURL
|
||||
print("Connected to " .. url)
|
||||
handle.send("Hello!")
|
||||
print(handle.receive())
|
||||
handle.close()
|
||||
```
|
200
doc/guides/speaker_audio.md
Normal file
200
doc/guides/speaker_audio.md
Normal file
@@ -0,0 +1,200 @@
|
||||
---
|
||||
module: [kind=guide] speaker_audio
|
||||
see: speaker.playAudio Play PCM audio using a speaker.
|
||||
see: cc.audio.dfpwm Provides utilities for encoding and decoding DFPWM files.
|
||||
---
|
||||
|
||||
# Playing audio with speakers
|
||||
CC: Tweaked's speaker peripheral provides a powerful way to play any audio you like with the @{speaker.playAudio}
|
||||
method. However, for people unfamiliar with digital audio, it's not the most intuitive thing to use. This guide provides
|
||||
an introduction to digital audio, demonstrates how to play music with CC: Tweaked's speakers, and then briefly discusses
|
||||
the more complex topic of audio processing.
|
||||
|
||||
## A short introduction to digital audio
|
||||
When sound is recorded it is captured as an analogue signal, effectively the electrical version of a sound
|
||||
wave. However, this signal is continuous, and so can't be used directly by a computer. Instead, we measure (or *sample*)
|
||||
the amplitude of the wave many times a second and then *quantise* that amplitude, rounding it to the nearest
|
||||
representable value.
|
||||
|
||||
This representation of sound - a long, uniformally sampled list of amplitudes is referred to as [Pulse-code
|
||||
Modulation][PCM] (PCM). PCM can be thought of as the "standard" audio format, as it's incredibly easy to work with. For
|
||||
instance, to mix two pieces of audio together, you can just add samples from the two tracks together and take the average.
|
||||
|
||||
CC: Tweaked's speakers also work with PCM audio. It plays back 48,000 samples a second, where each sample is an integer
|
||||
between -128 and 127. This is more commonly referred to as 48kHz and an 8-bit resolution.
|
||||
|
||||
Let's now look at a quick example. We're going to generate a [Sine Wave] at 220Hz, which sounds like a low monotonous
|
||||
hum. First we wrap our speaker peripheral, and then we fill a table (also referred to as a *buffer*) with 128×1024
|
||||
samples - this is the maximum number of samples a speaker can accept in one go.
|
||||
|
||||
In order to fill this buffer, we need to do a little maths. We want to play 220 sine waves each second, where each sine
|
||||
wave completes a full oscillation in 2π "units". This means one seconds worth of audio is 2×π×220 "units" long. We then
|
||||
need to split this into 48k samples, basically meaning for each sample we move 2×π×220/48k "along" the sine curve.
|
||||
|
||||
```lua {data-peripheral=speaker}
|
||||
local speaker = peripheral.find("speaker")
|
||||
|
||||
local buffer = {}
|
||||
local t, dt = 0, 2 * math.pi * 220 / 48000
|
||||
for i = 1, 128 * 1024 do
|
||||
buffer[i] = math.floor(math.sin(t) * 127)
|
||||
t = (t + dt) % (math.pi * 2)
|
||||
end
|
||||
|
||||
speaker.playAudio(buffer)
|
||||
```
|
||||
|
||||
## Streaming audio
|
||||
You might notice that the above snippet only generates a short bit of audio - 2.7s seconds to be precise. While we could
|
||||
try increasing the number of loop iterations, we'll get an error when we try to play it through the speaker: the sound
|
||||
buffer is too large for it to handle.
|
||||
|
||||
Our 2.7 seconds of audio is stored in a table with over 130 _thousand_ elements. If we wanted to play a full minute of
|
||||
sine waves (and why wouldn't you?), you'd need a table with almost 3 _million_. Suddenly you find these numbers adding
|
||||
up very quickly, and these tables take up more and more memory.
|
||||
|
||||
Instead of building our entire song (well, sine wave) in one go, we can produce it in small batches, each of which get
|
||||
passed off to @{speaker.playAudio} when the time is right. This allows us to build a _stream_ of audio, where we read
|
||||
chunks of audio one at a time (either from a file or a tone generator like above), do some optional processing to each
|
||||
one, and then play them.
|
||||
|
||||
Let's adapt our example from above to do that instead.
|
||||
|
||||
```lua {data-peripheral=speaker}
|
||||
local speaker = peripheral.find("speaker")
|
||||
|
||||
local t, dt = 0, 2 * math.pi * 220 / 48000
|
||||
while true do
|
||||
local buffer = {}
|
||||
for i = 1, 16 * 1024 * 8 do
|
||||
buffer[i] = math.floor(math.sin(t) * 127)
|
||||
t = (t + dt) % (math.pi * 2)
|
||||
end
|
||||
|
||||
while not speaker.playAudio(buffer) do
|
||||
os.pullEvent("speaker_audio_empty")
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
It looks pretty similar to before, aside from we've wrapped the generation and playing code in a while loop, and added a
|
||||
rather odd loop with @{speaker.playAudio} and @{os.pullEvent}.
|
||||
|
||||
Let's talk about this loop, why do we need to keep calling @{speaker.playAudio}? Remember that what we're trying to do
|
||||
here is avoid keeping too much audio in memory at once. However, if we're generating audio quicker than the speakers can
|
||||
play it, we're not helping at all - all this audio is still hanging around waiting to be played!
|
||||
|
||||
In order to avoid this, the speaker rejects any new chunks of audio if its backlog is too large. When this happens,
|
||||
@{speaker.playAudio} returns false. Once enough audio has played, and the backlog has been reduced, a
|
||||
@{speaker_audio_empty} event is queued, and we can try to play our chunk once more.
|
||||
|
||||
## Storing audio
|
||||
PCM is a fantastic way of representing audio when we want to manipulate it, but it's not very efficient when we want to
|
||||
store it to disk. Compare the size of a WAV file (which uses PCM) to an equivalent MP3, it's often 5 times the size.
|
||||
Instead, we store audio in special formats (or *codecs*) and then convert them to PCM when we need to do processing on
|
||||
them.
|
||||
|
||||
Modern audio codecs use some incredibly impressive techniques to compress the audio as much as possible while preserving
|
||||
sound quality. However, due to CC: Tweaked's limited processing power, it's not really possible to use these from your
|
||||
computer. Instead, we need something much simpler.
|
||||
|
||||
DFPWM (Dynamic Filter Pulse Width Modulation) is the de facto standard audio format of the ComputerCraft (and
|
||||
OpenComputers) world. Originally popularised by the addon mod [Computronics], CC:T now has built-in support for it with
|
||||
the @{cc.audio.dfpwm} module. This allows you to read DFPWM files from disk, decode them to PCM, and then play them
|
||||
using the speaker.
|
||||
|
||||
Let's dive in with an example, and we'll explain things afterwards:
|
||||
|
||||
```lua {data-peripheral=speaker}
|
||||
local dfpwm = require("cc.audio.dfpwm")
|
||||
local speaker = peripheral.find("speaker")
|
||||
|
||||
local decoder = dfpwm.make_decoder()
|
||||
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
|
||||
local buffer = decoder(chunk)
|
||||
|
||||
while not speaker.playAudio(buffer) do
|
||||
os.pullEvent("speaker_audio_empty")
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Once again, we see the @{speaker.playAudio}/@{speaker_audio_empty} loop. However, the rest of the program is a little
|
||||
different.
|
||||
|
||||
First, we require the dfpwm module and call @{cc.audio.dfpwm.make_decoder} to construct a new decoder. This decoder
|
||||
accepts blocks of DFPWM data and converts it to a list of 8-bit amplitudes, which we can then play with our speaker.
|
||||
|
||||
As mentioned to above, @{speaker.playAudio} accepts at most 128×1024 samples in one go. DFPMW uses a single bit for each
|
||||
sample, which means we want to process our audio in chunks of 16×1024 bytes (16KiB). In order to do this, we use
|
||||
@{io.lines}, which provides a nice way to loop over chunks of a file. You can of course just use @{fs.open} and
|
||||
@{fs.BinaryReadHandle.read} if you prefer.
|
||||
|
||||
## Processing audio
|
||||
As mentioned near the beginning of this guide, PCM audio is pretty easy to work with as it's just a list of amplitudes.
|
||||
You can mix together samples from different streams by adding their amplitudes, change the rate of playback by removing
|
||||
samples, etc...
|
||||
|
||||
Let's put together a small demonstration here. We're going to add a small delay effect to the song above, so that you
|
||||
hear a faint echo about a second later.
|
||||
|
||||
In order to do this, we'll follow a format similar to the previous example, decoding the audio and then playing it.
|
||||
However, we'll also add some new logic between those two steps, which loops over every sample in our chunk of audio, and
|
||||
adds the sample from one second ago to it.
|
||||
|
||||
For this, we'll need to keep track of the last 48k samples - exactly one seconds worth of audio. We can do this using a
|
||||
[Ring Buffer], which helps makes things a little more efficient.
|
||||
|
||||
```lua {data-peripheral=speaker}
|
||||
local dfpwm = require("cc.audio.dfpwm")
|
||||
local speaker = peripheral.find("speaker")
|
||||
|
||||
-- Speakers play at 48kHz, so one second is 48k samples. We first fill our buffer
|
||||
-- with 0s, as there's nothing to echo at the start of the track!
|
||||
local samples_i, samples_n = 1, 48000
|
||||
local samples = {}
|
||||
for i = 1, samples_n do samples[i] = 0 end
|
||||
|
||||
local decoder = dfpwm.make_decoder()
|
||||
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
|
||||
local buffer = decoder(chunk)
|
||||
|
||||
for i = 1, #buffer do
|
||||
local original_value = buffer[i]
|
||||
|
||||
-- Replace this sample with its current amplitude plus the amplitude from one second ago.
|
||||
-- We scale both to ensure the resulting value is still between -128 and 127.
|
||||
buffer[i] = original_value * 0.6 + samples[samples_i] * 0.4
|
||||
|
||||
-- Now store the current sample, and move the "head" of our ring buffer forward one place.
|
||||
samples[samples_i] = original_value
|
||||
samples_i = samples_i + 1
|
||||
if samples_i > samples_n then samples_i = 1 end
|
||||
end
|
||||
|
||||
while not speaker.playAudio(buffer) do
|
||||
os.pullEvent("speaker_audio_empty")
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
:::note Confused?
|
||||
Don't worry if you don't understand this example. It's quite advanced, and does use some ideas that this guide doesn't
|
||||
cover. That said, don't be afraid to ask on [Discord] or [IRC] either!
|
||||
:::
|
||||
|
||||
It's worth noting that the examples of audio processing we've mentioned here are about manipulating the _amplitude_ of
|
||||
the wave. If you wanted to modify the _frequency_ (for instance, shifting the pitch), things get rather more complex.
|
||||
For this, you'd need to use the [Fast Fourier transform][FFT] to convert the stream of amplitudes to frequencies,
|
||||
process those, and then convert them back to amplitudes.
|
||||
|
||||
This is, I'm afraid, left as an exercise to the reader.
|
||||
|
||||
[Computronics]: https://github.com/Vexatos/Computronics/ "Computronics on GitHub"
|
||||
[FFT]: https://en.wikipedia.org/wiki/Fast_Fourier_transform "Fast Fourier transform - Wikipedia"
|
||||
[PCM]: https://en.wikipedia.org/wiki/Pulse-code_modulation "Pulse-code Modulation - Wikipedia"
|
||||
[Ring Buffer]: https://en.wikipedia.org/wiki/Circular_buffer "Circular buffer - Wikipedia"
|
||||
[Sine Wave]: https://en.wikipedia.org/wiki/Sine_wave "Sine wave - Wikipedia"
|
||||
|
||||
[Discord]: https://discord.computercraft.cc "The Minecraft Computer Mods Discord"
|
||||
[IRC]: http://webchat.esper.net/?channels=computercraft "IRC webchat on EsperNet"
|
83
doc/guides/using_require.md
Normal file
83
doc/guides/using_require.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
module: [kind=guide] using_require
|
||||
---
|
||||
|
||||
# Reusing code with require
|
||||
A library is a collection of useful functions and other definitions which is stored separately to your main program. You
|
||||
might want to create a library because you have some functions which are used in multiple programs, or just to split
|
||||
your program into multiple more modular files.
|
||||
|
||||
Let's say we want to create a small library to make working with the @{term|terminal} a little easier. We'll provide two
|
||||
functions: `reset`, which clears the terminal and sets the cursor to (1, 1), and `write_center`, which prints some text
|
||||
in the middle of the screen.
|
||||
|
||||
Start off by creating a file called `more_term.lua`:
|
||||
|
||||
```lua {data-snippet=more_term}
|
||||
local function reset()
|
||||
term.clear()
|
||||
term.setCursorPos(1, 1)
|
||||
end
|
||||
|
||||
local function write_center(text)
|
||||
local x, y = term.getCursorPos()
|
||||
local width, height = term.getSize()
|
||||
term.setCursorPos(math.floor((width - #text) / 2) + 1, y)
|
||||
term.write(text)
|
||||
end
|
||||
|
||||
return { reset = reset, write_center = write_center }
|
||||
```
|
||||
|
||||
Now, what's going on here? We define our two functions as one might expect, and then at the bottom return a table with
|
||||
the two functions. When we require this library, this table is what is returned. With that, we can then call the
|
||||
original functions. Now create a new file, with the following:
|
||||
|
||||
```lua {data-mount=more_term:more_term.lua}
|
||||
local more_term = require("more_term")
|
||||
more_term.reset()
|
||||
more_term.write_center("Hello, world!")
|
||||
```
|
||||
|
||||
When run, this'll clear the screen and print some text in the middle of the first line.
|
||||
|
||||
## require in depth
|
||||
While the previous section is a good introduction to how @{require} operates, there are a couple of remaining points
|
||||
which are worth mentioning for more advanced usage.
|
||||
|
||||
### Libraries can return anything
|
||||
In our above example, we return a table containing the functions we want to expose. However, it's worth pointing out
|
||||
that you can return ''anything'' from your library - a table, a function or even just a string! @{require} treats them
|
||||
all the same, and just returns whatever your library provides.
|
||||
|
||||
### Module resolution and the package path
|
||||
In the above examples, we defined our library in a file, and @{require} read from it. While this is what you'll do most
|
||||
of the time, it is possible to make @{require} look elsewhere for your library, such as downloading from a website or
|
||||
loading from an in-memory library store.
|
||||
|
||||
As a result, the *module name* you pass to @{require} doesn't correspond to a file path. One common mistake is to load
|
||||
code from a sub-directory using `require("folder/library")` or even `require("folder/library.lua")`, neither of which
|
||||
will do quite what you expect.
|
||||
|
||||
When loading libraries (also referred to as *modules*) from files, @{require} searches along the *@{package.path|module
|
||||
path}*. By default, this looks something like:
|
||||
|
||||
* `?.lua`
|
||||
* `?/init.lua`
|
||||
* `/rom/modules/main/?.lua`
|
||||
* etc...
|
||||
|
||||
When you call `require("my_library")`, @{require} replaces the `?` in each element of the path with your module name, and
|
||||
checks if the file exists. In this case, we'd look for `my_library.lua`, `my_library/init.lua`,
|
||||
`/rom/modules/main/my_library.lua` and so on. Note that this works *relative to the current program*, so if your
|
||||
program is actually called `folder/program`, then we'll look for `folder/my_library.lua`, etc...
|
||||
|
||||
One other caveat is loading libraries from sub-directories. For instance, say we have a file
|
||||
`my/fancy/library.lua`. This can be loaded by using `require("my.fancy.library")` - the '.'s are replaced with '/'
|
||||
before we start looking for the library.
|
||||
|
||||
## External links
|
||||
There are several external resources which go into require in a little more detail:
|
||||
|
||||
- The [Lua Module tutorial](http://lua-users.org/wiki/ModulesTutorial) on the Lua wiki.
|
||||
- [Lua's manual section on @{require}](https://www.lua.org/manual/5.1/manual.html#pdf-require).
|
1
doc/head.html
Normal file
1
doc/head.html
Normal file
@@ -0,0 +1 @@
|
||||
<meta name="theme-color" content="#c8d87c">
|
BIN
doc/images/basic-terminal.png
Normal file
BIN
doc/images/basic-terminal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
BIN
doc/images/peripherals.png
Normal file
BIN
doc/images/peripherals.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 KiB |
BIN
doc/images/turtle.png
Normal file
BIN
doc/images/turtle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 163 KiB |
55
doc/index.md
Normal file
55
doc/index.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# 
|
||||
CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the
|
||||
much-beloved [ComputerCraft], it continues its legacy with better performance, stability, and a wealth of new features.
|
||||
|
||||
CC: Tweaked can be installed from [CurseForge] or [Modrinth]. It requires the [Minecraft Forge][forge] mod loader, but
|
||||
[versions are available for Fabric][ccrestitched].
|
||||
|
||||
## Features
|
||||
Controlled using the [Lua programming language][lua], CC: Tweaked's computers provides all the tools you need to start
|
||||
writing code and automating your Minecraft world.
|
||||
|
||||
{.big-image}
|
||||
|
||||
While computers are incredibly powerful, they're rather limited by their inability to move about. *Turtles* are the
|
||||
solution here. They can move about the world, placing and breaking blocks, swinging a sword to protect you from zombies,
|
||||
or whatever else you program them to!
|
||||
|
||||
{.big-image}
|
||||
|
||||
Not all problems can be solved with a pickaxe though, and so CC: Tweaked also provides a bunch of additional peripherals
|
||||
for your computers. You can play a tune with speakers, display text or images on a monitor, connect all your
|
||||
computers together with modems, and much more.
|
||||
|
||||
Computers can now also interact with inventories such as chests, allowing you to build complex inventory and item
|
||||
management systems.
|
||||
|
||||
{.big-image}
|
||||
|
||||
## Getting Started
|
||||
While ComputerCraft is lovely for both experienced programmers and for people who have never coded before, it can be a
|
||||
little daunting getting started. Thankfully, there's several fantastic tutorials out there:
|
||||
|
||||
- [Direwolf20's ComputerCraft tutorials](https://www.youtube.com/watch?v=wrUHUhfCY5A "ComputerCraft Tutorial Episode 1 - HELP! and Hello World")
|
||||
- [Sethbling's ComputerCraft series](https://www.youtube.com/watch?v=DSsx4VSe-Uk "Programming Tutorial with Minecraft Turtles -- Ep. 1: Intro to Turtles and If-Then-Else_End")
|
||||
- [Lyqyd's Computer Basics 1](http://www.computercraft.info/forums2/index.php?/topic/15033-computer-basics-i/ "Computer Basics I")
|
||||
|
||||
Once you're a little more familiar with the mod, the sidebar and links below provide more detailed documentation on the
|
||||
various APIs and peripherals provided by the mod.
|
||||
|
||||
If you get stuck, do pop in to the [Minecraft Computer Mod Discord guild][discord] or ComputerCraft's
|
||||
[IRC channel][irc].
|
||||
|
||||
## Get Involved
|
||||
CC: Tweaked lives on [GitHub]. If you've got any ideas, feedback or bugs please do [create an issue][bug].
|
||||
|
||||
[github]: https://github.com/cc-tweaked/CC-Tweaked/ "CC: Tweaked on GitHub"
|
||||
[bug]: https://github.com/cc-tweaked/CC-Tweaked/issues/new/choose
|
||||
[computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
|
||||
[curseforge]: https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked from CurseForge"
|
||||
[modrinth]: https://modrinth.com/mod/gu7yAYhd "Download CC: Tweaked from Modrinth"
|
||||
[forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
|
||||
[ccrestitched]: https://www.curseforge.com/minecraft/mc-mods/cc-restitched "Download CC: Restitched from CurseForge"
|
||||
[lua]: https://www.lua.org/ "Lua's main website"
|
||||
[discord]: https://discord.computercraft.cc "The Minecraft Computer Mods Discord"
|
||||
[irc]: http://webchat.esper.net/?channels=computercraft "IRC webchat on EsperNet"
|
BIN
doc/logo.png
Normal file
BIN
doc/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
36
doc/stub/fs.lua
Normal file
36
doc/stub/fs.lua
Normal file
@@ -0,0 +1,36 @@
|
||||
--- The FS API allows you to manipulate files and the filesystem.
|
||||
--
|
||||
-- @module fs
|
||||
|
||||
--- Returns true if a path is mounted to the parent filesystem.
|
||||
--
|
||||
-- The root filesystem "/" is considered a mount, along with disk folders and
|
||||
-- the rom folder. Other programs (such as network shares) can exstend this to
|
||||
-- make other mount types by correctly assigning their return value for getDrive.
|
||||
--
|
||||
-- @tparam string path The path to check.
|
||||
-- @treturn boolean If the path is mounted, rather than a normal file/folder.
|
||||
-- @throws If the path does not exist.
|
||||
-- @see getDrive
|
||||
-- @since 1.87.0
|
||||
function isDriveRoot(path) end
|
||||
|
||||
--[[- Provides completion for a file or directory name, suitable for use with
|
||||
@{_G.read}.
|
||||
|
||||
When a directory is a possible candidate for completion, two entries are
|
||||
included - one with a trailing slash (indicating that entries within this
|
||||
directory exist) and one without it (meaning this entry is an immediate
|
||||
completion candidate). `include_dirs` can be set to @{false} to only include
|
||||
those with a trailing slash.
|
||||
|
||||
@tparam string path The path to complete.
|
||||
@tparam string location The location where paths are resolved from.
|
||||
@tparam[opt] boolean include_files When @{false}, only directories will be
|
||||
included in the returned list.
|
||||
@tparam[opt] boolean include_dirs When @{false}, "raw" directories will not be
|
||||
included in the returned list.
|
||||
@treturn { string... } A list of possible completion candidates.
|
||||
@since 1.74
|
||||
]]
|
||||
function complete(path, location, include_files, include_dirs) end
|
133
doc/stub/global.lua
Normal file
133
doc/stub/global.lua
Normal file
@@ -0,0 +1,133 @@
|
||||
--[[-
|
||||
Functions in the global environment, defined in `bios.lua`. This does not
|
||||
include standard Lua functions.
|
||||
|
||||
@module _G
|
||||
]]
|
||||
|
||||
--[[- Pauses execution for the specified number of seconds.
|
||||
|
||||
As it waits for a fixed amount of world ticks, `time` will automatically be
|
||||
rounded up to the nearest multiple of 0.05 seconds. If you are using coroutines
|
||||
or the @{parallel|parallel API}, it will only pause execution of the current
|
||||
thread, not the whole program.
|
||||
|
||||
:::tip
|
||||
Because sleep internally uses timers, it is a function that yields. This means
|
||||
that you can use it to prevent "Too long without yielding" errors, however, as
|
||||
the minimum sleep time is 0.05 seconds, it will slow your program down.
|
||||
:::
|
||||
|
||||
:::caution
|
||||
Internally, this function queues and waits for a timer event (using
|
||||
@{os.startTimer}), however it does not listen for any other events. This means
|
||||
that any event that occurs while sleeping will be entirely discarded. If you
|
||||
need to receive events while sleeping, consider using @{os.startTimer|timers},
|
||||
or the @{parallel|parallel API}.
|
||||
:::
|
||||
|
||||
@tparam number time The number of seconds to sleep for, rounded up to the
|
||||
nearest multiple of 0.05.
|
||||
|
||||
@see os.startTimer
|
||||
@usage Sleep for three seconds.
|
||||
|
||||
print("Sleeping for three seconds")
|
||||
sleep(3)
|
||||
print("Done!")
|
||||
]]
|
||||
function sleep(time) end
|
||||
|
||||
--- Writes a line of text to the screen without a newline at the end, wrapping
|
||||
-- text if necessary.
|
||||
--
|
||||
-- @tparam string text The text to write to the string
|
||||
-- @treturn number The number of lines written
|
||||
-- @see print A wrapper around write that adds a newline and accepts multiple arguments
|
||||
-- @usage write("Hello, world")
|
||||
function write(text) end
|
||||
|
||||
--- Prints the specified values to the screen separated by spaces, wrapping if
|
||||
-- necessary. After printing, the cursor is moved to the next line.
|
||||
--
|
||||
-- @param ... The values to print on the screen
|
||||
-- @treturn number The number of lines written
|
||||
-- @usage print("Hello, world!")
|
||||
function print(...) end
|
||||
|
||||
--- Prints the specified values to the screen in red, separated by spaces,
|
||||
-- wrapping if necessary. After printing, the cursor is moved to the next line.
|
||||
--
|
||||
-- @param ... The values to print on the screen
|
||||
-- @usage printError("Something went wrong!")
|
||||
function printError(...) end
|
||||
|
||||
--[[- Reads user input from the terminal, automatically handling arrow keys,
|
||||
pasting, character replacement, history scrollback, auto-completion, and
|
||||
default values.
|
||||
|
||||
@tparam[opt] string replaceChar A character to replace each typed character with.
|
||||
This can be used for hiding passwords, for example.
|
||||
@tparam[opt] table history A table holding history items that can be scrolled
|
||||
back to with the up/down arrow keys. The oldest item is at index 1, while the
|
||||
newest item is at the highest index.
|
||||
@tparam[opt] function(partial: string):({ string... }|nil) completeFn A function
|
||||
to be used for completion. This function should take the partial text typed so
|
||||
far, and returns a list of possible completion options.
|
||||
@tparam[opt] string default Default text which should already be entered into
|
||||
the prompt.
|
||||
|
||||
@treturn string The text typed in.
|
||||
|
||||
@see cc.completion For functions to help with completion.
|
||||
@usage Read a string and echo it back to the user
|
||||
|
||||
write("> ")
|
||||
local msg = read()
|
||||
print(msg)
|
||||
|
||||
@usage Prompt a user for a password.
|
||||
|
||||
while true do
|
||||
write("Password> ")
|
||||
local pwd = read("*")
|
||||
if pwd == "let me in" then break end
|
||||
print("Incorrect password, try again.")
|
||||
end
|
||||
print("Logged in!")
|
||||
|
||||
@usage A complete example with completion, history and a default value.
|
||||
|
||||
local completion = require "cc.completion"
|
||||
local history = { "potato", "orange", "apple" }
|
||||
local choices = { "apple", "orange", "banana", "strawberry" }
|
||||
write("> ")
|
||||
local msg = read(nil, history, function(text) return completion.choice(text, choices) end, "app")
|
||||
print(msg)
|
||||
|
||||
@changed 1.74 Added `completeFn` parameter.
|
||||
@changed 1.80pr1 Added `default` parameter.
|
||||
]]
|
||||
function read(replaceChar, history, completeFn, default) end
|
||||
|
||||
--- The ComputerCraft and Minecraft version of the current computer environment.
|
||||
--
|
||||
-- For example, `ComputerCraft 1.93.0 (Minecraft 1.15.2)`.
|
||||
-- @usage _HOST
|
||||
-- @since 1.76
|
||||
_HOST = _HOST
|
||||
|
||||
--[[- The default computer settings as defined in the ComputerCraft
|
||||
configuration.
|
||||
|
||||
This is a comma-separated list of settings pairs defined by the mod
|
||||
configuration or server owner. By default, it is empty.
|
||||
|
||||
An example value to disable autocompletion:
|
||||
|
||||
shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false
|
||||
|
||||
@usage _CC_DEFAULT_SETTINGS
|
||||
@since 1.77
|
||||
]]
|
||||
_CC_DEFAULT_SETTINGS = _CC_DEFAULT_SETTINGS
|
181
doc/stub/http.lua
Normal file
181
doc/stub/http.lua
Normal file
@@ -0,0 +1,181 @@
|
||||
--- The http library allows communicating with web servers, sending and
|
||||
-- receiving data from them.
|
||||
--
|
||||
-- @module http
|
||||
-- @since 1.1
|
||||
|
||||
--- Asynchronously make a HTTP request to the given url.
|
||||
--
|
||||
-- This returns immediately, a [`http_success`](#http-success-event) or
|
||||
-- [`http_failure`](#http-failure-event) will be queued once the request has
|
||||
-- completed.
|
||||
--
|
||||
-- @tparam string url The url to request
|
||||
-- @tparam[opt] string body An optional string containing the body of the
|
||||
-- request. If specified, a `POST` request will be made instead.
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of this request.
|
||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
|
||||
-- the body will not be UTF-8 encoded, and the received response will not be
|
||||
-- decoded.
|
||||
--
|
||||
-- @tparam[2] {
|
||||
-- url = string, body? = string, headers? = { [string] = string },
|
||||
-- binary? = boolean, method? = string, redirect? = boolean,
|
||||
-- } request Options for the request.
|
||||
--
|
||||
-- This table form is an expanded version of the previous syntax. All arguments
|
||||
-- from above are passed in as fields instead (for instance,
|
||||
-- `http.request("https://example.com")` becomes `http.request { url =
|
||||
-- "https://example.com" }`).
|
||||
--
|
||||
-- This table also accepts several additional options:
|
||||
--
|
||||
-- - `method`: Which HTTP method to use, for instance `"PATCH"` or `"DELETE"`.
|
||||
-- - `redirect`: Whether to follow HTTP redirects. Defaults to true.
|
||||
--
|
||||
-- @see http.get For a synchronous way to make GET requests.
|
||||
-- @see http.post For a synchronous way to make POST requests.
|
||||
--
|
||||
-- @changed 1.63 Added argument for headers.
|
||||
-- @changed 1.80pr1 Added argument for binary handles.
|
||||
-- @changed 1.80pr1.6 Added support for table argument.
|
||||
-- @changed 1.86.0 Added PATCH and TRACE methods.
|
||||
function request(...) end
|
||||
|
||||
--- Make a HTTP GET request to the given url.
|
||||
--
|
||||
-- @tparam string url The url to request
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of this request.
|
||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
|
||||
-- the body will not be UTF-8 encoded, and the received response will not be
|
||||
-- decoded.
|
||||
--
|
||||
-- @tparam[2] {
|
||||
-- url = string, headers? = { [string] = string },
|
||||
-- binary? = boolean, method? = string, redirect? = boolean,
|
||||
-- } request Options for the request. See @{http.request} for details on how
|
||||
-- these options behave.
|
||||
--
|
||||
-- @treturn Response The resulting http response, which can be read from.
|
||||
-- @treturn[2] nil When the http request failed, such as in the event of a 404
|
||||
-- error or connection timeout.
|
||||
-- @treturn string A message detailing why the request failed.
|
||||
-- @treturn Response|nil The failing http response, if available.
|
||||
--
|
||||
-- @changed 1.63 Added argument for headers.
|
||||
-- @changed 1.80pr1 Response handles are now returned on error if available.
|
||||
-- @changed 1.80pr1 Added argument for binary handles.
|
||||
-- @changed 1.80pr1.6 Added support for table argument.
|
||||
-- @changed 1.86.0 Added PATCH and TRACE methods.
|
||||
--
|
||||
-- @usage Make a request to [example.tweaked.cc](https://example.tweaked.cc),
|
||||
-- and print the returned page.
|
||||
-- ```lua
|
||||
-- local request = http.get("https://example.tweaked.cc")
|
||||
-- print(request.readAll())
|
||||
-- -- => HTTP is working!
|
||||
-- request.close()
|
||||
-- ```
|
||||
function get(...) end
|
||||
|
||||
--- Make a HTTP POST request to the given url.
|
||||
--
|
||||
-- @tparam string url The url to request
|
||||
-- @tparam string body The body of the POST request.
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of this request.
|
||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
|
||||
-- the body will not be UTF-8 encoded, and the received response will not be
|
||||
-- decoded.
|
||||
--
|
||||
-- @tparam[2] {
|
||||
-- url = string, body? = string, headers? = { [string] = string },
|
||||
-- binary? = boolean, method? = string, redirect? = boolean,
|
||||
-- } request Options for the request. See @{http.request} for details on how
|
||||
-- these options behave.
|
||||
--
|
||||
-- @treturn Response The resulting http response, which can be read from.
|
||||
-- @treturn[2] nil When the http request failed, such as in the event of a 404
|
||||
-- error or connection timeout.
|
||||
-- @treturn string A message detailing why the request failed.
|
||||
-- @treturn Response|nil The failing http response, if available.
|
||||
--
|
||||
-- @since 1.31
|
||||
-- @changed 1.63 Added argument for headers.
|
||||
-- @changed 1.80pr1 Response handles are now returned on error if available.
|
||||
-- @changed 1.80pr1 Added argument for binary handles.
|
||||
-- @changed 1.80pr1.6 Added support for table argument.
|
||||
-- @changed 1.86.0 Added PATCH and TRACE methods.
|
||||
function post(...) end
|
||||
|
||||
--- Asynchronously determine whether a URL can be requested.
|
||||
--
|
||||
-- If this returns `true`, one should also listen for [`http_check`
|
||||
-- events](#http-check-event) which will container further information about
|
||||
-- whether the URL is allowed or not.
|
||||
--
|
||||
-- @tparam string url The URL to check.
|
||||
-- @treturn true When this url is not invalid. This does not imply that it is
|
||||
-- allowed - see the comment above.
|
||||
-- @treturn[2] false When this url is invalid.
|
||||
-- @treturn string A reason why this URL is not valid (for instance, if it is
|
||||
-- malformed, or blocked).
|
||||
--
|
||||
-- @see http.checkURL For a synchronous version.
|
||||
function checkURLAsync(url) end
|
||||
|
||||
--- Determine whether a URL can be requested.
|
||||
--
|
||||
-- If this returns `true`, one should also listen for [`http_check`
|
||||
-- events](#http-check-event) which will container further information about
|
||||
-- whether the URL is allowed or not.
|
||||
--
|
||||
-- @tparam string url The URL to check.
|
||||
-- @treturn true When this url is valid and can be requested via @{http.request}.
|
||||
-- @treturn[2] false When this url is invalid.
|
||||
-- @treturn string A reason why this URL is not valid (for instance, if it is
|
||||
-- malformed, or blocked).
|
||||
--
|
||||
-- @see http.checkURLAsync For an asynchronous version.
|
||||
--
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- print(http.checkURL("https://example.tweaked.cc/"))
|
||||
-- -- => true
|
||||
-- print(http.checkURL("http://localhost/"))
|
||||
-- -- => false Domain not permitted
|
||||
-- print(http.checkURL("not a url"))
|
||||
-- -- => false URL malformed
|
||||
-- ```
|
||||
function checkURL(url) end
|
||||
|
||||
--- Open a websocket.
|
||||
--
|
||||
-- @tparam string url The websocket url to connect to. This should have the
|
||||
-- `ws://` or `wss://` protocol.
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of the initial websocket connection.
|
||||
--
|
||||
-- @treturn Websocket The websocket connection.
|
||||
-- @treturn[2] false If the websocket connection failed.
|
||||
-- @treturn string An error message describing why the connection failed.
|
||||
-- @since 1.80pr1.1
|
||||
-- @changed 1.80pr1.3 No longer asynchronous.
|
||||
-- @changed 1.95.3 Added User-Agent to default headers.
|
||||
function websocket(url, headers) end
|
||||
|
||||
--- Asynchronously open a websocket.
|
||||
--
|
||||
-- This returns immediately, a [`websocket_success`](#websocket-success-event)
|
||||
-- or [`websocket_failure`](#websocket-failure-event) will be queued once the
|
||||
-- request has completed.
|
||||
--
|
||||
-- @tparam string url The websocket url to connect to. This should have the
|
||||
-- `ws://` or `wss://` protocol.
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of the initial websocket connection.
|
||||
-- @since 1.80pr1.3
|
||||
-- @changed 1.95.3 Added User-Agent to default headers.
|
||||
function websocketAsync(url, headers) end
|
128
doc/stub/os.lua
Normal file
128
doc/stub/os.lua
Normal file
@@ -0,0 +1,128 @@
|
||||
-- Defined in bios.lua
|
||||
|
||||
--[[- Loads the given API into the global environment.
|
||||
|
||||
This function loads and executes the file at the given path, and all global
|
||||
variables and functions exported by it will by available through the use of
|
||||
`myAPI.<function name>`, where `myAPI` is the base name of the API file.
|
||||
|
||||
@tparam string path The path of the API to load.
|
||||
@treturn boolean Whether or not the API was successfully loaded.
|
||||
@since 1.2
|
||||
|
||||
@deprecated When possible it's best to avoid using this function. It pollutes
|
||||
the global table and can mask errors.
|
||||
|
||||
@{require} should be used to load libraries instead.
|
||||
]]
|
||||
function loadAPI(path) end
|
||||
|
||||
--- Unloads an API which was loaded by @{os.loadAPI}.
|
||||
--
|
||||
-- This effectively removes the specified table from `_G`.
|
||||
--
|
||||
-- @tparam string name The name of the API to unload.
|
||||
-- @since 1.2
|
||||
-- @deprecated See @{os.loadAPI} for why.
|
||||
function unloadAPI(name) end
|
||||
|
||||
--[[- Pause execution of the current thread and waits for any events matching
|
||||
`filter`.
|
||||
|
||||
This function @{coroutine.yield|yields} the current process and waits for it
|
||||
to be resumed with a vararg list where the first element matches `filter`.
|
||||
If no `filter` is supplied, this will match all events.
|
||||
|
||||
Unlike @{os.pullEventRaw}, it will stop the application upon a "terminate"
|
||||
event, printing the error "Terminated".
|
||||
|
||||
@tparam[opt] string filter Event to filter for.
|
||||
@treturn string event The name of the event that fired.
|
||||
@treturn any param... Optional additional parameters of the event.
|
||||
@usage Listen for `mouse_click` events.
|
||||
|
||||
while true do
|
||||
local event, button, x, y = os.pullEvent("mouse_click")
|
||||
print("Button", button, "was clicked at", x, ",", y)
|
||||
end
|
||||
|
||||
@usage Listen for multiple events.
|
||||
|
||||
while true do
|
||||
local eventData = {os.pullEvent()}
|
||||
local event = eventData[1]
|
||||
|
||||
if event == "mouse_click" then
|
||||
print("Button", eventData[2], "was clicked at", eventData[3], ",", eventData[4])
|
||||
elseif event == "key" then
|
||||
print("Key code", eventData[2], "was pressed")
|
||||
end
|
||||
end
|
||||
|
||||
@see os.pullEventRaw To pull the terminate event.
|
||||
@changed 1.3 Added filter argument.
|
||||
]]
|
||||
function pullEvent(filter) end
|
||||
|
||||
--[[- Pause execution of the current thread and waits for events, including the
|
||||
`terminate` event.
|
||||
|
||||
This behaves almost the same as @{os.pullEvent}, except it allows you to handle
|
||||
the `terminate` event yourself - the program will not stop execution when
|
||||
<kbd>Ctrl+T</kbd> is pressed.
|
||||
|
||||
@tparam[opt] string filter Event to filter for.
|
||||
@treturn string event The name of the event that fired.
|
||||
@treturn any param... Optional additional parameters of the event.
|
||||
@usage Listen for `terminate` events.
|
||||
|
||||
while true do
|
||||
local event = os.pullEventRaw()
|
||||
if event == "terminate" then
|
||||
print("Caught terminate event!")
|
||||
end
|
||||
end
|
||||
|
||||
@see os.pullEvent To pull events normally.
|
||||
]]
|
||||
function pullEventRaw(filter) end
|
||||
|
||||
--- Pauses execution for the specified number of seconds, alias of @{_G.sleep}.
|
||||
--
|
||||
-- @tparam number time The number of seconds to sleep for, rounded up to the
|
||||
-- nearest multiple of 0.05.
|
||||
function sleep(time) end
|
||||
|
||||
--- Get the current CraftOS version (for example, `CraftOS 1.8`).
|
||||
--
|
||||
-- This is defined by `bios.lua`. For the current version of CC:Tweaked, this
|
||||
-- should return `CraftOS 1.8`.
|
||||
--
|
||||
-- @treturn string The current CraftOS version.
|
||||
-- @usage os.version()
|
||||
function version() end
|
||||
|
||||
--[[- Run the program at the given path with the specified environment and
|
||||
arguments.
|
||||
|
||||
This function does not resolve program names like the shell does. This means
|
||||
that, for example, `os.run("edit")` will not work. As well as this, it does not
|
||||
provide access to the @{shell} API in the environment. For this behaviour, use
|
||||
@{shell.run} instead.
|
||||
|
||||
If the program cannot be found, or failed to run, it will print the error and
|
||||
return `false`. If you want to handle this more gracefully, use an alternative
|
||||
such as @{loadfile}.
|
||||
|
||||
@tparam table env The environment to run the program with.
|
||||
@tparam string path The exact path of the program to run.
|
||||
@param ... The arguments to pass to the program.
|
||||
@treturn boolean Whether or not the program ran successfully.
|
||||
@usage Run the default shell from within your program:
|
||||
|
||||
os.run({}, "/rom/programs/shell.lua")
|
||||
|
||||
@see shell.run
|
||||
@see loadfile
|
||||
]]
|
||||
function run(env, path, ...) end
|
14
doc/stub/turtle.lua
Normal file
14
doc/stub/turtle.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
--[[- Craft a recipe based on the turtle's inventory.
|
||||
|
||||
The turtle's inventory should set up like a crafting grid. For instance, to
|
||||
craft sticks, slots 1 and 5 should contain planks. _All_ other slots should be
|
||||
empty, including those outside the crafting "grid".
|
||||
|
||||
@tparam[opt=64] number limit The maximum number of crafting steps to run.
|
||||
@throws When limit is less than 1 or greater than 64.
|
||||
@treturn[1] true If crafting succeeds.
|
||||
@treturn[2] false If crafting fails.
|
||||
@treturn string A string describing why crafting failed.
|
||||
@since 1.4
|
||||
]]
|
||||
function craft(limit) end
|
8
gradle.properties
Normal file
8
gradle.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
# Mod properties
|
||||
mod_version=1.100.4
|
||||
|
||||
# Minecraft properties (update mods.toml when changing)
|
||||
mc_version=1.16.5
|
||||
mapping_version=2021.08.08
|
||||
forge_version=36.2.20
|
||||
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip
|
||||
|
286
gradlew
vendored
286
gradlew
vendored
@@ -1,78 +1,129 @@
|
||||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -81,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@@ -89,84 +140,95 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
43
gradlew.bat
vendored
43
gradlew.bat
vendored
@@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -35,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@@ -45,28 +64,14 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
117
illuaminate.sexp
Normal file
117
illuaminate.sexp
Normal file
@@ -0,0 +1,117 @@
|
||||
; -*- mode: Lisp;-*-
|
||||
|
||||
(sources
|
||||
/doc/events/
|
||||
/doc/guides/
|
||||
/doc/stub/
|
||||
/build/docs/luaJavadoc/
|
||||
/src/main/resources/*/computercraft/lua/bios.lua
|
||||
/src/main/resources/*/computercraft/lua/rom/
|
||||
/src/test/resources/test-rom
|
||||
/src/web/mount)
|
||||
|
||||
|
||||
(doc
|
||||
(destination build/docs/lua)
|
||||
(index doc/index.md)
|
||||
|
||||
(site
|
||||
(title "CC: Tweaked")
|
||||
(logo src/main/resources/pack.png)
|
||||
(url https://tweaked.cc/)
|
||||
(source-link https://github.com/cc-tweaked/CC-Tweaked/blob/${commit}/${path}#L${line})
|
||||
|
||||
(styles src/web/styles.css)
|
||||
(scripts build/rollup/index.js)
|
||||
(head doc/head.html))
|
||||
|
||||
(module-kinds
|
||||
(peripheral Peripherals)
|
||||
(generic_peripheral "Generic Peripherals")
|
||||
(event Events)
|
||||
(guide Guides))
|
||||
|
||||
(library-path
|
||||
/doc/stub/
|
||||
/build/docs/luaJavadoc/
|
||||
|
||||
/src/main/resources/*/computercraft/lua/rom/apis/
|
||||
/src/main/resources/*/computercraft/lua/rom/apis/command/
|
||||
/src/main/resources/*/computercraft/lua/rom/apis/turtle/
|
||||
|
||||
/src/main/resources/*/computercraft/lua/rom/modules/main/
|
||||
/src/main/resources/*/computercraft/lua/rom/modules/command/
|
||||
/src/main/resources/*/computercraft/lua/rom/modules/turtle/))
|
||||
|
||||
(at /
|
||||
(linters
|
||||
syntax:string-index
|
||||
|
||||
;; It'd be nice to avoid this, but right now there's a lot of instances of
|
||||
;; it.
|
||||
-var:set-loop
|
||||
|
||||
;; It's useful to name arguments for documentation, so we allow this. It'd
|
||||
;; be good to find a compromise in the future, but this works for now.
|
||||
-var:unused-arg)
|
||||
|
||||
(lint
|
||||
(bracket-spaces
|
||||
(call no-space)
|
||||
(function-args no-space)
|
||||
(parens no-space)
|
||||
(table space)
|
||||
(index no-space))
|
||||
|
||||
(allow-clarifying-parens true)
|
||||
|
||||
;; colours imports from colors, and we don't handle that right now.
|
||||
;; keys is entirely dynamic, so we skip it.
|
||||
(dynamic-modules colours keys _G)
|
||||
|
||||
(globals
|
||||
:max
|
||||
_CC_DEFAULT_SETTINGS
|
||||
_CC_DISABLE_LUA51_FEATURES
|
||||
_HOST
|
||||
;; Ideally we'd pick these up from bios.lua, but illuaminate currently
|
||||
;; isn't smart enough.
|
||||
sleep write printError read rs)))
|
||||
|
||||
;; We disable the unused global linter in bios.lua and the APIs. In the future
|
||||
;; hopefully we'll get illuaminate to handle this.
|
||||
(at
|
||||
(/src/main/resources/*/computercraft/lua/bios.lua
|
||||
/src/main/resources/*/computercraft/lua/rom/apis/)
|
||||
(linters -var:unused-global)
|
||||
(lint (allow-toplevel-global true)))
|
||||
|
||||
;; Silence some variable warnings in documentation stubs.
|
||||
(at (/doc/stub/ /build/docs/luaJavadoc/)
|
||||
(linters -var:unused-global)
|
||||
(lint (allow-toplevel-global true)))
|
||||
|
||||
;; Suppress warnings for currently undocumented modules.
|
||||
(at
|
||||
(; Lua APIs
|
||||
/src/main/resources/*/computercraft/lua/rom/apis/io.lua
|
||||
/src/main/resources/*/computercraft/lua/rom/apis/window.lua)
|
||||
|
||||
(linters -doc:undocumented -doc:undocumented-arg -doc:undocumented-return))
|
||||
|
||||
;; Suppress warnings for various APIs using its own deprecated members.
|
||||
(at
|
||||
(/src/main/resources/*/computercraft/lua/bios.lua
|
||||
/src/main/resources/*/computercraft/lua/rom/apis/turtle/turtle.lua)
|
||||
(linters -var:deprecated))
|
||||
|
||||
(at /src/test/resources/test-rom
|
||||
; We should still be able to test deprecated members.
|
||||
(linters -var:deprecated)
|
||||
|
||||
(lint
|
||||
(globals
|
||||
:max sleep write
|
||||
cct_test describe expect howlci fail it pending stub)))
|
||||
|
||||
(at /src/web/mount/expr_template.lua (lint (globals :max __expr__)))
|
Binary file not shown.
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/core"/>
|
||||
<classpathentry excluding="org/luaj/vm2/luajc/antlr/|org/luaj/vm2/luajc/lst/|org/luaj/vm2/luajc/JavaCodeGenerator.java" kind="src" path="src/jse"/>
|
||||
<classpathentry kind="src" path="src/jme"/>
|
||||
<classpathentry kind="src" path="test/java"/>
|
||||
<classpathentry kind="src" path="test/junit"/>
|
||||
<classpathentry kind="src" path="test/lua"/>
|
||||
<classpathentry kind="src" path="examples/jse"/>
|
||||
<classpathentry kind="src" path="examples/jme"/>
|
||||
<classpathentry kind="src" path="examples/lua"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
|
||||
<classpathentry kind="lib" path="lib/midpapi20.jar"/>
|
||||
<classpathentry kind="lib" path="lib/cldcapi11.jar"/>
|
||||
<classpathentry kind="lib" path="lib/bcel-5.2.jar"/>
|
||||
<classpathentry kind="var" path="JRE_LIB"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>luaj-vm</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@@ -1,780 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Getting Started with LuaJ</title>
|
||||
<link rel="stylesheet" type="text/css" href="http://www.lua.org/lua.css">
|
||||
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<hr>
|
||||
<h1>
|
||||
<a href="README.html"><img src="http://sourceforge.net/dbimage.php?id=196139" alt="" border="0"></a>
|
||||
|
||||
Getting Started with LuaJ
|
||||
|
||||
</h1>
|
||||
James Roseborough, Ian Farmer, Version 2.0.3
|
||||
<p>
|
||||
<small>
|
||||
Copyright © 2009-2012 Luaj.org.
|
||||
Freely available under the terms of the
|
||||
<a href="http://sourceforge.net/dbimage.php?id=196142">Luaj license</a>.
|
||||
</small>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
<a href="#1">introduction</a>
|
||||
·
|
||||
<a href="#2">examples</a>
|
||||
·
|
||||
<a href="#3">concepts</a>
|
||||
·
|
||||
<a href="#4">libraries</a>
|
||||
·
|
||||
<a href="#5">luaj api</a>
|
||||
·
|
||||
<a href="#6">parser</a>
|
||||
·
|
||||
<a href="#7">building</a>
|
||||
·
|
||||
<a href="#8">downloads</a>
|
||||
·
|
||||
<a href="#9">release notes</a>
|
||||
|
||||
<!-- ====================================================================== -->
|
||||
<p>
|
||||
|
||||
<h1>1 - <a name="1">Introduction</a></h1>
|
||||
<h2>Goals of Luaj</h2>
|
||||
Luaj is a lua interpreter based on the 5.1.x version of lua with the following goals in mind:
|
||||
<ul>
|
||||
<li>Java-centric implementation of lua vm built to leverage standard Java features.
|
||||
<li>Lightweight, high performance execution of lua.
|
||||
<li>Multi-platform to be able to run on JME, JSE, or JEE environments.
|
||||
<li>Complete set of libraries and tools for integration into real-world projects.
|
||||
<li>Dependable due to sufficient unit testing of vm and library features.
|
||||
</ul>
|
||||
|
||||
<h2>Differences with 1.0</h2>
|
||||
In addition to the basic goals of luaj, version 2.0 is aimed
|
||||
at improving on the 1.0 vm in the following aspects.
|
||||
<ul>
|
||||
<li>Support for compiling lua source code into Java source code.
|
||||
<li>Support for compiling lua bytecode directly into Java bytecode.
|
||||
<li>Improved performance of of lua bytecode processing.
|
||||
<li>Stackless vm design centered around dynamically typed objects.
|
||||
<li>More alignment with C API (see <a href="names.csv">names.csv</a> for details)
|
||||
<li>Improved class and package naming conventions.
|
||||
<li>Improved unit tests of core classes.
|
||||
<li>Improved quality due to major redesign and rewrite of core elements.
|
||||
<li>More complete implementation including weak keys and values, and all metatags.
|
||||
</ul>
|
||||
|
||||
<h2>Performance</h2>
|
||||
Good performance is a major goal of luaj.
|
||||
The following table provides measured execution times on a subset of benchmarks from
|
||||
<a href="http://shootout.alioth.debian.org/">the computer language benchmarks game</a>
|
||||
in comparison with the standard C distribution.
|
||||
<table cellspacing="10"><tr><td><table>
|
||||
<tr valign="top">
|
||||
<td><u>Project</td>
|
||||
<td><u>Version</td>
|
||||
<td><u>Mode</td>
|
||||
<td rowspan="9"> </td>
|
||||
<td colspan="4" align="center"><u>Benchmark execution time (sec)</td>
|
||||
<td rowspan="9"> </td>
|
||||
<td><u>Language</td>
|
||||
<td><u>Sample command</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td colspan="2"></td>
|
||||
<td></td>
|
||||
<td><em>binarytrees 15</em></td>
|
||||
<td><em>fannkuch 10</em></td>
|
||||
<td><em>nbody 1e6</em></td>
|
||||
<td><em>nsieve 9</em></td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>luaj</td>
|
||||
<td>2.0</td>
|
||||
<td>-b (luajc)</td>
|
||||
<td>2.980</td>
|
||||
<td>5.073</td>
|
||||
<td>16.794</td>
|
||||
<td>11.274</td>
|
||||
<td>Java</td>
|
||||
<td>java -cp luaj-jse-2.0.3.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
|
||||
<tr valign="top">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>-j (lua2java)</td>
|
||||
<td>4.463</td>
|
||||
<td>5.884</td>
|
||||
<td>16.701</td>
|
||||
<td>13.789</td>
|
||||
<td></td>
|
||||
<td>java -cp luaj-jse-2.0.3.jar lua <b>-j</b> fannkuch.lua 10</td></tr>
|
||||
<tr valign="top">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>-n (interpreted)</td>
|
||||
<td>12.838</td>
|
||||
<td>23.290</td>
|
||||
<td>36.894</td>
|
||||
<td>15.163</td>
|
||||
<td></td>
|
||||
<td>java -cp luaj-jse-2.0.3.jar lua -n fannkuch.lua 10</td></tr>
|
||||
<tr valign="top">
|
||||
<td>lua</td>
|
||||
<td>5.1.4</td>
|
||||
<td></td>
|
||||
<td>17.637</td>
|
||||
<td>16.044</td>
|
||||
<td>15.201</td>
|
||||
<td>5.477</td>
|
||||
<td>C</td>
|
||||
<td>lua fannkuch.lua 10</td></tr>
|
||||
<tr valign="top">
|
||||
<td>jill</td>
|
||||
<td>1.0.1</td>
|
||||
<td></td>
|
||||
<td>44.512</td>
|
||||
<td>54.630</td>
|
||||
<td>72.172</td>
|
||||
<td>20.779</td>
|
||||
<td>Java</td>
|
||||
<td></td></tr>
|
||||
<tr valign="top">
|
||||
<td>kahlua</td>
|
||||
<td>1.0</td>
|
||||
<td>jse</td>
|
||||
<td>22.963</td>
|
||||
<td>63.277</td>
|
||||
<td>68.223</td>
|
||||
<td>21.529</td>
|
||||
<td>Java</td>
|
||||
<td></td></tr>
|
||||
<tr valign="top">
|
||||
<td>mochalua</td>
|
||||
<td>1.0</td>
|
||||
<td></td>
|
||||
<td>50.457</td>
|
||||
<td>70.368</td>
|
||||
<td>82.868</td>
|
||||
<td>41.262</td>
|
||||
<td>Java</td>
|
||||
<td></td></tr>
|
||||
</table></td></tr></table>
|
||||
|
||||
Luaj in interpreted mode performs well for the benchmarks, and even better when source-to-source (lua2java)
|
||||
or bytecode-to-bytecode (luajc) compilers are used,
|
||||
and actually executes <em>faster</em> than C-based lua in some cases.
|
||||
It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for all benchmarks tested.
|
||||
|
||||
<h1>2 - <a name="2">Simple Examples</a></h1>
|
||||
|
||||
<h2>Run a lua script in Java SE</h2>
|
||||
|
||||
<p>
|
||||
From the main distribution directory line type:
|
||||
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-2.0.3.jar lua examples/lua/hello.lua
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You should see the following output:
|
||||
<pre>
|
||||
hello, world
|
||||
</pre>
|
||||
|
||||
To see how luaj can be used to acccess most Java API's including swing, try:
|
||||
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-2.0.3.jar lua examples/lua/swingapp.lua
|
||||
</pre>
|
||||
|
||||
<h2>Compile lua source to lua bytecode</h2>
|
||||
|
||||
<p>
|
||||
From the main distribution directory line type:
|
||||
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-2.0.3.jar luac examples/lua/hello.lua
|
||||
java -cp lib/luaj-jse-2.0.3.jar lua luac.out
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The compiled output "luac.out" is lua bytecode and should run and produce the same result.
|
||||
|
||||
<h2>Compile lua source to java source</h2>
|
||||
|
||||
<p>
|
||||
Luaj can compile to lua source code to Java source code:
|
||||
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-2.0.3.jar lua2java -s examples/lua -d . hello.lua
|
||||
javac -cp lib/luaj-jse-2.0.3.jar hello.java
|
||||
java -cp "lib/luaj-jse-2.0.3.jar;." lua -l hello
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The output <em>hello.java</em> is Java source, that implements the logic in hello.lua directly.
|
||||
Once <em>hello.java</em> is compiled into <em>hello.class</em> it can be required and used in place of the original lua script, but with better performance.
|
||||
There are no additional dependencies for compiling or running source-to-source compiled lua.
|
||||
|
||||
<p>
|
||||
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-j</em></b> option when run in JDK 1.5 or higher:
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-2.0.3.jar lua -j examples/lua/hello.lua
|
||||
</pre>
|
||||
|
||||
<h2>Compile lua bytecode to java bytecode</h2>
|
||||
|
||||
<p>
|
||||
Luaj can compile lua sources or binaries directly to java bytecode if the bcel library is on the class path. From the main distribution directory line type:
|
||||
|
||||
<pre>
|
||||
ant bcel-lib
|
||||
java -cp "lib/luaj-jse-2.0.3.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua
|
||||
java -cp "lib/luaj-jse-2.0.3.jar;." lua -l hello
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The output <em>hello.class</em> is Java bytecode, should run and produce the same result.
|
||||
There is no runtime dependency on the bcel library,
|
||||
but the compiled classes must be in the class path at runtime, unless runtime jit-compiling via luajc and bcel are desired (see later sections).
|
||||
|
||||
<p>
|
||||
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
|
||||
<pre>
|
||||
java -cp "lib/luaj-jse-2.0.3.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Run a script in a Java Application</h2>
|
||||
|
||||
<p>
|
||||
The following pattern is used within Java SE
|
||||
|
||||
<pre>
|
||||
import org.luaj.vm2.*;
|
||||
import org.luaj.vm2.lib.jse.*;
|
||||
|
||||
String script = "examples/lua/hello.lua";
|
||||
LuaValue _G = JsePlatform.standardGlobals();
|
||||
_G.get("dofile").call( LuaValue.valueOf(script) );
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
A simple example may be found in
|
||||
<pre>
|
||||
examples/jse/SampleJseMain.java
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You must include the library <b>lib/luaj-jse-2.0.3.jar</b> in your class path.
|
||||
|
||||
<h2>Run a script in a MIDlet</h2>
|
||||
|
||||
<p>
|
||||
The for MIDlets the <em>JmePlatform</em> is used instead:
|
||||
|
||||
<pre>
|
||||
import org.luaj.vm2.*;
|
||||
import org.luaj.vm2.lib.jme.*;
|
||||
|
||||
String script = "examples/lua/hello.lua";
|
||||
LuaValue _G = JmePlatform.standardGlobals();
|
||||
_G.get("dofile").call( LuaValue.valueOf(script) );
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The file must be a resource within within the midlet jar for <em>dofile()</em> to find it.
|
||||
Any files included via <em>require()</em> must also be part of the midlet resources.
|
||||
|
||||
<p>
|
||||
A simple example may be found in
|
||||
<pre>
|
||||
examples/jme/SampleMIDlet.java
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You must include the library <b>lib/luaj-jme-2.0.3.jar</b> in your midlet jar.
|
||||
|
||||
<p>
|
||||
An ant script to build and run the midlet is in
|
||||
<pre>
|
||||
build-midlet.xml
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You must install the wireless toolkit and define <em>WTK_HOME</em> for this script to work.
|
||||
|
||||
<h2>Run a script using JSR-223 Dynamic Scripting</h2>
|
||||
|
||||
<p>
|
||||
The standard use of JSR-223 scripting engines may be used:
|
||||
|
||||
<pre>
|
||||
ScriptEngineManager mgr = new ScriptEngineManager();
|
||||
ScriptEngine e = mgr.getEngineByExtension(".lua");
|
||||
e.put("x", 25);
|
||||
e.eval("y = math.sqrt(x)");
|
||||
System.out.println( "y="+e.get("y") );
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
All standard aspects of script engines including compiled statements should be supported.
|
||||
|
||||
<p>
|
||||
You must include the library <b>lib/luaj-jse-2.0.3.jar</b> in your class path.
|
||||
|
||||
<p>
|
||||
A working example may be found in
|
||||
<pre>
|
||||
examples/jse/ScriptEngineSample.java
|
||||
</pre>
|
||||
|
||||
To compile and run it using Java 1.6 or higher:
|
||||
|
||||
<pre>
|
||||
javac examples/jse/ScriptEngineSample.java
|
||||
java -cp "lib/luaj-jse-2.0.3.jar;examples/jse" ScriptEngineSample
|
||||
</pre>
|
||||
|
||||
<h2>Excluding the lua bytecode compiler</h2>
|
||||
|
||||
By default, the compiler is included whenever <em>standardGlobals()</em> or <em>debugGlobals()</em> are called.
|
||||
Without a compiler, files can still be executed, but they must be compiled elsewhere beforehand.
|
||||
The "luac" utility is provided in the jse jar for this purpose, or a standard lua compiler can be used.
|
||||
|
||||
<p>
|
||||
To exclude the lua-to-lua-bytecode compiler, do not call
|
||||
<em>standardGlobals()</em> or <em>debugGlobals()</em>
|
||||
but instead initialize globals with including only those libraries
|
||||
that are needed and omitting the line:
|
||||
<pre>
|
||||
org.luaj.vm2.compiler.LuaC.install();
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Including the Lua2Java lua-source-to-Java-source compiler</h2>
|
||||
|
||||
<p>
|
||||
To compile from lua sources to Java sources for all lua loaded at runtime,
|
||||
install the Lua2Java compiler <em>after</em> globals have been created using:
|
||||
|
||||
<pre>
|
||||
org.luaj.vm2.jse.lua2java.Lua2Java.install();
|
||||
</pre>
|
||||
|
||||
This uses the system Java compiler to compile from Java source to Java bytecode,
|
||||
and cannot compile lua binary files containing lua bytecode at runtime.
|
||||
|
||||
<h2>Including the LuaJC lua-bytecode-to-Java-bytecode compiler</h2>
|
||||
|
||||
<p>
|
||||
To compile from lua to Java bytecode for all lua loaded at runtime,
|
||||
install the LuaJC compiler <em>after</em> globals have been created using:
|
||||
|
||||
<pre>
|
||||
org.luaj.vm2.jse.luajc.LuaJC.install();
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
This will compile all lua bytecode into Java bytecode, regardless of if they are loaded as
|
||||
lua source or lua binary files.
|
||||
|
||||
<p>
|
||||
The requires <em>bcel</em> to be on the class path, and the ClassLoader of JSE or CDC.
|
||||
|
||||
<h1>3 - <a name="3">Concepts</a></h1>
|
||||
|
||||
<h2>Globals</h2>
|
||||
The old notion of platform has been replaced with creation of globals.
|
||||
Two classes are provided to encapsulate common combinations of libraries.
|
||||
|
||||
<h3>JsePlatform</h3>
|
||||
|
||||
This class can be used as a factory for globals in a typical Java SE application.
|
||||
All standard libraries are included, as well as the luajava library.
|
||||
The default search path is the current directory,
|
||||
and the math operations include all those supported by Java SE.
|
||||
|
||||
<h3>JmePlatform</h3>
|
||||
|
||||
This class can be used to set up the basic environment for a Java ME application.
|
||||
The default search path is limited to the jar resources,
|
||||
and the math operations are limited to those supported by Java ME.
|
||||
All libraries are included except luajava, and the os, io, and math libraries are
|
||||
limited to those functions that can be supported on that platform.
|
||||
|
||||
|
||||
<h1>4 - <a name="4">Libraries</a></h1>
|
||||
|
||||
<h2>Standard Libraries</h2>
|
||||
|
||||
Libraries are coded to closely match the behavior specified in
|
||||
See <a href="http://www.lua.org/manual/5.1/">standard lua documentation</a> for details on the library API's
|
||||
|
||||
<p>
|
||||
The following libraries are loaded by both <em>JsePlatform.standardGlobals()</em> and <em>JmePlatform.standardGlobals()</em>:
|
||||
<pre> base
|
||||
coroutine
|
||||
io
|
||||
math
|
||||
os
|
||||
package
|
||||
string
|
||||
table
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <em>JsePlatform.standardGlobals()</em> globals also include:
|
||||
<pre> luajava
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <em>JsePlatform.debugGlobals()</em> and <em>JsePlatform.debugGlobals()</em> functions produce globals that include:
|
||||
<pre> debug
|
||||
</pre>
|
||||
|
||||
<h3>I/O Library</h3>
|
||||
The implementation of the <em>io</em> library differs by platform owing to platform limitations.
|
||||
|
||||
<p>
|
||||
The <em>JmePlatform.standardGlobals()</em> instantiated the io library <em>io</em> in
|
||||
<pre>
|
||||
src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java
|
||||
</pre>
|
||||
|
||||
The <em>JsePlatform.standardGlobals()</em> includes support for random access and is in
|
||||
<pre>
|
||||
src/jse/org/luaj/vm2/lib/jse/JseIoLib.java
|
||||
</pre>
|
||||
|
||||
<h3>OS Library</h3>
|
||||
The implementation of the <em>os</em> library also differs per platform.
|
||||
|
||||
<p>
|
||||
The basic <em>os</em> library implementation us used by <em>JmePlatform</em> and is in:
|
||||
<pre>
|
||||
src/core/org/luaj/lib/OsLib.java
|
||||
</pre>
|
||||
|
||||
A richer version for use by <em>JsePlatform</em> is :
|
||||
<pre>
|
||||
src/jse/org/luaj/vm2/lib/jse/JseOsLib.java
|
||||
</pre>
|
||||
|
||||
Time is a represented as number of milliseconds since the epoch,
|
||||
and most time and date formatting, locales, and other features
|
||||
are not implemented.
|
||||
|
||||
<h3>Coroutine Library</h3>
|
||||
The <em>coroutine</em> library is implemented using one JavaThread per coroutine.
|
||||
This allows <em>coroutine.yield()</em> can be called from anywhere,
|
||||
as with the yield-from-anywhere patch in C-based lua.
|
||||
|
||||
<p>
|
||||
Luaj uses WeakReferences and the OrphanedThread error to ensure that coroutines that are no longer referenced
|
||||
are properly garbage collected. For thread safety, OrphanedThread should not be caught by Java code.
|
||||
See <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/LuaThread.html">LuaThread</a>
|
||||
and <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/OrphanedThread.html">OrphanedThread</a>
|
||||
javadoc for details.
|
||||
|
||||
<h3>Debug Library</h3>
|
||||
The <em>debug</em> library is not included by default by
|
||||
<em>JmePlatform.standardGlobals()</em> or <em>JsePlatform.standardGlobsls()</em> .
|
||||
|
||||
The functions <em>JmePlatform.debugGlobals()</em> and <em>JsePlatform.debugGlobsls()</em>
|
||||
create globals that contain the debug library in addition to the other standard libraries.
|
||||
|
||||
To install dynamically from lua use java-class-based require:</em>:
|
||||
<pre>
|
||||
require 'org.luaj.vm2.lib.DebugLib'
|
||||
</pre>
|
||||
|
||||
The <em>lua</em> command line utility includes the <em>debug</em> library by default.
|
||||
|
||||
|
||||
<h3>The Luajava Library</h3>
|
||||
The <em>JsePlatform.standardGlobals()</em> includes the <em>luajava</em> library, which simplifies binding to Java classes and methods.
|
||||
It is patterned after the original <a href="http://www.keplerproject.org/luajava/">luajava project</a>.
|
||||
|
||||
<p>
|
||||
The following lua script will open a swing frame on Java SE:
|
||||
<pre>
|
||||
jframe = luajava.bindClass( "javax.swing.JFrame" )
|
||||
frame = luajava.newInstance( "javax.swing.JFrame", "Texts" );
|
||||
frame:setDefaultCloseOperation(jframe.EXIT_ON_CLOSE)
|
||||
frame:setSize(300,400)
|
||||
frame:setVisible(true)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading.
|
||||
Or try running it using:
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-2.0.3.jar lua examples/lua/swingapp.lua
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The Java ME platform does not include this library, and it cannot be made to work because of the lack of a reflection API in Java ME.
|
||||
|
||||
<p>
|
||||
The <em>lua</em> connand line tool includes <em>luajava</em>.
|
||||
|
||||
<h1>5 - <a name="5">LuaJ API</a></h1>
|
||||
|
||||
<h2>API Javadoc</h2>
|
||||
The javadoc for the main classes in the LuaJ API are on line at
|
||||
<pre>
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0</a>
|
||||
</pre>
|
||||
|
||||
You can also build a local version from sources using
|
||||
<pre>
|
||||
ant doc
|
||||
</pre>
|
||||
|
||||
<h2>LuaValue and Varargs</h2>
|
||||
All lua value manipulation is now organized around
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/LuaValue.html">LuaValue</a>
|
||||
which exposes the majority of interfaces used for lua computation.
|
||||
<pre>
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/LuaValue.html">org.luaj.vm2.LuaValue</a>
|
||||
</pre>
|
||||
|
||||
<h3>Common Functions</h3>
|
||||
<em>LuaValue</em> exposes functions for each of the operations in LuaJ.
|
||||
Some commonly used functions and constants include:
|
||||
<pre>
|
||||
call(); // invoke the function with no arguments
|
||||
call(LuaValue arg1); // call the function with 1 argument
|
||||
invoke(Varargs arg); // call the function with variable arguments, variable return values
|
||||
get(int index); // get a table entry using an integer key
|
||||
get(LuaValue key); // get a table entry using an arbitrary key, may be a LuaInteger
|
||||
rawget(int index); // raw get without metatable calls
|
||||
valueOf(int i); // return LuaValue corresponding to an integer
|
||||
valueOf(String s); // return LuaValue corresponding to a String
|
||||
toint(); // return value as a Java int
|
||||
tojstring(); // return value as a Java String
|
||||
isnil(); // is the value nil
|
||||
NIL; // the value nil
|
||||
NONE; // a Varargs instance with no values
|
||||
</pre>
|
||||
|
||||
<h2>Varargs</h2>
|
||||
The interface <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">Varargs</a> provides an abstraction for
|
||||
both a variable argument list and multiple return values.
|
||||
For convenience, <em>LuaValue</em> implements <em>Varargs</em> so a single value can be supplied anywhere
|
||||
variable arguments are expected.
|
||||
<pre>
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">org.luaj.vm2.Varargs</a>
|
||||
</pre>
|
||||
|
||||
<h3>Common Functions</h3>
|
||||
<em>Varargs</em> exposes functions for accessing elements, and coercing them to specific types:
|
||||
<pre>
|
||||
narg(); // return number of arguments
|
||||
arg1(); // return the first argument
|
||||
arg(int n); // return the nth argument
|
||||
isnil(int n); // true if the nth argument is nil
|
||||
checktable(int n); // return table or throw error
|
||||
optlong(int n,long d); // return n if a long, d if no argument, or error if not a long
|
||||
</pre>
|
||||
|
||||
See the <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">Varargs</a> API for a complete list.
|
||||
|
||||
<h2>LibFunction</h2>
|
||||
The simplest way to implement a function is to choose a base class based on the number of arguments to the function.
|
||||
LuaJ provides 5 base classes for this purpose, depending if the function has 0, 1, 2, 3 or variable arguments,
|
||||
and if it provide multiple return values.
|
||||
<pre>
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/ZeroArgFunction.html">org.luaj.vm2.lib.ZeroArgFunction</a>
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/OneArgFunction.html">org.luaj.vm2.lib.OneArgFunction</a>
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/TwoArgFunction.html">org.luaj.vm2.lib.TwoArgFunction</a>
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/ThreeArgFunction.html">org.luaj.vm2.lib.ThreeArgFunction</a>
|
||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/VarArgFunction.html">org.luaj.vm2.lib.VarArgFunction</a>
|
||||
</pre>
|
||||
|
||||
Each of these functions has an abstract method that must be implemented,
|
||||
and argument fixup is done automatically by the classes as each Java function is invoked.
|
||||
|
||||
<p>
|
||||
For example, to implement a "hello, world" function, we could supply:
|
||||
<pre>
|
||||
pubic class hello extends ZeroArgFunction {
|
||||
public LuaValue call() {
|
||||
env.get("print").call(valueOf("hello, world"));
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
The value <em>env</em> is the environment of the function, and is normally supplied
|
||||
by the instantiating object whenever default loading is used.
|
||||
|
||||
<p>
|
||||
Calling this function from lua could be done by:
|
||||
<pre>
|
||||
require( 'hello' )()
|
||||
</pre>
|
||||
|
||||
while calling this function from Java would look like:
|
||||
<pre>
|
||||
new hello().call();
|
||||
</pre>
|
||||
|
||||
Note that in both the lua and Java case, extra arguments will be ignored, and the function will be called.
|
||||
Also, no virtual machine instance is necessary to call the function.
|
||||
To allow for arguments, or return multiple values, extend one of the other base classes.
|
||||
|
||||
<h2>Closures</h2>
|
||||
Closures still exist in this framework, but are optional, and are only used to implement lua bytecode execution.
|
||||
|
||||
<h1>6 - <a name="6">Parser</a></h1>
|
||||
|
||||
<h2>Javacc Grammar</h2>
|
||||
A Javacc grammarwas developed to simplify the creation of Java-based parsers for the lua language.
|
||||
The grammar is specified for <a href="https://javacc.dev.java.net/">javacc version 5.0</a> because that tool generates standalone
|
||||
parsers that do not require a separate runtime.
|
||||
|
||||
<p>
|
||||
A plain undecorated grammer that can be used for validation is available in <a href="grammar/Lua51.jj">grammar/Lua51.jj</a>
|
||||
while a grammar that generates a typed parse tree is in <a href="grammar/LuaParser.jj">grammar/LuaParser.jj</a>
|
||||
|
||||
<h2>Creating a Parse Tree from Lua Source</h2>
|
||||
The default lu compiler does a single-pass compile of lua source to lua bytecode, so no explicit parse tree is produced.
|
||||
|
||||
<p>
|
||||
To simplify the creation of abstract syntax trees from lua sources, the LuaParser class is generated as part of the JME build.
|
||||
To use it, provide an input stream, and invoke the root generator, which will return a Chunk if the file is valid,
|
||||
or throw a ParseException if there is a syntax error.
|
||||
|
||||
<p>
|
||||
For example, to parse a file and print all variable names, use code like:
|
||||
<pre>
|
||||
try {
|
||||
String file = "main.lua";
|
||||
LuaParser parser = new LuaParser(new FileInputStream(file));
|
||||
Chunk chunk = parser.Chunk();
|
||||
chunk.accept( new Visitor() {
|
||||
public void visit(Exp.NameExp exp) {
|
||||
System.out.println("Name in use: "+exp.name.name);
|
||||
}
|
||||
} );
|
||||
} catch ( ParseException e ) {
|
||||
System.out.println("parse failed: " + e.getMessage() + "\n"
|
||||
+ "Token Image: '" + e.currentToken.image + "'\n"
|
||||
+ "Location: " + e.currentToken.beginLine + ":" + e.currentToken.beginColumn
|
||||
+ "-" + e.currentToken.endLine + "," + e.currentToken.endColumn);
|
||||
}
|
||||
</pre>
|
||||
In luaj 2.0.3 error reporting was turned on in the parser so line numbers are avaiable for most parse exceptions.
|
||||
This example may be found in
|
||||
<pre>
|
||||
examples/jse/SampleParser.java
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
See the <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/ast/package-summary.html">org.luaj.vm2.ast package</a> javadoc for the API relating to the syntax tree that is produced.
|
||||
|
||||
<h1>7 - <a name="7">Building and Testing</a></h1>
|
||||
|
||||
<h2>Building the jars</h2>
|
||||
An ant file is included in the root directory which builds the libraries by default.
|
||||
|
||||
<p>
|
||||
Other targets exist for creating distribution file an measuring code coverage of unit tests.
|
||||
|
||||
<h2>Unit tests</h2>
|
||||
|
||||
<p>
|
||||
The main luaj JUnit tests are organized into a JUnit 3 suite:
|
||||
<pre>
|
||||
test/junit/org/luaj/vm2/AllTests.lua
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Unit test scripts can be found in these locations
|
||||
<pre>
|
||||
test/lua/*.lua
|
||||
test/junit/org/luaj/vm2/compiler/lua5.1-tests.zip
|
||||
test/junit/org/luaj/vm2/compiler/regressions.zip
|
||||
test/junit/org/luaj/vm2/vm1/luajvm1-tests.zip
|
||||
</pre>
|
||||
|
||||
<h2>Code coverage</h2>
|
||||
|
||||
<p>
|
||||
A build script for running unit tests and producing code coverage statistics is in
|
||||
<pre>
|
||||
build-coverage.xml
|
||||
</pre>
|
||||
|
||||
It relies on the cobertura code coverage library.
|
||||
|
||||
<h1>8 - <a name="8">Downloads</a></h1>
|
||||
|
||||
<h2>Downloads and Project Pages</h2>
|
||||
Downloads for all version available on SourceForge or LuaForge.
|
||||
Sources are hosted on SourceForge and available via sourceforge.net
|
||||
<br/>
|
||||
<pre>
|
||||
<a href="http://luaj.sourceforge.net/">SourceForge Luaj Project Page</a>
|
||||
<a href="http://sourceforge.net/project/platformdownload.php?group_id=197627">SourceForge Luaj Download Area</a>
|
||||
</pre>
|
||||
<p/>
|
||||
and LuaForge:
|
||||
<pre>
|
||||
<a href="http://luaforge.net/projects/luaj/">LuaForge Luaj Project Page</a>
|
||||
<a href="http://luaforge.net/frs/?group_id=457">LuaForge Luaj Project Area</a>
|
||||
</pre>
|
||||
|
||||
<h1>9 - <a name="9">Release Notes</a></h1>
|
||||
|
||||
<h2>Main Changes by Version</h2>
|
||||
<table cellspacing="10"><tr><td><table cellspacing="4">
|
||||
<tr valign="top"><td> <b>2.0</b></td><td><ul>
|
||||
<li>Initial release of 2.0 version </li>
|
||||
</ul></td></tr>
|
||||
<tr valign="top"><td> <b>2.0.1</b></td><td><ul>
|
||||
<li>Improve correctness of singleton construction related to static initialization </li>
|
||||
<li>Fix nan-related error in constant folding logic that was failing on some JVMs </li>
|
||||
<li>JSR-223 fixes: add META-INF/services entry in jse jar, improve bindings implementation </li>
|
||||
</ul></td></tr>
|
||||
<tr valign="top"><td> <b>2.0.2</b></td><td><ul>
|
||||
<li>JSR-223 bindings change: non Java-primitives will now be passed as LuaValue </li>
|
||||
<li>JSR-223 enhancement: allow both ".lua" and "lua" as extensions in getScriptEngine() </li>
|
||||
<li>JSR-223 fix: use system class loader to support using luaj as JRE extension </li>
|
||||
<li>Improve selection logic when binding to overloaded functions using luajava</li>
|
||||
<li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a> and <a href="http://luaj.sourceforge.net/api/2.0/index.html">on line</a></li>
|
||||
<li>Major refactor of luajava type coercion logic, improve method selection.</li>
|
||||
<li>Add lib/luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
|
||||
<tr valign="top"><td> <b>2.0.3</b></td><td><ul>
|
||||
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
|
||||
<li>Fix lua command vararg values passed into main script to match what is in global arg table </li>
|
||||
<li>Add arithmetic metatag processing when left hand side is a number and right hand side has metatable </li>
|
||||
<li>Fix load(func) when mutiple string fragments are supplied by calls to func </li>
|
||||
<li>Allow access to public members of private inner classes where possible </li>
|
||||
<li>Turn on error reporting in LuaParser so line numbers ar available in ParseException </li>
|
||||
<li>Improve compatibility of table.remove() </li>
|
||||
<li>Disallow base library setfenv() calls on Java functions </li>
|
||||
</ul></td></tr>
|
||||
</table></td></tr></table>
|
||||
|
||||
<h2>Known Issues</h2>
|
||||
<ul>
|
||||
<li>debug code may not be completely removed by some obfuscators
|
||||
<li>tail calls are not tracked in debug information
|
||||
<li>using both version 1 and 2 libraries together in the same java vm has not been tested
|
||||
<li>module() and setfenv() only partially supported for lau2java or luajc compiled lua
|
||||
<li>values associated with weak keys may linger longer than expected
|
||||
<li>behavior of luaj when a SecurityManager is used has not been fully characterized
|
||||
</ul>
|
||||
|
@@ -1,119 +0,0 @@
|
||||
<project default="all" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
|
||||
<!--
|
||||
Run code coverage for unit tests on the luaj vm and libraries.
|
||||
-->
|
||||
|
||||
<property name="classes.dir" value="build/classes-debug" />
|
||||
<property name="instrumented.dir" value="build/instrumented" />
|
||||
<property name="reports.xml.dir" value="build/reports-junit-xml" />
|
||||
<property name="reports.html.dir" value="build/reports-junit-html" />
|
||||
<property name="coverage.xml.dir" value="build/reports-coverage-xml" />
|
||||
<property name="coverage.html.dir" value="build/reports-coverage-html" />
|
||||
<property name="cobertura.serfile" value="cobertura.ser" />
|
||||
<property name="cobertura.logfile" value="cobertura.log" />
|
||||
|
||||
<artifact:dependencies filesetId="cobutura.fileset">
|
||||
<dependency groupId="net.sourceforge.cobertura" artifactId="cobertura" version="1.9.4.1"/>
|
||||
<dependency groupId="junit" artifactId="junit" version="3.8.1"/>
|
||||
</artifact:dependencies>
|
||||
|
||||
<path id="cobertura.classpath">
|
||||
<fileset refid="cobutura.fileset" />
|
||||
</path>
|
||||
|
||||
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
|
||||
|
||||
<import file="wtk.xml"/>
|
||||
|
||||
<property environment="env"/>
|
||||
|
||||
<target name="clean" description="Remove all files created by the build/test process.">
|
||||
<delete dir="${classes.dir}" failonerror="yes"/>
|
||||
<delete dir="${instrumented.dir}" failonerror="yes"/>
|
||||
<delete file="${cobertura.logfile}" />
|
||||
<delete file="${cobertura.serfile}" />
|
||||
</target>
|
||||
|
||||
<target name="init">
|
||||
<ant antfile="build.xml" target="bcel-lib"/>
|
||||
<ant antfile="build.xml" target="luaj1-lib"/>
|
||||
<mkdir dir="${classes.dir}" />
|
||||
<mkdir dir="${instrumented.dir}" />
|
||||
<mkdir dir="${reports.xml.dir}" />
|
||||
<mkdir dir="${reports.html.dir}" />
|
||||
<mkdir dir="${coverage.xml.dir}" />
|
||||
<mkdir dir="${coverage.html.dir}" />
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init,wtk-or-fail">
|
||||
<javac destdir="${classes.dir}" debug="yes" target="1.5">
|
||||
<classpath refid="cobertura.classpath" />
|
||||
<classpath refid="wtk-libs" />
|
||||
<classpath path="lib/bcel-5.2.jar" />
|
||||
<src path="src/core"/>
|
||||
<src path="src/jme"/>
|
||||
<src path="src/jse"/>
|
||||
<src path="test/junit"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="instrument" depends="compile">
|
||||
<delete file="${cobertura.serfile}"/>
|
||||
<delete dir="${instrumented.dir}" failonerror="no"/>
|
||||
<cobertura-instrument datafile="${cobertura.serfile}" todir="${instrumented.dir}">
|
||||
<fileset dir="${classes.dir}">
|
||||
<include name="org/luaj/vm2/*.class" />
|
||||
<include name="org/luaj/vm2/lib/*.class" />
|
||||
<include name="org/luaj/vm2/lib/jse/*.class" />
|
||||
<include name="org/luaj/vm2/lib/jme/*.class" />
|
||||
<include name="org/luaj/vm2/compiler/*.class" />
|
||||
<include name="org/luaj/vm2/luajc/*.class" />
|
||||
<include name="org/luaj/vm2/lua2java/*.class" />
|
||||
<include name="org/luaj/vm2/parser/*.class" />
|
||||
<include name="org/luaj/vm2/ast/*.class" />
|
||||
<exclude name="**/*Test*.class" />
|
||||
</fileset>
|
||||
</cobertura-instrument>
|
||||
</target>
|
||||
|
||||
<target name="test">
|
||||
<junit fork="yes" dir="${basedir}" showoutput="yes">
|
||||
<sysproperty key="net.sourceforge.cobertura.serfile"
|
||||
file="${basedir}/${cobertura.serfile}" />
|
||||
<classpath location="${instrumented.dir}" />
|
||||
<classpath location="${classes.dir}" />
|
||||
<classpath refid="cobertura.classpath" />
|
||||
<classpath location="test/lua" />
|
||||
<classpath location="test/junit/org/luaj/vm2/compiler" />
|
||||
<classpath location="test/junit/org/luaj/vm2/vm1" />
|
||||
<classpath path="lib/bcel-5.2.jar" />
|
||||
<formatter type="xml" />
|
||||
<batchtest todir="${reports.xml.dir}">
|
||||
<fileset dir="test/junit">
|
||||
<include name="org/luaj/vm2/AllTests.java" />
|
||||
</fileset>
|
||||
</batchtest>
|
||||
</junit>
|
||||
|
||||
<junitreport todir="${reports.xml.dir}">
|
||||
<fileset dir="${reports.xml.dir}">
|
||||
<include name="TEST-*.xml" />
|
||||
</fileset>
|
||||
<report format="frames" todir="${reports.html.dir}" />
|
||||
</junitreport>
|
||||
</target>
|
||||
|
||||
<target name="report">
|
||||
<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.xml.dir}" format="xml" />
|
||||
<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.html.dir}">
|
||||
<fileset dir="src/core"/>
|
||||
<fileset dir="src/jse"/>
|
||||
<fileset dir="src/jme"/>
|
||||
</cobertura-report>
|
||||
</target>
|
||||
|
||||
<target name="coverage" depends="clean,init,compile,instrument,test,report"/>
|
||||
|
||||
<target name="all" depends="coverage" />
|
||||
|
||||
</project>
|
@@ -1,56 +0,0 @@
|
||||
<project default="all-libs">
|
||||
|
||||
<available file="lib/midpapi20.jar" property="midpapi.lib.exists"/>
|
||||
<available file="lib/bcel-5.2.jar" property="bcel.lib.exists"/>
|
||||
<available file="lib/javacc.jar" property="javacc.lib.exists"/>
|
||||
<available file="lib/proguard.jar" property="proguard.lib.exists"/>
|
||||
<available file="lib/antenna-bin-1.2.0-beta.jar" property="antenna.lib.exists"/>
|
||||
<available file="lib/junit.jar" property="junit.lib.exists"/>
|
||||
<available file="lib/cobertura.jar" property="cobertura.lib.exists"/>
|
||||
<available file="lib/microemulator.jar" property="microemulator.lib.exists"/>
|
||||
|
||||
<macrodef name="download">
|
||||
<attribute name="zipname"/>
|
||||
<attribute name="jars" default="**/*.jar"/>
|
||||
<sequential>
|
||||
<mkdir dir="lib"/>
|
||||
<get src="http://luaj.sourceforge.net/lib/@{zipname}.tar.gz"
|
||||
dest="lib/@{zipname}.tar.gz"/>
|
||||
<gunzip src="lib/@{zipname}.tar.gz" dest="lib/@{zipname}.tar"/>
|
||||
<untar src="lib/@{zipname}.tar" dest="lib" overwrite="true">
|
||||
<patternset>
|
||||
<include name="@{jars}"/>
|
||||
</patternset>
|
||||
<mapper type="flatten"/>
|
||||
</untar>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<target name="wtk-libs" unless="midpapi.lib.exists">
|
||||
<download zipname="wtk-2.5.2-api"/>
|
||||
</target>
|
||||
<target name="bcel-lib" unless="bcel.lib.exists">
|
||||
<download zipname="/bcel-5.2"/>
|
||||
</target>
|
||||
<target name="javacc-lib" unless="javacc.lib.exists">
|
||||
<download zipname="javacc-5.0"/>
|
||||
</target>
|
||||
<target name="proguard-lib" unless="proguard.lib.exists">
|
||||
<download zipname="proguard4.6"/>
|
||||
</target>
|
||||
<target name="antenna-lib" unless="antenna.lib.exists">
|
||||
<download zipname="antenna-bin-1.2.0-beta"/>
|
||||
</target>
|
||||
<target name="junit-lib" unless="junit.lib.exists">
|
||||
<download zipname="junit-3.8.2"/>
|
||||
</target>
|
||||
<target name="cobertura-lib" unless="cobertura.lib.exists">
|
||||
<download zipname="cobertura-1.9.4.1-bin"/>
|
||||
</target>
|
||||
<target name="microemulator-lib" unless="microemulator.lib.exists">
|
||||
<download zipname="microemulator-2.0.4" jars="**/microemulator.jar"/>
|
||||
</target>
|
||||
|
||||
<target name="all-libs" depends="wtk-libs,bcel-lib,javacc-lib,proguard-lib,antenna-lib,junit-lib,cobertura-lib"/>
|
||||
|
||||
</project>
|
@@ -1,172 +0,0 @@
|
||||
<project default="all">
|
||||
<property file="version.properties"/>
|
||||
|
||||
<property name="jar.name.jme" value="luaj-jme-${version}.jar"/>
|
||||
<property name="jar.name.jse" value="luaj-jse-${version}.jar"/>
|
||||
<property name="jar.name.sources" value="luaj-sources-${version}.jar"/>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="build"/>
|
||||
<delete>
|
||||
<fileset dir="." includes="luaj-*.jar"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<import file="build-libs.xml"/>
|
||||
|
||||
<target name="parser" depends="javacc-lib">
|
||||
<java classname="javacc" classpath="lib/javacc.jar">
|
||||
<arg line="grammar/LuaParser.jj"/>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="wtk-libs,bcel-lib">
|
||||
<delete dir="build/jme/src"/>
|
||||
<delete dir="build/jse/src"/>
|
||||
<mkdir dir="build/jme/src"/>
|
||||
<mkdir dir="build/jse/src"/>
|
||||
<mkdir dir="build/jme/classes"/>
|
||||
<mkdir dir="build/jse/classes"/>
|
||||
<copy todir="build/jme/src">
|
||||
<fileset dir="src/core"/>
|
||||
<fileset dir="src/jme"/>
|
||||
<filterchain>
|
||||
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jme ${version}"'/></tokenfilter>
|
||||
</filterchain>
|
||||
</copy>
|
||||
<copy todir="build/jse/src">
|
||||
<fileset dir="src/core"/>
|
||||
<filterchain>
|
||||
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jse ${version}"'/></tokenfilter>
|
||||
</filterchain>
|
||||
</copy>
|
||||
<copy todir="build/jse/src">
|
||||
<fileset dir="src/jse"/>
|
||||
<filterchain>
|
||||
<tokenfilter><replacestring from='<String>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Stat>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Exp>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Name>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Block>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<TableField>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<VarExp>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Exp.VarExp>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Object,String>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Double,String>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Integer,Integer>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<Exp,Integer>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<String,byte[]>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<String,Variable>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<LuaValue,String>' to=''/></tokenfilter>
|
||||
<tokenfilter><replacestring from='<LuaString,String>' to=''/></tokenfilter>
|
||||
</filterchain>
|
||||
</copy>
|
||||
<path id="wtk-libs">
|
||||
<pathelement path="lib/cldcapi11.jar"/>
|
||||
<pathelement path="lib/midpapi20.jar"/>
|
||||
<pathelement path="lib/mmapi.jar"/>
|
||||
</path>
|
||||
<javac destdir="build/jme/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
|
||||
srcdir="build/jme/src"/>
|
||||
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
|
||||
classpath="lib/bcel-5.2.jar"
|
||||
srcdir="build/jse/src"
|
||||
excludes="**/script/*,**/Lua2Java*,lua*"/>
|
||||
<javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
|
||||
classpath="build/jse/classes"
|
||||
srcdir="build/jse/src"
|
||||
includes="**/script/*,**/Lua2Java*"/>
|
||||
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
|
||||
classpath="build/jse/classes"
|
||||
srcdir="build/jse/src"
|
||||
includes="lua*"/>
|
||||
</target>
|
||||
|
||||
<target name="jar-jme" depends="compile">
|
||||
<jar destfile="${jar.name.jme}" basedir="build/jme/classes"/>
|
||||
</target>
|
||||
|
||||
<target name="jar-jse" depends="compile">
|
||||
<jar destfile="${jar.name.jse}">
|
||||
<fileset dir="build/jse/classes"/>
|
||||
<fileset dir="src/jse/">
|
||||
<include name="META-INF/services/**"/>
|
||||
</fileset>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="jar-jse-sources" depends="compile">
|
||||
<jar destfile="${jar.name.sources}">
|
||||
<fileset dir="build/jme/src"/>
|
||||
<fileset dir="build/jse/src"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="doc">
|
||||
<delete dir="docs/api"/>
|
||||
<mkdir dir="docs/api"/>
|
||||
<javadoc defaultexcludes="yes"
|
||||
destdir="docs/api"
|
||||
author="true"
|
||||
version="true"
|
||||
use="true"
|
||||
windowtitle="Luaj API">
|
||||
<fileset dir="src/core" defaultexcludes="yes" includes="org/luaj/vm2/*.java,org/luaj/vm2/compiler/LuaC.java,org/luaj/vm2/lib/*.java"/>
|
||||
<fileset dir="src/jse" defaultexcludes="yes" includes="org/luaj/vm2/lib/jse/*.java,org/luaj/vm2/luajc/LuaJC.java"/>
|
||||
<fileset dir="src/jme" defaultexcludes="yes" includes="org/luaj/vm2/lib/jme/*.java"/>
|
||||
<doctitle><![CDATA[<h1>Luaj API</h1>]]></doctitle>
|
||||
<bottom><![CDATA[<i>Copyright © 2007-2008 Luaj.org. All Rights Reserved.</i>]]></bottom>
|
||||
<tag name="todo" scope="all" description="To do:"/>
|
||||
<group title="Core VM" packages="org.luaj.vm.*"/>
|
||||
<link offline="true" href="http://sourceforge.net/projects/luaj/" packagelistLoc="C:\tmp"/>
|
||||
<link href="http://sourceforge.net/projects/luaj/"/>
|
||||
</javadoc>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="all,doc">
|
||||
<delete dir="build/luaj-${version}"/>
|
||||
<mkdir dir="build/luaj-${version}/src"/>
|
||||
<mkdir dir="build/luaj-${version}/lib"/>
|
||||
<copy todir="build/luaj-${version}/src">
|
||||
<fileset dir="src">
|
||||
<exclude name="src/test/**"/>
|
||||
<exclude name="**/antlr/**"/>
|
||||
<exclude name="**/lst/**"/>
|
||||
<exclude name="**/JavaCodeGenerator.java"/>
|
||||
<exclude name="**/LuaJCompiler.java"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="build/luaj-${version}/test">
|
||||
<fileset dir="test"/>
|
||||
</copy>
|
||||
<copy todir="build/luaj-${version}/examples">
|
||||
<fileset dir="examples"/>
|
||||
</copy>
|
||||
<copy todir="build/luaj-${version}/lib">
|
||||
<fileset dir=".">
|
||||
<include name="*-${version}.jar"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="build/luaj-${version}">
|
||||
<fileset dir=".">
|
||||
<include name="build.xml"/>
|
||||
<include name="build-libs.xml"/>
|
||||
<include name="build-coverage.xml"/>
|
||||
<include name="version.properties"/>
|
||||
<include name="wtk.xml"/>
|
||||
<include name="README.html"/>
|
||||
<include name="names.csv"/>
|
||||
<include name=".classpath"/>
|
||||
<include name=".project"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="build/luaj-${version}/docs">
|
||||
<fileset dir="docs"/>
|
||||
</copy>
|
||||
<zip destfile="luaj-${version}.zip"
|
||||
basedir="build" includes="luaj-${version}/**"/>
|
||||
</target>
|
||||
|
||||
<target name="all" depends="clean,jar-jme,jar-jse,jar-jse-sources"/>
|
||||
|
||||
</project>
|
@@ -1,89 +0,0 @@
|
||||
LuaValue Consructors,,Return type,,,,,,,,,,
|
||||
,valueOf(boolean),LuaBoolean,,,,,,,,,,
|
||||
,valueOf(null),LuaNil,,,,,,,,,,
|
||||
,valueOf(int) ,LuaInteger,,,,,,,,,,
|
||||
,valueOf(double),LuaNumber,,,,,,,,,,
|
||||
,valueOf(long),LuaNumber,,,,,,,,,,
|
||||
,valueOf(String),LuaString,,,,,,,,,,
|
||||
,tableOf(...),LuaTable,,,,,,,,,,
|
||||
,listOf(LuaValue[]),LuaTable,,,,,,,,,,
|
||||
,userdataOf(Object),LuaUserdata,,,,,,,,,,
|
||||
,"uerdataOf(Object,Value)",LuaUserdata,,,,,,,,,,
|
||||
,,,,,,,Arugment type,,,,,
|
||||
,,,LuaBoolean,LuaClosure,LuaFunction,LuaDouble,LuaInteger,LuaNil,LuaString,LuaTable,LuaThread,LuaUserdata
|
||||
Type Check Functions,,,,,,,,,,,,
|
||||
,isboolean,boolean,TRUE,f,f,f,f,f,f,f,f,f
|
||||
,isclosure,boolean,f,TRUE,f,f,f,f,f,f,f,f
|
||||
,isfunction,boolean,f,TRUE,TRUE,f,f,f,f,f,f,f
|
||||
,isint,boolean,f,f,f,f,TRUE,f,true | f,f,f,f
|
||||
,isinttype,boolean,f,f,f,f,TRUE,f,f,f,f,f
|
||||
,isnumber,boolean,f,f,f,TRUE,TRUE,f,true | f,f,f,f
|
||||
,islong,boolean,f,f,f,true | f,TRUE,f,true | f,f,f,f
|
||||
,isnil,boolean,f,f,f,f,f,TRUE,f,f,f,f
|
||||
,isstring,boolean,f,f,f,true | f,TRUE,f,TRUE,f,f,f
|
||||
,istable,boolean,f,f,f,f,f,f,f,TRUE,f,f
|
||||
,isthread,boolean,f,f,f,f,f,f,f,f,TRUE,f
|
||||
,isuserdata,boolean,f,f,f,f,f,f,f,f,f,TRUE
|
||||
,isuserdata(Class c),boolean,f,f,f,f,f,f,f,f,f,true | f
|
||||
|
||||
|
||||
Java Type Coercion Functions,,,,,,,,,,,,
|
||||
,toboolean,boolean,this.v,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE
|
||||
,tobyte,byte,0,0,0,0,this.v | 0,0,this.v | 0,0,0,0
|
||||
,tochar,char,0,0,0,0,this.v | 0,0,this.v | 0,0,0,0
|
||||
,todouble,double,0,0,0,this.v,this.v,0,this.v | 0,0,0,0
|
||||
,tofloat,float,0,0,0,this.v | 0,this.v,0,this.v | 0,0,0,0
|
||||
,toint,int,0,0,0,0,this.v,0,this.v | 0,0,0,0
|
||||
,tolong,long,0,0,0,0,this.v,0,this.v | 0,0,0,0
|
||||
,toshort,short,0,0,0,0,this.v | 0,0,this.v | 0,0,0,0
|
||||
,tojstring,String,"""true""|""false""","""closure: x""","""name""",(str) this.v,(str) this.v,"""nil""",this.v,"""table: x""","""thread: x""","""userdata: x"""
|
||||
,touserdata,Object,null,null,null,null,null,null,null,null,this,this.instance
|
||||
|
||||
,,,LuaBoolean,LuaClosure,LuaFunction,LuaDouble,LuaInteger,LuaNil,LuaString,LuaTable,LuaThread,LuaUserdata
|
||||
Optional Argument Conversion Functions,,,,,,,,,,,,
|
||||
,optboolean,boolean,this,e,e,e,e,defval,e,e,e,e
|
||||
,optclosure,LuaClosure,n,this,e,e,e,defval,e,e,e,e
|
||||
,optdouble,double,e,e,e,this,this,defval,this | e,e,e,e
|
||||
,optfunction,LuaFunction,n,this,this,e,e,defval,e,e,e,e
|
||||
,optint,int,e,e,e,(int) this,this,defval,this | e,e,e,e
|
||||
,optinteger,LuaInteger,e,e,e,(int) this,this,defval,this | e,e,e,e
|
||||
,optlong,long,e,e,e,(long) this,this,defval,this | e,e,e,e
|
||||
,optnumber,LuaNumber,e,e,e,this,this,defval,this | e,e,e,e
|
||||
,optjstring,String,e,e,e,(str) this.v,(str) this.v,defval,this,e,e,e
|
||||
,optstring,LuaString,e,e,e,(str) this.v,(str) this.v,defval,this,e,e,e
|
||||
,opttable,LuaTable,e,e,e,e,e,defval,e,this,e,e
|
||||
,optthread,LuaThread,e,e,e,e,e,defval,e,e,this,n
|
||||
,optuserdata,Object,e,e,e,e,e,defval,e,e,e,instance
|
||||
,optuserdata(Class c),Object,e,e,e,e,e,defval,e,e,e,instance | e
|
||||
|
||||
Required Argument Conversion Functions,,,,,,,,,,,,
|
||||
,checkboolean,boolean,this,e,e,e,e,e,e,e,e,e
|
||||
,checkclosure,LuaClosure,e,this,e,e,e,e,e,e,e,e
|
||||
,checkdouble,double,e,e,e,this,this,e,e,e,e,e
|
||||
,checkfunction,LuaFunction,e,this,this,e,e,e,e,e,e,e
|
||||
,checkint,int,e,e,e,this | e,this,e,e,e,e,e
|
||||
,checkinteger,LuaInteger,e,e,e,e,this,e,e,e,e,e
|
||||
,checklong,LuaNumber,e,e,e,this | e,this,e,e,e,e,e
|
||||
,checknumber,LuaNumber,e,e,e,this,this,e,e,e,e,e
|
||||
,checkjstring,String,e,e,e,(str) this.v,(str) this.v,e,(str) this.v,e,e,e
|
||||
,checkstring,LuaString,e,e,e,(str) this.v,(str) this.v,e,this,e,e,e
|
||||
,checktable,LuaTable,e,e,e,e,e,e,e,this,e,e
|
||||
,checkthread,LuaThread,e,e,e,e,e,e,e,e,this,e
|
||||
,checkuserdata,Object,e,e,e,e,e,e,e,e,e,instance
|
||||
,checkuserdata(Class c),Object,e,e,e,e,e,e,e,e,e,instance | e
|
||||
,checkvalue,LuaValue,this,this,this,this,this,e,this,this,this,this
|
||||
|
||||
,,,LuaBoolean,LuaClosure,LuaFunction,LuaDouble,LuaInteger,LuaNil,LuaString,LuaTable,LuaThread,LuaUserdata
|
||||
Lua Language Operations,,,,,,,,,,,,
|
||||
,type,int,TBOOLEAN,TFUNCTION,TFUNCTION,TNUMBER,TNUMBER,TNIL,TSTRING,TTABLE,TTHREAD,TUSERDATA
|
||||
,typename,string,"""boolean""","""function""","""function""","""number""","""number""","""nil""","""string""","""table""","""thread""","""userdata"""
|
||||
,len,LuaInteger,e,e,e,e,e,e,#v,#v,e,e
|
||||
,length,int,e,e,e,e,e,e,#v,#v,e,e
|
||||
,getmetatable,LuaValue,static,static,static,static,static,static,static,instance,static ,instance
|
||||
,setmetatable,LuaValue,e,e,e,e,e,e,e,instance,e,instance
|
||||
,getfenv,LuaTable,e,instance,instance,e,e,e,e,e,instance,e
|
||||
,setfenv,LuaFunction,e,instance,instance,e,e,e,e,e,instance,e
|
||||
,call,LuaValue,__call,call,call,__call,__call,__call,__call,__call,__call,__call
|
||||
,invoke,Varargs,__call,call,call,__call,__call,__call,__call,__call,__call,__call
|
||||
,get,LuaValue,__index,__index,__index,__index,__index,__index,__index,get,__index,__index
|
||||
,set,LuaValue,__newindex,__newindex,__newindex,__newindex,__newindex,__newindex,__newindex,set,__newindex,__newindex
|
|
@@ -1,260 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
|
||||
/**
|
||||
* String buffer for use in string library methods, optimized for production
|
||||
* of StrValue instances.
|
||||
* <p>
|
||||
* The buffer can begin initially as a wrapped {@link LuaValue}
|
||||
* and only when concatenation actually occurs are the bytes first copied.
|
||||
* <p>
|
||||
* To convert back to a {@link LuaValue} again,
|
||||
* the function {@link Buffer#value()} is used.
|
||||
* @see LuaValue
|
||||
* @see LuaValue#buffer()
|
||||
* @see LuaString
|
||||
*/
|
||||
public final class Buffer {
|
||||
|
||||
/** Default capacity for a buffer: 64 */
|
||||
private static final int DEFAULT_CAPACITY = 64;
|
||||
|
||||
/** Shared static array with no bytes */
|
||||
private static final byte[] NOBYTES = {};
|
||||
|
||||
/** Bytes in this buffer */
|
||||
private byte[] bytes;
|
||||
|
||||
/** Length of this buffer */
|
||||
private int length;
|
||||
|
||||
/** Offset into the byte array */
|
||||
private int offset;
|
||||
|
||||
/** Value of this buffer, when not represented in bytes */
|
||||
private LuaValue value;
|
||||
|
||||
/**
|
||||
* Create buffer with default capacity
|
||||
* @see #DEFAULT_CAPACITY
|
||||
*/
|
||||
public Buffer() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create buffer with specified initial capacity
|
||||
* @param initialCapacity the initial capacity
|
||||
*/
|
||||
public Buffer( int initialCapacity ) {
|
||||
bytes = new byte[ initialCapacity ];
|
||||
length = 0;
|
||||
offset = 0;
|
||||
value = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create buffer with specified initial value
|
||||
* @param value the initial value
|
||||
*/
|
||||
public Buffer(LuaValue value) {
|
||||
bytes = NOBYTES;
|
||||
length = offset = 0;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get buffer contents as a {@link LuaValue}
|
||||
* @return value as a {@link LuaValue}, converting as necessary
|
||||
*/
|
||||
public LuaValue value() {
|
||||
return value != null? value: this.tostring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set buffer contents as a {@link LuaValue}
|
||||
* @param value value to set
|
||||
*/
|
||||
public Buffer setvalue(LuaValue value) {
|
||||
bytes = NOBYTES;
|
||||
offset = length = 0;
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the buffer to a {@link LuaString}
|
||||
* @return the value as a {@link LuaString}
|
||||
*/
|
||||
public final LuaString tostring() {
|
||||
realloc( length, 0 );
|
||||
return LuaString.valueOf( bytes, offset, length );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the buffer to a Java String
|
||||
* @return the value as a Java String
|
||||
*/
|
||||
public String tojstring() {
|
||||
return value().tojstring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the buffer to a Java String
|
||||
* @return the value as a Java String
|
||||
*/
|
||||
public String toString() {
|
||||
return tojstring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a single byte to the buffer.
|
||||
* @return {@code this} to allow call chaining
|
||||
*/
|
||||
public final Buffer append( byte b ) {
|
||||
makeroom( 0, 1 );
|
||||
bytes[ offset + length++ ] = b;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a {@link LuaValue} to the buffer.
|
||||
* @return {@code this} to allow call chaining
|
||||
*/
|
||||
public final Buffer append( LuaValue val ) {
|
||||
append( val.strvalue() );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a {@link LuaString} to the buffer.
|
||||
* @return {@code this} to allow call chaining
|
||||
*/
|
||||
public final Buffer append( LuaString str ) {
|
||||
final int n = str.m_length;
|
||||
makeroom( 0, n );
|
||||
str.copyInto( 0, bytes, offset + length, n );
|
||||
length += n;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a Java String to the buffer.
|
||||
* The Java string will be converted to bytes using the UTF8 encoding.
|
||||
* @return {@code this} to allow call chaining
|
||||
* @see LuaString#encodeToUtf8(char[], byte[], int)
|
||||
*/
|
||||
public final Buffer append( String str ) {
|
||||
char[] chars = str.toCharArray();
|
||||
/* DAN200 START */
|
||||
/*
|
||||
final int n = LuaString.lengthAsUtf8( chars );
|
||||
makeroom( 0, n );
|
||||
LuaString.encodeToUtf8( chars, bytes, offset + length );
|
||||
length += n;
|
||||
*/
|
||||
makeroom( 0, chars.length );
|
||||
for( int i=0; i<chars.length; ++i )
|
||||
{
|
||||
char ch = chars[i];
|
||||
bytes[ offset + length + i ] = (ch < 256) ? (byte)ch : (byte)'?';
|
||||
}
|
||||
length += chars.length;
|
||||
/* DAN200 END */
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Concatenate this buffer onto a {@link LuaValue}
|
||||
* @param lhs the left-hand-side value onto which we are concatenating {@code this}
|
||||
* @return {@link Buffer} for use in call chaining.
|
||||
*/
|
||||
public Buffer concatTo(LuaValue lhs) {
|
||||
return setvalue(lhs.concat(value()));
|
||||
}
|
||||
|
||||
/** Concatenate this buffer onto a {@link LuaString}
|
||||
* @param lhs the left-hand-side value onto which we are concatenating {@code this}
|
||||
* @return {@link Buffer} for use in call chaining.
|
||||
*/
|
||||
public Buffer concatTo(LuaString lhs) {
|
||||
return value!=null&&!value.isstring()? setvalue(lhs.concat(value)): prepend(lhs);
|
||||
}
|
||||
|
||||
/** Concatenate this buffer onto a {@link LuaNumber}
|
||||
* <p>
|
||||
* The {@link LuaNumber} will be converted to a string before concatenating.
|
||||
* @param lhs the left-hand-side value onto which we are concatenating {@code this}
|
||||
* @return {@link Buffer} for use in call chaining.
|
||||
*/
|
||||
public Buffer concatTo(LuaNumber lhs) {
|
||||
return value!=null&&!value.isstring()? setvalue(lhs.concat(value)): prepend(lhs.strvalue());
|
||||
}
|
||||
|
||||
/** Concatenate bytes from a {@link LuaString} onto the front of this buffer
|
||||
* @param s the left-hand-side value which we will concatenate onto the front of {@code this}
|
||||
* @return {@link Buffer} for use in call chaining.
|
||||
*/
|
||||
public Buffer prepend(LuaString s) {
|
||||
int n = s.m_length;
|
||||
makeroom( n, 0 );
|
||||
System.arraycopy( s.m_bytes, s.m_offset, bytes, offset-n, n );
|
||||
offset -= n;
|
||||
length += n;
|
||||
value = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Ensure there is enough room before and after the bytes.
|
||||
* @param nbefore number of unused bytes which must precede the data after this completes
|
||||
* @param nafter number of unused bytes which must follow the data after this completes
|
||||
*/
|
||||
public final void makeroom( int nbefore, int nafter ) {
|
||||
if ( value != null ) {
|
||||
LuaString s = value.strvalue();
|
||||
value = null;
|
||||
length = s.m_length;
|
||||
offset = nbefore;
|
||||
bytes = new byte[nbefore+length+nafter];
|
||||
System.arraycopy(s.m_bytes, s.m_offset, bytes, offset, length);
|
||||
} else if ( offset+length+nafter > bytes.length || offset<nbefore ) {
|
||||
int n = nbefore+length+nafter;
|
||||
int m = n<32? 32: n<length*2? length*2: n;
|
||||
realloc( m, nbefore==0? 0: m-length-nafter );
|
||||
}
|
||||
}
|
||||
|
||||
/** Reallocate the internal storage for the buffer
|
||||
* @param newSize the size of the buffer to use
|
||||
* @param newOffset the offset to use
|
||||
*/
|
||||
private final void realloc( int newSize, int newOffset ) {
|
||||
if ( newSize != bytes.length ) {
|
||||
byte[] newBytes = new byte[ newSize ];
|
||||
System.arraycopy( bytes, offset, newBytes, newOffset, length );
|
||||
bytes = newBytes;
|
||||
offset = newOffset;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,428 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage loading of {@link Prototype} instances.
|
||||
* <p>
|
||||
* The {@link LoadState} class exposes one main function,
|
||||
* namely {@link #load(InputStream, String, LuaValue)},
|
||||
* to be used to load code from a particular input stream.
|
||||
* <p>
|
||||
* A simple pattern for loading and executing code is
|
||||
* <pre> {@code
|
||||
* LuaValue _G = JsePlatform.standardGlobals();
|
||||
* LoadState.load( new FileInputStream("main.lua"), "main.lua", _G ).call();
|
||||
* } </pre>
|
||||
* This should work regardless of which {@link LuaCompiler}
|
||||
* has been installed.
|
||||
* <p>
|
||||
*
|
||||
* Prior to loading code, a compiler should be installed.
|
||||
* <p>
|
||||
* By default, when using {@link JsePlatform} or {@JmePlatform}
|
||||
* to construct globals, the {@link LuaC} compiler is installed.
|
||||
* <p>
|
||||
* To override the default compiler with, say, the {@link LuaJC}
|
||||
* lua-to-java bytecode compiler, install it before loading,
|
||||
* for example:
|
||||
* <pre> {@code
|
||||
* LuaValue _G = JsePlatform.standardGlobals();
|
||||
* LuaJC.install();
|
||||
* LoadState.load( new FileInputStream("main.lua"), "main.lua", _G ).call();
|
||||
* } </pre>
|
||||
*
|
||||
* @see LuaCompiler
|
||||
* @see LuaClosure
|
||||
* @see LuaFunction
|
||||
* @see LoadState#compiler
|
||||
* @see LoadState#load(InputStream, String, LuaValue)
|
||||
* @see LuaC
|
||||
* @see LuaJC
|
||||
*/
|
||||
public class LoadState {
|
||||
|
||||
/** format corresponding to non-number-patched lua, all numbers are floats or doubles */
|
||||
public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES = 0;
|
||||
|
||||
/** format corresponding to non-number-patched lua, all numbers are ints */
|
||||
public static final int NUMBER_FORMAT_INTS_ONLY = 1;
|
||||
|
||||
/** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */
|
||||
public static final int NUMBER_FORMAT_NUM_PATCH_INT32 = 4;
|
||||
|
||||
// type constants
|
||||
public static final int LUA_TINT = (-2);
|
||||
public static final int LUA_TNONE = (-1);
|
||||
public static final int LUA_TNIL = 0;
|
||||
public static final int LUA_TBOOLEAN = 1;
|
||||
public static final int LUA_TLIGHTUSERDATA = 2;
|
||||
public static final int LUA_TNUMBER = 3;
|
||||
public static final int LUA_TSTRING = 4;
|
||||
public static final int LUA_TTABLE = 5;
|
||||
public static final int LUA_TFUNCTION = 6;
|
||||
public static final int LUA_TUSERDATA = 7;
|
||||
public static final int LUA_TTHREAD = 8;
|
||||
public static final int LUA_TVALUE = 9;
|
||||
|
||||
/** Interface for the compiler, if it is installed.
|
||||
* <p>
|
||||
* See the {@link LuaClosure} documentation for examples of how to use the compiler.
|
||||
* @see LuaClosure
|
||||
* @see #load(InputStream, String, LuaValue)
|
||||
* */
|
||||
public interface LuaCompiler {
|
||||
|
||||
/** Load into a Closure or LuaFunction from a Stream and initializes the environment
|
||||
* @throws IOException */
|
||||
public LuaFunction load(InputStream stream, String filename, LuaValue env) throws IOException;
|
||||
}
|
||||
|
||||
/** Compiler instance, if installed */
|
||||
public static LuaCompiler compiler = null;
|
||||
|
||||
/** Signature byte indicating the file is a compiled binary chunk */
|
||||
private static final byte[] LUA_SIGNATURE = { '\033', 'L', 'u', 'a' };
|
||||
|
||||
/** Name for compiled chunks */
|
||||
public static final String SOURCE_BINARY_STRING = "binary string";
|
||||
|
||||
|
||||
/** for header of binary files -- this is Lua 5.1 */
|
||||
public static final int LUAC_VERSION = 0x51;
|
||||
|
||||
/** for header of binary files -- this is the official format */
|
||||
public static final int LUAC_FORMAT = 0;
|
||||
|
||||
/** size of header of binary files */
|
||||
public static final int LUAC_HEADERSIZE = 12;
|
||||
|
||||
// values read from the header
|
||||
private int luacVersion;
|
||||
private int luacFormat;
|
||||
private boolean luacLittleEndian;
|
||||
private int luacSizeofInt;
|
||||
private int luacSizeofSizeT;
|
||||
private int luacSizeofInstruction;
|
||||
private int luacSizeofLuaNumber;
|
||||
private int luacNumberFormat;
|
||||
|
||||
/** input stream from which we are loading */
|
||||
public final DataInputStream is;
|
||||
|
||||
/** Name of what is being loaded? */
|
||||
String name;
|
||||
|
||||
private static final LuaValue[] NOVALUES = {};
|
||||
private static final Prototype[] NOPROTOS = {};
|
||||
private static final LocVars[] NOLOCVARS = {};
|
||||
private static final LuaString[] NOSTRVALUES = {};
|
||||
private static final int[] NOINTS = {};
|
||||
|
||||
/** Read buffer */
|
||||
private byte[] buf = new byte[512];
|
||||
|
||||
|
||||
/** Load a 4-byte int value from the input stream
|
||||
* @return the int value laoded.
|
||||
**/
|
||||
int loadInt() throws IOException {
|
||||
is.readFully(buf,0,4);
|
||||
return luacLittleEndian?
|
||||
(buf[3] << 24) | ((0xff & buf[2]) << 16) | ((0xff & buf[1]) << 8) | (0xff & buf[0]):
|
||||
(buf[0] << 24) | ((0xff & buf[1]) << 16) | ((0xff & buf[2]) << 8) | (0xff & buf[3]);
|
||||
}
|
||||
|
||||
/** Load an array of int values from the input stream
|
||||
* @return the array of int values laoded.
|
||||
**/
|
||||
int[] loadIntArray() throws IOException {
|
||||
int n = loadInt();
|
||||
if ( n == 0 )
|
||||
return NOINTS;
|
||||
|
||||
// read all data at once
|
||||
int m = n << 2;
|
||||
if ( buf.length < m )
|
||||
buf = new byte[m];
|
||||
is.readFully(buf,0,m);
|
||||
int[] array = new int[n];
|
||||
for ( int i=0, j=0; i<n; ++i, j+=4 )
|
||||
array[i] = luacLittleEndian?
|
||||
(buf[j+3] << 24) | ((0xff & buf[j+2]) << 16) | ((0xff & buf[j+1]) << 8) | (0xff & buf[j+0]):
|
||||
(buf[j+0] << 24) | ((0xff & buf[j+1]) << 16) | ((0xff & buf[j+2]) << 8) | (0xff & buf[j+3]);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/** Load a long value from the input stream
|
||||
* @return the long value laoded.
|
||||
**/
|
||||
long loadInt64() throws IOException {
|
||||
int a,b;
|
||||
if ( this.luacLittleEndian ) {
|
||||
a = loadInt();
|
||||
b = loadInt();
|
||||
} else {
|
||||
b = loadInt();
|
||||
a = loadInt();
|
||||
}
|
||||
return (((long)b)<<32) | (((long)a)&0xffffffffL);
|
||||
}
|
||||
|
||||
/** Load a lua strin gvalue from the input stream
|
||||
* @return the {@link LuaString} value laoded.
|
||||
**/
|
||||
LuaString loadString() throws IOException {
|
||||
int size = this.luacSizeofSizeT == 8? (int) loadInt64(): loadInt();
|
||||
if ( size == 0 )
|
||||
return null;
|
||||
byte[] bytes = new byte[size];
|
||||
is.readFully( bytes, 0, size );
|
||||
return LuaString.valueOf( bytes, 0, bytes.length - 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert bits in a long value to a {@link LuaValue}.
|
||||
* @param bits long value containing the bits
|
||||
* @return {@link LuaInteger} or {@link LuaDouble} whose value corresponds to the bits provided.
|
||||
*/
|
||||
public static LuaValue longBitsToLuaNumber( long bits ) {
|
||||
if ( ( bits & ( ( 1L << 63 ) - 1 ) ) == 0L ) {
|
||||
return LuaValue.ZERO;
|
||||
}
|
||||
|
||||
int e = (int)((bits >> 52) & 0x7ffL) - 1023;
|
||||
|
||||
if ( e >= 0 && e < 31 ) {
|
||||
long f = bits & 0xFFFFFFFFFFFFFL;
|
||||
int shift = 52 - e;
|
||||
long intPrecMask = ( 1L << shift ) - 1;
|
||||
if ( ( f & intPrecMask ) == 0 ) {
|
||||
int intValue = (int)( f >> shift ) | ( 1 << e );
|
||||
return LuaInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue );
|
||||
}
|
||||
}
|
||||
|
||||
return LuaValue.valueOf( Double.longBitsToDouble(bits) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a number from a binary chunk
|
||||
* @return the {@link LuaValue} loaded
|
||||
* @throws IOException if an i/o exception occurs
|
||||
*/
|
||||
LuaValue loadNumber() throws IOException {
|
||||
if ( luacNumberFormat == NUMBER_FORMAT_INTS_ONLY ) {
|
||||
return LuaInteger.valueOf( loadInt() );
|
||||
} else {
|
||||
return longBitsToLuaNumber( loadInt64() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a list of constants from a binary chunk
|
||||
* @param f the function prototype
|
||||
* @throws IOException if an i/o exception occurs
|
||||
*/
|
||||
void loadConstants(Prototype f) throws IOException {
|
||||
int n = loadInt();
|
||||
LuaValue[] values = n>0? new LuaValue[n]: NOVALUES;
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
switch ( is.readByte() ) {
|
||||
case LUA_TNIL:
|
||||
values[i] = LuaValue.NIL;
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
values[i] = (0 != is.readUnsignedByte()? LuaValue.TRUE: LuaValue.FALSE);
|
||||
break;
|
||||
case LUA_TINT:
|
||||
values[i] = LuaInteger.valueOf( loadInt() );
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
values[i] = loadNumber();
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
values[i] = loadString();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("bad constant");
|
||||
}
|
||||
}
|
||||
f.k = values;
|
||||
|
||||
n = loadInt();
|
||||
Prototype[] protos = n>0? new Prototype[n]: NOPROTOS;
|
||||
for ( int i=0; i<n; i++ )
|
||||
protos[i] = loadFunction(f.source);
|
||||
f.p = protos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the debug infor for a function prototype
|
||||
* @param f the function Prototype
|
||||
* @throws IOException if there is an i/o exception
|
||||
*/
|
||||
void loadDebug( Prototype f ) throws IOException {
|
||||
f.lineinfo = loadIntArray();
|
||||
int n = loadInt();
|
||||
f.locvars = n>0? new LocVars[n]: NOLOCVARS;
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
LuaString varname = loadString();
|
||||
int startpc = loadInt();
|
||||
int endpc = loadInt();
|
||||
f.locvars[i] = new LocVars(varname, startpc, endpc);
|
||||
}
|
||||
|
||||
n = loadInt();
|
||||
f.upvalues = n>0? new LuaString[n]: NOSTRVALUES;
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
f.upvalues[i] = loadString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a function prototype from the input stream
|
||||
* @param p name of the source
|
||||
* @return {@link Prototype} instance that was loaded
|
||||
* @throws IOException
|
||||
*/
|
||||
public Prototype loadFunction(LuaString p) throws IOException {
|
||||
Prototype f = new Prototype();
|
||||
// this.L.push(f);
|
||||
f.source = loadString();
|
||||
if ( f.source == null )
|
||||
f.source = p;
|
||||
f.linedefined = loadInt();
|
||||
f.lastlinedefined = loadInt();
|
||||
f.nups = is.readUnsignedByte();
|
||||
f.numparams = is.readUnsignedByte();
|
||||
f.is_vararg = is.readUnsignedByte();
|
||||
f.maxstacksize = is.readUnsignedByte();
|
||||
f.code = loadIntArray();
|
||||
loadConstants(f);
|
||||
loadDebug(f);
|
||||
|
||||
// TODO: add check here, for debugging purposes, I believe
|
||||
// see ldebug.c
|
||||
// IF (!luaG_checkcode(f), "bad code");
|
||||
|
||||
// this.L.pop();
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the lua chunk header values.
|
||||
* @throws IOException if an i/o exception occurs.
|
||||
*/
|
||||
public void loadHeader() throws IOException {
|
||||
luacVersion = is.readByte();
|
||||
luacFormat = is.readByte();
|
||||
luacLittleEndian = (0 != is.readByte());
|
||||
luacSizeofInt = is.readByte();
|
||||
luacSizeofSizeT = is.readByte();
|
||||
luacSizeofInstruction = is.readByte();
|
||||
luacSizeofLuaNumber = is.readByte();
|
||||
luacNumberFormat = is.readByte();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load lua in either binary or text form from an input stream.
|
||||
* @param firstByte the first byte of the input stream
|
||||
* @param stream InputStream to read, after having read the first byte already
|
||||
* @param name Name to apply to the loaded chunk
|
||||
* @return {@link Prototype} that was loaded
|
||||
* @throws IllegalArgumentException if the signature is bac
|
||||
* @throws IOException if an IOException occurs
|
||||
*/
|
||||
public static LuaFunction load( InputStream stream, String name, LuaValue env ) throws IOException {
|
||||
if ( compiler != null )
|
||||
return compiler.load(stream, name, env);
|
||||
else {
|
||||
int firstByte = stream.read();
|
||||
if ( firstByte != LUA_SIGNATURE[0] )
|
||||
throw new LuaError("no compiler");
|
||||
Prototype p = loadBinaryChunk( firstByte, stream, name );
|
||||
return new LuaClosure( p, env );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load lua thought to be a binary chunk from its first byte from an input stream.
|
||||
* @param firstByte the first byte of the input stream
|
||||
* @param stream InputStream to read, after having read the first byte already
|
||||
* @param name Name to apply to the loaded chunk
|
||||
* @return {@link Prototype} that was loaded
|
||||
* @throws IllegalArgumentException if the signature is bac
|
||||
* @throws IOException if an IOException occurs
|
||||
*/
|
||||
public static Prototype loadBinaryChunk( int firstByte, InputStream stream, String name ) throws IOException {
|
||||
|
||||
// check rest of signature
|
||||
if ( firstByte != LUA_SIGNATURE[0]
|
||||
|| stream.read() != LUA_SIGNATURE[1]
|
||||
|| stream.read() != LUA_SIGNATURE[2]
|
||||
|| stream.read() != LUA_SIGNATURE[3] )
|
||||
throw new IllegalArgumentException("bad signature");
|
||||
|
||||
// load file as a compiled chunk
|
||||
String sname = getSourceName(name);
|
||||
LoadState s = new LoadState( stream, sname );
|
||||
s.loadHeader();
|
||||
|
||||
// check format
|
||||
switch ( s.luacNumberFormat ) {
|
||||
case NUMBER_FORMAT_FLOATS_OR_DOUBLES:
|
||||
case NUMBER_FORMAT_INTS_ONLY:
|
||||
case NUMBER_FORMAT_NUM_PATCH_INT32:
|
||||
break;
|
||||
default:
|
||||
throw new LuaError("unsupported int size");
|
||||
}
|
||||
return s.loadFunction( LuaString.valueOf(sname) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a source name from a supplied chunk name
|
||||
* @param name String name that appears in the chunk
|
||||
* @return source file name
|
||||
*/
|
||||
public static String getSourceName(String name) {
|
||||
String sname = name;
|
||||
if ( name.startsWith("@") || name.startsWith("=") )
|
||||
sname = name.substring(1);
|
||||
else if ( name.startsWith("\033") )
|
||||
sname = SOURCE_BINARY_STRING;
|
||||
return sname;
|
||||
}
|
||||
|
||||
/** Private constructor for create a load state */
|
||||
private LoadState( InputStream stream, String name ) {
|
||||
this.name = name;
|
||||
this.is = new DataInputStream( stream );
|
||||
}
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
/**
|
||||
* Data class to hold debug information relatign to local variables for a {@link Prototype}
|
||||
*/
|
||||
public class LocVars {
|
||||
/** The local variable name */
|
||||
public LuaString varname;
|
||||
|
||||
/** The instruction offset when the variable comes into scope */
|
||||
public int startpc;
|
||||
|
||||
/** The instruction offset when the variable goes out of scope */
|
||||
public int endpc;
|
||||
|
||||
/**
|
||||
* Construct a LocVars instance.
|
||||
* @param varname The local variable name
|
||||
* @param startpc The instruction offset when the variable comes into scope
|
||||
* @param endpc The instruction offset when the variable goes out of scope
|
||||
*/
|
||||
public LocVars(LuaString varname, int startpc, int endpc) {
|
||||
this.varname = varname;
|
||||
this.startpc = startpc;
|
||||
this.endpc = endpc;
|
||||
}
|
||||
|
||||
public String tojstring() {
|
||||
return varname+" "+startpc+"-"+endpc;
|
||||
}
|
||||
}
|
@@ -1,337 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
|
||||
/**
|
||||
* Constants for lua limits and opcodes.
|
||||
* <p>
|
||||
* This is a direct translation of C lua distribution header file constants
|
||||
* for bytecode creation and processing.
|
||||
*/
|
||||
public class Lua {
|
||||
/** version is supplied by ant build task */
|
||||
public static final String _VERSION = "Luaj 0.0";
|
||||
|
||||
/** use return values from previous op */
|
||||
public static final int LUA_MULTRET = -1;
|
||||
|
||||
/** masks for new-style vararg */
|
||||
public static final int VARARG_HASARG = 1;
|
||||
public static final int VARARG_ISVARARG = 2;
|
||||
public static final int VARARG_NEEDSARG = 4;
|
||||
|
||||
// from lopcodes.h
|
||||
|
||||
/*===========================================================================
|
||||
We assume that instructions are unsigned numbers.
|
||||
All instructions have an opcode in the first 6 bits.
|
||||
Instructions can have the following fields:
|
||||
`A' : 8 bits
|
||||
`B' : 9 bits
|
||||
`C' : 9 bits
|
||||
`Bx' : 18 bits (`B' and `C' together)
|
||||
`sBx' : signed Bx
|
||||
|
||||
A signed argument is represented in excess K; that is, the number
|
||||
value is the unsigned value minus K. K is exactly the maximum value
|
||||
for that argument (so that -max is represented by 0, and +max is
|
||||
represented by 2*max), which is half the maximum for the corresponding
|
||||
unsigned argument.
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
/* basic instruction format */
|
||||
public static final int iABC = 0;
|
||||
public static final int iABx = 1;
|
||||
public static final int iAsBx = 2;
|
||||
|
||||
|
||||
/*
|
||||
** size and position of opcode arguments.
|
||||
*/
|
||||
public static final int SIZE_C = 9;
|
||||
public static final int SIZE_B = 9;
|
||||
public static final int SIZE_Bx = (SIZE_C + SIZE_B);
|
||||
public static final int SIZE_A = 8;
|
||||
|
||||
public static final int SIZE_OP = 6;
|
||||
|
||||
public static final int POS_OP = 0;
|
||||
public static final int POS_A = (POS_OP + SIZE_OP);
|
||||
public static final int POS_C = (POS_A + SIZE_A);
|
||||
public static final int POS_B = (POS_C + SIZE_C);
|
||||
public static final int POS_Bx = POS_C;
|
||||
|
||||
|
||||
public static final int MAX_OP = ((1<<SIZE_OP)-1);
|
||||
public static final int MAXARG_A = ((1<<SIZE_A)-1);
|
||||
public static final int MAXARG_B = ((1<<SIZE_B)-1);
|
||||
public static final int MAXARG_C = ((1<<SIZE_C)-1);
|
||||
public static final int MAXARG_Bx = ((1<<SIZE_Bx)-1);
|
||||
public static final int MAXARG_sBx = (MAXARG_Bx>>1); /* `sBx' is signed */
|
||||
|
||||
public static final int MASK_OP = ((1<<SIZE_OP)-1)<<POS_OP;
|
||||
public static final int MASK_A = ((1<<SIZE_A)-1)<<POS_A;
|
||||
public static final int MASK_B = ((1<<SIZE_B)-1)<<POS_B;
|
||||
public static final int MASK_C = ((1<<SIZE_C)-1)<<POS_C;
|
||||
public static final int MASK_Bx = ((1<<SIZE_Bx)-1)<<POS_Bx;
|
||||
|
||||
public static final int MASK_NOT_OP = ~MASK_OP;
|
||||
public static final int MASK_NOT_A = ~MASK_A;
|
||||
public static final int MASK_NOT_B = ~MASK_B;
|
||||
public static final int MASK_NOT_C = ~MASK_C;
|
||||
public static final int MASK_NOT_Bx = ~MASK_Bx;
|
||||
|
||||
/*
|
||||
** the following macros help to manipulate instructions
|
||||
*/
|
||||
public static int GET_OPCODE(int i) {
|
||||
return (i >> POS_OP) & MAX_OP;
|
||||
}
|
||||
|
||||
public static int GETARG_A(int i) {
|
||||
return (i >> POS_A) & MAXARG_A;
|
||||
}
|
||||
|
||||
public static int GETARG_B(int i) {
|
||||
return (i >> POS_B) & MAXARG_B;
|
||||
}
|
||||
|
||||
public static int GETARG_C(int i) {
|
||||
return (i >> POS_C) & MAXARG_C;
|
||||
}
|
||||
|
||||
public static int GETARG_Bx(int i) {
|
||||
return (i >> POS_Bx) & MAXARG_Bx;
|
||||
}
|
||||
|
||||
public static int GETARG_sBx(int i) {
|
||||
return ((i >> POS_Bx) & MAXARG_Bx) - MAXARG_sBx;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Macros to operate RK indices
|
||||
*/
|
||||
|
||||
/** this bit 1 means constant (0 means register) */
|
||||
public static final int BITRK = (1 << (SIZE_B - 1));
|
||||
|
||||
/** test whether value is a constant */
|
||||
public static boolean ISK(int x) {
|
||||
return 0 != ((x) & BITRK);
|
||||
}
|
||||
|
||||
/** gets the index of the constant */
|
||||
public static int INDEXK(int r) {
|
||||
return ((int)(r) & ~BITRK);
|
||||
}
|
||||
|
||||
public static final int MAXINDEXRK = (BITRK - 1);
|
||||
|
||||
/** code a constant index as a RK value */
|
||||
public static int RKASK(int x) {
|
||||
return ((x) | BITRK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** invalid register that fits in 8 bits
|
||||
*/
|
||||
public static final int NO_REG = MAXARG_A;
|
||||
|
||||
|
||||
/*
|
||||
** R(x) - register
|
||||
** Kst(x) - constant (in constant table)
|
||||
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** grep "ORDER OP" if you change these enums
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
name args description
|
||||
------------------------------------------------------------------------*/
|
||||
public static final int OP_MOVE = 0;/* A B R(A) := R(B) */
|
||||
public static final int OP_LOADK = 1;/* A Bx R(A) := Kst(Bx) */
|
||||
public static final int OP_LOADBOOL = 2;/* A B C R(A) := (Bool)B; if (C) pc++ */
|
||||
public static final int OP_LOADNIL = 3; /* A B R(A) := ... := R(B) := nil */
|
||||
public static final int OP_GETUPVAL = 4; /* A B R(A) := UpValue[B] */
|
||||
|
||||
public static final int OP_GETGLOBAL = 5; /* A Bx R(A) := Gbl[Kst(Bx)] */
|
||||
public static final int OP_GETTABLE = 6; /* A B C R(A) := R(B)[RK(C)] */
|
||||
|
||||
public static final int OP_SETGLOBAL = 7; /* A Bx Gbl[Kst(Bx)] := R(A) */
|
||||
public static final int OP_SETUPVAL = 8; /* A B UpValue[B] := R(A) */
|
||||
public static final int OP_SETTABLE = 9; /* A B C R(A)[RK(B)] := RK(C) */
|
||||
|
||||
public static final int OP_NEWTABLE = 10; /* A B C R(A) := {} (size = B,C) */
|
||||
|
||||
public static final int OP_SELF = 11; /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
|
||||
|
||||
public static final int OP_ADD = 12; /* A B C R(A) := RK(B) + RK(C) */
|
||||
public static final int OP_SUB = 13; /* A B C R(A) := RK(B) - RK(C) */
|
||||
public static final int OP_MUL = 14; /* A B C R(A) := RK(B) * RK(C) */
|
||||
public static final int OP_DIV = 15; /* A B C R(A) := RK(B) / RK(C) */
|
||||
public static final int OP_MOD = 16; /* A B C R(A) := RK(B) % RK(C) */
|
||||
public static final int OP_POW = 17; /* A B C R(A) := RK(B) ^ RK(C) */
|
||||
public static final int OP_UNM = 18; /* A B R(A) := -R(B) */
|
||||
public static final int OP_NOT = 19; /* A B R(A) := not R(B) */
|
||||
public static final int OP_LEN = 20; /* A B R(A) := length of R(B) */
|
||||
|
||||
public static final int OP_CONCAT = 21; /* A B C R(A) := R(B).. ... ..R(C) */
|
||||
|
||||
public static final int OP_JMP = 22; /* sBx pc+=sBx */
|
||||
|
||||
public static final int OP_EQ = 23; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||
public static final int OP_LT = 24; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||
public static final int OP_LE = 25; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||
|
||||
public static final int OP_TEST = 26; /* A C if not (R(A) <=> C) then pc++ */
|
||||
public static final int OP_TESTSET = 27; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
|
||||
|
||||
public static final int OP_CALL = 28; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
public static final int OP_TAILCALL = 29; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
public static final int OP_RETURN = 30; /* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||
|
||||
public static final int OP_FORLOOP = 31; /* A sBx R(A)+=R(A+2);
|
||||
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
|
||||
public static final int OP_FORPREP = 32; /* A sBx R(A)-=R(A+2); pc+=sBx */
|
||||
|
||||
public static final int OP_TFORLOOP = 33; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
|
||||
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
|
||||
public static final int OP_SETLIST = 34; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
||||
|
||||
public static final int OP_CLOSE = 35; /* A close all variables in the stack up to (>=) R(A)*/
|
||||
public static final int OP_CLOSURE = 36; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
||||
public static final int OP_VARARG = 37; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
|
||||
|
||||
public static final int NUM_OPCODES = OP_VARARG + 1;
|
||||
|
||||
/* pseudo-opcodes used in parsing only. */
|
||||
public static final int OP_GT = 63; // >
|
||||
public static final int OP_GE = 62; // >=
|
||||
public static final int OP_NEQ = 61; // ~=
|
||||
public static final int OP_AND = 60; // and
|
||||
public static final int OP_OR = 59; // or
|
||||
|
||||
/*===========================================================================
|
||||
Notes:
|
||||
(*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
|
||||
and can be 0: OP_CALL then sets `top' to last_result+1, so
|
||||
next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
|
||||
|
||||
(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
|
||||
set top (like in OP_CALL with C == 0).
|
||||
|
||||
(*) In OP_RETURN, if (B == 0) then return up to `top'
|
||||
|
||||
(*) In OP_SETLIST, if (B == 0) then B = `top';
|
||||
if (C == 0) then next `instruction' is real C
|
||||
|
||||
(*) For comparisons, A specifies what condition the test should accept
|
||||
(true or false).
|
||||
|
||||
(*) All `skips' (pc++) assume that next instruction is a jump
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
/*
|
||||
** masks for instruction properties. The format is:
|
||||
** bits 0-1: op mode
|
||||
** bits 2-3: C arg mode
|
||||
** bits 4-5: B arg mode
|
||||
** bit 6: instruction set register A
|
||||
** bit 7: operator is a test
|
||||
*/
|
||||
|
||||
public static final int OpArgN = 0; /* argument is not used */
|
||||
public static final int OpArgU = 1; /* argument is used */
|
||||
public static final int OpArgR = 2; /* argument is a register or a jump offset */
|
||||
public static final int OpArgK = 3; /* argument is a constant or register/constant */
|
||||
|
||||
public static final int[] luaP_opmodes = {
|
||||
/* T A B C mode opcode */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_MOVE */
|
||||
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_LOADK */
|
||||
(0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_LOADBOOL */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LOADNIL */
|
||||
(0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_GETUPVAL */
|
||||
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_GETGLOBAL */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC), /* OP_GETTABLE */
|
||||
(0<<7) | (0<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_SETGLOBAL */
|
||||
(0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_SETUPVAL */
|
||||
(0<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SETTABLE */
|
||||
(0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_NEWTABLE */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC), /* OP_SELF */
|
||||
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_ADD */
|
||||
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SUB */
|
||||
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MUL */
|
||||
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_DIV */
|
||||
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MOD */
|
||||
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_POW */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_UNM */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_NOT */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LEN */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC), /* OP_CONCAT */
|
||||
(0<<7) | (0<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_JMP */
|
||||
(1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_EQ */
|
||||
(1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_LT */
|
||||
(1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_LE */
|
||||
(1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC), /* OP_TEST */
|
||||
(1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC), /* OP_TESTSET */
|
||||
(0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_CALL */
|
||||
(0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_TAILCALL */
|
||||
(0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_RETURN */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_FORLOOP */
|
||||
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_FORPREP */
|
||||
(1<<7) | (0<<6) | (OpArgN<<4) | (OpArgU<<2) | (iABC), /* OP_TFORLOOP */
|
||||
(0<<7) | (0<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_SETLIST */
|
||||
(0<<7) | (0<<6) | (OpArgN<<4) | (OpArgN<<2) | (iABC), /* OP_CLOSE */
|
||||
(0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABx), /* OP_CLOSURE */
|
||||
(0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_VARARG */
|
||||
};
|
||||
|
||||
public static int getOpMode(int m) {
|
||||
return luaP_opmodes[m] & 3;
|
||||
}
|
||||
public static int getBMode(int m) {
|
||||
return (luaP_opmodes[m] >> 4) & 3;
|
||||
}
|
||||
public static int getCMode(int m) {
|
||||
return (luaP_opmodes[m] >> 2) & 3;
|
||||
}
|
||||
public static boolean testAMode(int m) {
|
||||
return 0 != (luaP_opmodes[m] & (1 << 6));
|
||||
}
|
||||
public static boolean testTMode(int m) {
|
||||
return 0 != (luaP_opmodes[m] & (1 << 7));
|
||||
}
|
||||
|
||||
/* number of list items to accumulate before a SETLIST instruction */
|
||||
public static final int LFIELDS_PER_FLUSH = 50;
|
||||
|
||||
}
|
@@ -1,103 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
/**
|
||||
* Extension of {@link LuaValue} which can hold a Java boolean as its value.
|
||||
* <p>
|
||||
* These instance are not instantiated directly by clients.
|
||||
* Instead, there are exactly twon instances of this class,
|
||||
* {@link LuaValue#TRUE} and {@link LuaValue#FALSE}
|
||||
* representing the lua values {@code true} and {@link false}.
|
||||
* The function {@link LuaValue#valueOf(boolean)} will always
|
||||
* return one of these two values.
|
||||
* <p>
|
||||
* Any {@link LuaValue} can be converted to its equivalent
|
||||
* boolean representation using {@link LuaValue#toboolean()}
|
||||
* <p>
|
||||
* @see LuaValue
|
||||
* @see LuaValue#valueOf(boolean)
|
||||
* @see LuaValue#TRUE
|
||||
* @see LuaValue#FALSE
|
||||
*/
|
||||
public final class LuaBoolean extends LuaValue {
|
||||
|
||||
/** The singleton instance representing lua {@code true} */
|
||||
static final LuaBoolean _TRUE = new LuaBoolean(true);
|
||||
|
||||
/** The singleton instance representing lua {@code false} */
|
||||
static final LuaBoolean _FALSE = new LuaBoolean(false);
|
||||
|
||||
/** Shared static metatable for boolean values represented in lua. */
|
||||
public static LuaValue s_metatable;
|
||||
|
||||
/** The value of the boolean */
|
||||
public final boolean v;
|
||||
|
||||
LuaBoolean(boolean b) {
|
||||
this.v = b;
|
||||
}
|
||||
|
||||
public int type() {
|
||||
return LuaValue.TBOOLEAN;
|
||||
}
|
||||
|
||||
public String typename() {
|
||||
return "boolean";
|
||||
}
|
||||
|
||||
public boolean isboolean() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public LuaValue not() {
|
||||
return v ? FALSE : LuaValue.TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the boolean value for this boolean
|
||||
* @return value as a Java boolean
|
||||
*/
|
||||
public boolean booleanValue() {
|
||||
return v;
|
||||
}
|
||||
|
||||
public boolean toboolean() {
|
||||
return v;
|
||||
}
|
||||
|
||||
public String tojstring() {
|
||||
return v ? "true" : "false";
|
||||
}
|
||||
|
||||
public boolean optboolean(boolean defval) {
|
||||
return this.v;
|
||||
}
|
||||
|
||||
public boolean checkboolean() {
|
||||
return v;
|
||||
}
|
||||
|
||||
public LuaValue getmetatable() {
|
||||
return s_metatable;
|
||||
}
|
||||
}
|
@@ -1,521 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.luaj.vm2.LoadState.LuaCompiler;
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
import org.luaj.vm2.lib.DebugLib;
|
||||
|
||||
/**
|
||||
* Extension of {@link LuaFunction} which executes lua bytecode.
|
||||
* <p>
|
||||
* A {@link LuaClosure} is a combination of a {@link Prototype}
|
||||
* and a {@link LuaValue} to use as an environment for execution.
|
||||
* <p>
|
||||
* There are three main ways {@link LuaClosure} instances are created:
|
||||
* <ul>
|
||||
* <li>Construct an instance using {@link #LuaClosure(Prototype, LuaValue)}</li>
|
||||
* <li>Construct it indirectly by loading a chunk via {@link LuaCompiler#load(java.io.InputStream, String, LuaValue)}
|
||||
* <li>Execute the lua bytecode {@link Lua#OP_CLOSURE} as part of bytecode processing
|
||||
* </ul>
|
||||
* <p>
|
||||
* To construct it directly, the {@link Prototype} is typically created via a compiler such as {@link LuaC}:
|
||||
* <pre> {@code
|
||||
* InputStream is = new ByteArrayInputStream("print('hello,world').getBytes());
|
||||
* Prototype p = LuaC.instance.compile(is, "script");
|
||||
* LuaValue _G = JsePlatform.standardGlobals()
|
||||
* LuaClosure f = new LuaClosure(p, _G);
|
||||
* }</pre>
|
||||
* <p>
|
||||
* To construct it indirectly, the {@link LuaC} compiler may be used,
|
||||
* which implements the {@link LuaCompiler} interface:
|
||||
* <pre> {@code
|
||||
* LuaFunction f = LuaC.instance.load(is, "script", _G);
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Typically, a closure that has just been loaded needs to be initialized by executing it,
|
||||
* and its return value can be saved if needed:
|
||||
* <pre> {@code
|
||||
* LuaValue r = f.call();
|
||||
* _G.set( "mypkg", r )
|
||||
* }</pre>
|
||||
* <p>
|
||||
* In the preceding, the loaded value is typed as {@link LuaFunction}
|
||||
* to allow for the possibility of other compilers such as {@link LuaJC}
|
||||
* producing {@link LuaFunction} directly without
|
||||
* creating a {@link Prototype} or {@link LuaClosure}.
|
||||
* <p>
|
||||
* Since a {@link LuaClosure} is a {@link LuaFunction} which is a {@link LuaValue},
|
||||
* all the value operations can be used directly such as:
|
||||
* <ul>
|
||||
* <li>{@link LuaValue#setfenv(LuaValue)}</li>
|
||||
* <li>{@link LuaValue#call()}</li>
|
||||
* <li>{@link LuaValue#call(LuaValue)}</li>
|
||||
* <li>{@link LuaValue#invoke()}</li>
|
||||
* <li>{@link LuaValue#invoke(Varargs)}</li>
|
||||
* <li>{@link LuaValue#method(String)}</li>
|
||||
* <li>{@link LuaValue#method(String,LuaValue)}</li>
|
||||
* <li>{@link LuaValue#invokemethod(String)}</li>
|
||||
* <li>{@link LuaValue#invokemethod(String,Varargs)}</li>
|
||||
* <li> ...</li>
|
||||
* </ul>
|
||||
* @see LuaValue
|
||||
* @see LuaFunction
|
||||
* @see LuaValue#isclosure()
|
||||
* @see LuaValue#checkclosure()
|
||||
* @see LuaValue#optclosure(LuaClosure)
|
||||
* @see LoadState
|
||||
* @see LoadState#compiler
|
||||
*/
|
||||
public class LuaClosure extends LuaFunction {
|
||||
private static final UpValue[] NOUPVALUES = new UpValue[0];
|
||||
|
||||
public final Prototype p;
|
||||
public final UpValue[] upValues;
|
||||
|
||||
LuaClosure() {
|
||||
p = null;
|
||||
upValues = null;
|
||||
}
|
||||
/** Supply the initial environment */
|
||||
public LuaClosure(Prototype p, LuaValue env) {
|
||||
super( env );
|
||||
this.p = p;
|
||||
this.upValues = p.nups>0? new UpValue[p.nups]: NOUPVALUES;
|
||||
}
|
||||
|
||||
protected LuaClosure(int nupvalues, LuaValue env) {
|
||||
super( env );
|
||||
this.p = null;
|
||||
this.upValues = nupvalues>0? new UpValue[nupvalues]: NOUPVALUES;
|
||||
}
|
||||
|
||||
public boolean isclosure() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public LuaClosure optclosure(LuaClosure defval) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LuaClosure checkclosure() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LuaValue getmetatable() {
|
||||
return s_metatable;
|
||||
}
|
||||
|
||||
public final LuaValue call() {
|
||||
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
|
||||
return execute(stack,NONE).arg1();
|
||||
}
|
||||
|
||||
public final LuaValue call(LuaValue arg) {
|
||||
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
|
||||
switch ( p.numparams ) {
|
||||
default: stack[0]=arg; return execute(stack,NONE).arg1();
|
||||
case 0: return execute(stack,arg).arg1();
|
||||
}
|
||||
}
|
||||
|
||||
public final LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
|
||||
switch ( p.numparams ) {
|
||||
default: stack[0]=arg1; stack[1]=arg2; return execute(stack,NONE).arg1();
|
||||
case 1: stack[0]=arg1; return execute(stack,arg2).arg1();
|
||||
case 0: return execute(stack,p.is_vararg!=0? varargsOf(arg1,arg2): NONE).arg1();
|
||||
}
|
||||
}
|
||||
|
||||
public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
||||
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
|
||||
switch ( p.numparams ) {
|
||||
default: stack[0]=arg1; stack[1]=arg2; stack[2]=arg3; return execute(stack,NONE).arg1();
|
||||
case 2: stack[0]=arg1; stack[1]=arg2; return execute(stack,arg3).arg1();
|
||||
case 1: stack[0]=arg1; return execute(stack,p.is_vararg!=0? varargsOf(arg2,arg3): NONE).arg1();
|
||||
case 0: return execute(stack,p.is_vararg!=0? varargsOf(arg1,arg2,arg3): NONE).arg1();
|
||||
}
|
||||
}
|
||||
|
||||
public final Varargs invoke(Varargs varargs) {
|
||||
return onInvoke( varargs ).eval();
|
||||
}
|
||||
|
||||
public Varargs onInvoke(Varargs varargs) {
|
||||
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
|
||||
for ( int i=0; i<p.numparams; i++ )
|
||||
stack[i] = varargs.arg(i+1);
|
||||
return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
|
||||
}
|
||||
|
||||
|
||||
protected Varargs execute( LuaValue[] stack, Varargs varargs ) {
|
||||
// loop through instructions
|
||||
int i,a,b,c,pc=0,top=0;
|
||||
LuaValue o;
|
||||
Varargs v = NONE;
|
||||
int[] code = p.code;
|
||||
LuaValue[] k = p.k;
|
||||
|
||||
// upvalues are only possible when closures create closures
|
||||
UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
|
||||
|
||||
// create varargs "arg" table
|
||||
if ( p.is_vararg >= Lua.VARARG_NEEDSARG )
|
||||
stack[p.numparams] = new LuaTable(varargs);
|
||||
|
||||
// debug wants args to this function
|
||||
if (DebugLib.DEBUG_ENABLED)
|
||||
DebugLib.debugSetupCall(varargs, stack);
|
||||
|
||||
// process instructions
|
||||
LuaThread.CallStack cs = LuaThread.onCall( this );
|
||||
try {
|
||||
while ( true ) {
|
||||
if (DebugLib.DEBUG_ENABLED)
|
||||
DebugLib.debugBytecode(pc, v, top);
|
||||
|
||||
// pull out instruction
|
||||
i = code[pc++];
|
||||
a = ((i>>6) & 0xff);
|
||||
|
||||
// process the op code
|
||||
switch ( i & 0x3f ) {
|
||||
|
||||
case Lua.OP_MOVE:/* A B R(A):= R(B) */
|
||||
stack[a] = stack[i>>>23];
|
||||
continue;
|
||||
|
||||
case Lua.OP_LOADK:/* A Bx R(A):= Kst(Bx) */
|
||||
stack[a] = k[i>>>14];
|
||||
continue;
|
||||
|
||||
case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */
|
||||
stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
|
||||
if ((i&(0x1ff<<14)) != 0)
|
||||
pc++; /* skip next instruction (if C) */
|
||||
continue;
|
||||
|
||||
case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(B):= nil */
|
||||
for ( b=i>>>23; a<=b; )
|
||||
stack[a++] = LuaValue.NIL;
|
||||
continue;
|
||||
|
||||
case Lua.OP_GETUPVAL: /* A B R(A):= UpValue[B] */
|
||||
stack[a] = upValues[i>>>23].getValue();
|
||||
continue;
|
||||
|
||||
case Lua.OP_GETGLOBAL: /* A Bx R(A):= Gbl[Kst(Bx)] */
|
||||
stack[a] = env.get(k[i>>>14]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_GETTABLE: /* A B C R(A):= R(B)[RK(C)] */
|
||||
stack[a] = stack[i>>>23].get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_SETGLOBAL: /* A Bx Gbl[Kst(Bx)]:= R(A) */
|
||||
env.set(k[i>>>14], stack[a]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_SETUPVAL: /* A B UpValue[B]:= R(A) */
|
||||
upValues[i>>>23].setValue(stack[a]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_SETTABLE: /* A B C R(A)[RK(B)]:= RK(C) */
|
||||
stack[a].set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_NEWTABLE: /* A B C R(A):= {} (size = B,C) */
|
||||
stack[a] = new LuaTable(i>>>23,(i>>14)&0x1ff);
|
||||
continue;
|
||||
|
||||
case Lua.OP_SELF: /* A B C R(A+1):= R(B): R(A):= R(B)[RK(C)] */
|
||||
stack[a+1] = (o = stack[i>>>23]);
|
||||
stack[a] = o.get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_ADD: /* A B C R(A):= RK(B) + RK(C) */
|
||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).add((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_SUB: /* A B C R(A):= RK(B) - RK(C) */
|
||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).sub((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_MUL: /* A B C R(A):= RK(B) * RK(C) */
|
||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mul((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_DIV: /* A B C R(A):= RK(B) / RK(C) */
|
||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).div((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_MOD: /* A B C R(A):= RK(B) % RK(C) */
|
||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mod((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_POW: /* A B C R(A):= RK(B) ^ RK(C) */
|
||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).pow((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||
continue;
|
||||
|
||||
case Lua.OP_UNM: /* A B R(A):= -R(B) */
|
||||
stack[a] = stack[i>>>23].neg();
|
||||
continue;
|
||||
|
||||
case Lua.OP_NOT: /* A B R(A):= not R(B) */
|
||||
stack[a] = stack[i>>>23].not();
|
||||
continue;
|
||||
|
||||
case Lua.OP_LEN: /* A B R(A):= length of R(B) */
|
||||
stack[a] = stack[i>>>23].len();
|
||||
continue;
|
||||
|
||||
case Lua.OP_CONCAT: /* A B C R(A):= R(B).. ... ..R(C) */
|
||||
b = i>>>23;
|
||||
c = (i>>14)&0x1ff;
|
||||
{
|
||||
if ( c > b+1 ) {
|
||||
Buffer sb = stack[c].buffer();
|
||||
while ( --c>=b )
|
||||
sb = stack[c].concat(sb);
|
||||
stack[a] = sb.value();
|
||||
} else {
|
||||
stack[a] = stack[c-1].concat(stack[c]);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case Lua.OP_JMP: /* sBx pc+=sBx */
|
||||
pc += (i>>>14)-0x1ffff;
|
||||
continue;
|
||||
|
||||
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).eq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
||||
++pc;
|
||||
continue;
|
||||
|
||||
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lt_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
||||
++pc;
|
||||
continue;
|
||||
|
||||
case Lua.OP_LE: /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lteq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
||||
++pc;
|
||||
continue;
|
||||
|
||||
case Lua.OP_TEST: /* A C if not (R(A) <=> C) then pc++ */
|
||||
if ( stack[a].toboolean() != ((i&(0x1ff<<14))!=0) )
|
||||
++pc;
|
||||
continue;
|
||||
|
||||
case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */
|
||||
/* note: doc appears to be reversed */
|
||||
if ( (o=stack[i>>>23]).toboolean() != ((i&(0x1ff<<14))!=0) )
|
||||
++pc;
|
||||
else
|
||||
stack[a] = o; // TODO: should be sBx?
|
||||
continue;
|
||||
|
||||
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
switch ( i & (Lua.MASK_B | Lua.MASK_C) ) {
|
||||
case (1<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(NONE); top=a+v.narg(); continue;
|
||||
case (2<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(stack[a+1]); top=a+v.narg(); continue;
|
||||
case (1<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(); continue;
|
||||
case (2<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1]); continue;
|
||||
case (3<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2]); continue;
|
||||
case (4<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
|
||||
case (1<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(); continue;
|
||||
case (2<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1]); continue;
|
||||
case (3<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2]); continue;
|
||||
case (4<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
|
||||
default:
|
||||
b = i>>>23;
|
||||
c = (i>>14)&0x1ff;
|
||||
v = b>0?
|
||||
varargsOf(stack,a+1,b-1): // exact arg count
|
||||
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
|
||||
v = stack[a].invoke(v);
|
||||
if ( c > 0 ) {
|
||||
while ( --c > 0 )
|
||||
stack[a+c-1] = v.arg(c);
|
||||
v = NONE; // TODO: necessary?
|
||||
} else {
|
||||
top = a + v.narg();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
switch ( i & Lua.MASK_B ) {
|
||||
case (1<<Lua.POS_B): return new TailcallVarargs(stack[a], NONE);
|
||||
case (2<<Lua.POS_B): return new TailcallVarargs(stack[a], stack[a+1]);
|
||||
case (3<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2]));
|
||||
case (4<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2],stack[a+3]));
|
||||
default:
|
||||
b = i>>>23;
|
||||
v = b>0?
|
||||
varargsOf(stack,a+1,b-1): // exact arg count
|
||||
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
|
||||
return new TailcallVarargs( stack[a], v );
|
||||
}
|
||||
|
||||
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||
b = i>>>23;
|
||||
switch ( b ) {
|
||||
case 0: return varargsOf(stack, a, top-v.narg()-a, v);
|
||||
case 1: return NONE;
|
||||
case 2: return stack[a];
|
||||
default:
|
||||
return varargsOf(stack, a, b-1);
|
||||
}
|
||||
|
||||
case Lua.OP_FORLOOP: /* A sBx R(A)+=R(A+2): if R(A) <?= R(A+1) then { pc+=sBx: R(A+3)=R(A) }*/
|
||||
{
|
||||
LuaValue limit = stack[a + 1];
|
||||
LuaValue step = stack[a + 2];
|
||||
LuaValue idx = step.add(stack[a]);
|
||||
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
|
||||
stack[a] = idx;
|
||||
stack[a + 3] = idx;
|
||||
pc += (i>>>14)-0x1ffff;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case Lua.OP_FORPREP: /* A sBx R(A)-=R(A+2): pc+=sBx */
|
||||
{
|
||||
LuaValue init = stack[a].checknumber("'for' initial value must be a number");
|
||||
LuaValue limit = stack[a + 1].checknumber("'for' limit must be a number");
|
||||
LuaValue step = stack[a + 2].checknumber("'for' step must be a number");
|
||||
stack[a] = init.sub(step);
|
||||
stack[a + 1] = limit;
|
||||
stack[a + 2] = step;
|
||||
pc += (i>>>14)-0x1ffff;
|
||||
}
|
||||
continue;
|
||||
|
||||
case Lua.OP_TFORLOOP: /*
|
||||
* A C R(A+3), ... ,R(A+2+C):= R(A)(R(A+1),
|
||||
* R(A+2)): if R(A+3) ~= nil then R(A+2)=R(A+3)
|
||||
* else pc++
|
||||
*/
|
||||
// TODO: stack call on for loop body, such as: stack[a].call(ci);
|
||||
v = stack[a].invoke(varargsOf(stack[a+1],stack[a+2]));
|
||||
if ( (o=v.arg1()).isnil() )
|
||||
++pc;
|
||||
else {
|
||||
stack[a+2] = stack[a+3] = o;
|
||||
for ( c=(i>>14)&0x1ff; c>1; --c )
|
||||
stack[a+2+c] = v.arg(c);
|
||||
v = NONE; // todo: necessary?
|
||||
}
|
||||
continue;
|
||||
|
||||
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
||||
{
|
||||
if ( (c=(i>>14)&0x1ff) == 0 )
|
||||
c = code[pc++];
|
||||
int offset = (c-1) * Lua.LFIELDS_PER_FLUSH;
|
||||
o = stack[a];
|
||||
if ( (b=i>>>23) == 0 ) {
|
||||
b = top - a - 1;
|
||||
int m = b - v.narg();
|
||||
int j=1;
|
||||
for ( ;j<=m; j++ )
|
||||
o.set(offset+j, stack[a + j]);
|
||||
for ( ;j<=b; j++ )
|
||||
o.set(offset+j, v.arg(j-m));
|
||||
} else {
|
||||
o.presize( offset + b );
|
||||
for (int j=1; j<=b; j++)
|
||||
o.set(offset+j, stack[a + j]);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case Lua.OP_CLOSE: /* A close all variables in the stack up to (>=) R(A)*/
|
||||
for ( b=openups.length; --b>=a; )
|
||||
if ( openups[b]!=null ) {
|
||||
openups[b].close();
|
||||
openups[b] = null;
|
||||
}
|
||||
continue;
|
||||
|
||||
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
||||
{
|
||||
Prototype newp = p.p[i>>>14];
|
||||
LuaClosure newcl = new LuaClosure(newp, env);
|
||||
for ( int j=0, nup=newp.nups; j<nup; ++j ) {
|
||||
i = code[pc++];
|
||||
//b = B(i);
|
||||
b = i>>>23;
|
||||
newcl.upValues[j] = (i&4) != 0?
|
||||
upValues[b]:
|
||||
openups[b]!=null? openups[b]: (openups[b]=new UpValue(stack,b));
|
||||
}
|
||||
stack[a] = newcl;
|
||||
}
|
||||
continue;
|
||||
|
||||
case Lua.OP_VARARG: /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
|
||||
b = i>>>23;
|
||||
if ( b == 0 ) {
|
||||
top = a + (b = varargs.narg());
|
||||
v = varargs;
|
||||
} else {
|
||||
for ( int j=1; j<b; ++j )
|
||||
stack[a+j-1] = varargs.arg(j);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch ( LuaError le ) {
|
||||
throw le;
|
||||
} catch ( Exception e ) {
|
||||
throw new LuaError(e);
|
||||
} finally {
|
||||
cs.onReturn();
|
||||
if ( openups != null )
|
||||
for ( int u=openups.length; --u>=0; )
|
||||
if ( openups[u] != null )
|
||||
openups[u].close();
|
||||
}
|
||||
}
|
||||
|
||||
protected LuaValue getUpvalue(int i) {
|
||||
return upValues[i].getValue();
|
||||
}
|
||||
|
||||
protected void setUpvalue(int i, LuaValue v) {
|
||||
upValues[i].setValue(v);
|
||||
}
|
||||
}
|
@@ -1,288 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
import org.luaj.vm2.lib.MathLib;
|
||||
|
||||
/**
|
||||
* Extension of {@link LuaNumber} which can hold a Java double as its value.
|
||||
* <p>
|
||||
* These instance are not instantiated directly by clients, but indirectly
|
||||
* via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)}
|
||||
* functions. This ensures that values which can be represented as int
|
||||
* are wrapped in {@link LuaInteger} instead of {@link LuaDouble}.
|
||||
* <p>
|
||||
* Almost all API's implemented in LuaDouble are defined and documented in {@link LuaValue}.
|
||||
* <p>
|
||||
* However the constants {@link #NAN}, {@link #POSINF}, {@link #NEGINF},
|
||||
* {@link #JSTR_NAN}, {@link #JSTR_POSINF}, and {@link #JSTR_NEGINF} may be useful
|
||||
* when dealing with Nan or Infinite values.
|
||||
* <p>
|
||||
* LuaDouble also defines functions for handling the unique math rules of lua devision and modulo in
|
||||
* <ul>
|
||||
* <li>{@link #ddiv(double, double)}</li>
|
||||
* <li>{@link #ddiv_d(double, double)}</li>
|
||||
* <li>{@link #dmod(double, double)}</li>
|
||||
* <li>{@link #dmod_d(double, double)}</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* @see LuaValue
|
||||
* @see LuaNumber
|
||||
* @see LuaInteger
|
||||
* @see LuaValue#valueOf(int)
|
||||
* @see LuaValue#valueOf(double)
|
||||
*/
|
||||
public class LuaDouble extends LuaNumber {
|
||||
|
||||
/** Constant LuaDouble representing NaN (not a number) */
|
||||
public static final LuaDouble NAN = new LuaDouble( Double.NaN );
|
||||
|
||||
/** Constant LuaDouble representing positive infinity */
|
||||
public static final LuaDouble POSINF = new LuaDouble( Double.POSITIVE_INFINITY );
|
||||
|
||||
/** Constant LuaDouble representing negative infinity */
|
||||
public static final LuaDouble NEGINF = new LuaDouble( Double.NEGATIVE_INFINITY );
|
||||
|
||||
/** Constant String representation for NaN (not a number), "nan" */
|
||||
public static final String JSTR_NAN = "nan";
|
||||
|
||||
/** Constant String representation for positive infinity, "inf" */
|
||||
public static final String JSTR_POSINF = "inf";
|
||||
|
||||
/** Constant String representation for negative infinity, "-inf" */
|
||||
public static final String JSTR_NEGINF = "-inf";
|
||||
|
||||
/** The value being held by this instance. */
|
||||
final double v;
|
||||
|
||||
public static LuaNumber valueOf(double d) {
|
||||
int id = (int) d;
|
||||
return d==id? (LuaNumber) LuaInteger.valueOf(id): (LuaNumber) new LuaDouble(d);
|
||||
}
|
||||
|
||||
/** Don't allow ints to be boxed by DoubleValues */
|
||||
private LuaDouble(double d) {
|
||||
this.v = d;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
long l = Double.doubleToLongBits(v);
|
||||
return ((int)(l>>32)) | (int) l;
|
||||
}
|
||||
|
||||
public boolean islong() {
|
||||
return v == (long) v;
|
||||
}
|
||||
|
||||
public byte tobyte() { return (byte) (long) v; }
|
||||
public char tochar() { return (char) (long) v; }
|
||||
public double todouble() { return v; }
|
||||
public float tofloat() { return (float) v; }
|
||||
public int toint() { return (int) (long) v; }
|
||||
public long tolong() { return (long) v; }
|
||||
public short toshort() { return (short) (long) v; }
|
||||
|
||||
public double optdouble(double defval) { return v; }
|
||||
public int optint(int defval) { return (int) (long) v; }
|
||||
public LuaInteger optinteger(LuaInteger defval) { return LuaInteger.valueOf((int) (long)v); }
|
||||
public long optlong(long defval) { return (long) v; }
|
||||
|
||||
public LuaInteger checkinteger() { return LuaInteger.valueOf( (int) (long) v ); }
|
||||
|
||||
// unary operators
|
||||
public LuaValue neg() { return valueOf(-v); }
|
||||
|
||||
// object equality, used for key comparison
|
||||
public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; }
|
||||
|
||||
// equality w/ metatable processing
|
||||
public LuaValue eq( LuaValue val ) { return val.raweq(v)? TRUE: FALSE; }
|
||||
public boolean eq_b( LuaValue val ) { return val.raweq(v); }
|
||||
|
||||
// equality w/o metatable processing
|
||||
public boolean raweq( LuaValue val ) { return val.raweq(v); }
|
||||
public boolean raweq( double val ) { return v == val; }
|
||||
public boolean raweq( int val ) { return v == val; }
|
||||
|
||||
// basic binary arithmetic
|
||||
public LuaValue add( LuaValue rhs ) { return rhs.add(v); }
|
||||
public LuaValue add( double lhs ) { return LuaDouble.valueOf(lhs + v); }
|
||||
public LuaValue sub( LuaValue rhs ) { return rhs.subFrom(v); }
|
||||
public LuaValue sub( double rhs ) { return LuaDouble.valueOf(v - rhs); }
|
||||
public LuaValue sub( int rhs ) { return LuaDouble.valueOf(v - rhs); }
|
||||
public LuaValue subFrom( double lhs ) { return LuaDouble.valueOf(lhs - v); }
|
||||
public LuaValue mul( LuaValue rhs ) { return rhs.mul(v); }
|
||||
public LuaValue mul( double lhs ) { return LuaDouble.valueOf(lhs * v); }
|
||||
public LuaValue mul( int lhs ) { return LuaDouble.valueOf(lhs * v); }
|
||||
public LuaValue pow( LuaValue rhs ) { return rhs.powWith(v); }
|
||||
public LuaValue pow( double rhs ) { return MathLib.dpow(v,rhs); }
|
||||
public LuaValue pow( int rhs ) { return MathLib.dpow(v,rhs); }
|
||||
public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); }
|
||||
public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); }
|
||||
public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); }
|
||||
public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); }
|
||||
public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); }
|
||||
public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); }
|
||||
public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); }
|
||||
public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); }
|
||||
public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); }
|
||||
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs,v); }
|
||||
|
||||
|
||||
/** Divide two double numbers according to lua math, and return a {@link LuaValue} result.
|
||||
* @param lhs Left-hand-side of the division.
|
||||
* @param rhs Right-hand-side of the division.
|
||||
* @return {@link LuaValue} for the result of the division,
|
||||
* taking into account positive and negiative infinity, and Nan
|
||||
* @see #ddiv_d(double, double)
|
||||
*/
|
||||
public static LuaValue ddiv(double lhs, double rhs) {
|
||||
return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF;
|
||||
}
|
||||
|
||||
/** Divide two double numbers according to lua math, and return a double result.
|
||||
* @param lhs Left-hand-side of the division.
|
||||
* @param rhs Right-hand-side of the division.
|
||||
* @return Value of the division, taking into account positive and negative infinity, and Nan
|
||||
* @see #ddiv(double, double)
|
||||
*/
|
||||
public static double ddiv_d(double lhs, double rhs) {
|
||||
return rhs!=0? lhs / rhs: lhs>0? Double.POSITIVE_INFINITY: lhs==0? Double.NaN: Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
/** Take modulo double numbers according to lua math, and return a {@link LuaValue} result.
|
||||
* @param lhs Left-hand-side of the modulo.
|
||||
* @param rhs Right-hand-side of the modulo.
|
||||
* @return {@link LuaValue} for the result of the modulo,
|
||||
* using lua's rules for modulo
|
||||
* @see #dmod_d(double, double)
|
||||
*/
|
||||
public static LuaValue dmod(double lhs, double rhs) {
|
||||
return rhs!=0? valueOf( lhs-rhs*Math.floor(lhs/rhs) ): NAN;
|
||||
}
|
||||
|
||||
/** Take modulo for double numbers according to lua math, and return a double result.
|
||||
* @param lhs Left-hand-side of the modulo.
|
||||
* @param rhs Right-hand-side of the modulo.
|
||||
* @return double value for the result of the modulo,
|
||||
* using lua's rules for modulo
|
||||
* @see #dmod(double, double)
|
||||
*/
|
||||
public static double dmod_d(double lhs, double rhs) {
|
||||
return rhs!=0? lhs-rhs*Math.floor(lhs/rhs): Double.NaN;
|
||||
}
|
||||
|
||||
// relational operators
|
||||
public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? LuaValue.TRUE: FALSE; }
|
||||
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
|
||||
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
|
||||
public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); }
|
||||
public boolean lt_b( int rhs ) { return v < rhs; }
|
||||
public boolean lt_b( double rhs ) { return v < rhs; }
|
||||
public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? LuaValue.TRUE: FALSE; }
|
||||
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||
public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); }
|
||||
public boolean lteq_b( int rhs ) { return v <= rhs; }
|
||||
public boolean lteq_b( double rhs ) { return v <= rhs; }
|
||||
public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? LuaValue.TRUE: FALSE; }
|
||||
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
|
||||
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
|
||||
public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); }
|
||||
public boolean gt_b( int rhs ) { return v > rhs; }
|
||||
public boolean gt_b( double rhs ) { return v > rhs; }
|
||||
public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? LuaValue.TRUE: FALSE; }
|
||||
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||
public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); }
|
||||
public boolean gteq_b( int rhs ) { return v >= rhs; }
|
||||
public boolean gteq_b( double rhs ) { return v >= rhs; }
|
||||
|
||||
// string comparison
|
||||
public int strcmp( LuaString rhs ) { typerror("attempt to compare number with string"); return 0; }
|
||||
|
||||
public String tojstring() {
|
||||
/*
|
||||
if ( v == 0.0 ) { // never occurs in J2me
|
||||
long bits = Double.doubleToLongBits( v );
|
||||
return ( bits >> 63 == 0 ) ? "0" : "-0";
|
||||
}
|
||||
*/
|
||||
long l = (long) v;
|
||||
if ( l == v )
|
||||
return Long.toString(l);
|
||||
if ( Double.isNaN(v) )
|
||||
return JSTR_NAN;
|
||||
if ( Double.isInfinite(v) )
|
||||
return (v<0? JSTR_NEGINF: JSTR_POSINF);
|
||||
return Float.toString((float)v);
|
||||
}
|
||||
|
||||
public LuaString strvalue() {
|
||||
return LuaString.valueOf(tojstring());
|
||||
}
|
||||
|
||||
public LuaString optstring(LuaString defval) {
|
||||
return LuaString.valueOf(tojstring());
|
||||
}
|
||||
|
||||
public LuaValue tostring() {
|
||||
return LuaString.valueOf(tojstring());
|
||||
}
|
||||
|
||||
public String optjstring(String defval) {
|
||||
return tojstring();
|
||||
}
|
||||
|
||||
public LuaNumber optnumber(LuaNumber defval) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isnumber() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isstring() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public LuaValue tonumber() {
|
||||
return this;
|
||||
}
|
||||
public int checkint() { return (int) (long) v; }
|
||||
public long checklong() { return (long) v; }
|
||||
public LuaNumber checknumber() { return this; }
|
||||
public double checkdouble() { return v; }
|
||||
|
||||
public String checkjstring() {
|
||||
return tojstring();
|
||||
}
|
||||
public LuaString checkstring() {
|
||||
return LuaString.valueOf(tojstring());
|
||||
}
|
||||
|
||||
public LuaValue checkvalidkey() {
|
||||
if ( Double.isNaN(v) )
|
||||
throw new LuaError("table index expected, got nan");
|
||||
return this;
|
||||
}
|
||||
}
|
@@ -1,132 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
import org.luaj.vm2.lib.DebugLib;
|
||||
|
||||
/**
|
||||
* RuntimeException that is thrown and caught in response to a lua error.
|
||||
* <p>
|
||||
* {@link LuaError} is used wherever a lua call to {@code error()}
|
||||
* would be used within a script.
|
||||
* <p>
|
||||
* Since it is an unchecked exception inheriting from {@link RuntimeException},
|
||||
* Java method signatures do notdeclare this exception, althoug it can
|
||||
* be thrown on almost any luaj Java operation.
|
||||
* This is analagous to the fact that any lua script can throw a lua error at any time.
|
||||
* <p>
|
||||
*/
|
||||
public class LuaError extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String traceback;
|
||||
|
||||
/**
|
||||
* Run the error hook if there is one
|
||||
* @param msg the message to use in error hook processing.
|
||||
* */
|
||||
private static String errorHook(String msg) {
|
||||
LuaThread thread = LuaThread.getRunning();
|
||||
if ( thread.err != null ) {
|
||||
LuaValue errfunc = thread.err;
|
||||
thread.err = null;
|
||||
try {
|
||||
return errfunc.call( LuaValue.valueOf(msg) ).tojstring();
|
||||
} catch ( Throwable t ) {
|
||||
return "error in error handling";
|
||||
} finally {
|
||||
thread.err = errfunc;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
private Throwable cause;
|
||||
|
||||
/** Construct LuaError when a program exception occurs.
|
||||
* <p>
|
||||
* All errors generated from lua code should throw LuaError(String) instead.
|
||||
* @param cause the Throwable that caused the error, if known.
|
||||
*/
|
||||
public LuaError(Throwable cause) {
|
||||
super( errorHook( addFileLine( "vm error: "+cause ) ) );
|
||||
this.cause = cause;
|
||||
this.traceback = DebugLib.traceback(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a LuaError with a specific message.
|
||||
*
|
||||
* @param message message to supply
|
||||
*/
|
||||
public LuaError(String message) {
|
||||
super( errorHook( addFileLine( message ) ) );
|
||||
this.traceback = DebugLib.traceback(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a LuaError with a message, and level to draw line number information from.
|
||||
* @param message message to supply
|
||||
* @param level where to supply line info from in call stack
|
||||
*/
|
||||
public LuaError(String message, int level) {
|
||||
super( errorHook( addFileLine( message, level ) ) );
|
||||
this.traceback = DebugLib.traceback(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add file and line info to a message at a particular level
|
||||
* @param message the String message to use
|
||||
* @param level where to supply line info from in call stack
|
||||
* */
|
||||
private static String addFileLine( String message, int level ) {
|
||||
if ( message == null ) return null;
|
||||
if ( level == 0 ) return message;
|
||||
String fileline = DebugLib.fileline(level-1);
|
||||
return fileline!=null? fileline+": "+message: message;
|
||||
}
|
||||
|
||||
/** Add file and line info for the nearest enclosing closure
|
||||
* @param message the String message to use
|
||||
* */
|
||||
private static String addFileLine( String message ) {
|
||||
if ( message == null ) return null;
|
||||
String fileline = DebugLib.fileline();
|
||||
return fileline!=null? fileline+": "+message: message;
|
||||
}
|
||||
|
||||
/** Print the message and stack trace */
|
||||
public void printStackTrace() {
|
||||
System.out.println( toString() );
|
||||
if ( traceback != null )
|
||||
System.out.println( traceback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cause, if any.
|
||||
*/
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user