Compare commits
1014 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
621f05c687 | ||
|
|
daf97eabab | ||
|
|
ee3d11cb53 | ||
|
|
1bc7e5e0a5 | ||
|
|
9280d23b1a | ||
|
|
cacd52f81d | ||
|
|
95f64761ca | ||
|
|
6e24792b9b | ||
|
|
9afe26f1d6 | ||
|
|
e7d959da90 | ||
|
|
c3f0867d2c | ||
|
|
1eaf124d4e | ||
|
|
03076bdc76 | ||
|
|
cd32d6debe | ||
|
|
3212f059ff | ||
|
|
9ae4b93083 | ||
|
|
aae7af2194 | ||
|
|
63f4c73ef0 | ||
|
|
f93d3381e0 | ||
|
|
099c80e04b | ||
|
|
14face336e | ||
|
|
67b10d8d38 | ||
|
|
1219230168 | ||
|
|
8d840e694d | ||
|
|
87382aad4d | ||
|
|
aca3a05222 | ||
|
|
84ca145663 | ||
|
|
01d0338851 | ||
|
|
f427c0532d | ||
|
|
c8532a548c | ||
|
|
1e3aef5b94 | ||
|
|
0d3180271b | ||
|
|
f0d17b13f2 | ||
|
|
9a46301d46 | ||
|
|
3bd609ee41 | ||
|
|
2c7f0e8583 | ||
|
|
ce36a25ba3 | ||
|
|
c53484f92e | ||
|
|
f391ccb8e8 | ||
|
|
a96d6a8148 | ||
|
|
bdca09007d | ||
|
|
c0e84043c9 | ||
|
|
0a884df74f | ||
|
|
519b14d506 | ||
|
|
f008a65d91 | ||
|
|
61bb70cd30 | ||
|
|
68fa3dadb0 | ||
|
|
eb38d03976 | ||
|
|
d480bb3ecd | ||
|
|
dfdb6fa1a6 | ||
|
|
42352d9f57 | ||
|
|
eae1c5db70 | ||
|
|
cc37097164 | ||
|
|
6597cc9ce8 | ||
|
|
b3f752d46c | ||
|
|
679e2d0f6b | ||
|
|
4607079ca9 | ||
|
|
ad1a42d6a5 | ||
|
|
afdf31a66c | ||
|
|
37956e2f05 | ||
|
|
dc6aa66f9a | ||
|
|
f16f16c15e | ||
|
|
3b95cbd960 | ||
|
|
3b5e8edd37 | ||
|
|
5f4571e895 | ||
|
|
2d5e991eaf | ||
|
|
7ba8bb4405 | ||
|
|
82aa181540 | ||
|
|
1a3e17bae8 | ||
|
|
e0e3664fdb | ||
|
|
23bfaf1ba2 | ||
|
|
e7d72b6f53 | ||
|
|
eab26deab9 | ||
|
|
49540dbe5e | ||
|
|
cbd891785e | ||
|
|
b1cc732cb2 | ||
|
|
b3b4f55c68 | ||
|
|
8b6b039c13 | ||
|
|
9dca62ff8b | ||
|
|
e0892fcebb | ||
|
|
adf1443105 | ||
|
|
53c2558d26 | ||
|
|
a5ea240793 | ||
|
|
4cd1629118 | ||
|
|
ce32a73e86 | ||
|
|
8a13fc7cd9 | ||
|
|
708de50887 | ||
|
|
4df478316c | ||
|
|
a5dff9fb15 | ||
|
|
b51f4d53b6 | ||
|
|
7d045842dd | ||
|
|
a9ece9e49d | ||
|
|
e6da067cf8 | ||
|
|
bae40c82b9 | ||
|
|
651edf5bc0 | ||
|
|
3a8642b1e0 | ||
|
|
09b6b9259c | ||
|
|
907f326788 | ||
|
|
4a350d8ad9 | ||
|
|
3881db0b4e | ||
|
|
9edae3e877 | ||
|
|
236208e393 | ||
|
|
4ff98de707 | ||
|
|
54964629fe | ||
|
|
072f606784 | ||
|
|
21d2338ec1 | ||
|
|
0d468e0df4 | ||
|
|
5007d49c83 | ||
|
|
35ba69a175 | ||
|
|
fa0ce2a14c | ||
|
|
389750d7d8 | ||
|
|
6c7db7ad23 | ||
|
|
2986426251 | ||
|
|
56444ebcaf | ||
|
|
c63a1978cb | ||
|
|
9d9e998d49 | ||
|
|
f7c991fa9a | ||
|
|
4d14fbb1e7 | ||
|
|
5428730e7a | ||
|
|
bf773df099 | ||
|
|
6dea5100b1 | ||
|
|
aa55f4dceb | ||
|
|
516e92926a | ||
|
|
2cd9994321 | ||
|
|
e69306a2ba | ||
|
|
93ecd031bd | ||
|
|
4eaf69dfa7 | ||
|
|
bc93bda1b7 | ||
|
|
6923f0df2a | ||
|
|
bc584aa56e | ||
|
|
ec95d06f6c | ||
|
|
c5d18d9046 | ||
|
|
af06983c60 | ||
|
|
e027872f50 | ||
|
|
e98e4fde8d | ||
|
|
2daf9de890 | ||
|
|
ae50511135 | ||
|
|
2227f83b1d | ||
|
|
e764a2298d | ||
|
|
ed4a8c2a36 | ||
|
|
8cc3e571e3 | ||
|
|
66a89a7d54 | ||
|
|
666be94a71 | ||
|
|
49fabf23a8 | ||
|
|
a3b23e348a | ||
|
|
384e887fdb | ||
|
|
d3e84cbc4c | ||
|
|
1b06948fb0 | ||
|
|
98d075728f | ||
|
|
1a7ecda67c | ||
|
|
067078db86 | ||
|
|
37650fae75 | ||
|
|
13be3e3216 | ||
|
|
87a7809104 | ||
|
|
e82c33716a | ||
|
|
9ebdddad1f | ||
|
|
90f85bb9c3 | ||
|
|
002d04a3a1 | ||
|
|
88a0b12e73 | ||
|
|
5828e7f576 | ||
|
|
a11da90d10 | ||
|
|
d8026833dc | ||
|
|
8029bb6142 | ||
|
|
baaddd395c | ||
|
|
8bcbe7b3c6 | ||
|
|
4297320886 | ||
|
|
614994d8c7 | ||
|
|
65e1f261c0 | ||
|
|
aa4caa6938 | ||
|
|
9741574516 | ||
|
|
c27c654180 | ||
|
|
c63580ee38 | ||
|
|
e9d4328fad | ||
|
|
545f9f2cca | ||
|
|
db6930d9e4 | ||
|
|
9379a41b37 | ||
|
|
c0eeedc71a | ||
|
|
400197def8 | ||
|
|
0f8b202531 | ||
|
|
1eb9775f34 | ||
|
|
89bdb315d5 | ||
|
|
ab1afd68b7 | ||
|
|
e1109e9e51 | ||
|
|
7230e19166 | ||
|
|
eb7a94bb55 | ||
|
|
18de4e57eb | ||
|
|
74cc12133e | ||
|
|
7583354f44 | ||
|
|
14c49dd681 | ||
|
|
e060208417 | ||
|
|
635eea7acb | ||
|
|
2c47f4a23d | ||
|
|
2223577302 | ||
|
|
f42d235dec | ||
|
|
06a3e278ff | ||
|
|
17c30b5fdc | ||
|
|
024b30d0b7 | ||
|
|
a108610a67 | ||
|
|
12b6abe6a3 | ||
|
|
6f82b36962 | ||
|
|
ea6b397526 | ||
|
|
118bb3f3ba | ||
|
|
bd68075f4d | ||
|
|
5fa68f8cdd | ||
|
|
199aaf2d05 | ||
|
|
892efcc166 | ||
|
|
bc90c6b82f | ||
|
|
82d3d1f0f3 | ||
|
|
576b3198f1 | ||
|
|
f55cad8f1c | ||
|
|
d98654b50d | ||
|
|
675d9d8c09 | ||
|
|
bab0bb349f | ||
|
|
65d3ed8ce8 | ||
|
|
8fc4000b63 | ||
|
|
5b35f781cb | ||
|
|
2cd11b7da7 | ||
|
|
cf30d2923c | ||
|
|
8fc97794e8 | ||
|
|
df2ba37687 | ||
|
|
85b16b2a54 | ||
|
|
eeabc6b61a | ||
|
|
2b3dafed61 | ||
|
|
7232fc36ab | ||
|
|
a8e1fd1054 | ||
|
|
c248a50338 | ||
|
|
fa0ca23798 | ||
|
|
ed224cf912 | ||
|
|
b51df25371 | ||
|
|
db8cc8eb7b | ||
|
|
a027e9fe14 | ||
|
|
b882ca809a | ||
|
|
daf0a9dc9a | ||
|
|
f2dafa7544 | ||
|
|
7fe22875a6 | ||
|
|
3da3c8ecd8 | ||
|
|
254acbbbe2 | ||
|
|
519c850f17 | ||
|
|
1cf57508b0 | ||
|
|
f8bacfcc67 | ||
|
|
9daa77c1a4 | ||
|
|
c4775dd313 | ||
|
|
ae87cb031e | ||
|
|
3c049f25ee | ||
|
|
85a90b62b7 | ||
|
|
10b0124951 | ||
|
|
c0d7ff9543 | ||
|
|
74012d4869 | ||
|
|
830c40440f | ||
|
|
21a2f71ad9 | ||
|
|
cf75e3e664 | ||
|
|
ffc307323a | ||
|
|
ff0aec28c5 | ||
|
|
31394b03ae | ||
|
|
2ab93cb385 | ||
|
|
172b396dc9 | ||
|
|
9b82d08087 | ||
|
|
410617f73b | ||
|
|
ade0d38a7c | ||
|
|
3ce55a2ac4 | ||
|
|
cc6e4dbec0 | ||
|
|
2935ae7bf1 | ||
|
|
96e418e63b | ||
|
|
e4a84dcfe9 | ||
|
|
9ea91cfce3 | ||
|
|
8c7f0cf988 | ||
|
|
afa9a00259 | ||
|
|
a0ee11c300 | ||
|
|
6e02dace18 | ||
|
|
93bac6f26f | ||
|
|
8657fbd810 | ||
|
|
68203be004 | ||
|
|
b2323ef2e7 | ||
|
|
70b017fb72 | ||
|
|
607e3bbc11 | ||
|
|
315c9285de | ||
|
|
c22427b8fd | ||
|
|
2fcfac9e84 | ||
|
|
7cc857233f | ||
|
|
f85aa09784 | ||
|
|
0b0cecc2a9 | ||
|
|
3b5b9c9587 | ||
|
|
cbe190fa70 | ||
|
|
9156466351 | ||
|
|
f79caf095d | ||
|
|
d31dcd13fc | ||
|
|
552224bbfe | ||
|
|
5ba01674fb | ||
|
|
7390afc5e1 | ||
|
|
85ec23d552 | ||
|
|
007064c0ac | ||
|
|
fd53756170 | ||
|
|
9e6dd9f23d | ||
|
|
ef8be6c7c2 | ||
|
|
de4b5b70da | ||
|
|
9edeee4b3f | ||
|
|
767a0cc1fd | ||
|
|
ae09247e34 | ||
|
|
a3ea4798bc | ||
|
|
af54a22d16 | ||
|
|
b026bfc71b | ||
|
|
80d80ad8aa | ||
|
|
dbecf33924 | ||
|
|
2b08e3604d | ||
|
|
7d3a672c2b | ||
|
|
022e46ae38 | ||
|
|
3f930d228e | ||
|
|
5eba370f7b | ||
|
|
e138951e9e | ||
|
|
5cd18d7275 | ||
|
|
d7ff5a53a7 | ||
|
|
aa14bb6fdf | ||
|
|
c275f682a9 | ||
|
|
08894025bc | ||
|
|
b063a48520 | ||
|
|
858d38d314 | ||
|
|
f5875d09e9 | ||
|
|
34db181686 | ||
|
|
be55ea2b0b | ||
|
|
aa0dd4d10d | ||
|
|
39533e4209 | ||
|
|
4bba3bf1d2 | ||
|
|
2d29d1549a | ||
|
|
c7a078f17f | ||
|
|
2cf92037e9 | ||
|
|
452ee7a103 | ||
|
|
68f70af2f3 | ||
|
|
11682e487e | ||
|
|
4d006230f9 | ||
|
|
a32f4bb05c | ||
|
|
6d4e260127 | ||
|
|
45404b5bcf | ||
|
|
861551b2ba | ||
|
|
aac820a8d5 | ||
|
|
a5ff25b0fe | ||
|
|
b81638794f | ||
|
|
88cfeb2791 | ||
|
|
d0b57535ed | ||
|
|
528add4702 | ||
|
|
dd47971877 | ||
|
|
d51a99c8e2 | ||
|
|
e192f01dc3 | ||
|
|
aedaf57249 | ||
|
|
222e58e76e | ||
|
|
c8fc80f4a0 | ||
|
|
1ed180887d | ||
|
|
d6a38a567f | ||
|
|
ae9c3276bc | ||
|
|
35d34cd4e8 | ||
|
|
4f45824632 | ||
|
|
532da174dd | ||
|
|
dbe13feba2 | ||
|
|
1c93061a7f | ||
|
|
0e371930e6 | ||
|
|
06bd748bd6 | ||
|
|
b64775772b | ||
|
|
5f76314085 | ||
|
|
57588ea936 | ||
|
|
3f344b55bb | ||
|
|
e4ae0980b4 | ||
|
|
e41da0d697 | ||
|
|
ce3955d393 | ||
|
|
22a2cc564f | ||
|
|
2b19513a05 | ||
|
|
60f8fe6f41 | ||
|
|
a2fd010521 | ||
|
|
a36d5b6302 | ||
|
|
2c14dc16dd | ||
|
|
4c7f3f7972 | ||
|
|
794df59265 | ||
|
|
3dd71713c2 | ||
|
|
c0777d1a0a | ||
|
|
55392cb047 | ||
|
|
070eedda18 | ||
|
|
ae6ec78dc3 | ||
|
|
9fe1b2a565 | ||
|
|
f374419be3 | ||
|
|
0ff25cb116 | ||
|
|
d7e50f352a | ||
|
|
aa9254eeb0 | ||
|
|
c1eba336a8 | ||
|
|
a5d7fc484a | ||
|
|
7a294e6d4e | ||
|
|
2f79417d0d | ||
|
|
73b42f924d | ||
|
|
ccf915e798 | ||
|
|
62ffa14f10 | ||
|
|
5d7840a34c | ||
|
|
fd14f6ff73 | ||
|
|
88962f9358 | ||
|
|
5bec1729f1 | ||
|
|
f3662fc152 | ||
|
|
c5047186dd | ||
|
|
1e39bd8336 | ||
|
|
e58de234ac | ||
|
|
903cc181c4 | ||
|
|
2183a098c3 | ||
|
|
1d4cba9180 | ||
|
|
ed724c5280 | ||
|
|
fbd13ac42c | ||
|
|
ea6eab557b | ||
|
|
a1cb2a0589 | ||
|
|
5de5a8ca94 | ||
|
|
274026d338 | ||
|
|
3875bc34bd | ||
|
|
8db3ccce2e | ||
|
|
34bb6fd851 | ||
|
|
ffa74db136 | ||
|
|
66f2cbb91f | ||
|
|
a57d49b057 | ||
|
|
7b41a0ff16 | ||
|
|
4ca50f8973 | ||
|
|
abe2c6870b | ||
|
|
c0ae681d69 | ||
|
|
b4745c0134 | ||
|
|
d369a6429e | ||
|
|
af3e326178 | ||
|
|
8e256a2d5d | ||
|
|
bdcbd9008d | ||
|
|
453faa6a76 | ||
|
|
b0941faf88 | ||
|
|
91ba215568 | ||
|
|
be32f4072e | ||
|
|
bcb217c1da | ||
|
|
490a16a8df | ||
|
|
28d8c56534 | ||
|
|
46423ed166 | ||
|
|
4286a510b4 | ||
|
|
8d193ab39f | ||
|
|
439e377111 | ||
|
|
28ebce6b65 | ||
|
|
2ccd1625e7 | ||
|
|
e05e61a59b | ||
|
|
4660eae8c7 | ||
|
|
e55e90db1a | ||
|
|
23da63767c | ||
|
|
13b19c35c6 | ||
|
|
7e25ec1ac3 | ||
|
|
ab1d05642e | ||
|
|
079b28fddf | ||
|
|
d52d62badb | ||
|
|
fa53135c8a | ||
|
|
d6a3f9fd8f | ||
|
|
75ca4af74e | ||
|
|
dc5fc6bdc2 | ||
|
|
67f8ee61a4 | ||
|
|
2153cf39b5 | ||
|
|
0ead82ae21 | ||
|
|
98d4cf7585 | ||
|
|
3259536411 | ||
|
|
f3a79cc779 | ||
|
|
c45c6dbe67 | ||
|
|
a1518c33af | ||
|
|
a9f7cdb630 | ||
|
|
6f678294a0 | ||
|
|
de07abee98 | ||
|
|
437edefa0c | ||
|
|
f5b36ecbac | ||
|
|
8772c85964 | ||
|
|
a31454327a | ||
|
|
9e55cb114c | ||
|
|
04416a67d3 | ||
|
|
dd2cdaf49a | ||
|
|
8c45eb7524 | ||
|
|
c20bea50e3 | ||
|
|
fe18c35dab | ||
|
|
f6ef6abdf1 | ||
|
|
43a6837e81 | ||
|
|
dc4b933000 | ||
|
|
c90703dc13 | ||
|
|
2165941026 | ||
|
|
4a28893171 | ||
|
|
369581976a | ||
|
|
7fef683980 | ||
|
|
8358f68086 | ||
|
|
0aa6b03c2a | ||
|
|
44f8c98660 | ||
|
|
188ec6ea1d | ||
|
|
8169d8509f | ||
|
|
e217d39882 | ||
|
|
887ee0fd41 | ||
|
|
137e93319e | ||
|
|
48a1384197 | ||
|
|
8aed4d634b | ||
|
|
fd0cb4c458 | ||
|
|
82735f0fab | ||
|
|
1d3710afd8 | ||
|
|
e8ae92f4d4 | ||
|
|
b2e54a0590 | ||
|
|
d64d220b49 | ||
|
|
2523a95a9a | ||
|
|
207c41581c | ||
|
|
6fc4a3ed04 | ||
|
|
2fabb6951e | ||
|
|
8c2f5f91d5 | ||
|
|
7443d41444 | ||
|
|
4421734da1 | ||
|
|
4385ca0966 | ||
|
|
57fa592a13 | ||
|
|
1298118b59 | ||
|
|
3f2cb40cc1 | ||
|
|
5448abb304 | ||
|
|
892fab5455 | ||
|
|
ef3619350d | ||
|
|
846fb3e7f3 | ||
|
|
e00e9ba5aa | ||
|
|
f41511047e | ||
|
|
16352df5b1 | ||
|
|
5238c2457d | ||
|
|
4d57f414f5 | ||
|
|
6305088cb0 | ||
|
|
e2db1cd425 | ||
|
|
16561a8e84 | ||
|
|
cae1b3ebd4 | ||
|
|
e68737dcfb | ||
|
|
00448d23c0 | ||
|
|
272ae547ef | ||
|
|
3fd688191c | ||
|
|
5c0b6f2225 | ||
|
|
cc530e3446 | ||
|
|
fdc1d46b89 | ||
|
|
5dce677091 | ||
|
|
d0fb5a4b04 | ||
|
|
e27daed0ec | ||
|
|
d2183a8b32 | ||
|
|
0b2d6407dd | ||
|
|
ec1b1ffe16 | ||
|
|
32a66be555 | ||
|
|
c090c34491 | ||
|
|
4f7d3ad76c | ||
|
|
ce81872686 | ||
|
|
2314c41103 | ||
|
|
df39b66e11 | ||
|
|
adeb5de19f | ||
|
|
26312e0c0e | ||
|
|
cd6d4021b1 | ||
|
|
24d345a970 | ||
|
|
b4fd4a0c38 | ||
|
|
451e695006 | ||
|
|
26b771f9f9 | ||
|
|
0679aedb7e | ||
|
|
bfa4e08a4e | ||
|
|
c1185a34aa | ||
|
|
be0ce57375 | ||
|
|
b204b90ffc | ||
|
|
364b6938a5 | ||
|
|
e188925d2b | ||
|
|
10a47cdbbb | ||
|
|
67014ae4f8 | ||
|
|
b93fc3f028 | ||
|
|
b6e5980510 | ||
|
|
79e8921f76 | ||
|
|
34fe3ca4fc | ||
|
|
f26311c60e | ||
|
|
43f9907af7 | ||
|
|
0e6f5d154e | ||
|
|
7042dd8447 | ||
|
|
05031e0979 | ||
|
|
28b3f6780c | ||
|
|
f8335c6df9 | ||
|
|
9dcdc1f8f3 | ||
|
|
9ae7d4f2bf | ||
|
|
c158169bdf | ||
|
|
e4c1285eaf | ||
|
|
02a5375503 | ||
|
|
32883b4e18 | ||
|
|
6d585e88a4 | ||
|
|
73570b5628 | ||
|
|
e7fcb068d9 | ||
|
|
a137a70278 | ||
|
|
72113991a8 | ||
|
|
a04fb8e7de | ||
|
|
ca2f30cd61 | ||
|
|
ebfad05e3f | ||
|
|
f54ea9d978 | ||
|
|
d4c84cee19 | ||
|
|
4da59cdc97 | ||
|
|
d4e7eb5888 | ||
|
|
f8b0a7105b | ||
|
|
aecde91d33 | ||
|
|
870dde232a | ||
|
|
f7d7f81c49 | ||
|
|
1f04c61482 | ||
|
|
5d957a6b7c | ||
|
|
94f61b0a0c | ||
|
|
de6535b722 | ||
|
|
6dd18e4328 | ||
|
|
c46e4453c7 | ||
|
|
2e6312ec03 | ||
|
|
1566a834e1 | ||
|
|
607deaa3c4 | ||
|
|
686186d5ba | ||
|
|
0c1ef72285 | ||
|
|
d6bd12cfcd | ||
|
|
4a1712f4cd | ||
|
|
b4e298230d | ||
|
|
6cb42a4251 | ||
|
|
3ead4b4d4b | ||
|
|
3c0e321538 | ||
|
|
1f67434c8c | ||
|
|
6058b9851c | ||
|
|
c586319978 | ||
|
|
0591fe0e8b | ||
|
|
dabe3b17e6 | ||
|
|
fbf50d45cb | ||
|
|
d59075e897 | ||
|
|
2b491179f7 | ||
|
|
a62d17b1b1 | ||
|
|
2431758218 | ||
|
|
b94586fdf4 | ||
|
|
a6b83d77bd | ||
|
|
43c55b36c8 | ||
|
|
24c7928c4b | ||
|
|
8c876c302a | ||
|
|
778a4373ae | ||
|
|
7a15cf1157 | ||
|
|
54e3210d7e | ||
|
|
a3197c12a8 | ||
|
|
e7de841939 | ||
|
|
29ba00f370 | ||
|
|
e35d70f338 | ||
|
|
0271c65ca2 | ||
|
|
e604524301 | ||
|
|
298831d987 | ||
|
|
3b2e97a729 | ||
|
|
edaba44c87 | ||
|
|
dc2dc910e8 | ||
|
|
96bf260ce9 | ||
|
|
115ea4ccbb | ||
|
|
3fb400beb4 | ||
|
|
6442279a44 | ||
|
|
592500cb0c | ||
|
|
98f3e45c0a | ||
|
|
e365196ee3 | ||
|
|
f656499c23 | ||
|
|
180c019d2e | ||
|
|
7db50921bc | ||
|
|
257b3f3ee6 | ||
|
|
f7c69b6baf | ||
|
|
89a3b84ea1 | ||
|
|
bec29f99e6 | ||
|
|
72274bda82 | ||
|
|
04b62a62cb | ||
|
|
ab7329d3eb | ||
|
|
a819796ce2 | ||
|
|
8c6cdcc97e | ||
|
|
bf0148e047 | ||
|
|
bcf44b8ab2 | ||
|
|
ebc9711309 | ||
|
|
4097f90938 | ||
|
|
d73f77affc | ||
|
|
b4794dc541 | ||
|
|
5ee156057e | ||
|
|
68a63bb280 | ||
|
|
815677863f | ||
|
|
df2f13c9b6 | ||
|
|
3984037c98 | ||
|
|
9c8570b37d | ||
|
|
f7cddb81df | ||
|
|
dc1fbbf796 | ||
|
|
7b7b4e5f22 | ||
|
|
8c9b0285e4 | ||
|
|
3ff5caef94 | ||
|
|
4a3446a0a5 | ||
|
|
6f6d9b39ba | ||
|
|
7d2f68c5e4 | ||
|
|
5416e92dbf | ||
|
|
340b5bd165 | ||
|
|
fbd15a81b4 | ||
|
|
039d0abce2 | ||
|
|
aefb65b1b8 | ||
|
|
f7c322c311 | ||
|
|
b5507f79e4 | ||
|
|
a2703ce51b | ||
|
|
d48b12aa09 | ||
|
|
452c1fbfd4 | ||
|
|
f77fd2a944 | ||
|
|
2b1da5b231 | ||
|
|
1b48b98e22 | ||
|
|
4af872ddd5 | ||
|
|
6614107192 | ||
|
|
09e1f9addf | ||
|
|
baf282ecb2 | ||
|
|
6022b32227 | ||
|
|
9e9b08a5a3 | ||
|
|
8147b974aa | ||
|
|
0a5a0ef319 | ||
|
|
00c73b8388 | ||
|
|
dcb8eb7d6d | ||
|
|
7f11651311 | ||
|
|
71518b025d | ||
|
|
287722b1d2 | ||
|
|
3a6f5dd4ee | ||
|
|
4aa3d321fa | ||
|
|
abb04b177c | ||
|
|
764e0f0e7f | ||
|
|
b668175c62 | ||
|
|
5011c394d7 | ||
|
|
994502077a | ||
|
|
7d8bed16b0 | ||
|
|
a45be62b68 | ||
|
|
e0a25b5098 | ||
|
|
fa712aa3a0 | ||
|
|
1599ba0294 | ||
|
|
94d567bf8f | ||
|
|
17f17bcc9e | ||
|
|
12c262621e | ||
|
|
dd35f2c14d | ||
|
|
66a9fd928a | ||
|
|
da82e5dd04 | ||
|
|
98498c9180 | ||
|
|
7b0ed42d3b | ||
|
|
3e4fbde0b4 | ||
|
|
7b0d23f91f | ||
|
|
08d00fa234 | ||
|
|
2e32d9806f | ||
|
|
6e73fbf65e | ||
|
|
b9f74d349c | ||
|
|
5e45e38481 | ||
|
|
78b8455bba | ||
|
|
6f71885aa2 | ||
|
|
e107567997 | ||
|
|
8d42acec16 | ||
|
|
33d73eaecd | ||
|
|
47b20b01d0 | ||
|
|
b94cf700b4 | ||
|
|
a26d30be3c | ||
|
|
ec1cca7ca4 | ||
|
|
0c321c8c98 | ||
|
|
7a54967bee | ||
|
|
f3b6d25aaa | ||
|
|
419133d3e1 | ||
|
|
1402ff371e | ||
|
|
ee2d67c151 | ||
|
|
a8f1db0db1 | ||
|
|
4abcbb9b51 | ||
|
|
e33dd8acc3 | ||
|
|
64e96cc101 | ||
|
|
1aaa737dd6 | ||
|
|
31e3fc9060 | ||
|
|
b70b868552 | ||
|
|
7235357ef5 | ||
|
|
18eecbe9f4 | ||
|
|
505525134f | ||
|
|
7dd740f51a | ||
|
|
3d590f8eb6 | ||
|
|
42a5c6a19f | ||
|
|
2c4f6063a6 | ||
|
|
845767b1d7 | ||
|
|
3e144af127 | ||
|
|
45f470e3a7 | ||
|
|
42a5c60af6 | ||
|
|
29cebd1e1f | ||
|
|
4450f5a084 | ||
|
|
b8230e144a | ||
|
|
d500902eff | ||
|
|
b787de0163 | ||
|
|
2f0d525c2e | ||
|
|
3f0c65ebb2 | ||
|
|
f33796797d | ||
|
|
68a09b9804 | ||
|
|
5e5d149ca5 | ||
|
|
bdf1c275c4 | ||
|
|
439a69f413 | ||
|
|
a14974fbf2 | ||
|
|
1ecd9af2e1 | ||
|
|
c8cc2dac04 | ||
|
|
60dd33b48f | ||
|
|
8b7d8b7786 | ||
|
|
fb7ea7810e | ||
|
|
508e16aa80 | ||
|
|
a057db8756 | ||
|
|
a1c588bde8 | ||
|
|
9b17fdeae2 | ||
|
|
29c0c737ed | ||
|
|
be6986a7f6 | ||
|
|
63c03bb28c | ||
|
|
758f5b27c3 | ||
|
|
32bfb3d57e | ||
|
|
6bd8822a90 | ||
|
|
abf461a049 | ||
|
|
4e98055b9c | ||
|
|
e6ab5bd86d | ||
|
|
02e0651eab | ||
|
|
93be634673 | ||
|
|
a1978f661b | ||
|
|
9bda864fed | ||
|
|
b6903c6b99 | ||
|
|
1e7394135d | ||
|
|
61ccaab55b | ||
|
|
f17c3c52c4 | ||
|
|
f16e721d01 | ||
|
|
6dfdca2d19 | ||
|
|
ee848e66ac | ||
|
|
91e1fa6aff | ||
|
|
6049cf9047 | ||
|
|
e91366c328 | ||
|
|
d6a5aaf4ad | ||
|
|
fcf3f2abc7 | ||
|
|
ae77622026 | ||
|
|
878b395e20 | ||
|
|
92aee9b69c | ||
|
|
fe10ddc720 | ||
|
|
46899f042f | ||
|
|
d4249da131 | ||
|
|
6cae018066 | ||
|
|
95c1886df5 | ||
|
|
fbd8cb07ea | ||
|
|
4868903844 | ||
|
|
62e721b1c8 | ||
|
|
1ceaf1df22 | ||
|
|
21c9f7b7fb | ||
|
|
f5526f73c7 | ||
|
|
15fad2e841 | ||
|
|
3ecb43072d | ||
|
|
2fce2318ed | ||
|
|
226fd29af8 | ||
|
|
c48b39baab | ||
|
|
ed19a6960e | ||
|
|
11b4de63ee | ||
|
|
b9d1d52ab3 | ||
|
|
fe548e580d | ||
|
|
fd7d2765c8 | ||
|
|
a226a70383 | ||
|
|
519e69a7f8 | ||
|
|
3d599f8044 | ||
|
|
bbf0393008 | ||
|
|
f1a4af013a | ||
|
|
05af9f9810 | ||
|
|
f68aada9f8 | ||
|
|
52d60d9623 | ||
|
|
2ddf8a44bc | ||
|
|
281fbc2bee | ||
|
|
c174568081 | ||
|
|
f4a519c824 | ||
|
|
62e4e2f716 | ||
|
|
193e6dfc93 | ||
|
|
7596658e6c | ||
|
|
73d6bd8400 | ||
|
|
922fabd935 | ||
|
|
2f3d267439 | ||
|
|
bdaf7ff30b | ||
|
|
cfca98512a | ||
|
|
23d9e86c46 | ||
|
|
6ac6fb0192 | ||
|
|
aaa36b9d3b | ||
|
|
2c799a8ccf | ||
|
|
56a5a7d72e | ||
|
|
410f9dd759 | ||
|
|
ba45217756 | ||
|
|
5a5929048d | ||
|
|
bfc3c7fbf9 | ||
|
|
e151bd4cd1 | ||
|
|
bfe68520f4 | ||
|
|
45734c0b5c | ||
|
|
d689062fc3 | ||
|
|
881574ed39 | ||
|
|
0bd5aa873b | ||
|
|
51f3ac2376 | ||
|
|
e5802853c0 | ||
|
|
edb5e36916 | ||
|
|
33ba94e784 | ||
|
|
9c969e0026 | ||
|
|
858622a98d | ||
|
|
c673489461 | ||
|
|
53a39b6947 | ||
|
|
8f82d86a5d | ||
|
|
f607cd8bad | ||
|
|
5b0965dc53 | ||
|
|
0db78100cd | ||
|
|
2196f2259f | ||
|
|
55814cbda4 | ||
|
|
6fb48023f2 | ||
|
|
76c1800a53 | ||
|
|
3b2f01e974 | ||
|
|
db141e1f3f | ||
|
|
8ca8824165 | ||
|
|
2e49161415 | ||
|
|
e5f38a6fc1 | ||
|
|
8c105d87c1 | ||
|
|
8c2946a41b | ||
|
|
4f21915f35 | ||
|
|
585bdb549f | ||
|
|
8091c9e737 | ||
|
|
fc504e18d2 | ||
|
|
90c76bb992 | ||
|
|
3da1aa3ec6 | ||
|
|
0a0d72e016 | ||
|
|
550889808a | ||
|
|
1c1da6433a | ||
|
|
963d7958ea | ||
|
|
7031247614 | ||
|
|
07738e13ef | ||
|
|
3ab96aa1ee | ||
|
|
bdd3f6ed44 | ||
|
|
3328847e27 | ||
|
|
4a6f072361 | ||
|
|
5bbcdd121a | ||
|
|
8e89dc8aa9 | ||
|
|
c458b726b4 | ||
|
|
c0a156f347 | ||
|
|
8e12cd6b02 | ||
|
|
a6f92b8ff9 | ||
|
|
cdb1cf1b63 | ||
|
|
877b397e04 | ||
|
|
df13e3ab82 | ||
|
|
8536fe4987 | ||
|
|
eba08334d1 | ||
|
|
165a99fd83 | ||
|
|
6754a9f3da | ||
|
|
12b0d81dda | ||
|
|
95da7c1c87 | ||
|
|
c903785864 | ||
|
|
eae94c5f23 | ||
|
|
ddabfdca3d | ||
|
|
5cf6a30027 | ||
|
|
91c9b4e168 | ||
|
|
914a0c60b0 | ||
|
|
773fb7c75b | ||
|
|
afe20ffe92 | ||
|
|
0b72c0b25c | ||
|
|
f06899303c | ||
|
|
b121d1730b | ||
|
|
5d570b5140 | ||
|
|
980a537930 | ||
|
|
d700c78f6c | ||
|
|
c7abc03fee | ||
|
|
9f243563b9 | ||
|
|
5eac8d860a | ||
|
|
1c8f860b6e | ||
|
|
1226308f3d | ||
|
|
40dd25c122 | ||
|
|
fa71885cf9 | ||
|
|
2a7be0eabb | ||
|
|
ab7c828cfa | ||
|
|
e6f8cfb16c | ||
|
|
0283a42273 | ||
|
|
d1a6d29fdd | ||
|
|
ee15aa888f | ||
|
|
3cc975813d | ||
|
|
f226177bca | ||
|
|
995478adac | ||
|
|
62915d5af5 | ||
|
|
825e2eec51 | ||
|
|
b7f2bae2ef | ||
|
|
9b4701fed7 | ||
|
|
937e55eb46 | ||
|
|
7c003e9e7a | ||
|
|
f0f973eb00 | ||
|
|
f399dd3498 | ||
|
|
d2e5bb99ef | ||
|
|
77eeea95c7 | ||
|
|
056ad51c24 | ||
|
|
97e38255c6 | ||
|
|
88004cac76 | ||
|
|
1162a5f916 | ||
|
|
418c37dd52 | ||
|
|
b66827998d | ||
|
|
b195656900 | ||
|
|
2628ee98f3 | ||
|
|
176c0b2d36 | ||
|
|
4986592dd7 | ||
|
|
a4c4324ba3 | ||
|
|
6442ab2f20 | ||
|
|
c19786bdfb | ||
|
|
1b498128ef | ||
|
|
556939139b | ||
|
|
d5dfd37385 | ||
|
|
508b4d648d | ||
|
|
163813145d | ||
|
|
5baa1aaa2a | ||
|
|
59b7d5a9f4 | ||
|
|
bbd1187a9c | ||
|
|
3f65ae39af | ||
|
|
8bac9853fa | ||
|
|
301a6736ac | ||
|
|
55ee21421e | ||
|
|
1a4ca389cd | ||
|
|
27cfeefef1 | ||
|
|
cc357b2b7d | ||
|
|
6335ac6a47 | ||
|
|
e61ebb4eb9 | ||
|
|
a6b8edde62 | ||
|
|
a4450db277 | ||
|
|
b7e38e95f0 | ||
|
|
cda572fd59 | ||
|
|
af4a0ffa21 | ||
|
|
f786c86f77 | ||
|
|
55365b1d17 | ||
|
|
d605c850b7 | ||
|
|
5bb33ce420 | ||
|
|
39268c681f | ||
|
|
a2b82c18d7 | ||
|
|
83a9ab44bd | ||
|
|
3bf3a276de | ||
|
|
9a7fbaee00 | ||
|
|
6ed01f24be | ||
|
|
04428c5aed | ||
|
|
ba8e48be38 | ||
|
|
bc2613c42b | ||
|
|
ac71a45b3b | ||
|
|
30425a194e | ||
|
|
63e678928b | ||
|
|
e32896137e | ||
|
|
0787909045 | ||
|
|
1acfb53c4c | ||
|
|
46c7e53ca1 | ||
|
|
7228709616 | ||
|
|
2ca5d39f7d | ||
|
|
08583463be | ||
|
|
84d3f6ac9c | ||
|
|
0f8fc7bdee | ||
|
|
cc0ae5e229 | ||
|
|
5750447826 |
89
.github/workflows/go.yml
vendored
89
.github/workflows/go.yml
vendored
@@ -5,51 +5,44 @@ name: Go
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "*" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "*" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
test-macos:
|
test:
|
||||||
runs-on: macos-latest
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
llvm: [17]
|
os:
|
||||||
|
- macos-latest
|
||||||
|
- ubuntu-24.04
|
||||||
|
llvm: [18]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Update Homebrew
|
- name: Install dependencies
|
||||||
if: matrix.llvm == 17 # needed as long as LLVM 17 is still fresh
|
if: startsWith(matrix.os, 'macos')
|
||||||
run: brew update
|
|
||||||
- name: Install LLVM ${{ matrix.llvm }}
|
|
||||||
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }}
|
|
||||||
|
|
||||||
- name: Set up Go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.20'
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: go build -v ./...
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: go test -v ./...
|
|
||||||
|
|
||||||
test-linux:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
llvm: [17]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install LLVM ${{ matrix.llvm }}
|
|
||||||
run: |
|
run: |
|
||||||
echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${{ matrix.llvm }} main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
brew update
|
||||||
|
brew install llvm@${{ matrix.llvm }} pkg-config bdw-gc openssl cjson sqlite python@3.12
|
||||||
|
echo "$(brew --prefix llvm@${{ matrix.llvm }})/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
if: startsWith(matrix.os, 'ubuntu')
|
||||||
|
run: |
|
||||||
|
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{ matrix.llvm }} main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install --no-install-recommends llvm-${{ matrix.llvm }}-dev
|
sudo apt-get install -y llvm-${{ matrix.llvm }}-dev clang-${{ matrix.llvm }} lld-${{ matrix.llvm }} pkg-config libgc-dev libssl-dev libcjson-dev libsqlite3-dev python3.12-dev
|
||||||
|
echo "/usr/lib/llvm-${{ matrix.llvm }}/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Clang information
|
||||||
|
run: |
|
||||||
|
echo $PATH
|
||||||
|
which clang
|
||||||
|
clang --version
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
@@ -60,8 +53,38 @@ jobs:
|
|||||||
run: go build -v ./...
|
run: go build -v ./...
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
|
if: matrix.os != 'macos-latest'
|
||||||
|
run: go test -v ./...
|
||||||
|
|
||||||
|
- name: Test with coverage
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
|
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: go install ./...
|
||||||
|
|
||||||
|
- name: LLGO tests
|
||||||
|
if: matrix.os != 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
echo "Test result on ${{ matrix.os }} with LLVM ${{ matrix.llvm }}" > result.md
|
||||||
|
LLGOROOT=$PWD bash .github/workflows/test_llgo.sh
|
||||||
|
|
||||||
|
- name: Test _demo and _pydemo
|
||||||
|
run: |
|
||||||
|
set +e
|
||||||
|
LLGOROOT=$PWD bash .github/workflows/test_demo.sh
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
- name: Show test result
|
||||||
|
run: cat result.md
|
||||||
|
|
||||||
|
- name: PR comment with test result
|
||||||
|
uses: thollander/actions-comment-pull-request@v2
|
||||||
|
if: false
|
||||||
|
with:
|
||||||
|
filePath: result.md
|
||||||
|
comment_tag: test-result-on-${{ matrix.os }}-with-llvm-${{ matrix.llvm }}
|
||||||
|
|
||||||
- name: Upload coverage reports to Codecov
|
- name: Upload coverage reports to Codecov
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
40
.github/workflows/populate_darwin_sysroot.sh
vendored
Executable file
40
.github/workflows/populate_darwin_sysroot.sh
vendored
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMPDIR="$(mktemp -d)"
|
||||||
|
export TMPDIR
|
||||||
|
trap 'rm -rf "${TMPDIR}"' EXIT
|
||||||
|
|
||||||
|
DARWIN_AMD64_LLVM_PREFIX=.sysroot/darwin/amd64/usr/local/opt/llvm@18
|
||||||
|
DARWIN_ARM64_LLVM_PREFIX=.sysroot/darwin/arm64/opt/homebrew/opt/llvm@18
|
||||||
|
mkdir -p "${DARWIN_AMD64_LLVM_PREFIX}" "${DARWIN_ARM64_LLVM_PREFIX}"
|
||||||
|
|
||||||
|
BREW_LLVM_FORMULA_JSON="$(mktemp)"
|
||||||
|
curl -fsSL https://formulae.brew.sh/api/formula/llvm.json > "${BREW_LLVM_FORMULA_JSON}"
|
||||||
|
BREW_LLVM_AMD64_BOTTLE_URL=$(jq -r '.bottle.stable.files.sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
||||||
|
BREW_LLVM_ARM64_BOTTLE_URL=$(jq -r '.bottle.stable.files.arm64_sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
||||||
|
curl -fsSL -H "Authorization: Bearer QQ==" "${BREW_LLVM_AMD64_BOTTLE_URL}" | tar -xzf - --strip-components=2 -C "${DARWIN_AMD64_LLVM_PREFIX}"
|
||||||
|
curl -fsSL -H "Authorization: Bearer QQ==" "${BREW_LLVM_ARM64_BOTTLE_URL}" | tar -xzf - --strip-components=2 -C "${DARWIN_ARM64_LLVM_PREFIX}"
|
||||||
|
|
||||||
|
patch_homebrew_lib_dir() {
|
||||||
|
local LIB_DIR="$1"
|
||||||
|
local HOMEBREW_PREFIX="$2"
|
||||||
|
for DYLIB_FILE in "${LIB_DIR}"/*.dylib; do
|
||||||
|
if [[ -f "${DYLIB_FILE}" ]]; then
|
||||||
|
ID=$(otool -D "${DYLIB_FILE}" | grep '@@HOMEBREW_PREFIX@@' | awk '{print $1}')
|
||||||
|
if [[ -n "${ID}" ]]; then
|
||||||
|
NEW_ID=${ID/'@@HOMEBREW_PREFIX@@'/${HOMEBREW_PREFIX}}
|
||||||
|
install_name_tool -id "${NEW_ID}" "${DYLIB_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEPS=$(otool -L "${DYLIB_FILE}" | grep '@@HOMEBREW_PREFIX@@' | awk '{print $1}')
|
||||||
|
for DEP in ${DEPS}; do
|
||||||
|
NEW_DEP=${DEP/'@@HOMEBREW_PREFIX@@'/${HOMEBREW_PREFIX}}
|
||||||
|
install_name_tool -change "${DEP}" "${NEW_DEP}" "${DYLIB_FILE}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
patch_homebrew_lib_dir "${DARWIN_AMD64_LLVM_PREFIX}/lib" /usr/lib
|
||||||
|
patch_homebrew_lib_dir "${DARWIN_ARM64_LLVM_PREFIX}/lib" /opt/homebrew
|
||||||
143
.github/workflows/populate_linux_sysroot.sh
vendored
Executable file
143
.github/workflows/populate_linux_sysroot.sh
vendored
Executable file
@@ -0,0 +1,143 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMPDIR="$(mktemp -d)"
|
||||||
|
export TMPDIR
|
||||||
|
trap 'rm -rf "${TMPDIR}"' EXIT
|
||||||
|
|
||||||
|
LINUX_AMD64_PREFIX=.sysroot/linux/amd64
|
||||||
|
LINUX_ARM64_PREFIX=.sysroot/linux/arm64
|
||||||
|
mkdir -p "${LINUX_AMD64_PREFIX}" "${LINUX_ARM64_PREFIX}"
|
||||||
|
|
||||||
|
POPULATE_LINUX_SYSROOT_SCRIPT="$(mktemp)"
|
||||||
|
cat > "${POPULATE_LINUX_SYSROOT_SCRIPT}" << EOF
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y lsb-release gnupg2 wget rsync
|
||||||
|
|
||||||
|
echo "deb http://apt.llvm.org/\$(lsb_release -cs)/ llvm-toolchain-\$(lsb_release -cs)-18 main" | tee /etc/apt/sources.list.d/llvm.list
|
||||||
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y llvm-18-dev
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "\$1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
exclude_list=()
|
||||||
|
include_list=()
|
||||||
|
|
||||||
|
exclude_list+=(--exclude "/bin")
|
||||||
|
exclude_list+=(--exclude "/boot")
|
||||||
|
exclude_list+=(--exclude "/boot*")
|
||||||
|
exclude_list+=(--exclude "/dev")
|
||||||
|
exclude_list+=(--exclude "/etc")
|
||||||
|
exclude_list+=(--exclude "/home")
|
||||||
|
exclude_list+=(--exclude "/lib/dhcpd")
|
||||||
|
exclude_list+=(--exclude "/lib/firmware")
|
||||||
|
exclude_list+=(--exclude "/lib/hdparm")
|
||||||
|
exclude_list+=(--exclude "/lib/ifupdown")
|
||||||
|
exclude_list+=(--exclude "/lib/modules")
|
||||||
|
exclude_list+=(--exclude "/lib/modprobe.d")
|
||||||
|
exclude_list+=(--exclude "/lib/modules-load.d")
|
||||||
|
exclude_list+=(--exclude "/lib/resolvconf")
|
||||||
|
exclude_list+=(--exclude "/lib/startpar")
|
||||||
|
exclude_list+=(--exclude "/lib/systemd")
|
||||||
|
exclude_list+=(--exclude "/lib/terminfo")
|
||||||
|
exclude_list+=(--exclude "/lib/udev")
|
||||||
|
exclude_list+=(--exclude "/lib/xtables")
|
||||||
|
exclude_list+=(--exclude "/lib/ssl/private")
|
||||||
|
exclude_list+=(--exclude "/lost+found")
|
||||||
|
exclude_list+=(--exclude "/media")
|
||||||
|
exclude_list+=(--exclude "/mnt")
|
||||||
|
exclude_list+=(--exclude "/proc")
|
||||||
|
exclude_list+=(--exclude "/root")
|
||||||
|
exclude_list+=(--exclude "/run")
|
||||||
|
exclude_list+=(--exclude "/sbin")
|
||||||
|
exclude_list+=(--exclude "/srv")
|
||||||
|
exclude_list+=(--exclude "/sys")
|
||||||
|
exclude_list+=(--exclude "/tmp")
|
||||||
|
exclude_list+=(--exclude "/usr/bin")
|
||||||
|
exclude_list+=(--exclude "/usr/games")
|
||||||
|
exclude_list+=(--exclude "/usr/sbin")
|
||||||
|
exclude_list+=(--exclude "/usr/share")
|
||||||
|
exclude_list+=(--exclude "/usr/src")
|
||||||
|
exclude_list+=(--exclude "/usr/local/bin")
|
||||||
|
exclude_list+=(--exclude "/usr/local/etc")
|
||||||
|
exclude_list+=(--exclude "/usr/local/games")
|
||||||
|
exclude_list+=(--exclude "/usr/local/man")
|
||||||
|
exclude_list+=(--exclude "/usr/local/sbin")
|
||||||
|
exclude_list+=(--exclude "/usr/local/share")
|
||||||
|
exclude_list+=(--exclude "/usr/local/src")
|
||||||
|
exclude_list+=(--exclude "/usr/lib/ssl/private")
|
||||||
|
exclude_list+=(--exclude "/var")
|
||||||
|
exclude_list+=(--exclude "/snap")
|
||||||
|
exclude_list+=(--exclude "*python*")
|
||||||
|
|
||||||
|
include_list+=(--include "*.a")
|
||||||
|
include_list+=(--include "*.so")
|
||||||
|
include_list+=(--include "*.so.*")
|
||||||
|
include_list+=(--include "*.h")
|
||||||
|
include_list+=(--include "*.hh")
|
||||||
|
include_list+=(--include "*.hpp")
|
||||||
|
include_list+=(--include "*.hxx")
|
||||||
|
include_list+=(--include "*.pc")
|
||||||
|
include_list+=(--include "*.def")
|
||||||
|
include_list+=(--include "*.inc")
|
||||||
|
include_list+=(--include "/lib")
|
||||||
|
include_list+=(--include "/lib32")
|
||||||
|
include_list+=(--include "/lib64")
|
||||||
|
include_list+=(--include "/libx32")
|
||||||
|
include_list+=(--include "*/")
|
||||||
|
|
||||||
|
do-sync() {
|
||||||
|
from=\$1
|
||||||
|
to=\$2
|
||||||
|
|
||||||
|
args=()
|
||||||
|
args+=(-a)
|
||||||
|
args+=(-z)
|
||||||
|
args+=(-m)
|
||||||
|
args+=(-d)
|
||||||
|
args+=(-h)
|
||||||
|
args+=(--keep-dirlinks)
|
||||||
|
args+=("--info=progress2")
|
||||||
|
args+=(--delete)
|
||||||
|
args+=(--prune-empty-dirs)
|
||||||
|
args+=(--sparse)
|
||||||
|
args+=(--links)
|
||||||
|
args+=(--copy-unsafe-links)
|
||||||
|
args+=("\${exclude_list[@]}")
|
||||||
|
args+=("\${include_list[@]}")
|
||||||
|
args+=(--exclude "*")
|
||||||
|
args+=("\${from}")
|
||||||
|
args+=("\${to}")
|
||||||
|
|
||||||
|
echo "\${args[@]}"
|
||||||
|
rsync "\${args[@]}"
|
||||||
|
|
||||||
|
exit \$?
|
||||||
|
}
|
||||||
|
|
||||||
|
do-sync / /sysroot/
|
||||||
|
EOF
|
||||||
|
chmod +x "${POPULATE_LINUX_SYSROOT_SCRIPT}"
|
||||||
|
|
||||||
|
populate_linux_sysroot() {
|
||||||
|
local ARCH="$1"
|
||||||
|
local PREFIX="$2"
|
||||||
|
docker run \
|
||||||
|
--rm \
|
||||||
|
--platform "linux/${ARCH}" \
|
||||||
|
-v "$(pwd)/${PREFIX}":/sysroot \
|
||||||
|
-v "${POPULATE_LINUX_SYSROOT_SCRIPT}":/populate_linux_sysroot.sh \
|
||||||
|
debian:bullseye \
|
||||||
|
/populate_linux_sysroot.sh
|
||||||
|
}
|
||||||
|
populate_linux_sysroot amd64 "${LINUX_AMD64_PREFIX}"
|
||||||
|
populate_linux_sysroot arm64 "${LINUX_ARM64_PREFIX}"
|
||||||
58
.github/workflows/release-build.yml
vendored
Normal file
58
.github/workflows/release-build.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
name: Release Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
populate-darwin-sysroot:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Populate Darwin sysroot
|
||||||
|
run: bash .github/workflows/populate_darwin_sysroot.sh
|
||||||
|
- name: Create Darwin sysroot tarball
|
||||||
|
run: tar -czvf .sysroot/darwin.tar.gz -C .sysroot darwin
|
||||||
|
- name: Upload Darwin sysroot tarball
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: darwin-sysroot-tarball
|
||||||
|
path: .sysroot/darwin.tar.gz
|
||||||
|
compression-level: 0
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: populate-darwin-sysroot
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: 1.20.x
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
- name: Download Darwin sysroot tarball
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: darwin-sysroot-tarball
|
||||||
|
path: .sysroot
|
||||||
|
- name: Populate Darwin sysroot
|
||||||
|
run: tar -xzvf .sysroot/darwin.tar.gz -C .sysroot
|
||||||
|
- name: Populate Linux sysroot
|
||||||
|
run: bash .github/workflows/populate_linux_sysroot.sh
|
||||||
|
- name: Run GoReleaser
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{github.token}}
|
||||||
|
run: |
|
||||||
|
docker run \
|
||||||
|
--rm \
|
||||||
|
-e GITHUB_TOKEN=${GITHUB_TOKEN} \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-v $(pwd):/go/src/llgo \
|
||||||
|
-w /go/src/llgo \
|
||||||
|
ghcr.io/goreleaser/goreleaser-cross:v1.22 \
|
||||||
|
release --clean --skip nfpm,snapcraft
|
||||||
29
.github/workflows/test_demo.sh
vendored
Normal file
29
.github/workflows/test_demo.sh
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# llgo run subdirectories under _demo and _pydemo
|
||||||
|
total=0
|
||||||
|
failed=0
|
||||||
|
failed_cases=""
|
||||||
|
for d in ./_demo/* ./_pydemo/*; do
|
||||||
|
total=$((total+1))
|
||||||
|
if [ -d "$d" ]; then
|
||||||
|
echo "Testing $d"
|
||||||
|
if ! llgo run "$d"; then
|
||||||
|
echo "FAIL"
|
||||||
|
failed=$((failed+1))
|
||||||
|
failed_cases="$failed_cases\n* :x: $d"
|
||||||
|
else
|
||||||
|
echo "PASS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "=== Done"
|
||||||
|
echo "$((total-failed))/$total tests passed"
|
||||||
|
|
||||||
|
if [ "$failed" -ne 0 ]; then
|
||||||
|
echo ":bangbang: Failed demo cases:" | tee -a result.md
|
||||||
|
echo -e "$failed_cases" | tee -a result.md
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo ":white_check_mark: All demo tests passed" | tee -a result.md
|
||||||
|
fi
|
||||||
38
.github/workflows/test_llgo.sh
vendored
Normal file
38
.github/workflows/test_llgo.sh
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export LLGOROOT=$PWD
|
||||||
|
|
||||||
|
testcmd=/tmp/test
|
||||||
|
llgo build -o $testcmd ./c/bdwgc/_test
|
||||||
|
cases=$($testcmd)
|
||||||
|
total=$(echo "$cases" | wc -l | tr -d ' ')
|
||||||
|
failed=0
|
||||||
|
failed_cases=""
|
||||||
|
|
||||||
|
for idx in $(seq 1 $((total))); do
|
||||||
|
case=$(echo "$cases" | sed -n "${idx}p")
|
||||||
|
case_name=$(echo "$case" | cut -d',' -f2)
|
||||||
|
echo "=== Test case: $case_name"
|
||||||
|
set +e
|
||||||
|
out=$("$testcmd" "$((idx-1))" 2>&1)
|
||||||
|
exit_code=$?
|
||||||
|
set -e
|
||||||
|
if [ "${exit_code:-0}" -ne 0 ]; then
|
||||||
|
echo "failed: $out"
|
||||||
|
failed=$((failed+1))
|
||||||
|
failed_cases="$failed_cases\n* :x: $case_name"
|
||||||
|
else
|
||||||
|
echo "passed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "=== Done"
|
||||||
|
echo "$((total-failed))/$total tests passed"
|
||||||
|
|
||||||
|
if [ "$failed" -ne 0 ]; then
|
||||||
|
echo ":bangbang: Failed llgo cases:" | tee -a result.md
|
||||||
|
echo -e "$failed_cases" | tee -a result.md
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo ":white_check_mark: All llgo tests passed" | tee -a result.md
|
||||||
|
fi
|
||||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -9,7 +9,8 @@
|
|||||||
*.dylib
|
*.dylib
|
||||||
|
|
||||||
test.db
|
test.db
|
||||||
llgo_autogen.ll
|
demo.ll
|
||||||
|
llgo_autogen*.ll
|
||||||
stories*.bin
|
stories*.bin
|
||||||
.DS_Store
|
.DS_Store
|
||||||
err.log
|
err.log
|
||||||
@@ -18,6 +19,7 @@ numpy.txt
|
|||||||
_go/
|
_go/
|
||||||
_runtime/
|
_runtime/
|
||||||
_tinygo/
|
_tinygo/
|
||||||
|
_output/
|
||||||
build.dir/
|
build.dir/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
@@ -33,3 +35,7 @@ build.dir/
|
|||||||
|
|
||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work*
|
go.work*
|
||||||
|
|
||||||
|
# GoReleaser
|
||||||
|
.dist/
|
||||||
|
.sysroot/
|
||||||
|
|||||||
145
.goreleaser.yaml
Normal file
145
.goreleaser.yaml
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
dist: .dist
|
||||||
|
|
||||||
|
env:
|
||||||
|
- SYSROOT_DARWIN_AMD64={{.Env.PWD}}/.sysroot/darwin/amd64
|
||||||
|
- SYSROOT_DARWIN_ARM64={{.Env.PWD}}/.sysroot/darwin/arm64
|
||||||
|
- SYSROOT_LINUX_AMD64={{.Env.PWD}}/.sysroot/linux/amd64
|
||||||
|
- SYSROOT_LINUX_ARM64={{.Env.PWD}}/.sysroot/linux/arm64
|
||||||
|
- CGO_ENABLED=1
|
||||||
|
- CGO_CXXFLAGS=-std=c++17
|
||||||
|
|
||||||
|
before:
|
||||||
|
hooks:
|
||||||
|
- go mod download
|
||||||
|
|
||||||
|
builds:
|
||||||
|
- id: llgo-darwin-amd64
|
||||||
|
main: ./cmd/llgo
|
||||||
|
flags:
|
||||||
|
- -tags=darwin,amd64,byollvm
|
||||||
|
ldflags:
|
||||||
|
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}}
|
||||||
|
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}}
|
||||||
|
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/local/opt/llvm@18/bin/llvm-config
|
||||||
|
env:
|
||||||
|
- CC=o64-clang
|
||||||
|
- CXX=o64-clang++
|
||||||
|
- CGO_CPPFLAGS=-I{{.Env.SYSROOT_DARWIN_AMD64}}/usr/local/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||||
|
- CGO_LDFLAGS=-L{{.Env.SYSROOT_DARWIN_AMD64}}/usr/local/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-18 -lz -lm
|
||||||
|
targets:
|
||||||
|
- darwin_amd64
|
||||||
|
mod_timestamp: "{{.CommitTimestamp}}"
|
||||||
|
- id: llgo-darwin-arm64
|
||||||
|
main: ./cmd/llgo
|
||||||
|
flags:
|
||||||
|
- -tags=darwin,arm64,byollvm
|
||||||
|
ldflags:
|
||||||
|
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}}
|
||||||
|
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}}
|
||||||
|
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/opt/homebrew/opt/llvm@18/bin/llvm-config
|
||||||
|
env:
|
||||||
|
- CC=oa64-clang
|
||||||
|
- CXX=oa64-clang++
|
||||||
|
- CGO_CPPFLAGS=-I{{.Env.SYSROOT_DARWIN_ARM64}}/opt/homebrew/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||||
|
- CGO_LDFLAGS=-L{{.Env.SYSROOT_DARWIN_ARM64}}/opt/homebrew/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-18 -lz -lm
|
||||||
|
targets:
|
||||||
|
- darwin_arm64
|
||||||
|
mod_timestamp: "{{.CommitTimestamp}}"
|
||||||
|
- id: llgo-linux-amd64
|
||||||
|
main: ./cmd/llgo
|
||||||
|
flags:
|
||||||
|
- -tags=linux,amd64,byollvm
|
||||||
|
ldflags:
|
||||||
|
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}}
|
||||||
|
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}}
|
||||||
|
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
|
||||||
|
env:
|
||||||
|
- CC=x86_64-linux-gnu-gcc
|
||||||
|
- CXX=x86_64-linux-gnu-g++
|
||||||
|
- CGO_CPPFLAGS=--sysroot={{.Env.SYSROOT_LINUX_AMD64}} -I{{.Env.SYSROOT_LINUX_AMD64}}/usr/include/llvm-18 -I{{.Env.SYSROOT_LINUX_AMD64}}/usr/include/llvm-c-18 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||||
|
- CGO_LDFLAGS=--sysroot={{.Env.SYSROOT_LINUX_AMD64}} -L{{.Env.SYSROOT_LINUX_AMD64}}/usr/lib/llvm-18/lib -lLLVM-18
|
||||||
|
targets:
|
||||||
|
- linux_amd64
|
||||||
|
mod_timestamp: "{{.CommitTimestamp}}"
|
||||||
|
- id: llgo-linux-arm64
|
||||||
|
main: ./cmd/llgo
|
||||||
|
flags:
|
||||||
|
- -tags=linux,arm64,byollvm
|
||||||
|
ldflags:
|
||||||
|
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}}
|
||||||
|
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}}
|
||||||
|
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
|
||||||
|
env:
|
||||||
|
- CC=aarch64-linux-gnu-gcc
|
||||||
|
- CXX=aarch64-linux-gnu-g++
|
||||||
|
- CGO_CPPFLAGS=--sysroot={{.Env.SYSROOT_LINUX_ARM64}} -I{{.Env.SYSROOT_LINUX_ARM64}}/usr/include/llvm-18 -I{{.Env.SYSROOT_LINUX_ARM64}}/usr/include/llvm-c-18 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||||
|
- CGO_LDFLAGS=--sysroot={{.Env.SYSROOT_LINUX_ARM64}} -L{{.Env.SYSROOT_LINUX_ARM64}}/usr/lib/llvm-18/lib -lLLVM-18
|
||||||
|
targets:
|
||||||
|
- linux_arm64
|
||||||
|
mod_timestamp: "{{.CommitTimestamp}}"
|
||||||
|
|
||||||
|
archives:
|
||||||
|
- format: tar.gz
|
||||||
|
name_template: >-
|
||||||
|
{{.ProjectName}}{{.Version}}.{{.Os}}-{{.Arch}}
|
||||||
|
{{- if .Arm}}v{{.Arm}}{{end}}
|
||||||
|
files:
|
||||||
|
- LICENSE
|
||||||
|
- README.md
|
||||||
|
|
||||||
|
checksum:
|
||||||
|
name_template: "{{.ProjectName}}{{.Version}}.checksums.txt"
|
||||||
|
|
||||||
|
nfpms:
|
||||||
|
- package_name: llgo
|
||||||
|
vendor: goplus
|
||||||
|
homepage: https://github.com/goplus/llgo
|
||||||
|
maintainer: Aofei Sheng <aofei@aofeisheng.com>
|
||||||
|
description: |
|
||||||
|
LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a
|
||||||
|
subproject of the Go+ project.
|
||||||
|
|
||||||
|
LLGo aims to expand the boundaries of Go/Go+, providing limitless possibilities such as:
|
||||||
|
|
||||||
|
- Game development
|
||||||
|
- AI and data science
|
||||||
|
- WebAssembly
|
||||||
|
- Embedded development
|
||||||
|
- ...
|
||||||
|
license: Apache-2.0
|
||||||
|
formats:
|
||||||
|
- deb
|
||||||
|
- rpm
|
||||||
|
file_name_template: >-
|
||||||
|
{{.ProjectName}}{{.Version}}.{{.Os}}-{{.Arch}}
|
||||||
|
{{- if .Arm}}v{{.Arm}}{{end}}
|
||||||
|
bindir: /usr/local/bin
|
||||||
|
|
||||||
|
snapcrafts:
|
||||||
|
- name: llgo
|
||||||
|
title: A Go compiler based on LLVM
|
||||||
|
summary: A Go compiler based on LLVM
|
||||||
|
description: |
|
||||||
|
LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a
|
||||||
|
subproject of the Go+ project.
|
||||||
|
|
||||||
|
LLGo aims to expand the boundaries of Go/Go+, providing limitless possibilities such as:
|
||||||
|
|
||||||
|
- Game development
|
||||||
|
- AI and data science
|
||||||
|
- WebAssembly
|
||||||
|
- Embedded development
|
||||||
|
- ...
|
||||||
|
license: Apache-2.0
|
||||||
|
confinement: classic
|
||||||
|
name_template: >-
|
||||||
|
{{.ProjectName}}{{.Version}}.{{.Os}}-{{.Arch}}
|
||||||
|
{{- if .Arm}}v{{.Arm}}{{end}}
|
||||||
|
|
||||||
|
snapshot:
|
||||||
|
name_template: '{{trimprefix .Summary "v"}}'
|
||||||
|
|
||||||
|
release:
|
||||||
|
prerelease: auto
|
||||||
293
README.md
293
README.md
@@ -10,8 +10,42 @@ llgo - A Go compiler based on LLVM
|
|||||||
|
|
||||||
LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of [the Go+ project](https://github.com/goplus/gop).
|
LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of [the Go+ project](https://github.com/goplus/gop).
|
||||||
|
|
||||||
|
LLGo aims to expand the boundaries of Go/Go+, providing limitless possibilities such as:
|
||||||
|
|
||||||
## C standard libary support
|
* Game development
|
||||||
|
* AI and data science
|
||||||
|
* WebAssembly
|
||||||
|
* Embedded development
|
||||||
|
* ...
|
||||||
|
|
||||||
|
How can these be achieved?
|
||||||
|
|
||||||
|
```
|
||||||
|
LLGo := Go + C + Python
|
||||||
|
```
|
||||||
|
|
||||||
|
LLGo is compatible with C and Python through the language's **Application Binary Interface (ABI)**, while LLGo is compatible with Go through its **syntax (source code)**.
|
||||||
|
|
||||||
|
|
||||||
|
## C/C++ standard libary support
|
||||||
|
|
||||||
|
You can import a C/C++ standard library in LLGo!
|
||||||
|
|
||||||
|
* [c](https://pkg.go.dev/github.com/goplus/llgo/c)
|
||||||
|
* [c/syscall](https://pkg.go.dev/github.com/goplus/llgo/c/syscall)
|
||||||
|
* [c/sys](https://pkg.go.dev/github.com/goplus/llgo/c/sys)
|
||||||
|
* [c/os](https://pkg.go.dev/github.com/goplus/llgo/c/os)
|
||||||
|
* [c/math](https://pkg.go.dev/github.com/goplus/llgo/c/math)
|
||||||
|
* [c/math/cmplx](https://pkg.go.dev/github.com/goplus/llgo/c/math/cmplx)
|
||||||
|
* [c/math/rand](https://pkg.go.dev/github.com/goplus/llgo/c/math/rand)
|
||||||
|
* [c/pthread](https://pkg.go.dev/github.com/goplus/llgo/c/pthread)
|
||||||
|
* [c/pthread/sync](https://pkg.go.dev/github.com/goplus/llgo/c/pthread/sync)
|
||||||
|
* [c/sync/atomic](https://pkg.go.dev/github.com/goplus/llgo/c/sync/atomic)
|
||||||
|
* [c/time](https://pkg.go.dev/github.com/goplus/llgo/c/time)
|
||||||
|
* [c/net](https://pkg.go.dev/github.com/goplus/llgo/c/net)
|
||||||
|
* [cpp/std](https://pkg.go.dev/github.com/goplus/llgo/cpp/std)
|
||||||
|
|
||||||
|
Here is a simple example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -34,46 +68,98 @@ The `_demo` directory contains some C standard libary related demos (it start wi
|
|||||||
To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)):
|
To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export LLGOROOT=`pwd`
|
|
||||||
cd <demo-directory> # eg. cd _demo/hello
|
cd <demo-directory> # eg. cd _demo/hello
|
||||||
llgo run .
|
llgo run .
|
||||||
```
|
```
|
||||||
|
|
||||||
See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for more detials.
|
|
||||||
|
## How support C/C++ and Python
|
||||||
|
|
||||||
|
LLGo use `go:linkname` to link an extern symbol througth its ABI:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import _ "unsafe" // for go:linkname
|
||||||
|
|
||||||
|
//go:linkname Sqrt C.sqrt
|
||||||
|
func Sqrt(x float64) float64
|
||||||
|
```
|
||||||
|
|
||||||
|
You can directly integrate it into [your own code](_demo/linkname/linkname.go):
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import _ "unsafe" // for go:linkname
|
||||||
|
|
||||||
|
//go:linkname Sqrt C.sqrt
|
||||||
|
func Sqrt(x float64) float64
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("sqrt(2) =", Sqrt(2))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or put it into a package (see [c/math](c/math/math.go)):
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/goplus/llgo/c/math"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("sqrt(2) =", math.Sqrt(2))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Python support
|
## Python support
|
||||||
|
|
||||||
You can import a Python library in LLGo!
|
You can import a Python library in LLGo!
|
||||||
|
|
||||||
And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The currently imported libraries include:
|
And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The following libraries have been included in `llgo`:
|
||||||
|
|
||||||
* [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)
|
* [py](https://pkg.go.dev/github.com/goplus/llgo/py) (abi)
|
||||||
* [os](https://pkg.go.dev/github.com/goplus/llgo/py/os)
|
* [py/std](https://pkg.go.dev/github.com/goplus/llgo/py/std) (builtins)
|
||||||
* [math](https://pkg.go.dev/github.com/goplus/llgo/py/math)
|
* [py/sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)
|
||||||
* [json](https://pkg.go.dev/github.com/goplus/llgo/py/json)
|
* [py/os](https://pkg.go.dev/github.com/goplus/llgo/py/os)
|
||||||
* [inspect](https://pkg.go.dev/github.com/goplus/llgo/py/inspect)
|
* [py/math](https://pkg.go.dev/github.com/goplus/llgo/py/math)
|
||||||
* [statistics](https://pkg.go.dev/github.com/goplus/llgo/py/statistics)
|
* [py/json](https://pkg.go.dev/github.com/goplus/llgo/py/json)
|
||||||
* [numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy)
|
* [py/inspect](https://pkg.go.dev/github.com/goplus/llgo/py/inspect)
|
||||||
|
* [py/statistics](https://pkg.go.dev/github.com/goplus/llgo/py/statistics)
|
||||||
|
* [py/numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy)
|
||||||
|
* [py/pandas](https://pkg.go.dev/github.com/goplus/llgo/py/pandas)
|
||||||
|
* [py/torch](https://pkg.go.dev/github.com/goplus/llgo/py/torch)
|
||||||
|
* [py/matplotlib](https://pkg.go.dev/github.com/goplus/llgo/py/matplotlib)
|
||||||
|
|
||||||
Here is an example using the Python `math` library:
|
Note: For third-party libraries (such as pandas and pytorch), you still need to install the library files.
|
||||||
|
|
||||||
|
Here is an example:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/py"
|
"github.com/goplus/llgo/py"
|
||||||
"github.com/goplus/llgo/py/math"
|
"github.com/goplus/llgo/py/math"
|
||||||
|
"github.com/goplus/llgo/py/std"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
x := math.Sqrt(py.Float(2))
|
x := math.Sqrt(py.Float(2)) // x = sqrt(2)
|
||||||
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
|
std.Print(py.Str("sqrt(2) ="), x) // print("sqrt(2) =", x)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python’s `math.sqrt` to get `x`. Then use `x.Float64()` to convert x to Go's `float64` type, and print the value through the C `printf` function.
|
It is equivalent to the following Python code:
|
||||||
|
|
||||||
|
```py
|
||||||
|
import math
|
||||||
|
|
||||||
|
x = math.sqrt(2)
|
||||||
|
print("sqrt =", x)
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python’s `math.sqrt` to get `x`. Then we call `std.Print` to print the result.
|
||||||
|
|
||||||
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
|
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
|
||||||
|
|
||||||
@@ -81,9 +167,9 @@ Let's look at a slightly more complex example. For example, we use `numpy` to ca
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/py"
|
"github.com/goplus/llgo/py"
|
||||||
"github.com/goplus/llgo/py/numpy"
|
"github.com/goplus/llgo/py/numpy"
|
||||||
|
"github.com/goplus/llgo/py/std"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -98,7 +184,7 @@ func main() {
|
|||||||
py.List(3.0, 2.0, 1.0),
|
py.List(3.0, 2.0, 1.0),
|
||||||
)
|
)
|
||||||
x := numpy.Add(a, b)
|
x := numpy.Add(a, b)
|
||||||
c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
|
std.Print(py.Str("a+b ="), x)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -111,83 +197,130 @@ The `_pydemo` directory contains some python related demos:
|
|||||||
* [statistics](_pydemo/statistics/statistics.go): define a python list and call `statistics.mean` to get the mean
|
* [statistics](_pydemo/statistics/statistics.go): define a python list and call `statistics.mean` to get the mean
|
||||||
* [matrix](_pydemo/matrix/matrix.go): a basic `numpy` demo
|
* [matrix](_pydemo/matrix/matrix.go): a basic `numpy` demo
|
||||||
|
|
||||||
To run these demos, you need to set the `LLGO_LIB_PYTHON` environment variable first.
|
To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)):
|
||||||
|
|
||||||
If Python is in the search path for `clang` linking, then `LLGO_LIB_PYTHON` only needs to be set to the name of the Python library. For example:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export LLGO_LIB_PYTHON=python3.12
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also specify the path to tell `llgo` where the Python library is located:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
export LLGO_LIB_PYTHON=/foo/bar/python3.12
|
|
||||||
```
|
|
||||||
|
|
||||||
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python library location under macOS. So we should set it like this:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the file name must be written in a platform-independent format, using `python3.12` instead of `libpython3.12.dylib`.
|
|
||||||
|
|
||||||
Then you can run the demos:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
export LLGOROOT=`pwd`
|
|
||||||
cd <demo-directory> # eg. cd _pydemo/callpy
|
cd <demo-directory> # eg. cd _pydemo/callpy
|
||||||
llgo run .
|
llgo run .
|
||||||
```
|
```
|
||||||
|
|
||||||
See [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py) for more detials.
|
|
||||||
|
|
||||||
|
|
||||||
## Other frequently used libraries
|
## Other frequently used libraries
|
||||||
|
|
||||||
LLGo can easily import any libraries from the C ecosystem. Currently, this import process is still manual, but in the future, it will be automated similar to Python library imports.
|
LLGo can easily import any libraries from the C ecosystem. Currently, this import process is still manual, but in the future, it will be automated similar to Python library imports.
|
||||||
|
|
||||||
The currently imported libraries include:
|
The currently supported libraries include:
|
||||||
|
|
||||||
* [llama2.c](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
|
* [c/bdwgc](https://pkg.go.dev/github.com/goplus/llgo/c/bdwgc)
|
||||||
* [cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
|
* [c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
|
||||||
* [sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite)
|
* [c/clang](https://pkg.go.dev/github.com/goplus/llgo/c/clang)
|
||||||
|
* [c/libuv](https://pkg.go.dev/github.com/goplus/llgo/c/libuv)
|
||||||
|
* [c/llama2](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
|
||||||
|
* [c/lua](https://pkg.go.dev/github.com/goplus/llgo/c/lua)
|
||||||
|
* [c/neco](https://pkg.go.dev/github.com/goplus/llgo/c/neco)
|
||||||
|
* [c/openssl](https://pkg.go.dev/github.com/goplus/llgo/c/openssl)
|
||||||
|
* [c/raylib](https://pkg.go.dev/github.com/goplus/llgo/c/raylib)
|
||||||
|
* [c/sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite)
|
||||||
|
* [c/zlib](https://pkg.go.dev/github.com/goplus/llgo/c/zlib)
|
||||||
|
* [cpp/inih](https://pkg.go.dev/github.com/goplus/llgo/cpp/inih)
|
||||||
|
* [cpp/llvm](https://pkg.go.dev/github.com/goplus/llgo/cpp/llvm)
|
||||||
|
|
||||||
Here are some examples related to them:
|
Here are some examples related to them:
|
||||||
|
|
||||||
* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example)
|
* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example)
|
||||||
* [mkjson](c/cjson/_demo/mkjson/mkjson.go): create a json object and print it
|
* [mkjson](c/cjson/_demo/mkjson/mkjson.go): create a json object and print it
|
||||||
* [sqlitedemo](c/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo
|
* [sqlitedemo](c/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo
|
||||||
|
* [tetris](c/raylib/_demo/tetris/tetris.go): a tetris game based on raylib
|
||||||
|
|
||||||
|
|
||||||
## Go syntax support
|
## Go syntax support
|
||||||
|
|
||||||
The priority of `llgo` feature iteration is:
|
All Go syntax (not including `cgo`) is already supported. Here are some examples:
|
||||||
|
|
||||||
* Popular C/Python libraries
|
|
||||||
* Full Go syntax
|
|
||||||
* Go standard libraries
|
|
||||||
* Popular Go packages
|
|
||||||
|
|
||||||
Common Go syntax is already supported. Except for the following, which needs to be improved:
|
|
||||||
|
|
||||||
* interface (Limited support)
|
|
||||||
* map (Very limited support)
|
|
||||||
* panic (Limited support)
|
|
||||||
* recover (Not supported yet)
|
|
||||||
* defer (Not supported yet)
|
|
||||||
* gc (Not supported yet)
|
|
||||||
* chan (Not supported yet)
|
|
||||||
* goroutine (Not supported yet)
|
|
||||||
* generics (Not supported yet)
|
|
||||||
|
|
||||||
Here are some examples related to Go syntax:
|
|
||||||
|
|
||||||
* [concat](_demo/concat/concat.go): define a variadic function
|
* [concat](_demo/concat/concat.go): define a variadic function
|
||||||
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
||||||
|
* [errors](_cmptest/errors/errors.go): demo to implement error interface
|
||||||
|
* [defer](_cmptest/defer/defer.go): defer demo
|
||||||
|
* [goroutine](_demo/goroutine/goroutine.go): goroutine demo
|
||||||
|
|
||||||
|
|
||||||
|
### Defer
|
||||||
|
|
||||||
|
LLGo `defer` does not support usage in loops. This is not a bug but a feature, because we think that using `defer` in a loop is a very unrecommended practice.
|
||||||
|
|
||||||
|
|
||||||
|
### Garbage Collection (GC)
|
||||||
|
|
||||||
|
By default, LLGo implements `gc` based on [bdwgc](https://www.hboehm.info/gc/) (also known as [libgc](https://www.hboehm.info/gc/)).
|
||||||
|
|
||||||
|
However, you can disable gc by specifying the `nogc` tag. For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
llgo run -tags nogc .
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Go packages support
|
||||||
|
|
||||||
|
Here are the Go packages that can be imported correctly:
|
||||||
|
|
||||||
|
* [unsafe](https://pkg.go.dev/unsafe)
|
||||||
|
* [unicode](https://pkg.go.dev/unicode)
|
||||||
|
* [unicode/utf8](https://pkg.go.dev/unicode/utf8)
|
||||||
|
* [unicode/utf16](https://pkg.go.dev/unicode/utf16)
|
||||||
|
* [math](https://pkg.go.dev/math)
|
||||||
|
* [math/bits](https://pkg.go.dev/math/bits)
|
||||||
|
* [math/cmplx](https://pkg.go.dev/math/cmplx)
|
||||||
|
* [math/rand](https://pkg.go.dev/math/rand)
|
||||||
|
* [errors](https://pkg.go.dev/errors)
|
||||||
|
* [context](https://pkg.go.dev/context)
|
||||||
|
* [io](https://pkg.go.dev/io)
|
||||||
|
* [io/fs](https://pkg.go.dev/io/fs)
|
||||||
|
* [log](https://pkg.go.dev/log)
|
||||||
|
* [flag](https://pkg.go.dev/flag)
|
||||||
|
* [sort](https://pkg.go.dev/sort)
|
||||||
|
* [bytes](https://pkg.go.dev/bytes)
|
||||||
|
* [bufio](https://pkg.go.dev/bufio)
|
||||||
|
* [strings](https://pkg.go.dev/strings)
|
||||||
|
* [strconv](https://pkg.go.dev/strconv)
|
||||||
|
* [path](https://pkg.go.dev/path)
|
||||||
|
* [path/filepath](https://pkg.go.dev/path/filepath)
|
||||||
|
* [sync/atomic](https://pkg.go.dev/sync/atomic)
|
||||||
|
* [sync](https://pkg.go.dev/sync) (partially)
|
||||||
|
* [syscall](https://pkg.go.dev/syscall) (partially)
|
||||||
|
* [runtime](https://pkg.go.dev/runtime) (partially)
|
||||||
|
* [os](https://pkg.go.dev/os) (partially)
|
||||||
|
* [os/exec](https://pkg.go.dev/os/exec) (partially)
|
||||||
|
* [fmt](https://pkg.go.dev/fmt) (partially)
|
||||||
|
* [reflect](https://pkg.go.dev/reflect) (partially)
|
||||||
|
* [time](https://pkg.go.dev/time) (partially)
|
||||||
|
* [encoding/binary](https://pkg.go.dev/encoding/binary)
|
||||||
|
* [encoding/hex](https://pkg.go.dev/encoding/hex)
|
||||||
|
* [encoding/base32](https://pkg.go.dev/encoding/base32)
|
||||||
|
* [encoding/base64](https://pkg.go.dev/encoding/base64)
|
||||||
|
* [encoding/csv](https://pkg.go.dev/encoding/csv)
|
||||||
|
* [hash](https://pkg.go.dev/hash)
|
||||||
|
* [hash/adler32](https://pkg.go.dev/hash/adler32)
|
||||||
|
* [hash/crc32](https://pkg.go.dev/hash/crc32) (partially)
|
||||||
|
* [hash/crc64](https://pkg.go.dev/hash/crc64)
|
||||||
|
* [crypto/md5](https://pkg.go.dev/crypto/md5)
|
||||||
|
* [regexp](https://pkg.go.dev/regexp)
|
||||||
|
* [regexp/syntax](https://pkg.go.dev/regexp/syntax)
|
||||||
|
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- [Go 1.20+](https://go.dev)
|
||||||
|
- [LLVM 18](https://llvm.org)
|
||||||
|
- [LLD 18](https://lld.llvm.org)
|
||||||
|
- [Clang 18](https://clang.llvm.org)
|
||||||
|
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
|
||||||
|
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
|
||||||
|
- [OpenSSL 3.0+](https://www.openssl.org/)
|
||||||
|
- [cJSON 1.7+](https://github.com/DaveGamble/cJSON) (optional, for [github.com/goplus/llgo/c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson))
|
||||||
|
- [SQLite 3](https://www.sqlite.org) (optional, for [github.com/goplus/llgo/c/sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite))
|
||||||
|
- [Python 3.12+](https://www.python.org) (optional, for [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py))
|
||||||
|
|
||||||
## How to install
|
## How to install
|
||||||
|
|
||||||
Follow these steps to generate the `llgo` command (its usage is the same as the `go` command):
|
Follow these steps to generate the `llgo` command (its usage is the same as the `go` command):
|
||||||
@@ -196,18 +329,22 @@ Follow these steps to generate the `llgo` command (its usage is the same as the
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
brew update # execute if needed
|
brew update # execute if needed
|
||||||
brew install llvm@17
|
brew install llvm@18 pkg-config bdw-gc openssl
|
||||||
go install -v ./...
|
brew install cjson sqlite python@3.12 # optional
|
||||||
|
export PATH=$(brew --prefix llvm@18)/bin:$PATH # you may want to add this to your shell RC file, e.g. ~/.zshrc
|
||||||
|
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### on Linux
|
### on Linux (Debian/Ubuntu)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-17 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||||
sudo apt-get update # execute if needed
|
sudo apt-get update # execute if needed
|
||||||
sudo apt-get install --no-install-recommends llvm-17-dev
|
sudo apt-get install -y llvm-18-dev clang-18 lld-18 pkg-config libgc-dev libssl-dev
|
||||||
go install -v ./...
|
sudo apt-get install -y libcjson-dev libsqlite3-dev python3.12-dev # optional
|
||||||
|
export PATH=/usr/lib/llvm-18/bin:$PATH # you may want to add this to your shell RC file, e.g. ~/.bashrc
|
||||||
|
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### on Windows
|
### on Windows
|
||||||
@@ -218,16 +355,20 @@ TODO
|
|||||||
## Development tools
|
## Development tools
|
||||||
|
|
||||||
* [pydump](chore/_xtool/pydump): It's the first program compiled by `llgo` (NOT `go`) in a production environment. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`.
|
* [pydump](chore/_xtool/pydump): It's the first program compiled by `llgo` (NOT `go`) in a production environment. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`.
|
||||||
* [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` to accomplish the task.
|
* [pysigfetch](https://github.com/goplus/hdq/tree/main/chore/pysigfetch): It generates symbol information by extracting information from Python's documentation site. This tool is not part of the `llgo` project, but we depend on it.
|
||||||
|
* [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` and `pysigfetch` to accomplish the task.
|
||||||
* [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll).
|
* [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll).
|
||||||
* [ssadump](chore/ssadump): It is a Go SSA builder and interpreter.
|
* [ssadump](chore/ssadump): It is a Go SSA builder and interpreter.
|
||||||
|
|
||||||
How do I generate these tools?
|
How do I generate these tools?
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go install -v ./... # compile all tools except pydump
|
git clone https://github.com/goplus/llgo.git
|
||||||
|
cd llgo
|
||||||
|
go install -v ./chore/... # compile all tools except pydump
|
||||||
cd chore/_xtool
|
cd chore/_xtool
|
||||||
llgo install ./... # compile pydump
|
llgo install ./... # compile pydump
|
||||||
|
go install github.com/goplus/hdq/chore/pysigfetch@v0.8.1 # compile pysigfetch
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key modules
|
## Key modules
|
||||||
|
|||||||
47
_cmptest/_bigsqrt2/sqrt2.go
Normal file
47
_cmptest/_bigsqrt2/sqrt2.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// We'll do computations with 200 bits of precision in the mantissa.
|
||||||
|
const prec = 200
|
||||||
|
|
||||||
|
// Compute the square root of 2 using Newton's Method. We start with
|
||||||
|
// an initial estimate for sqrt(2), and then iterate:
|
||||||
|
// x_{n+1} = 1/2 * ( x_n + (2.0 / x_n) )
|
||||||
|
|
||||||
|
// Since Newton's Method doubles the number of correct digits at each
|
||||||
|
// iteration, we need at least log_2(prec) steps.
|
||||||
|
steps := int(math.Log2(prec))
|
||||||
|
|
||||||
|
// Initialize values we need for the computation.
|
||||||
|
two := new(big.Float).SetPrec(prec).SetInt64(2)
|
||||||
|
half := new(big.Float).SetPrec(prec).SetFloat64(0.5)
|
||||||
|
|
||||||
|
// Use 1 as the initial estimate.
|
||||||
|
x := new(big.Float).SetPrec(prec).SetInt64(1)
|
||||||
|
|
||||||
|
// We use t as a temporary variable. There's no need to set its precision
|
||||||
|
// since big.Float values with unset (== 0) precision automatically assume
|
||||||
|
// the largest precision of the arguments when used as the result (receiver)
|
||||||
|
// of a big.Float operation.
|
||||||
|
t := new(big.Float)
|
||||||
|
|
||||||
|
// Iterate.
|
||||||
|
for i := 0; i <= steps; i++ {
|
||||||
|
t.Quo(two, x) // t = 2.0 / x_n
|
||||||
|
t.Add(x, t) // t = x_n + (2.0 / x_n)
|
||||||
|
x.Mul(half, t) // x_{n+1} = 0.5 * t
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can use the usual fmt.Printf verbs since big.Float implements fmt.Formatter
|
||||||
|
fmt.Printf("sqrt(2) = %.50f\n", x)
|
||||||
|
|
||||||
|
// Print the error between 2 and x*x.
|
||||||
|
t.Mul(x, x) // t = x*x
|
||||||
|
fmt.Printf("error = %e\n", t.Sub(two, t))
|
||||||
|
}
|
||||||
21
_cmptest/_chandemo/chan.go
Normal file
21
_cmptest/_chandemo/chan.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c1 := make(chan string)
|
||||||
|
c2 := make(chan string, 1)
|
||||||
|
go func() {
|
||||||
|
c1 <- "ch1"
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
c2 <- "ch2"
|
||||||
|
}()
|
||||||
|
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
select {
|
||||||
|
case msg1 := <-c1:
|
||||||
|
println(msg1)
|
||||||
|
case msg2 := <-c2:
|
||||||
|
println(msg2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
_cmptest/_jsondemo/json.go
Normal file
16
_cmptest/_jsondemo/json.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s := `{"name":"math","items":[{"name":"sqrt","sig":"(x, /)"},{"name":"pi"}]}`
|
||||||
|
data := unsafe.Slice(unsafe.StringData(s), len(s))
|
||||||
|
var v any
|
||||||
|
json.Unmarshal(data, &v)
|
||||||
|
b, _ := json.MarshalIndent(v, "", " ")
|
||||||
|
fmt.Println(string(b))
|
||||||
|
}
|
||||||
19
_cmptest/_timeout/timer.go
Normal file
19
_cmptest/_timeout/timer.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var c chan int
|
||||||
|
|
||||||
|
func handle(int) {}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
select {
|
||||||
|
case m := <-c:
|
||||||
|
handle(m)
|
||||||
|
case <-time.After(time.Second / 10):
|
||||||
|
fmt.Println("timed out")
|
||||||
|
}
|
||||||
|
}
|
||||||
48
_cmptest/base64demo/base64.go
Normal file
48
_cmptest/base64demo/base64.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base32"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func base64Demo() {
|
||||||
|
msg := "Hello, 世界"
|
||||||
|
encoded := base64.StdEncoding.EncodeToString([]byte(msg))
|
||||||
|
fmt.Println(encoded)
|
||||||
|
decoded, err := base64.StdEncoding.DecodeString(encoded)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("decode error:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(decoded))
|
||||||
|
}
|
||||||
|
|
||||||
|
func base32Demo() {
|
||||||
|
str := "JBSWY3DPFQQHO33SNRSCC==="
|
||||||
|
dst := make([]byte, base32.StdEncoding.DecodedLen(len(str)))
|
||||||
|
n, err := base32.StdEncoding.Decode(dst, []byte(str))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("decode error:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dst = dst[:n]
|
||||||
|
fmt.Printf("%q\n", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hexDemo() {
|
||||||
|
const s = "48656c6c6f20476f7068657221"
|
||||||
|
decoded, err := hex.DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("%s\n", decoded)
|
||||||
|
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
base64Demo()
|
||||||
|
base32Demo()
|
||||||
|
hexDemo()
|
||||||
|
}
|
||||||
11
_cmptest/chan/chan.go
Normal file
11
_cmptest/chan/chan.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ch := make(chan int, 10)
|
||||||
|
println(len(ch), cap(ch))
|
||||||
|
go func() {
|
||||||
|
ch <- 100
|
||||||
|
}()
|
||||||
|
n, ok := <-ch
|
||||||
|
println(n, ok)
|
||||||
|
}
|
||||||
26
_cmptest/chansel/chansel.go
Normal file
26
_cmptest/chansel/chansel.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func fibonacci(c, quit chan int) {
|
||||||
|
x, y := 0, 1
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case c <- x:
|
||||||
|
x, y = y, x+y
|
||||||
|
case <-quit:
|
||||||
|
println("quit")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c := make(chan int)
|
||||||
|
quit := make(chan int)
|
||||||
|
go func() {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
println(<-c)
|
||||||
|
}
|
||||||
|
close(quit)
|
||||||
|
}()
|
||||||
|
fibonacci(c, quit)
|
||||||
|
}
|
||||||
28
_cmptest/crcdemo/crc.go
Normal file
28
_cmptest/crcdemo/crc.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"hash/adler32"
|
||||||
|
"hash/crc32"
|
||||||
|
"hash/crc64"
|
||||||
|
)
|
||||||
|
|
||||||
|
func crc64Demo() {
|
||||||
|
crc := crc64.MakeTable(crc64.ECMA)
|
||||||
|
fmt.Printf("%016x\n", crc64.Checksum([]byte("Hello world"), crc))
|
||||||
|
}
|
||||||
|
|
||||||
|
func crc32Demo() {
|
||||||
|
crc32q := crc32.MakeTable(crc32.IEEE)
|
||||||
|
fmt.Printf("%08x\n", crc32.Checksum([]byte("Hello world"), crc32q))
|
||||||
|
}
|
||||||
|
|
||||||
|
func adler32Demo() {
|
||||||
|
fmt.Printf("%08x\n", adler32.Checksum([]byte("Hello world")))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
adler32Demo()
|
||||||
|
crc32Demo()
|
||||||
|
crc64Demo()
|
||||||
|
}
|
||||||
30
_cmptest/csvdemo/csv.go
Normal file
30
_cmptest/csvdemo/csv.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/csv"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
in := `first_name,last_name,username
|
||||||
|
"Rob","Pike",rob
|
||||||
|
Ken,Thompson,ken
|
||||||
|
"Robert","Griesemer","gri"
|
||||||
|
`
|
||||||
|
r := csv.NewReader(strings.NewReader(in))
|
||||||
|
|
||||||
|
for {
|
||||||
|
record, err := r.Read()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(record)
|
||||||
|
}
|
||||||
|
}
|
||||||
39
_cmptest/ctxcancel/ctx.go
Normal file
39
_cmptest/ctxcancel/ctx.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// gen generates integers in a separate goroutine and
|
||||||
|
// sends them to the returned channel.
|
||||||
|
// The callers of gen need to cancel the context once
|
||||||
|
// they are done consuming generated integers not to leak
|
||||||
|
// the internal goroutine started by gen.
|
||||||
|
gen := func(ctx context.Context) <-chan int {
|
||||||
|
dst := make(chan int)
|
||||||
|
n := 1
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return // returning not to leak the goroutine
|
||||||
|
case dst <- n:
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel() // cancel when we are finished consuming integers
|
||||||
|
|
||||||
|
for n := range gen(ctx) {
|
||||||
|
fmt.Println(n)
|
||||||
|
if n == 5 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
_cmptest/defer/defer.go
Normal file
17
_cmptest/defer/defer.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func f(s string) bool {
|
||||||
|
return len(s) > 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
defer func() {
|
||||||
|
println("hi")
|
||||||
|
}()
|
||||||
|
if s := "hello"; f(s) {
|
||||||
|
defer println(s)
|
||||||
|
} else {
|
||||||
|
defer println("world")
|
||||||
|
}
|
||||||
|
defer println("bye")
|
||||||
|
}
|
||||||
20
_cmptest/envexpand/expand.go
Normal file
20
_cmptest/envexpand/expand.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mapper := func(placeholderName string) string {
|
||||||
|
switch placeholderName {
|
||||||
|
case "DAY_PART":
|
||||||
|
return "morning"
|
||||||
|
case "NAME":
|
||||||
|
return "Gopher"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(os.Expand("Good ${DAY_PART}, $NAME!", mapper))
|
||||||
|
}
|
||||||
21
_cmptest/errors/errors.go
Normal file
21
_cmptest/errors/errors.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// New returns an error that formats as the given text.
|
||||||
|
// Each call to New returns a distinct error value even if the text is identical.
|
||||||
|
func New(text string) error {
|
||||||
|
return &errorString{text}
|
||||||
|
}
|
||||||
|
|
||||||
|
// errorString is a trivial implementation of error.
|
||||||
|
type errorString struct {
|
||||||
|
s string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errorString) Error() string {
|
||||||
|
return e.s
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := New("an error")
|
||||||
|
println(err.Error())
|
||||||
|
}
|
||||||
21
_cmptest/flagdemo/flagdemo.go
Normal file
21
_cmptest/flagdemo/flagdemo.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("args:", os.Args[1:])
|
||||||
|
if len(os.Args) == 1 {
|
||||||
|
os.Args = []string{"flagdemo", "-cpu", "100"}
|
||||||
|
}
|
||||||
|
|
||||||
|
verbose := flag.Bool("v", false, "verbose")
|
||||||
|
cpu := flag.Int("cpu", 1, "cpu number")
|
||||||
|
host := flag.String("host", ":8888", "host")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
fmt.Println("host:", *host, "cpu:", *cpu, "verbose:", *verbose)
|
||||||
|
}
|
||||||
12
_cmptest/fmtdemo/fmt.go
Normal file
12
_cmptest/fmtdemo/fmt.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello, world")
|
||||||
|
fmt.Printf("%f\n", 3.14)
|
||||||
|
fmt.Printf("%v\n", errors.New("error message"))
|
||||||
|
}
|
||||||
9
_cmptest/interf/foo/foo.go
Normal file
9
_cmptest/interf/foo/foo.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func Bar() any {
|
||||||
|
return struct{ V int }{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func F() any {
|
||||||
|
return struct{ v int }{1}
|
||||||
|
}
|
||||||
35
_cmptest/interf/interf.go
Normal file
35
_cmptest/interf/interf.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/_cmptest/interf/foo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Foo() any {
|
||||||
|
return struct{ v int }{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
v := Foo()
|
||||||
|
if x, ok := v.(struct{ v int }); ok {
|
||||||
|
println(x.v)
|
||||||
|
} else {
|
||||||
|
println("Foo: not ok")
|
||||||
|
}
|
||||||
|
bar := foo.Bar()
|
||||||
|
if x, ok := bar.(struct{ V int }); ok {
|
||||||
|
println(x.V)
|
||||||
|
} else {
|
||||||
|
println("Bar: not ok")
|
||||||
|
}
|
||||||
|
if x, ok := foo.F().(struct{ v int }); ok {
|
||||||
|
println(x.v)
|
||||||
|
} else {
|
||||||
|
println("F: not ok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
1
|
||||||
|
1
|
||||||
|
F: not ok
|
||||||
|
*/
|
||||||
14
_cmptest/iodemo/io.go
Normal file
14
_cmptest/iodemo/io.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func f(w io.Writer) {
|
||||||
|
w.Write([]byte("Hello, world\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f(os.Stdout)
|
||||||
|
}
|
||||||
14
_cmptest/md5demo/md5.go
Normal file
14
_cmptest/md5demo/md5.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
h := md5.New()
|
||||||
|
io.WriteString(h, "The fog is getting thicker!")
|
||||||
|
io.WriteString(h, "And Leon's getting laaarger!")
|
||||||
|
fmt.Printf("%x", h.Sum(nil))
|
||||||
|
}
|
||||||
18
_cmptest/osdemo/osd.go
Normal file
18
_cmptest/osdemo/osd.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
home, _ := os.UserHomeDir()
|
||||||
|
println("home:", home)
|
||||||
|
|
||||||
|
cfgdir, _ := os.UserConfigDir()
|
||||||
|
println("cfgdir:", cfgdir)
|
||||||
|
|
||||||
|
cache, _ := os.UserCacheDir()
|
||||||
|
println("cachedir:", cache)
|
||||||
|
|
||||||
|
os.Stdout.Write([]byte("Hello, World\n"))
|
||||||
|
}
|
||||||
24
_cmptest/osexec/exec.go
Normal file
24
_cmptest/osexec/exec.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/xtool/env/llvm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ls := "ls"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
ls = "dir"
|
||||||
|
}
|
||||||
|
cmd := exec.Command(ls)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
cmd.Run()
|
||||||
|
|
||||||
|
dir := llvm.New("").BinDir()
|
||||||
|
fmt.Println(dir)
|
||||||
|
}
|
||||||
30
_cmptest/osproc/exec.go
Normal file
30
_cmptest/osproc/exec.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ls := "ls"
|
||||||
|
args := []string{ls, "-l"}
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
ls = "dir"
|
||||||
|
args = []string{ls}
|
||||||
|
}
|
||||||
|
lspath, _ := exec.LookPath(ls)
|
||||||
|
if lspath != "" {
|
||||||
|
ls = lspath
|
||||||
|
}
|
||||||
|
proc, err := os.StartProcess(ls, args, &os.ProcAttr{
|
||||||
|
Files: []*os.File{nil, os.Stdout, os.Stderr},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("os.StartProcess error:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
proc.Wait()
|
||||||
|
fmt.Println("proc.Wait done")
|
||||||
|
}
|
||||||
26
_cmptest/pipedemo/pipe.go
Normal file
26
_cmptest/pipedemo/pipe.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
data := []byte("This is some data that needs to be stored in Body.")
|
||||||
|
pr, pw := io.Pipe()
|
||||||
|
go func() {
|
||||||
|
defer pw.Close()
|
||||||
|
if _, err := pw.Write(data); err != nil {
|
||||||
|
fmt.Println("Error writing to pipe:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
defer pr.Close()
|
||||||
|
|
||||||
|
readData, err := io.ReadAll(pr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error reading from Body:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Body:", string(readData))
|
||||||
|
}
|
||||||
12
_cmptest/printfdemo/demo.go
Normal file
12
_cmptest/printfdemo/demo.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/xtool/nm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
sym := nm.Symbol{Name: "abc", Type: nm.Text}
|
||||||
|
fmt.Printf("%016x %c %s\n", sym.Addr, sym.Type, sym.Name)
|
||||||
|
}
|
||||||
25
_cmptest/readfiledemo/readf.go
Normal file
25
_cmptest/readfiledemo/readf.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fileName := "err.log"
|
||||||
|
os.WriteFile(fileName, []byte("123"), 0644)
|
||||||
|
|
||||||
|
_, err := os.Stat(fileName)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
fmt.Fprintf(os.Stderr, "File %s not found\n", fileName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(fileName)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "ReadFile: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", data)
|
||||||
|
}
|
||||||
13
_cmptest/reflect/reflect.go
Normal file
13
_cmptest/reflect/reflect.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
tyIntSlice := reflect.SliceOf(reflect.TypeOf(0))
|
||||||
|
v := reflect.Zero(tyIntSlice)
|
||||||
|
v = reflect.Append(v, reflect.ValueOf(1), reflect.ValueOf(2), reflect.ValueOf(3))
|
||||||
|
for i, n := 0, v.Len(); i < n; i++ {
|
||||||
|
item := v.Index(i)
|
||||||
|
println(item.Int())
|
||||||
|
}
|
||||||
|
}
|
||||||
11
_cmptest/regexdemo/regex.go
Normal file
11
_cmptest/regexdemo/regex.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/xtool/env"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(env.ExpandEnv("$(pkg-config --libs bdw-gc)"))
|
||||||
|
}
|
||||||
14
_cmptest/rtype/rtype.go
Normal file
14
_cmptest/rtype/rtype.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
tyIntSlice := reflect.SliceOf(reflect.TypeOf(0))
|
||||||
|
println(tyIntSlice.String())
|
||||||
|
|
||||||
|
v := reflect.Zero(tyIntSlice)
|
||||||
|
println(v.Len())
|
||||||
|
|
||||||
|
v = reflect.ValueOf(100)
|
||||||
|
println(v.Int())
|
||||||
|
}
|
||||||
23
_cmptest/sortdemo/sort.go
Normal file
23
_cmptest/sortdemo/sort.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "sort"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
vals := []int{32, 58, 25, 92, 45, 78}
|
||||||
|
sort.Ints(vals)
|
||||||
|
for _, v := range vals {
|
||||||
|
println(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
texts := []string{"apple", "banana", "cherry", "date", "elderberry", "fig"}
|
||||||
|
sort.Slice(texts, func(i, j int) bool {
|
||||||
|
leni, lenj := len(texts[i]), len(texts[j])
|
||||||
|
if leni != lenj {
|
||||||
|
return leni < lenj
|
||||||
|
}
|
||||||
|
return texts[i] < texts[j]
|
||||||
|
})
|
||||||
|
for _, v := range texts {
|
||||||
|
println(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
12
_cmptest/strconv/strconv.go
Normal file
12
_cmptest/strconv/strconv.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(strconv.Itoa(-123))
|
||||||
|
fmt.Println(strings.Split("abc,def,123", ","))
|
||||||
|
}
|
||||||
11
_cmptest/syscall/syscall.go
Normal file
11
_cmptest/syscall/syscall.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
wd, err := syscall.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
println("cwd:", wd)
|
||||||
|
}
|
||||||
8
_cmptest/timedemo/time.go
Normal file
8
_cmptest/timedemo/time.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := time.Date(2018, time.January, 1, 2, 3, 4, 5, time.UTC)
|
||||||
|
println(t.String())
|
||||||
|
}
|
||||||
24
_demo/catomic/atomic.go
Normal file
24
_demo/catomic/atomic.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c/sync/atomic"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var v int64
|
||||||
|
|
||||||
|
atomic.Store(&v, 100)
|
||||||
|
println("store:", atomic.Load(&v))
|
||||||
|
|
||||||
|
ret := atomic.Add(&v, 1)
|
||||||
|
println("ret:", ret, "v:", v)
|
||||||
|
|
||||||
|
ret, _ = atomic.CompareAndExchange(&v, 100, 102)
|
||||||
|
println("ret:", ret, "vs 100, v:", v)
|
||||||
|
|
||||||
|
ret, _ = atomic.CompareAndExchange(&v, 101, 102)
|
||||||
|
println("ret:", ret, "vs 101, v:", v)
|
||||||
|
|
||||||
|
ret = atomic.Sub(&v, 1)
|
||||||
|
println("ret:", ret, "v:", v)
|
||||||
|
}
|
||||||
50
_demo/cchan/cchan.go
Normal file
50
_demo/cchan/cchan.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/internal/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eltSize = int(unsafe.Sizeof(0))
|
||||||
|
)
|
||||||
|
|
||||||
|
func doChan(cap int) {
|
||||||
|
c := runtime.NewChan(eltSize, cap)
|
||||||
|
go func() {
|
||||||
|
v := 100
|
||||||
|
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
|
||||||
|
}()
|
||||||
|
var ret int
|
||||||
|
runtime.ChanRecv(c, unsafe.Pointer(&ret), eltSize)
|
||||||
|
println(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
doChan(10)
|
||||||
|
doChan(0)
|
||||||
|
|
||||||
|
c := runtime.NewChan(eltSize, 3)
|
||||||
|
|
||||||
|
v := 1
|
||||||
|
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
|
||||||
|
v = 2
|
||||||
|
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
|
||||||
|
v = 3
|
||||||
|
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
|
||||||
|
runtime.ChanClose(c)
|
||||||
|
|
||||||
|
v = 10
|
||||||
|
|
||||||
|
if runtime.ChanTrySend(c, unsafe.Pointer(&v), eltSize) {
|
||||||
|
println("error: chan send to closed chan")
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if ok := runtime.ChanRecv(c, unsafe.Pointer(&v), eltSize); !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
println(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
41
_demo/cchansel/cchansel.go
Normal file
41
_demo/cchansel/cchansel.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/internal/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eltSize = int(unsafe.Sizeof(0))
|
||||||
|
)
|
||||||
|
|
||||||
|
func fibonacci(c, quit *runtime.Chan) {
|
||||||
|
x, y := 0, 1
|
||||||
|
for {
|
||||||
|
isel, _ := runtime.Select(
|
||||||
|
runtime.ChanOp{C: c, Send: true, Val: unsafe.Pointer(&x), Size: int32(eltSize)},
|
||||||
|
runtime.ChanOp{C: quit},
|
||||||
|
)
|
||||||
|
if isel == 0 {
|
||||||
|
x, y = y, x+y
|
||||||
|
} else {
|
||||||
|
println("quit")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c := runtime.NewChan(eltSize, 0)
|
||||||
|
quit := runtime.NewChan(eltSize, 0)
|
||||||
|
go func() {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
val := 0
|
||||||
|
runtime.ChanRecv(c, unsafe.Pointer(&val), eltSize)
|
||||||
|
println(val)
|
||||||
|
}
|
||||||
|
runtime.ChanClose(quit)
|
||||||
|
}()
|
||||||
|
fibonacci(c, quit)
|
||||||
|
}
|
||||||
11
_demo/cexec/exec.go
Normal file
11
_demo/cexec/exec.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ls := c.Str("ls")
|
||||||
|
os.Execlp(ls, ls, c.Str("-l"), nil)
|
||||||
|
}
|
||||||
18
_demo/cmd5demo/md5.go
Normal file
18
_demo/cmd5demo/md5.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c/openssl"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var md5 openssl.MD5_CTX
|
||||||
|
var h = make([]byte, openssl.MD5_LBLOCK)
|
||||||
|
md5.Init()
|
||||||
|
md5.UpdateString("The fog is getting thicker!")
|
||||||
|
md5.UpdateString("And Leon's getting laaarger!")
|
||||||
|
md5.Final(unsafe.SliceData(h))
|
||||||
|
fmt.Printf("%x", h)
|
||||||
|
}
|
||||||
9
_demo/complex/cmplx.go
Normal file
9
_demo/complex/cmplx.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/cmplx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("abs(3+4i):", cmplx.Abs(3+4i))
|
||||||
|
}
|
||||||
38
_demo/cppintf/cppintf.go
Normal file
38
_demo/cppintf/cppintf.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/_demo/cppintf/foo"
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Bar struct {
|
||||||
|
foo.Callback
|
||||||
|
a c.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBar(a c.Int) *Bar {
|
||||||
|
return &Bar{
|
||||||
|
Callback: foo.Callback{
|
||||||
|
Vptr: &foo.CallbackVtbl{
|
||||||
|
Val: c.Func((*Bar).getA),
|
||||||
|
Calc: c.Func((*Bar).sqrt),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
a: a,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Bar) getA() c.Int {
|
||||||
|
return p.a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Bar) sqrt(v float64) float64 {
|
||||||
|
return math.Sqrt(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
bar := NewBar(1)
|
||||||
|
foo.F(&bar.Callback)
|
||||||
|
foo.G(&bar.Callback)
|
||||||
|
}
|
||||||
15
_demo/cppintf/foo/bar/bar.cpp
Normal file
15
_demo/cppintf/foo/bar/bar.cpp
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#define interface struct
|
||||||
|
|
||||||
|
interface ICallback {
|
||||||
|
virtual int val() = 0;
|
||||||
|
virtual double calc(double v) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" void f(ICallback* cb) {
|
||||||
|
printf("val: %d\ncalc(2): %lf\n", cb->val(), cb->calc(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void g(ICallback* cb) {
|
||||||
|
f(cb);
|
||||||
|
}
|
||||||
25
_demo/cppintf/foo/foo.go
Normal file
25
_demo/cppintf/foo/foo.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoFiles = "bar/bar.cpp"
|
||||||
|
LLGoPackage = "link"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Callback struct {
|
||||||
|
Vptr *CallbackVtbl
|
||||||
|
}
|
||||||
|
|
||||||
|
type CallbackVtbl struct {
|
||||||
|
Val unsafe.Pointer
|
||||||
|
Calc unsafe.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname F C.f
|
||||||
|
func F(cb *Callback)
|
||||||
|
|
||||||
|
//go:linkname G C._Z1gP9ICallback
|
||||||
|
func G(cb *Callback)
|
||||||
50
_demo/cppmintf/cpp_multi_intf.go
Normal file
50
_demo/cppmintf/cpp_multi_intf.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/_demo/cppmintf/foo"
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Bar struct {
|
||||||
|
foo.Callback
|
||||||
|
a c.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBar(a c.Int) *Bar {
|
||||||
|
return &Bar{
|
||||||
|
Callback: foo.Callback{
|
||||||
|
ICalc: foo.ICalc{
|
||||||
|
Vptr: &foo.ICalcVtbl{
|
||||||
|
Calc: c.Func((*Bar).sqrt),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IVal: foo.IVal{
|
||||||
|
Vptr: &foo.IValVtbl{
|
||||||
|
Val: c.Func(bar_IVal_getA),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
a: a,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Bar) getA() c.Int {
|
||||||
|
return p.a
|
||||||
|
}
|
||||||
|
|
||||||
|
func bar_IVal_getA(this c.Pointer) c.Int {
|
||||||
|
const delta = -int(unsafe.Offsetof(foo.Callback{}.IVal))
|
||||||
|
return (*Bar)(c.Advance(this, delta)).getA()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Bar) sqrt(v float64) float64 {
|
||||||
|
return math.Sqrt(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
bar := NewBar(1)
|
||||||
|
foo.F(&bar.Callback)
|
||||||
|
}
|
||||||
17
_demo/cppmintf/foo/bar/bar.cpp
Normal file
17
_demo/cppmintf/foo/bar/bar.cpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#define interface struct
|
||||||
|
|
||||||
|
interface ICalc {
|
||||||
|
virtual double calc(double v) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IVal {
|
||||||
|
virtual int val() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Callback : public ICalc, public IVal {
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" void f(Callback* cb) {
|
||||||
|
printf("val: %d\ncalc(2): %lf\n", cb->val(), cb->calc(2));
|
||||||
|
}
|
||||||
42
_demo/cppmintf/foo/foo.go
Normal file
42
_demo/cppmintf/foo/foo.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoFiles = "bar/bar.cpp"
|
||||||
|
LLGoPackage = "link"
|
||||||
|
)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type ICalc struct {
|
||||||
|
Vptr *ICalcVtbl
|
||||||
|
}
|
||||||
|
|
||||||
|
type ICalcVtbl struct {
|
||||||
|
Calc unsafe.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type IVal struct {
|
||||||
|
Vptr *IValVtbl
|
||||||
|
}
|
||||||
|
|
||||||
|
type IValVtbl struct {
|
||||||
|
Val unsafe.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type Callback struct {
|
||||||
|
ICalc
|
||||||
|
IVal
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname F C.f
|
||||||
|
func F(cb *Callback)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
26
_demo/crand/rand.go
Normal file
26
_demo/crand/rand.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/math/rand"
|
||||||
|
"github.com/goplus/llgo/c/time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func fastrand64() uint64 {
|
||||||
|
v1 := uint64(rand.Random())
|
||||||
|
v2 := uint64(rand.Random())
|
||||||
|
return v1 ^ (v2 << 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rand.Srand(c.Uint(time.Time(nil)))
|
||||||
|
fmt.Printf("%x\n", rand.Rand())
|
||||||
|
fmt.Printf("%x\n", rand.Rand())
|
||||||
|
|
||||||
|
rand.Srandom(c.Uint(time.Time(nil)))
|
||||||
|
fmt.Printf("%x\n", rand.Random())
|
||||||
|
fmt.Printf("%x\n", rand.Random())
|
||||||
|
fmt.Printf("%x\n", fastrand64())
|
||||||
|
}
|
||||||
68
_demo/cshademo/sha.go
Normal file
68
_demo/cshademo/sha.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c/openssl"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
str := "His money is twice tainted:"
|
||||||
|
|
||||||
|
var sha1 openssl.SHA_CTX
|
||||||
|
sha1.Init()
|
||||||
|
sha1.UpdateString(str)
|
||||||
|
|
||||||
|
h1 := make([]byte, openssl.SHA_DIGEST_LENGTH)
|
||||||
|
sha1.Final(unsafe.SliceData(h1))
|
||||||
|
fmt.Printf("%x\n", h1)
|
||||||
|
|
||||||
|
h2 := make([]byte, openssl.SHA_DIGEST_LENGTH)
|
||||||
|
openssl.SHA1String(str, unsafe.SliceData(h2))
|
||||||
|
fmt.Printf("%x\n", h2)
|
||||||
|
|
||||||
|
var sha256 openssl.SHA256_CTX
|
||||||
|
sha256.Init()
|
||||||
|
sha256.UpdateString(str)
|
||||||
|
h3 := make([]byte, openssl.SHA256_DIGEST_LENGTH)
|
||||||
|
sha256.Final(unsafe.SliceData(h3))
|
||||||
|
fmt.Printf("%x\n", h3)
|
||||||
|
|
||||||
|
h4 := make([]byte, openssl.SHA256_DIGEST_LENGTH)
|
||||||
|
openssl.SHA256String(str, unsafe.SliceData(h4))
|
||||||
|
fmt.Printf("%x\n", h4)
|
||||||
|
|
||||||
|
var sha512 openssl.SHA512_CTX
|
||||||
|
sha512.Init()
|
||||||
|
sha512.UpdateString("His money is twice tainted:")
|
||||||
|
|
||||||
|
h5 := make([]byte, openssl.SHA512_DIGEST_LENGTH)
|
||||||
|
sha512.Final(unsafe.SliceData(h5))
|
||||||
|
fmt.Printf("%x\n", h5)
|
||||||
|
|
||||||
|
h6 := make([]byte, openssl.SHA512_DIGEST_LENGTH)
|
||||||
|
openssl.SHA512String(str, unsafe.SliceData(h6))
|
||||||
|
fmt.Printf("%x\n", h6)
|
||||||
|
|
||||||
|
var sha224 openssl.SHA224_CTX
|
||||||
|
sha224.Init()
|
||||||
|
sha224.UpdateString(str)
|
||||||
|
|
||||||
|
h7 := make([]byte, openssl.SHA224_DIGEST_LENGTH)
|
||||||
|
sha224.Final(unsafe.SliceData(h7))
|
||||||
|
fmt.Printf("%x\n", h7)
|
||||||
|
h8 := make([]byte, openssl.SHA224_DIGEST_LENGTH)
|
||||||
|
openssl.SHA224String(str, unsafe.SliceData(h8))
|
||||||
|
fmt.Printf("%x\n", h8)
|
||||||
|
|
||||||
|
var sha384 openssl.SHA384_CTX
|
||||||
|
sha384.Init()
|
||||||
|
sha384.UpdateString(str)
|
||||||
|
h9 := make([]byte, openssl.SHA384_DIGEST_LENGTH)
|
||||||
|
sha384.Final(unsafe.SliceData(h9))
|
||||||
|
fmt.Printf("%x\n", h9)
|
||||||
|
h10 := make([]byte, openssl.SHA384_DIGEST_LENGTH)
|
||||||
|
openssl.SHA384String(str, unsafe.SliceData(h10))
|
||||||
|
fmt.Printf("%x\n", h10)
|
||||||
|
}
|
||||||
12
_demo/ctime/time.go
Normal file
12
_demo/ctime/time.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/goplus/llgo/c/time"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var tv time.Timespec
|
||||||
|
time.ClockGettime(time.CLOCK_REALTIME, &tv)
|
||||||
|
println("REALTIME sec:", tv.Sec, "nsec:", tv.Nsec)
|
||||||
|
|
||||||
|
time.ClockGettime(time.CLOCK_MONOTONIC, &tv)
|
||||||
|
println("MONOTONIC sec:", tv.Sec, "nsec:", tv.Nsec)
|
||||||
|
}
|
||||||
77
_demo/fcntl/fcntl.go
Normal file
77
_demo/fcntl/fcntl.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/os"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
filename := c.Str("testfile.txt")
|
||||||
|
data := c.Str("Hello, os!")
|
||||||
|
var buffer [20]c.Char
|
||||||
|
|
||||||
|
// Open a file, O_CREAT|O_WRONLY|O_TRUNC means create, write only, or clear the file
|
||||||
|
fd := os.Open(filename, os.O_CREAT|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||||
|
if fd == -1 {
|
||||||
|
c.Printf(c.Str("open error\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writing data to a file
|
||||||
|
bytesWritten := os.Write(fd, c.Pointer(data), c.Strlen(data))
|
||||||
|
if bytesWritten == -1 {
|
||||||
|
c.Printf(c.Str("write error\n"))
|
||||||
|
os.Close(fd)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Printf(c.Str("Written %ld bytes to %s\n"), bytesWritten, filename)
|
||||||
|
|
||||||
|
// Get file status flags
|
||||||
|
flags := os.Fcntl(fd, os.F_GETFL)
|
||||||
|
if flags == -1 {
|
||||||
|
c.Printf(c.Str("os error\n"))
|
||||||
|
os.Close(fd)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Printf(c.Str("File flags: %d\n"), flags)
|
||||||
|
|
||||||
|
// Set the file status flag to non-blocking mode
|
||||||
|
if os.Fcntl(fd, os.F_SETFL, flags|os.O_NONBLOCK) == -1 {
|
||||||
|
c.Printf(c.Str("os error\n"))
|
||||||
|
os.Close(fd)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Printf(c.Str("set file status successfully\n"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
c.Printf(c.Str("111"))
|
||||||
|
// Close file
|
||||||
|
os.Close(fd)
|
||||||
|
|
||||||
|
// Reopen the file, O_RDONLY means read-only
|
||||||
|
fd = os.Open(filename, os.O_RDONLY)
|
||||||
|
if fd == -1 {
|
||||||
|
c.Printf(c.Str("open error\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reading data from a file
|
||||||
|
// &buffer[:][0]
|
||||||
|
// unsafe.SliceData(buffer[:])
|
||||||
|
bytesRead := os.Read(fd, c.Pointer(unsafe.SliceData(buffer[:])), unsafe.Sizeof(buffer)-1)
|
||||||
|
if bytesRead == -1 {
|
||||||
|
c.Printf(c.Str("read error\n"))
|
||||||
|
os.Close(fd)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the buffer is null-terminated
|
||||||
|
buffer[bytesRead] = c.Char(0)
|
||||||
|
c.Printf(c.Str("Read %ld bytes: %s\n"), bytesRead, &buffer[0])
|
||||||
|
|
||||||
|
// Close file
|
||||||
|
os.Close(fd)
|
||||||
|
}
|
||||||
11
_demo/getcwd/getcwd.go
Normal file
11
_demo/getcwd/getcwd.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
wd := os.Getcwd(c.Alloca(os.PATH_MAX), os.PATH_MAX)
|
||||||
|
c.Printf(c.Str("cwd: %s\n"), wd)
|
||||||
|
}
|
||||||
12
_demo/goroutine/goroutine.go
Normal file
12
_demo/goroutine/goroutine.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
done := false
|
||||||
|
go func() {
|
||||||
|
println("Hello, goroutine")
|
||||||
|
done = true
|
||||||
|
}()
|
||||||
|
for !done {
|
||||||
|
print(".")
|
||||||
|
}
|
||||||
|
}
|
||||||
7
_demo/gotime/time.go
Normal file
7
_demo/gotime/time.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(time.Now().String())
|
||||||
|
}
|
||||||
@@ -9,5 +9,5 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Expected output:
|
/* Expected output:
|
||||||
Hello World
|
Hello world
|
||||||
*/
|
*/
|
||||||
|
|||||||
10
_demo/linkname/linkname.go
Normal file
10
_demo/linkname/linkname.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import _ "unsafe" // for go:linkname
|
||||||
|
|
||||||
|
//go:linkname Sqrt C.sqrt
|
||||||
|
func Sqrt(x float64) float64
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("sqrt(2) =", Sqrt(2))
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
"github.com/goplus/llgo/c/llama2"
|
"github.com/goplus/llgo/c/llama2"
|
||||||
|
"github.com/goplus/llgo/c/time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -11,7 +12,7 @@ func main() {
|
|||||||
var tokenizerPath *c.Char = c.Str("tokenizer.bin")
|
var tokenizerPath *c.Char = c.Str("tokenizer.bin")
|
||||||
var temperature, topp c.Float = 1.0, 0.9
|
var temperature, topp c.Float = 1.0, 0.9
|
||||||
var steps c.Int = 256
|
var steps c.Int = 256
|
||||||
var rngSeed uint64 = uint64(c.Time(nil))
|
var rngSeed uint64 = uint64(time.Time(nil))
|
||||||
|
|
||||||
loop: // parse command line arguments
|
loop: // parse command line arguments
|
||||||
for {
|
for {
|
||||||
|
|||||||
9
_demo/logdemo/log.go
Normal file
9
_demo/logdemo/log.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.Println("Hello")
|
||||||
|
}
|
||||||
11
_demo/math/math.go
Normal file
11
_demo/math/math.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println(math.Sqrt(2))
|
||||||
|
println(math.Abs(-1.2))
|
||||||
|
println(math.Ldexp(1.2, 3))
|
||||||
|
}
|
||||||
20
_demo/netdbdemo/netdb.go
Normal file
20
_demo/netdbdemo/netdb.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var hints net.AddrInfo
|
||||||
|
hints.Family = net.AF_UNSPEC
|
||||||
|
hints.SockType = net.SOCK_STREAM
|
||||||
|
|
||||||
|
host := "httpbin.org"
|
||||||
|
port := "80"
|
||||||
|
|
||||||
|
var result *net.AddrInfo
|
||||||
|
c.Printf(c.Str("%d\n"), net.Getaddrinfo(c.Str(host), c.Str(port), &hints, &result))
|
||||||
|
|
||||||
|
c.Printf(c.Str("%d\n"), net.Freeaddrinfo(result))
|
||||||
|
}
|
||||||
19
_demo/oslookpath/lookpath.go
Normal file
19
_demo/oslookpath/lookpath.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ls := "ls"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
ls = "dir"
|
||||||
|
}
|
||||||
|
lspath, _ := exec.LookPath(ls)
|
||||||
|
if lspath != "" {
|
||||||
|
ls = lspath
|
||||||
|
}
|
||||||
|
fmt.Println(ls)
|
||||||
|
}
|
||||||
12
_demo/randdemo/rand.go
Normal file
12
_demo/randdemo/rand.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(rand.Intn(100))
|
||||||
|
fmt.Println(rand.Intn(100))
|
||||||
|
fmt.Println(rand.Intn(100))
|
||||||
|
}
|
||||||
16
_demo/setjmp/setjmp.go
Normal file
16
_demo/setjmp/setjmp.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c/setjmp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var jb setjmp.SigjmpBuf
|
||||||
|
switch ret := setjmp.Sigsetjmp(&jb, 0); ret {
|
||||||
|
case 0:
|
||||||
|
println("Hello, setjmp!")
|
||||||
|
setjmp.Siglongjmp(&jb, 1)
|
||||||
|
default:
|
||||||
|
println("exception:", ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
32
_demo/socket/client/client.go
Normal file
32
_demo/socket/client/client.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/net"
|
||||||
|
"github.com/goplus/llgo/c/os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
sockfd := net.Socket(net.AF_INET, net.SOCK_STREAM, 0)
|
||||||
|
msg := c.Str("Hello, World!")
|
||||||
|
defer os.Close(sockfd)
|
||||||
|
|
||||||
|
server := net.GetHostByName(c.Str("localhost"))
|
||||||
|
if server == nil {
|
||||||
|
c.Perror(c.Str("hostname get error"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
servAddr := &net.SockaddrIn{}
|
||||||
|
servAddr.Family = net.AF_INET
|
||||||
|
servAddr.Port = net.Htons(uint16(1234))
|
||||||
|
c.Memcpy(unsafe.Pointer(&servAddr.Addr.Addr), unsafe.Pointer(*server.AddrList), uintptr(server.Length))
|
||||||
|
|
||||||
|
if res := net.Connect(sockfd, (*net.SockAddr)(unsafe.Pointer(servAddr)), c.Uint(16)); res < 0 {
|
||||||
|
c.Perror(c.Str("connect error"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
os.Write(sockfd, unsafe.Pointer(msg), c.Strlen(msg))
|
||||||
|
}
|
||||||
43
_demo/socket/server/server.go
Normal file
43
_demo/socket/server/server.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/net"
|
||||||
|
"github.com/goplus/llgo/c/os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var buffer [256]c.Char
|
||||||
|
|
||||||
|
sockfd := net.Socket(net.AF_INET, net.SOCK_STREAM, 0)
|
||||||
|
defer os.Close(sockfd)
|
||||||
|
|
||||||
|
servAddr := &net.SockaddrIn{
|
||||||
|
Family: net.AF_INET,
|
||||||
|
Port: net.Htons(uint16(1234)),
|
||||||
|
Addr: net.InAddr{Addr: 0x00000000},
|
||||||
|
Zero: [8]c.Char{0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
}
|
||||||
|
if res := net.Bind(sockfd, servAddr, c.Uint(unsafe.Sizeof(*servAddr))); res < 0 {
|
||||||
|
c.Perror(c.Str("bind error"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if net.Listen(sockfd, 5) < 0 {
|
||||||
|
c.Printf(c.Str("listen error"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Printf(c.Str("Listening on port 1234...\n"))
|
||||||
|
|
||||||
|
cliAddr, clilen := &net.SockaddrIn{}, c.Uint(unsafe.Sizeof(servAddr))
|
||||||
|
|
||||||
|
newsockfd := net.Accept(sockfd, cliAddr, &clilen)
|
||||||
|
defer os.Close(newsockfd)
|
||||||
|
c.Printf(c.Str("Connection accepted."))
|
||||||
|
|
||||||
|
os.Read(newsockfd, unsafe.Pointer(unsafe.SliceData(buffer[:])), 256)
|
||||||
|
c.Printf(c.Str("Received: %s"), &buffer[0])
|
||||||
|
|
||||||
|
}
|
||||||
26
_demo/sysexec/exec.go
Normal file
26
_demo/sysexec/exec.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ls := "ls"
|
||||||
|
args := []string{ls, "-l"}
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
ls = "dir"
|
||||||
|
args = []string{ls}
|
||||||
|
}
|
||||||
|
lspath, _ := exec.LookPath(ls)
|
||||||
|
if lspath != "" {
|
||||||
|
ls = lspath
|
||||||
|
}
|
||||||
|
err := syscall.Exec(ls, args, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("syscall.Exec error:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
25
_demo/thread/thd.go
Normal file
25
_demo/thread/thd.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/pthread"
|
||||||
|
)
|
||||||
|
|
||||||
|
var key pthread.Key
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
key.Create(nil)
|
||||||
|
key.Set(c.Pointer(c.Str("main value\n")))
|
||||||
|
|
||||||
|
var thd pthread.Thread
|
||||||
|
pthread.Create(&thd, nil, func(arg c.Pointer) c.Pointer {
|
||||||
|
key.Set(c.Pointer(c.Str("thread value\n")))
|
||||||
|
c.Printf(c.Str("Hello, thread\nTLS: %s"), key.Get())
|
||||||
|
return c.Pointer(c.Str("Back to main\n"))
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
var retval c.Pointer
|
||||||
|
pthread.Join(thd, &retval)
|
||||||
|
|
||||||
|
c.Printf(c.Str("%sTLS: %s"), retval, key.Get())
|
||||||
|
}
|
||||||
11
_demo/timedur/timedur.go
Normal file
11
_demo/timedur/timedur.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := time.Now().Add(time.Second * 5)
|
||||||
|
fmt.Println(time.Until(t))
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/py"
|
"github.com/goplus/llgo/py"
|
||||||
"github.com/goplus/llgo/py/math"
|
"github.com/goplus/llgo/py/math"
|
||||||
|
"github.com/goplus/llgo/py/std"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
x := math.Sqrt(py.Float(2))
|
x := math.Sqrt(py.Float(2)) // x = sqrt(2)
|
||||||
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
|
std.Print(py.Str("sqrt(2) ="), x) // print("sqrt(2) =", x)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/py"
|
"github.com/goplus/llgo/py"
|
||||||
"github.com/goplus/llgo/py/numpy"
|
"github.com/goplus/llgo/py/numpy"
|
||||||
|
"github.com/goplus/llgo/py/std"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -18,5 +18,5 @@ func main() {
|
|||||||
py.List(3.0, 2.0, 1.0),
|
py.List(3.0, 2.0, 1.0),
|
||||||
)
|
)
|
||||||
x := numpy.Add(a, b)
|
x := numpy.Add(a, b)
|
||||||
c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
|
std.Print(py.Str("a+b ="), x)
|
||||||
}
|
}
|
||||||
|
|||||||
15
_pydemo/max/max.go
Normal file
15
_pydemo/max/max.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/std"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
x := std.Max(py.Float(3.0), py.Float(9.0), py.Float(23.0), py.Float(100.0))
|
||||||
|
std.Print(x)
|
||||||
|
|
||||||
|
list := py.List(3.0, 9.0, 23.0, 100.0)
|
||||||
|
y := std.Max(std.Iter(list))
|
||||||
|
std.Print(y)
|
||||||
|
}
|
||||||
11
_pydemo/print/print.go
Normal file
11
_pydemo/print/print.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/std"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
x := py.Float(3.14)
|
||||||
|
std.Print(x)
|
||||||
|
}
|
||||||
16
_pydemo/tensor/tensor.go
Normal file
16
_pydemo/tensor/tensor.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/std"
|
||||||
|
"github.com/goplus/llgo/py/torch"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
data := py.List(
|
||||||
|
py.List(1.0, 2.0),
|
||||||
|
py.List(3.0, 4.0),
|
||||||
|
)
|
||||||
|
x := torch.Tensor(data)
|
||||||
|
std.Print(x)
|
||||||
|
}
|
||||||
101
c/bdwgc/_test/bdwgc.go
Normal file
101
c/bdwgc/_test/bdwgc.go
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/bdwgc"
|
||||||
|
"github.com/goplus/llgo/c/bdwgc/_test/testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ------ Test malloc ------
|
||||||
|
|
||||||
|
func TestMalloc(t *testing.T) {
|
||||||
|
pn := (*int)(bdwgc.Malloc(unsafe.Sizeof(int(0))))
|
||||||
|
*pn = 1 << 30
|
||||||
|
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
|
||||||
|
|
||||||
|
pl := (*int64)(bdwgc.Realloc(c.Pointer(pn), unsafe.Sizeof(int64(0))))
|
||||||
|
*pl = 1 << 60
|
||||||
|
c.Printf(c.Str("value: %lld, %llx, %p, %p\n"), *pl, *pl, pl, &pl)
|
||||||
|
|
||||||
|
bdwgc.Free(c.Pointer(pl))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------ Test finalizer ------
|
||||||
|
|
||||||
|
const (
|
||||||
|
RETURN_VALUE_FREED = 1 << 31
|
||||||
|
)
|
||||||
|
|
||||||
|
var called uint = 0
|
||||||
|
|
||||||
|
func setReturnValueFreed(pobj c.Pointer, clientData c.Pointer) {
|
||||||
|
called |= RETURN_VALUE_FREED
|
||||||
|
c.Printf(c.Str("called: %x\n"), called)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setLoopValueFreed(pobj c.Pointer, clientData c.Pointer) {
|
||||||
|
pmask := (*uint)(clientData)
|
||||||
|
called |= *pmask
|
||||||
|
c.Printf(c.Str("called: %x\n"), called)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isCalled(mask uint) bool {
|
||||||
|
return called&mask != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func returnValue() *int {
|
||||||
|
pn := bdwgc.Malloc(unsafe.Sizeof(int(0)))
|
||||||
|
bdwgc.RegisterFinalizer(pn, setReturnValueFreed, nil, nil, nil)
|
||||||
|
return (*int)(pn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func callFunc() {
|
||||||
|
pn := returnValue()
|
||||||
|
*pn = 1 << 30
|
||||||
|
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
|
||||||
|
bdwgc.Gcollect()
|
||||||
|
check(!isCalled(RETURN_VALUE_FREED), c.Str("finalizer should not be called"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func loop() {
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
p := bdwgc.Malloc(unsafe.Sizeof(int(0)))
|
||||||
|
pn := (*int)(p)
|
||||||
|
*pn = i
|
||||||
|
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
|
||||||
|
pflag := (*uint)(c.Malloc(unsafe.Sizeof(uint(0))))
|
||||||
|
*pflag = 1 << i
|
||||||
|
bdwgc.RegisterFinalizer(p, setLoopValueFreed, c.Pointer(pflag), nil, nil)
|
||||||
|
bdwgc.Gcollect()
|
||||||
|
check(!isCalled(1<<i), c.Str("finalizer should not be called"))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
check(isCalled(1<<j), c.Str("finalizers of previous objects should be called"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear stack to avoid reference
|
||||||
|
func clearStack() {
|
||||||
|
p := c.Alloca(128)
|
||||||
|
c.Memset(p, 0, 128)
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(b bool, msg *c.Char) {
|
||||||
|
if !b {
|
||||||
|
c.Printf(c.Str("check failed: %s\n"), msg)
|
||||||
|
panic("check failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFinalizer(t *testing.T) {
|
||||||
|
bdwgc.Init()
|
||||||
|
|
||||||
|
callFunc()
|
||||||
|
clearStack()
|
||||||
|
bdwgc.Gcollect()
|
||||||
|
check(isCalled(RETURN_VALUE_FREED), c.Str("finalizer should be called"))
|
||||||
|
|
||||||
|
loop()
|
||||||
|
}
|
||||||
31
c/bdwgc/_test/main.go
Normal file
31
c/bdwgc/_test/main.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/bdwgc/_test/testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestCase struct {
|
||||||
|
Name string
|
||||||
|
F func(*testing.T)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
tests := []TestCase{
|
||||||
|
{"TestMalloc", TestMalloc},
|
||||||
|
{"TestFinalizer", TestFinalizer},
|
||||||
|
}
|
||||||
|
if c.Argc == 1 {
|
||||||
|
for _, test := range tests {
|
||||||
|
c.Printf(c.Str("%s\n"), c.AllocaCStr(test.Name))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Fprintf(c.Stderr, c.Str("arg: %s\n"), c.Index(c.Argv, 1))
|
||||||
|
idx := int(c.Atoi(c.Index(c.Argv, 1)))
|
||||||
|
if idx < 0 || idx >= len(tests) {
|
||||||
|
c.Printf(c.Str("invalid test index %d"), idx)
|
||||||
|
panic("invalid test index")
|
||||||
|
}
|
||||||
|
tests[idx].F(nil)
|
||||||
|
}
|
||||||
4
c/bdwgc/_test/testing/testing.go
Normal file
4
c/bdwgc/_test/testing/testing.go
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
}
|
||||||
103
c/bdwgc/bdwgc.go
Normal file
103
c/bdwgc/bdwgc.go
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bdwgc
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "link: $(pkg-config --libs bdw-gc); -lgc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname Init C.GC_init
|
||||||
|
func Init()
|
||||||
|
|
||||||
|
//go:linkname Malloc C.GC_malloc
|
||||||
|
func Malloc(size uintptr) c.Pointer
|
||||||
|
|
||||||
|
//go:linkname Realloc C.GC_realloc
|
||||||
|
func Realloc(ptr c.Pointer, size uintptr) c.Pointer
|
||||||
|
|
||||||
|
//go:linkname Free C.GC_free
|
||||||
|
func Free(ptr c.Pointer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname RegisterFinalizer C.GC_register_finalizer
|
||||||
|
func RegisterFinalizer(
|
||||||
|
obj c.Pointer,
|
||||||
|
fn func(c.Pointer, c.Pointer), cd c.Pointer,
|
||||||
|
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
|
||||||
|
|
||||||
|
//go:linkname RegisterFinalizerNoOrder C.GC_register_finalizer_no_order
|
||||||
|
func RegisterFinalizerNoOrder(
|
||||||
|
obj c.Pointer,
|
||||||
|
fn func(c.Pointer, c.Pointer), cd c.Pointer,
|
||||||
|
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
|
||||||
|
|
||||||
|
//go:linkname RegisterFinalizerIgnoreSelf C.GC_register_finalizer_ignore_self
|
||||||
|
func RegisterFinalizerIgnoreSelf(
|
||||||
|
obj c.Pointer,
|
||||||
|
fn func(c.Pointer, c.Pointer), cd c.Pointer,
|
||||||
|
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
|
||||||
|
|
||||||
|
//go:linkname RegisterFinalizerUnreachable C.GC_register_finalizer_unreachable
|
||||||
|
func RegisterFinalizerUnreachable(
|
||||||
|
obj c.Pointer,
|
||||||
|
fn func(c.Pointer, c.Pointer), cd c.Pointer,
|
||||||
|
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname Enable C.GC_enable
|
||||||
|
func Enable()
|
||||||
|
|
||||||
|
//go:linkname Disable C.GC_disable
|
||||||
|
func Disable()
|
||||||
|
|
||||||
|
//go:linkname IsDisabled C.GC_is_disabled
|
||||||
|
func IsDisabled() c.Int
|
||||||
|
|
||||||
|
//go:linkname Gcollect C.GC_gcollect
|
||||||
|
func Gcollect()
|
||||||
|
|
||||||
|
//go:linkname GetMemoryUse C.GC_get_memory_use
|
||||||
|
func GetMemoryUse() uintptr
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname EnableIncremental C.GC_enable_incremental
|
||||||
|
func EnableIncremental()
|
||||||
|
|
||||||
|
//go:linkname IsIncrementalMode C.GC_is_incremental_mode
|
||||||
|
func IsIncrementalMode() c.Int
|
||||||
|
|
||||||
|
//go:linkname IncrementalProtectionNeeds C.GC_incremental_protection_needs
|
||||||
|
func IncrementalProtectionNeeds() c.Int
|
||||||
|
|
||||||
|
//go:linkname StartIncrementalCollection C.GC_start_incremental_collection
|
||||||
|
func StartIncrementalCollection()
|
||||||
|
|
||||||
|
//go:linkname CollectALittle C.GC_collect_a_little
|
||||||
|
func CollectALittle()
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
17
c/bitcast/_cast/cast.c
Normal file
17
c/bitcast/_cast/cast.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
typedef union {
|
||||||
|
double d;
|
||||||
|
float f;
|
||||||
|
long v;
|
||||||
|
} castUnion;
|
||||||
|
|
||||||
|
double llgoToFloat64(long v) {
|
||||||
|
castUnion k;
|
||||||
|
k.v = v;
|
||||||
|
return k.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
float llgoToFloat32(long v) {
|
||||||
|
castUnion k;
|
||||||
|
k.v = v;
|
||||||
|
return k.f;
|
||||||
|
}
|
||||||
30
c/bitcast/bitcast.go
Normal file
30
c/bitcast/bitcast.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bitcast
|
||||||
|
|
||||||
|
import _ "unsafe"
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoFiles = "_cast/cast.c"
|
||||||
|
LLGoPackage = "link"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:linkname ToFloat64 C.llgoToFloat64
|
||||||
|
func ToFloat64(v uintptr) float64
|
||||||
|
|
||||||
|
//go:linkname ToFloat32 C.llgoToFloat32
|
||||||
|
func ToFloat32(v uintptr) float32
|
||||||
156
c/c.go
156
c/c.go
@@ -17,6 +17,9 @@
|
|||||||
package c
|
package c
|
||||||
|
|
||||||
// typedef unsigned int uint;
|
// typedef unsigned int uint;
|
||||||
|
// typedef unsigned long ulong;
|
||||||
|
// typedef unsigned long long ulonglong;
|
||||||
|
// typedef long long longlong;
|
||||||
import "C"
|
import "C"
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
@@ -25,19 +28,25 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
Void = [0]byte
|
||||||
Char = int8
|
Char = int8
|
||||||
Int = C.int
|
|
||||||
Uint = C.uint
|
|
||||||
Long = int32
|
|
||||||
Ulong = uint32
|
|
||||||
LongLong = int64
|
|
||||||
UlongLong = uint64
|
|
||||||
Float = float32
|
Float = float32
|
||||||
Double = float64
|
Double = float64
|
||||||
Pointer = unsafe.Pointer
|
Pointer = unsafe.Pointer
|
||||||
FilePtr = unsafe.Pointer
|
FilePtr = unsafe.Pointer
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Int C.int
|
||||||
|
Uint C.uint
|
||||||
|
|
||||||
|
Long C.long
|
||||||
|
Ulong C.ulong
|
||||||
|
|
||||||
|
LongLong C.longlong
|
||||||
|
UlongLong C.ulonglong
|
||||||
|
)
|
||||||
|
|
||||||
type integer interface {
|
type integer interface {
|
||||||
~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64
|
~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64
|
||||||
}
|
}
|
||||||
@@ -45,8 +54,11 @@ type integer interface {
|
|||||||
//go:linkname Str llgo.cstr
|
//go:linkname Str llgo.cstr
|
||||||
func Str(string) *Char
|
func Str(string) *Char
|
||||||
|
|
||||||
|
//go:linkname Func llgo.funcAddr
|
||||||
|
func Func(any) Pointer
|
||||||
|
|
||||||
// llgo:link Advance llgo.advance
|
// llgo:link Advance llgo.advance
|
||||||
func Advance[PtrT any](ptr PtrT, offset int) PtrT { return ptr }
|
func Advance[PtrT any, I integer](ptr PtrT, offset I) PtrT { return ptr }
|
||||||
|
|
||||||
// llgo:link Index llgo.index
|
// llgo:link Index llgo.index
|
||||||
func Index[T any, I integer](ptr *T, offset I) T { return *ptr }
|
func Index[T any, I integer](ptr *T, offset I) T { return *ptr }
|
||||||
@@ -57,27 +69,114 @@ func Alloca(size uintptr) Pointer
|
|||||||
//go:linkname AllocaCStr llgo.allocaCStr
|
//go:linkname AllocaCStr llgo.allocaCStr
|
||||||
func AllocaCStr(s string) *Char
|
func AllocaCStr(s string) *Char
|
||||||
|
|
||||||
//go:linkname Unreachable llgo.unreachable
|
//go:linkname AllocaCStrs llgo.allocaCStrs
|
||||||
func Unreachable()
|
func AllocaCStrs(strs []string, endWithNil bool) **Char
|
||||||
|
|
||||||
|
// TODO(xsw):
|
||||||
|
// llgo:link AllocaNew llgo.allocaNew
|
||||||
|
func AllocaNew[T any]() *T { return nil }
|
||||||
|
|
||||||
//go:linkname Malloc C.malloc
|
//go:linkname Malloc C.malloc
|
||||||
func Malloc(size uintptr) Pointer
|
func Malloc(size uintptr) Pointer
|
||||||
|
|
||||||
|
//go:linkname Free C.free
|
||||||
|
func Free(ptr Pointer)
|
||||||
|
|
||||||
//go:linkname Memcpy C.memcpy
|
//go:linkname Memcpy C.memcpy
|
||||||
func Memcpy(dst, src Pointer, n uintptr) Pointer
|
func Memcpy(dst, src Pointer, n uintptr) Pointer
|
||||||
|
|
||||||
|
//go:linkname Memmove C.memmove
|
||||||
|
func Memmove(dst, src Pointer, n uintptr) Pointer
|
||||||
|
|
||||||
//go:linkname Memset C.memset
|
//go:linkname Memset C.memset
|
||||||
func Memset(s Pointer, c Int, n uintptr) Pointer
|
func Memset(s Pointer, c Int, n uintptr) Pointer
|
||||||
|
|
||||||
|
//go:linkname Memchr C.memchr
|
||||||
|
func Memchr(s Pointer, c Int, n uintptr) Pointer
|
||||||
|
|
||||||
|
//go:linkname Memcmp C.memcmp
|
||||||
|
func Memcmp(s1, s2 Pointer, n uintptr) Int
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname Strlen C.strlen
|
||||||
|
func Strlen(s *Char) uintptr
|
||||||
|
|
||||||
|
//go:linkname Strcpy C.strcpy
|
||||||
|
func Strcpy(dst, src *Char) *Char
|
||||||
|
|
||||||
|
//go:linkname Strncpy C.strncpy
|
||||||
|
func Strncpy(dst, src *Char, n uintptr) *Char
|
||||||
|
|
||||||
|
//go:linkname Strcat C.strcat
|
||||||
|
func Strcat(dst, src *Char) *Char
|
||||||
|
|
||||||
|
//go:linkname Strncat C.strncat
|
||||||
|
func Strncat(dst, src *Char, n uintptr) *Char
|
||||||
|
|
||||||
|
//go:linkname Strcmp C.strcmp
|
||||||
|
func Strcmp(s1, s2 *Char) Int
|
||||||
|
|
||||||
|
//go:linkname Strncmp C.strncmp
|
||||||
|
func Strncmp(s1, s2 *Char, n uintptr) Int
|
||||||
|
|
||||||
|
//go:linkname Strchr C.strchr
|
||||||
|
func Strchr(s *Char, c Int) *Char
|
||||||
|
|
||||||
|
//go:linkname Strrchr C.strrchr
|
||||||
|
func Strrchr(s *Char, c Int) *Char
|
||||||
|
|
||||||
|
//go:linkname Strstr C.strstr
|
||||||
|
func Strstr(s1, s2 *Char) *Char
|
||||||
|
|
||||||
|
//go:linkname Strdup C.strdup
|
||||||
|
func Strdup(s *Char) *Char
|
||||||
|
|
||||||
|
//go:linkname Strndup C.strndup
|
||||||
|
func Strndup(s *Char, n uintptr) *Char
|
||||||
|
|
||||||
|
//go:linkname Strtok C.strtok
|
||||||
|
func Strtok(s, delim *Char) *Char
|
||||||
|
|
||||||
|
//go:linkname Strerror C.strerror
|
||||||
|
func Strerror(errnum Int) *Char
|
||||||
|
|
||||||
|
//go:linkname Sprintf C.sprintf
|
||||||
|
func Sprintf(s *Char, format *Char, __llgo_va_list ...any) Int
|
||||||
|
|
||||||
|
//go:linkname Snprintf C.snprintf
|
||||||
|
func Snprintf(s *Char, n uintptr, format *Char, __llgo_va_list ...any) Int
|
||||||
|
|
||||||
|
//go:linkname Vsnprintf C.vsnprintf
|
||||||
|
func Vsnprintf(s *Char, n uintptr, format *Char, ap Pointer) Int
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// GoString converts a C string to a Go string.
|
||||||
|
// TODO(xsw): any => int
|
||||||
|
//
|
||||||
|
//go:linkname GoString llgo.string
|
||||||
|
func GoString(cstr *Char, __llgo_va_list /* n */ ...any) string
|
||||||
|
|
||||||
//go:linkname GoStringData llgo.stringData
|
//go:linkname GoStringData llgo.stringData
|
||||||
func GoStringData(string) *Char
|
func GoStringData(string) *Char
|
||||||
|
|
||||||
|
//go:linkname GoDeferData llgo.deferData
|
||||||
|
func GoDeferData() Pointer
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
//go:linkname Remove C.remove
|
//go:linkname AllocaSigjmpBuf llgo.sigjmpbuf
|
||||||
func Remove(path *Char) Int
|
func AllocaSigjmpBuf() Pointer
|
||||||
|
|
||||||
|
//go:linkname Sigsetjmp llgo.sigsetjmp
|
||||||
|
func Sigsetjmp(jb Pointer, savemask Int) Int
|
||||||
|
|
||||||
|
//go:linkname Siglongjmp llgo.siglongjmp
|
||||||
|
func Siglongjmp(jb Pointer, retval Int)
|
||||||
|
|
||||||
|
//go:linkname Unreachable llgo.unreachable
|
||||||
|
func Unreachable()
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -94,14 +193,10 @@ func Qsort(base Pointer, count, elem uintptr, compar func(a, b Pointer) Int)
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
//go:linkname Stdin __stdinp
|
//go:linkname Atoi C.atoi
|
||||||
var Stdin FilePtr
|
func Atoi(s *Char) Int
|
||||||
|
|
||||||
//go:linkname Stdout __stdoutp
|
// -----------------------------------------------------------------------------
|
||||||
var Stdout FilePtr
|
|
||||||
|
|
||||||
//go:linkname Stderr __stderrp
|
|
||||||
var Stderr FilePtr
|
|
||||||
|
|
||||||
//go:linkname Printf C.printf
|
//go:linkname Printf C.printf
|
||||||
func Printf(format *Char, __llgo_va_list ...any) Int
|
func Printf(format *Char, __llgo_va_list ...any) Int
|
||||||
@@ -109,10 +204,31 @@ func Printf(format *Char, __llgo_va_list ...any) Int
|
|||||||
//go:linkname Fprintf C.fprintf
|
//go:linkname Fprintf C.fprintf
|
||||||
func Fprintf(fp FilePtr, format *Char, __llgo_va_list ...any) Int
|
func Fprintf(fp FilePtr, format *Char, __llgo_va_list ...any) Int
|
||||||
|
|
||||||
|
//go:linkname Fwrite C.fwrite
|
||||||
|
func Fwrite(data Pointer, size, count uintptr, fp FilePtr) uintptr
|
||||||
|
|
||||||
|
//go:linkname Fputc C.fputc
|
||||||
|
func Fputc(c Int, fp FilePtr) Int
|
||||||
|
|
||||||
|
//go:linkname Fputs C.fputs
|
||||||
|
func Fputs(s *Char, fp FilePtr) Int
|
||||||
|
|
||||||
|
//go:linkname Fflush C.fflush
|
||||||
|
func Fflush(fp FilePtr) Int
|
||||||
|
|
||||||
|
//go:linkname Fopen C.fopen
|
||||||
|
func Fopen(c *Char, mod *Char) FilePtr
|
||||||
|
|
||||||
|
//go:linkname Fclose C.fclose
|
||||||
|
func Fclose(fp FilePtr) Int
|
||||||
|
|
||||||
|
//go:linkname Perror C.perror
|
||||||
|
func Perror(s *Char)
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
//go:linkname Time C.time
|
//go:linkname Usleep C.usleep
|
||||||
func Time(*int32) int32
|
func Usleep(useconds Uint) Int
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
31
c/c_default.go
Normal file
31
c/c_default.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
//go:build !linux
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package c
|
||||||
|
|
||||||
|
import _ "unsafe"
|
||||||
|
|
||||||
|
//go:linkname Stdin __stdinp
|
||||||
|
var Stdin FilePtr
|
||||||
|
|
||||||
|
//go:linkname Stdout __stdoutp
|
||||||
|
var Stdout FilePtr
|
||||||
|
|
||||||
|
//go:linkname Stderr __stderrp
|
||||||
|
var Stderr FilePtr
|
||||||
31
c/c_linux.go
Normal file
31
c/c_linux.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package c
|
||||||
|
|
||||||
|
import _ "unsafe"
|
||||||
|
|
||||||
|
//go:linkname Stdin stdin
|
||||||
|
var Stdin FilePtr
|
||||||
|
|
||||||
|
//go:linkname Stdout stdout
|
||||||
|
var Stdout FilePtr
|
||||||
|
|
||||||
|
//go:linkname Stderr stderr
|
||||||
|
var Stderr FilePtr
|
||||||
@@ -1,22 +1,18 @@
|
|||||||
LLGo wrapper of DaveGamble/cJSON
|
LLGo wrapper of DaveGamble/cJSON
|
||||||
=====
|
=====
|
||||||
[](https://github.com/goplus/cjson/actions/workflows/go.yml)
|
|
||||||
[](https://github.com/goplus/cjson/releases)
|
|
||||||
[](https://pkg.go.dev/github.com/goplus/cjson)
|
|
||||||
[](https://github.com/goplus/llgo)
|
|
||||||
[](https://github.com/goplus/gop)
|
|
||||||
|
|
||||||
## How to install
|
## How to install
|
||||||
|
|
||||||
|
### on macOS (Homebrew)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/goplus/cjson.git
|
brew install cjson
|
||||||
cd cjson
|
```
|
||||||
git submodule init
|
|
||||||
git submodule update
|
### on Linux (Debian/Ubuntu)
|
||||||
mkdir build.dir
|
|
||||||
cd build.dir
|
```sh
|
||||||
cmake ../cJSON
|
apt-get install -y libcjson-dev
|
||||||
sudo make install
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Demos
|
## Demos
|
||||||
|
|||||||
@@ -22,6 +22,22 @@ func main() {
|
|||||||
|
|
||||||
mod.SetItem(c.Str("items"), syms)
|
mod.SetItem(c.Str("items"), syms)
|
||||||
|
|
||||||
c.Printf(c.Str("%s\n"), mod.CStr())
|
cstr := mod.CStr()
|
||||||
|
str := c.GoString(cstr)
|
||||||
|
c.Printf(c.Str("%s\n"), cstr)
|
||||||
|
cjson.FreeCStr(cstr)
|
||||||
|
|
||||||
|
mod.Delete()
|
||||||
|
|
||||||
|
cjsonLoad(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cjsonLoad(str string) {
|
||||||
|
mod := cjson.ParseString(str)
|
||||||
|
|
||||||
|
cstr := mod.Print()
|
||||||
|
c.Printf(c.Str("%s\n"), cstr)
|
||||||
|
cjson.FreeCStr(cstr)
|
||||||
|
|
||||||
mod.Delete()
|
mod.Delete()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,13 @@
|
|||||||
package cjson
|
package cjson
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LLGoPackage = "link: cjson"
|
LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
// llgo:type C
|
// llgo:type C
|
||||||
@@ -31,6 +31,20 @@ type JSON struct {
|
|||||||
Unused [0]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname Parse C.cJSON_Parse
|
||||||
|
func Parse(value *c.Char) *JSON
|
||||||
|
|
||||||
|
//go:linkname ParseWithLength C.cJSON_ParseWithLength
|
||||||
|
func ParseWithLength(value *byte, valueLength uintptr) *JSON
|
||||||
|
|
||||||
|
func ParseBytes(value []byte) *JSON {
|
||||||
|
return ParseWithLength(unsafe.SliceData(value), uintptr(len(value)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseString(value string) *JSON {
|
||||||
|
return ParseWithLength(unsafe.StringData(value), uintptr(len(value)))
|
||||||
|
}
|
||||||
|
|
||||||
//go:linkname Null C.cJSON_CreateNull
|
//go:linkname Null C.cJSON_CreateNull
|
||||||
func Null() *JSON
|
func Null() *JSON
|
||||||
|
|
||||||
@@ -119,3 +133,21 @@ func (o *JSON) PrintUnformatted() *c.Char { return nil }
|
|||||||
//
|
//
|
||||||
// llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered
|
// llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered
|
||||||
func (o *JSON) PrintBuffered(prebuffer c.Int, fmt c.Int) *c.Char { return nil }
|
func (o *JSON) PrintBuffered(prebuffer c.Int, fmt c.Int) *c.Char { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*JSON).GetObjectItemCaseSensitive C.cJSON_GetObjectItemCaseSensitive
|
||||||
|
func (o *JSON) GetObjectItemCaseSensitive(key *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*JSON).GetArraySize C.cJSON_GetArraySize
|
||||||
|
func (o *JSON) GetArraySize() c.Int { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*JSON).GetArrayItem C.cJSON_GetArrayItem
|
||||||
|
func (o *JSON) GetArrayItem(index c.Int) *JSON { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*JSON).GetStringValue C.cJSON_GetStringValue
|
||||||
|
func (o *JSON) GetStringValue() *c.Char { return nil }
|
||||||
|
|
||||||
|
//go:linkname Free C.cJSON_free
|
||||||
|
func Free(ptr unsafe.Pointer)
|
||||||
|
|
||||||
|
//go:linkname FreeCStr C.cJSON_free
|
||||||
|
func FreeCStr(*c.Char)
|
||||||
|
|||||||
Binary file not shown.
61
c/clang/_demo/castdump/astdump.go
Normal file
61
c/clang/_demo/castdump/astdump.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/clang"
|
||||||
|
)
|
||||||
|
|
||||||
|
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
|
||||||
|
depth := *(*c.Uint)(clientData)
|
||||||
|
printAST(cursor, depth+1)
|
||||||
|
return clang.ChildVisit_Continue
|
||||||
|
}
|
||||||
|
|
||||||
|
func printAST(cursor clang.Cursor, depth c.Uint) {
|
||||||
|
cursorKind := cursor.Kind.String()
|
||||||
|
|
||||||
|
cursorSpelling := cursor.String()
|
||||||
|
|
||||||
|
for i := c.Uint(0); i < depth; i++ {
|
||||||
|
c.Fputs(c.Str(" "), c.Stdout)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Printf(c.Str("%s: %s\n"), cursorKind.CStr(), cursorSpelling.CStr())
|
||||||
|
|
||||||
|
cursorKind.Dispose()
|
||||||
|
cursorSpelling.Dispose()
|
||||||
|
|
||||||
|
clang.VisitChildren(cursor, visit, c.Pointer(&depth))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if c.Argc != 2 {
|
||||||
|
fmt.Fprintln(os.Stderr, "Usage: castdump <headerFile>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sourceFile := *c.Advance(c.Argv, 1)
|
||||||
|
|
||||||
|
index := clang.CreateIndex(0, 0)
|
||||||
|
|
||||||
|
unit := index.ParseTranslationUnit(
|
||||||
|
sourceFile,
|
||||||
|
nil, 0,
|
||||||
|
nil, 0,
|
||||||
|
clang.TranslationUnit_None,
|
||||||
|
)
|
||||||
|
|
||||||
|
if unit == nil {
|
||||||
|
println("Unable to parse translation unit. Quitting.")
|
||||||
|
c.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor := unit.Cursor()
|
||||||
|
|
||||||
|
printAST(cursor, 0)
|
||||||
|
|
||||||
|
unit.Dispose()
|
||||||
|
index.Dispose()
|
||||||
|
}
|
||||||
131
c/clang/_demo/symboldump/symboldump.go
Normal file
131
c/clang/_demo/symboldump/symboldump.go
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/clang"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
namespaceName string
|
||||||
|
className string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newContext() *Context {
|
||||||
|
return &Context{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) setNamespaceName(name string) {
|
||||||
|
c.namespaceName = name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) setClassName(name string) {
|
||||||
|
c.className = name
|
||||||
|
}
|
||||||
|
|
||||||
|
var context = newContext()
|
||||||
|
|
||||||
|
func print_cursor_info(cursor clang.Cursor) {
|
||||||
|
loc := cursor.Location()
|
||||||
|
var file clang.File
|
||||||
|
var line, column c.Uint
|
||||||
|
|
||||||
|
loc.SpellingLocation(&file, &line, &column, nil)
|
||||||
|
filename := file.FileName()
|
||||||
|
|
||||||
|
c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column)
|
||||||
|
|
||||||
|
cursorStr := cursor.String()
|
||||||
|
symbol := cursor.Mangling()
|
||||||
|
defer symbol.Dispose()
|
||||||
|
defer cursorStr.Dispose()
|
||||||
|
defer filename.Dispose()
|
||||||
|
|
||||||
|
if context.namespaceName != "" && context.className != "" {
|
||||||
|
fmt.Printf("%s:%s:", context.namespaceName, context.className)
|
||||||
|
} else if context.namespaceName != "" {
|
||||||
|
fmt.Printf("%s:", context.namespaceName)
|
||||||
|
}
|
||||||
|
c.Printf(c.Str("%s\n"), cursorStr.CStr())
|
||||||
|
|
||||||
|
if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl {
|
||||||
|
c.Printf(c.Str("symbol:%s\n"), symbol.CStr())
|
||||||
|
|
||||||
|
typeStr := cursor.ResultType().String()
|
||||||
|
defer typeStr.Dispose()
|
||||||
|
c.Printf(c.Str("Return Type: %s\n"), typeStr.CStr())
|
||||||
|
c.Printf(c.Str("Parameters(%d): ( "), cursor.NumArguments())
|
||||||
|
|
||||||
|
for i := 0; i < int(cursor.NumArguments()); i++ {
|
||||||
|
argCurSor := cursor.Argument(c.Uint(i))
|
||||||
|
argType := argCurSor.Type().String()
|
||||||
|
argName := argCurSor.String()
|
||||||
|
c.Printf(c.Str("%s %s"), argType.CStr(), argName.CStr())
|
||||||
|
if i < int(cursor.NumArguments())-1 {
|
||||||
|
c.Printf(c.Str(", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
argType.Dispose()
|
||||||
|
argName.Dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Printf(c.Str(" )\n"))
|
||||||
|
println("--------------------------------")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
|
||||||
|
if cursor.Kind == clang.Namespace {
|
||||||
|
nameStr := cursor.String()
|
||||||
|
context.setNamespaceName(c.GoString(nameStr.CStr()))
|
||||||
|
clang.VisitChildren(cursor, visit, nil)
|
||||||
|
context.setNamespaceName("")
|
||||||
|
} else if cursor.Kind == clang.ClassDecl {
|
||||||
|
nameStr := cursor.String()
|
||||||
|
context.setClassName(c.GoString(nameStr.CStr()))
|
||||||
|
clang.VisitChildren(cursor, visit, nil)
|
||||||
|
context.setClassName("")
|
||||||
|
} else if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl {
|
||||||
|
print_cursor_info(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
return clang.ChildVisit_Continue
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse(filename *c.Char) {
|
||||||
|
index := clang.CreateIndex(0, 0)
|
||||||
|
args := make([]*c.Char, 3)
|
||||||
|
args[0] = c.Str("-x")
|
||||||
|
args[1] = c.Str("c++")
|
||||||
|
args[2] = c.Str("-std=c++11")
|
||||||
|
unit := index.ParseTranslationUnit(
|
||||||
|
filename,
|
||||||
|
unsafe.SliceData(args), 3,
|
||||||
|
nil, 0,
|
||||||
|
clang.TranslationUnit_None,
|
||||||
|
)
|
||||||
|
|
||||||
|
if unit == nil {
|
||||||
|
println("Unable to parse translation unit. Quitting.")
|
||||||
|
c.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor := unit.Cursor()
|
||||||
|
|
||||||
|
clang.VisitChildren(cursor, visit, nil)
|
||||||
|
unit.Dispose()
|
||||||
|
index.Dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if c.Argc != 2 {
|
||||||
|
fmt.Fprintln(os.Stderr, "Usage: <C++ header file>\n")
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
sourceFile := *c.Advance(c.Argv, 1)
|
||||||
|
parse(sourceFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
50
c/clang/_wrap/cursor.cpp
Normal file
50
c/clang/_wrap/cursor.cpp
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include <clang-c/Index.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef enum CXChildVisitResult (*wrap_CXCursorVisitor)(CXCursor *cursor, CXCursor *parent, CXClientData client_data);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CXClientData data;
|
||||||
|
wrap_CXCursorVisitor visitor;
|
||||||
|
} wrap_data;
|
||||||
|
|
||||||
|
CXChildVisitResult wrap_visitor(CXCursor cursor, CXCursor parent, CXClientData data) {
|
||||||
|
wrap_data *d = (wrap_data *)(data);
|
||||||
|
return d->visitor(&cursor, &parent, d->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
CXString wrap_clang_getCursorSpelling(CXCursor *cur) { return clang_getCursorSpelling(*cur); }
|
||||||
|
|
||||||
|
CXString wrap_clang_Cursor_getMangling(CXCursor *cur) { return clang_Cursor_getMangling(*cur); }
|
||||||
|
|
||||||
|
int wrap_clang_Cursor_getNumArguments(CXCursor *cur) { return clang_Cursor_getNumArguments(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_Cursor_getArgument(CXCursor *C, unsigned i, CXCursor *argCur) {
|
||||||
|
*argCur = clang_Cursor_getArgument(*C, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur) {
|
||||||
|
*cur = clang_getTranslationUnitCursor(uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); }
|
||||||
|
|
||||||
|
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
|
||||||
|
unsigned *offset) {
|
||||||
|
clang_getSpellingLocation(*loc, file, line, column, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor, CXClientData client_data) {
|
||||||
|
wrap_data data = {client_data, visitor};
|
||||||
|
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
7
c/clang/_wrap/llgo_check.cpp
Normal file
7
c/clang/_wrap/llgo_check.cpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <clang-c/Index.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
printf("sizeof(clang.Cursor) = %lu\n", sizeof(CXCursor));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
16
c/clang/_wrap/llgo_check.go
Normal file
16
c/clang/_wrap/llgo_check.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/clang"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoCFlags = "-I$(llvm-config --includedir)"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c.Printf(c.Str("sizeof(clang.Cursor) = %lu\n"), unsafe.Sizeof(clang.Cursor{}))
|
||||||
|
}
|
||||||
59
c/clang/basic.go
Normal file
59
c/clang/basic.go
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package clang
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A character string.
|
||||||
|
*
|
||||||
|
* The \c CXString type is used to return strings from the interface when
|
||||||
|
* the ownership of that string might differ from one call to the next.
|
||||||
|
* Use \c clang_getCString() to retrieve the string data and, once finished
|
||||||
|
* with the string data, call \c clang_disposeString() to free the string.
|
||||||
|
*/
|
||||||
|
type String struct {
|
||||||
|
Data c.Pointer
|
||||||
|
PrivateFlags c.Uint
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the character data associated with the given string.
|
||||||
|
*/
|
||||||
|
// llgo:link String.CStr C.clang_getCString
|
||||||
|
func (String) CStr() *c.Char { return nil }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the given string.
|
||||||
|
*/
|
||||||
|
// llgo:link String.Dispose C.clang_disposeString
|
||||||
|
func (String) Dispose() {}
|
||||||
|
|
||||||
|
type StringSet struct {
|
||||||
|
Strings *String
|
||||||
|
Count c.Uint
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the given string set.
|
||||||
|
*/
|
||||||
|
// llgo:link (*StringSet).Dispose C.clang_disposeStringSet
|
||||||
|
func (*StringSet) Dispose() {}
|
||||||
1520
c/clang/clang.go
Normal file
1520
c/clang/clang.go
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user