Compare commits
826 Commits
dev
...
balsoft/pa
Author | SHA1 | Date | |
---|---|---|---|
7273e38a0f | |||
a5874d7c2e | |||
5105e0e692 | |||
977bb1095c | |||
db9371bfa6 | |||
417b427f6d | |||
|
7f3a662cbc | ||
|
ee86539685 | ||
|
c44a35d4d1 | ||
|
04724a1db2 | ||
|
7f6820c368 | ||
|
619a7de432 | ||
|
d5154dff36 | ||
|
7c43cd9574 | ||
|
0b1590e324 | ||
|
283f41738d | ||
|
5d8f2c8526 | ||
|
15fc6f25fd | ||
|
b48b461c28 | ||
|
f0005c982a | ||
|
fd862676b3 | ||
|
d2a020434e | ||
|
28714af8cc | ||
|
f2a3f0b579 | ||
|
da6ca97a9d | ||
|
5533b07270 | ||
|
f554551f75 | ||
|
3037be689b | ||
|
1828fd6d46 | ||
|
1c684a791c | ||
|
7fa947e92e | ||
|
5e0cf40ea7 | ||
|
41a49da1e0 | ||
|
6e2f592094 | ||
|
1a948bcae7 | ||
|
26d11eea19 | ||
|
fe929fbe70 | ||
|
ba66f6e8e4 | ||
|
28e16ca068 | ||
|
78c408b76a | ||
|
f1938eb2af | ||
|
31b5ffbeef | ||
|
a1a846b554 | ||
|
820d73f345 | ||
|
99321a59bb | ||
|
0fbfd134ec | ||
|
2a8cda17ce | ||
|
38c32f01d4 | ||
|
107018e6f3 | ||
|
08a0eb55d1 | ||
|
31274e1507 | ||
|
9f29dab195 | ||
|
6bd5d9ef84 | ||
|
226b7264aa | ||
|
b5e5bc25a1 | ||
|
3233270dba | ||
|
58e5128142 | ||
|
508b111374 | ||
|
20014a7926 | ||
|
a11e92af60 | ||
|
5737cd5686 | ||
|
e5ec32f46a | ||
|
c26bc044ee | ||
|
ba3c0a76d9 | ||
|
29bc1721d1 | ||
|
bf6cc6ca16 | ||
|
65fc5bec75 | ||
|
24cc24b0d7 | ||
|
b35a28853b | ||
|
583d7f8997 | ||
|
03b89bc5b7 | ||
|
8d61a36918 | ||
|
9f124bf5af | ||
|
9cf2e0cf97 | ||
|
20de97c5c6 | ||
|
44defb2114 | ||
|
19f05f5afc | ||
|
e701e196fe | ||
|
9d81ecf353 | ||
|
1f7af3c8cb | ||
|
9b95006a71 | ||
|
41403426b0 | ||
|
f3fbfb49a1 | ||
|
95707100c2 | ||
|
9856476ebf | ||
|
923a5bb9fe | ||
|
d380e46737 | ||
|
113a2425a4 | ||
|
11fdc0afa1 | ||
|
5c643a3b63 | ||
|
67de82edec | ||
|
1536590edb | ||
|
bc155bea16 | ||
|
c8b4c2bd35 | ||
|
e1a3903e18 | ||
|
020b3ba334 | ||
|
19e1018620 | ||
|
c497da5841 | ||
|
916d9897bd | ||
|
7ff8226e1b | ||
|
6dc1eb23cd | ||
|
b62cd58add | ||
|
eace901195 | ||
|
e6299a50ff | ||
|
b4e6231340 | ||
|
2f269e32ea | ||
|
d928aaa39c | ||
|
6e862bf5b9 | ||
|
1ed617c7d0 | ||
|
a8b898d396 | ||
|
83cc13dd48 | ||
|
f3c537d2ca | ||
|
ad7650ea48 | ||
|
0cec59988e | ||
|
00b4dabe36 | ||
|
efe1afb61d | ||
|
c603cd399d | ||
|
017db45f8d | ||
|
cb40392554 | ||
|
510cda6613 | ||
|
0c0889f514 | ||
|
9b4e881827 | ||
|
b905c49579 | ||
|
fcb6647551 | ||
|
0b0de1ea59 | ||
|
ca50603a7c | ||
|
c489989cd3 | ||
|
61898eb52d | ||
|
42c0baa00b | ||
|
99448ef371 | ||
|
cbf1680e36 | ||
|
ec2c1571af | ||
|
ab773a56a4 | ||
|
567515a5ce | ||
|
f25c9bd33a | ||
|
93d96b2e7b | ||
|
2893fc0412 | ||
|
43b70361bc | ||
|
d0071ca0e8 | ||
|
2f0ffc10ac | ||
|
3656d9e1ff | ||
|
6c50ec0ed1 | ||
|
42893548c5 | ||
|
e1177de402 | ||
|
6a3ab09f7c | ||
|
728cf3f1ba | ||
|
01423174b2 | ||
|
f9b3887753 | ||
|
50a1e48f28 | ||
|
8a551114c3 | ||
|
4026411e10 | ||
|
21904f7e53 | ||
|
2659570b8a | ||
|
2a9ef440db | ||
|
ca2ec3d795 | ||
|
bff67e3779 | ||
|
ead7832c50 | ||
|
e9db0afffa | ||
|
b304b82e11 | ||
|
d1b7388550 | ||
|
b1ccaef07e | ||
|
bc259fcde7 | ||
|
12f7b7c904 | ||
|
0dc4315359 | ||
|
e319e2d2cd | ||
|
351018f8d2 | ||
|
9e02cb2969 | ||
|
1bd7af80b8 | ||
|
5589d47123 | ||
|
a4e414bd76 | ||
|
2eb16c2c56 | ||
|
b07c57c159 | ||
|
942000065b | ||
|
c1d211d98c | ||
|
1cc64d6812 | ||
|
283dcf418a | ||
|
bd8a57df44 | ||
|
018e269b2e | ||
|
65161148d3 | ||
|
2351dda44e | ||
|
362e33c7f9 | ||
|
27d7856e52 | ||
|
d743605aee | ||
|
b4bf0ae159 | ||
|
db051e7d3b | ||
|
7a2e4b35d2 | ||
|
242d99fd5e | ||
|
0cf9dc576e | ||
|
ae4a13b63f | ||
|
5cbeab0a3b | ||
|
2b790b0ebc | ||
|
72bff930cc | ||
|
591f28014d | ||
|
64c6b8896d | ||
|
19f02a4b36 | ||
|
424a0b0ba7 | ||
|
2c5f1f0e2b | ||
|
60c4f591fb | ||
|
18e645c73f | ||
|
8e558041f0 | ||
|
02d66cf536 | ||
|
aa849f6dcb | ||
|
c539f2d5f6 | ||
|
d34b345edc | ||
|
3ec21a8762 | ||
|
77eb1335a1 | ||
|
c379d1078e | ||
|
e42381fb84 | ||
|
fb4a888867 | ||
|
94039c4d65 | ||
|
bc5a5cd75b | ||
|
8f4ed11539 | ||
|
92e6d55aa8 | ||
|
e26b142c3c | ||
|
8ce7ae0f27 | ||
|
46bd0315e2 | ||
|
36df068dfc | ||
ae8a3752ef | |||
|
027f73fa01 | ||
|
98487d8bb7 | ||
|
c2e4f2f36d | ||
|
c8b8492ed9 | ||
|
988776bd31 | ||
|
b3da13251c | ||
|
429a1dc412 | ||
|
4969b34225 | ||
|
3fd93fc7b5 | ||
|
c6b95bf07a | ||
|
05923fbb4c | ||
|
a7f6de9fac | ||
|
d53be83490 | ||
|
9eabec28dc | ||
ed3f2dcbff | |||
|
1c5ea4b3f2 | ||
|
195175287a | ||
|
c6ad617524 | ||
|
9ea4c97dd4 | ||
|
8937b762cd | ||
|
44ee2be055 | ||
|
0b8effbf2b | ||
|
f25456a7a6 | ||
|
c110670a38 | ||
|
dd4abbf46a | ||
|
a4e2fe2447 | ||
|
97e33a99da | ||
|
dfcccff748 | ||
|
b044a4fbc5 | ||
|
5f4e1b83c7 | ||
|
9e5ae133d2 | ||
|
fa7cc825eb | ||
|
7872a1d4bc | ||
|
5365f97f47 | ||
|
62e9cd5796 | ||
|
fd26ad82cd | ||
|
82a8ee5697 | ||
|
358ae530b8 | ||
|
c57f499fea | ||
|
a0d2eb733d | ||
|
29b483aa0c | ||
|
eb2facfc11 | ||
|
22699525b3 | ||
|
582dacf5d5 | ||
|
612694d603 | ||
|
86a30b1e6f | ||
|
34d726c2f3 | ||
|
d810ccc921 | ||
|
816afdd1b8 | ||
|
5470893f68 | ||
|
206f52d8e6 | ||
|
dfbba95cbf | ||
|
94a3c1c3da | ||
|
a688a1afe4 | ||
|
cee9cc841e | ||
|
a58dca7097 | ||
|
d7b4a97731 | ||
046f31f7c1 | |||
|
aee524ffc4 | ||
cb11295405 | |||
|
4382c3c042 | ||
|
c770aa3541 | ||
|
eea9d8f627 | ||
|
838fdf6a5f | ||
|
2d65ba638e | ||
|
8d291b2d2e | ||
|
b76d44e9f2 | ||
|
d99d1bbe66 | ||
|
534447dc9e | ||
|
bfac7f3b0a | ||
|
77920a1c58 | ||
|
574903ed2f | ||
|
be9478bec1 | ||
|
cb39217c8c | ||
|
63086db0f1 | ||
|
db0fdf4abd | ||
|
49d2c870ae | ||
|
623e6f1251 | ||
|
54cefddd51 | ||
|
9495901b75 | ||
|
3dd4568a3d | ||
|
4c2a271898 | ||
|
a952cc496d | ||
|
57caa4ea85 | ||
|
6f56b297f2 | ||
|
5896b2a63a | ||
|
a6972bf28b | ||
|
8606528ddb | ||
|
3bec051115 | ||
|
c67fc4aa34 | ||
|
adee60c444 | ||
|
64076d882b | ||
|
fbc854f4d1 | ||
|
c30ade3b85 | ||
|
5cfe6e893c | ||
|
10b373e8fc | ||
|
f7069de52d | ||
|
18bf6f92e4 | ||
|
ac124b0c4d | ||
|
7d65000e2a | ||
|
2b0f3ce969 | ||
|
2032485b60 | ||
|
c380729785 | ||
|
8f529a059a | ||
|
cc615f1c9f | ||
|
b29c667901 | ||
|
81358db582 | ||
|
7257aaaff4 | ||
|
861ab57a43 | ||
|
c8ed8c38cc | ||
|
4c56515d6b | ||
|
dc17676447 | ||
|
d18837a6a6 | ||
|
a28b81379f | ||
|
562f08dabc | ||
|
62fe3b793a | ||
|
c82e3ffa6a | ||
|
7fbac4dc1b | ||
|
08ee216f1b | ||
|
13eae4be18 | ||
|
267e282174 | ||
|
9d0da34f96 | ||
|
a5419d0158 | ||
|
f29cf5a612 | ||
|
5b398b47c2 | ||
|
fa1185c20e | ||
|
4d51aa62cb | ||
|
0c9aeeeb64 | ||
|
74dab76fb4 | ||
|
e42e79eff3 | ||
|
37a3fde6fd | ||
|
4d16b006c6 | ||
|
4e984850c1 | ||
|
8d781eebca | ||
|
2112e5dee7 | ||
|
b12e9a5baa | ||
|
db3533bcd4 | ||
|
c376650ee5 | ||
|
435716fb34 | ||
|
2d43f67893 | ||
|
1681b33b12 | ||
|
2d74681c96 | ||
|
3264277310 | ||
|
6cab827f17 | ||
|
e2bf0f6466 | ||
|
4a860830b9 | ||
|
d5a6f46452 | ||
|
b2ee003577 | ||
|
4cb34a1d7e | ||
|
2633d732a3 | ||
|
36e4c426c9 | ||
|
69a007cca9 | ||
|
6dd296260e | ||
|
e9f5c3e1ae | ||
|
d644872729 | ||
|
612f8aaf5e | ||
|
d5983de522 | ||
|
b7da8e3fd4 | ||
|
54a0fb63d8 | ||
|
4779d12295 | ||
|
96f9c032c0 | ||
|
daf6971fd1 | ||
|
e661416056 | ||
fcfa2944c6 | |||
|
294e048aff | ||
|
c19c34d5d3 | ||
|
d53d4829b5 | ||
|
9eb603a1e8 | ||
|
78166c13d3 | ||
|
6d6556107a | ||
|
8e2a889b1d | ||
|
b816a2e529 | ||
|
dba6335bfc | ||
1fe9b29732 | |||
|
a4831a05e7 | ||
|
bc2d95d6f6 | ||
|
66c1e51cb2 | ||
|
f455fa2376 | ||
|
2de18b8727 | ||
|
705c29aeed | ||
|
d4801d942a | ||
|
cade57a47c | ||
|
88c652a25f | ||
|
a4128d037b | ||
|
a0c6048633 | ||
|
b88348ce60 | ||
|
d44b5a7af0 | ||
|
daa1c18573 | ||
|
851132528d | ||
|
ee5e484bf4 | ||
|
008f228ed7 | ||
|
92069077df | ||
|
9a017e5f63 | ||
|
b2d80e0154 | ||
|
413dc7cc1b | ||
|
7db2c24bd3 | ||
|
0289565025 | ||
|
b97d2d4000 | ||
|
320e31cb41 | ||
|
5ae429c4ef | ||
|
5293b2951f | ||
|
42989944b3 | ||
|
85c08d8ad3 | ||
|
22b0c9ec46 | ||
|
11f1cf01ee | ||
|
b9ee504dd6 | ||
|
2bf34e9ff5 | ||
|
417bd0f5f8 | ||
|
8041ce5ddb | ||
76715ebee3 | |||
|
2a9a628861 | ||
|
041a48bc7b | ||
|
1a0db2fc87 | ||
|
41d1f5e1b0 | ||
|
9163caf3da | ||
|
2d88d2145e | ||
|
7992a4e507 | ||
|
6a3dab69a2 | ||
|
07320d181d | ||
|
a3e330da12 | ||
|
5ef842298d | ||
|
ecebfb37cc | ||
|
5e14528a9a | ||
|
a7c6eaf910 | ||
|
8b7594c2d1 | ||
|
0e48b5bb54 | ||
|
b871b7d64f | ||
|
c8b1ff0e9e | ||
b5d1cd6b5b | |||
3d78114b25 | |||
a14bf15e77 | |||
b522e50ce2 | |||
91f31f2914 | |||
|
d5089bfa13 | ||
b6aa71d6ac | |||
340622350d | |||
|
16bcee1aad | ||
5c2b9646ec | |||
85c7429f0c | |||
f970a9a536 | |||
e8a69cb498 | |||
|
a72d95d9a1 | ||
|
bd9b3cb012 | ||
|
36cecfb019 | ||
|
dd970385e4 | ||
|
0199f3e448 | ||
|
ea306bf685 | ||
|
e04918047c | ||
|
85dc95dc7b | ||
|
7f32937d6d | ||
|
a0f8bd941e | ||
|
e6e1bc5876 | ||
|
0f7fde19f5 | ||
|
fdb7697806 | ||
|
551bf176fe | ||
|
114a309aed | ||
|
6c8b76b3de | ||
|
f6ff6b85c4 | ||
|
281477bbaf | ||
|
2db55ae965 | ||
|
255e381e01 | ||
|
ae3a555c91 | ||
|
9ead5f2f24 | ||
|
2934e49f93 | ||
|
1c9240703c | ||
|
34b9ee14da | ||
|
c021254cd4 | ||
|
57f0106fd4 | ||
f7a2bffd77 | |||
|
b44da17ee0 | ||
|
7244b91c45 | ||
|
41eded82f4 | ||
|
9e81aaa1f8 | ||
|
0ccc637c9b | ||
|
937bc99738 | ||
|
f3ed135926 | ||
|
ec0a0dbd01 | ||
a2557d7893 | |||
|
44c85daee4 | ||
|
85aa1a21d1 | ||
|
7bcf46d3bc | ||
|
262f34f214 | ||
|
8c0275b42c | ||
|
599944343d | ||
|
673fb67c1c | ||
|
da5b9c1612 | ||
|
98d49959b7 | ||
|
546856e14a | ||
|
2b96bbbdc3 | ||
|
c307f251c8 | ||
|
f1c444da22 | ||
|
0160c1b7ef | ||
|
eb098d12e3 | ||
|
19866476d7 | ||
|
9eeac11628 | ||
|
736860611f | ||
|
a1c5b471fe | ||
|
5d06630b2c | ||
|
e93e3ccbdd | ||
|
ec99230c63 | ||
|
288e6646eb | ||
|
e0be6fc36f | ||
|
77b5e15088 | ||
|
c54d650a2a | ||
|
cadd0d66a9 | ||
|
7bbfa9ff97 | ||
|
38af497cc3 | ||
|
29de1278b4 | ||
|
ddb2eac6ca | ||
|
426a1b6620 | ||
|
51c043b7cb | ||
|
5891a6f4cc | ||
|
059a566d4b | ||
|
66aea1b8d1 | ||
|
0aa69ed35b | ||
|
8fdf9a8b95 | ||
|
0a44a22cac | ||
|
8e3230bf29 | ||
|
b54bcb8db7 | ||
|
fb2f3e89e7 | ||
|
1f6bc4fc6b | ||
|
9d200a1b56 | ||
|
3333742037 | ||
|
f4b9261104 | ||
|
2667c10990 | ||
|
716751553e | ||
|
82b3d634c1 | ||
|
62f97e2f7f | ||
|
b0998f417a | ||
|
8d59389f7d | ||
|
2c62f9d32e | ||
|
f4deb32561 | ||
|
71e0509910 | ||
|
61ef304a46 | ||
|
2372f30ed3 | ||
|
057bd19ca7 | ||
|
4587862da7 | ||
|
cf492f03cb | ||
|
9b1e66622a | ||
|
94b9404d1b | ||
|
dfb82aa479 | ||
|
40474dcc68 | ||
|
c8f3bb4f04 | ||
|
164a32a9b2 | ||
|
8e9ee21cd4 | ||
|
0580f21896 | ||
|
12cbc9ca07 | ||
|
a0b450a34d | ||
|
31858a7a24 | ||
edb3fce642 | |||
|
e467642f14 | ||
|
92d741f5f8 | ||
|
7bcf706fcc | ||
|
d0d495ccce | ||
|
6ce6ebfec3 | ||
|
de7864a500 | ||
|
005b7fd69b | ||
|
5c61bfaa95 | ||
|
877c86b6e4 | ||
|
56fe3b6021 | ||
|
94c35e15dd | ||
|
b05e7ef613 | ||
|
710f1699a6 | ||
|
0895467f74 | ||
|
6b00a60986 | ||
|
9618a48848 | ||
|
8e34c4a678 | ||
|
7dd63652cf | ||
|
f3777b4af8 | ||
|
ce5464f9af | ||
|
51eb1a2855 | ||
|
b62dfa1920 | ||
|
2d3b68f57b | ||
|
9de281e7ef | ||
|
8dfc8a0469 | ||
|
30f2581f8b | ||
|
ca3549bdee | ||
|
0e452ffbf1 | ||
|
c58e3220a7 | ||
|
b47b5b1c37 | ||
|
2a8edb53da | ||
|
1cbadbc7cf | ||
|
79f2df2314 | ||
|
1fbbc09313 | ||
|
d659b32169 | ||
|
3cb72f8ec2 | ||
|
c46210b656 | ||
|
eafbe83151 | ||
|
bd8cf09f9e | ||
|
e6cba7c34f | ||
|
f67bd010c4 | ||
|
3788dac613 | ||
|
54dadc33d6 | ||
|
0bf6d09e85 | ||
|
79270d6022 | ||
|
8066e4df26 | ||
|
16ecd532b9 | ||
|
5df005f4b7 | ||
|
c302a1a9d5 | ||
|
5323475097 | ||
|
40f2d41b13 | ||
|
173a0c4031 | ||
|
85222c1d65 | ||
|
c892c469f4 | ||
|
5622b52a36 | ||
|
5bed9dadef | ||
|
e94f445a51 | ||
|
5d35aaec58 | ||
|
2d7e177ba7 | ||
|
53cf214f80 | ||
|
f2a23029bd | ||
|
6acf91a3f2 | ||
|
11f4e6e3a6 | ||
|
f27bbb317e | ||
|
8848226b85 | ||
|
7a18cbd8fc | ||
|
c5c1e4d657 | ||
|
f547caa80f | ||
|
7b5acbcef0 | ||
|
7c29b075bb | ||
|
2a24290ed0 | ||
|
9796cd2e8f | ||
|
23912411e1 | ||
|
4e9ee0bcb2 | ||
|
0680633806 | ||
|
a2c03ad848 | ||
|
990ae0e3a8 | ||
|
fb7abe045f | ||
|
b7c3e77c82 | ||
|
1f0491e367 | ||
|
313afab565 | ||
|
422623ce1e | ||
|
3e447c40b7 | ||
|
741bfcf9b4 | ||
|
f8c16e5764 | ||
|
5f4c5299d8 | ||
|
d49e856ece | ||
|
2b82a74d93 | ||
|
b9310023ad | ||
|
0d77cbe1c4 | ||
|
3171001395 | ||
|
9e21123de0 | ||
|
22fce03844 | ||
|
1f0ab67baa | ||
|
93063d8c70 | ||
|
1b710bd952 | ||
|
0e699702ad | ||
|
ed3343cd76 | ||
|
4a7edafcb7 | ||
|
e001154714 | ||
|
08aefa4580 | ||
|
0704676724 | ||
|
b536d3f591 | ||
|
12aec6edd0 | ||
|
ded76b41d6 | ||
|
a49f0806c0 | ||
|
1e1728e5dd | ||
|
be38b5269c | ||
|
642c947ee4 | ||
|
ab8274eae2 | ||
|
253da1e9f5 | ||
|
20a51381bc | ||
|
2991e48ce6 | ||
|
e92ba202cf | ||
|
9639c2f775 | ||
|
6585ce3a09 | ||
|
ba9441a134 | ||
|
2cbc8bbf0c | ||
|
9d25773d61 | ||
|
fcbcea9382 | ||
|
79593e6f3e | ||
|
58fc08b6a7 | ||
|
516a3a85ff | ||
|
b3b8fab26d | ||
|
f524692370 | ||
|
bdb8c5a612 | ||
|
1ccf6f247d | ||
|
ffb3d05864 | ||
|
af48efe195 | ||
|
f7b0c4fe6b | ||
|
d9148699cc | ||
|
6a6c8468a6 | ||
|
42b05c0437 | ||
|
a4a8e9d2bc | ||
|
ce1b55e548 | ||
|
b23b2d1dbb | ||
|
6f0fb02bf6 | ||
|
6c02482bf9 | ||
|
3ed303f60d | ||
|
46eecb4027 | ||
|
79967be726 | ||
|
3359848565 | ||
|
a12febe08b | ||
|
432877f954 | ||
|
1f0519c8ee | ||
|
6613883296 | ||
|
b15694b5bc | ||
|
f9d1928d8e | ||
|
be5ad35fb9 | ||
|
4af42cb1bd | ||
|
951348feb9 | ||
|
e983ef4c94 | ||
|
53223e9d8e | ||
|
a343989a6b | ||
|
c0ee726fb2 | ||
|
96b3ecf248 | ||
|
a021038991 | ||
|
79540f9a40 | ||
|
4770a6e0d5 | ||
|
f1274497bd | ||
|
954558da60 | ||
|
38edf5ce74 | ||
|
edb5d4b6bf | ||
|
4f61c75799 | ||
|
2ed7ea4112 | ||
|
1941f9ae4b | ||
|
6c1a1f91e2 | ||
|
5a8dd7233b | ||
|
b41a59d2cf | ||
|
1f118f7233 | ||
|
bc7df6a5b4 | ||
|
2b09906a37 | ||
|
588306ecd3 | ||
|
d0ccaabf3e | ||
|
82c60cbdd1 | ||
|
d09205aebc | ||
|
16bf367ea7 | ||
|
13799b3181 | ||
|
d449231421 | ||
|
cbf2c7680e | ||
|
2e528e3e49 | ||
|
c4199a9708 | ||
|
221359ca64 | ||
|
3d1ee50685 | ||
|
e543c2cf9a | ||
|
a7d4f6691b | ||
|
d0094addd2 | ||
|
5c453354fc | ||
|
7e2a09e81e | ||
|
951235d105 | ||
|
fdb53381d1 | ||
|
d756f94c0c | ||
|
803222f646 | ||
|
6fed8998bb | ||
|
57fc351907 | ||
|
f5e0dad979 | ||
|
3e46e226c0 | ||
|
86de9d27e7 | ||
|
60070cc8d0 | ||
|
ec7c6e8ad9 | ||
|
c764f89881 | ||
|
3d3da33e3e | ||
|
037c1cb302 | ||
|
1202ffc8df | ||
|
9dc7e7fcb9 | ||
|
968e73b342 | ||
|
1fff3dee21 | ||
|
059bbc8457 | ||
|
c9e509f636 | ||
|
13e9405dee | ||
|
0d46be7425 | ||
|
257821a764 | ||
|
9fc3c3f01b | ||
|
c8175a7550 | ||
|
9cd750442a | ||
|
aac7dd3462 | ||
|
6a9547e910 | ||
|
330c48e66a | ||
|
a39c900b72 | ||
|
c5d9c9ffa3 | ||
|
3cbd8f0113 | ||
|
d91753e493 | ||
|
21e8298a4e | ||
|
ebff258882 | ||
|
63793ddc76 | ||
|
54af2138bf | ||
|
4003aa4e06 | ||
|
1ac6835726 | ||
|
3c65eafa7b | ||
|
62d1a77b3d | ||
|
b5a3fb9367 | ||
|
c28a0f0a60 | ||
|
9e84d29326 | ||
|
c4796d5695 | ||
|
40fd4cc2fe | ||
|
ca48e152a0 | ||
|
24f4364978 | ||
|
8f62a15f73 | ||
|
0220aac83e | ||
|
91a6affdad | ||
|
38a61f5cb3 | ||
|
cb54cd1210 | ||
|
84d8da97ec | ||
|
b24f1f6b1d | ||
|
7e59312454 | ||
|
ab79fe4eda | ||
|
9b6b13cda3 | ||
|
8ce6d00d06 | ||
|
2a1167428f | ||
|
9c9321029a | ||
|
75735cd6ed | ||
|
715c3a8eac | ||
|
d059cf991b | ||
|
cb592dfd9c | ||
|
37faf9022e | ||
|
7896de89f3 | ||
|
ebbaccd064 | ||
|
35ae307f6c |
16
.gitignore
vendored
@ -3,6 +3,8 @@
|
||||
*.merlin
|
||||
cache/*
|
||||
Version.ml
|
||||
/result
|
||||
/result-*
|
||||
/_opam/
|
||||
/*.pp.ligo
|
||||
/*.pp.mligo
|
||||
@ -12,4 +14,16 @@ Version.ml
|
||||
/ligo.install
|
||||
*.coverage
|
||||
/_coverage/
|
||||
/_coverage_*/
|
||||
/_coverage_*/
|
||||
*.gyp
|
||||
|
||||
# lsp-related
|
||||
node_modules/
|
||||
tools/lsp/squirrel/grammar/*/src
|
||||
tools/lsp/squirrel/vendor/**
|
||||
.stack-work
|
||||
nix/result
|
||||
.idea
|
||||
*.iml
|
||||
stale_outputs_checked
|
||||
*.cabal
|
||||
|
398
.gitlab-ci.yml
@ -1,274 +1,156 @@
|
||||
# TODO: remove this as submodules aren't used anymore.
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
build_binary_script: "./scripts/distribution/generic/build.sh"
|
||||
package_binary_script: "./scripts/distribution/generic/package.sh"
|
||||
LIGO_REGISTRY_IMAGE_BASE_NAME: "${CI_PROJECT_PATH}/${CI_PROJECT_NAME}"
|
||||
WEBIDE_IMAGE_NAME: "registry.gitlab.com/${CI_PROJECT_PATH}/ligo_webide"
|
||||
|
||||
stages:
|
||||
- test
|
||||
- build_and_package_binaries
|
||||
- build_docker
|
||||
- build_and_deploy
|
||||
- ide-unit-test
|
||||
- ide-build
|
||||
- ide-e2e-test
|
||||
- build
|
||||
- push
|
||||
- ide-deploy
|
||||
- versioning
|
||||
|
||||
# TODO provide sensible CI for master
|
||||
dont-merge-to-master:
|
||||
stage: test
|
||||
script:
|
||||
- "false"
|
||||
only:
|
||||
- master
|
||||
|
||||
.build_binary: &build_binary
|
||||
stage: test # To run in sequence and save CPU usage, use stage: build_and_package_binaries
|
||||
script:
|
||||
- $build_binary_script "$target_os_family" "$target_os" "$target_os_version"
|
||||
- $package_binary_script "$target_os_family" "$target_os" "$target_os_version"
|
||||
artifacts:
|
||||
paths:
|
||||
- dist/package/**/*
|
||||
|
||||
.website_build: &website_build
|
||||
stage: build_and_deploy
|
||||
image: node:12
|
||||
dependencies:
|
||||
- build-and-package-debian-9
|
||||
- build-and-package-debian-10
|
||||
- build-and-package-ubuntu-18-04
|
||||
- build-and-package-ubuntu-19-04
|
||||
before_script:
|
||||
- export TERM=dumb
|
||||
- scripts/install_native_dependencies.sh
|
||||
- scripts/install_opam.sh # TODO: or scripts/install_build_environment.sh ?
|
||||
- export PATH="/usr/local/bin${PATH:+:}${PATH:-}"
|
||||
- eval $(opam config env)
|
||||
- scripts/setup_switch.sh
|
||||
- eval $(opam config env)
|
||||
- scripts/setup_repos.sh
|
||||
|
||||
# install deps for internal documentation
|
||||
- scripts/install_vendors_deps.sh
|
||||
- opam install -y odoc
|
||||
- scripts/build_ligo_local.sh
|
||||
|
||||
# build with odoc
|
||||
- dune build @doc
|
||||
|
||||
# copy .deb packages into website
|
||||
- find dist -name \*.deb -exec sh -c 'cp {} gitlab-pages/website/static/deb/ligo_$(basename $(dirname {})).deb' \;
|
||||
|
||||
# yarn
|
||||
- cd gitlab-pages/website
|
||||
- yarn install
|
||||
script:
|
||||
- yarn build
|
||||
# move internal odoc documentation to the website folder
|
||||
- mv ../../_build/default/_doc/_html/ build/odoc
|
||||
after_script:
|
||||
- cp -r gitlab-pages/website/build public
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
|
||||
.docker: &docker
|
||||
.docker-image:
|
||||
stage: push
|
||||
image: docker:19.03.5
|
||||
services:
|
||||
- docker:19.03.5-dind
|
||||
|
||||
.before_script: &before_script
|
||||
before_script:
|
||||
# Install dependencies
|
||||
# rsync is needed by opam to sync a package installed from a local directory with the copy in ~/.opam
|
||||
- export TERM=dumb
|
||||
- scripts/install_native_dependencies.sh
|
||||
- scripts/install_opam.sh # TODO: or scripts/install_build_environment.sh ?
|
||||
- export PATH="/usr/local/bin${PATH:+:}${PATH:-}"
|
||||
- eval $(opam config env)
|
||||
- scripts/setup_switch.sh
|
||||
- eval $(opam config env)
|
||||
- scripts/setup_repos.sh
|
||||
|
||||
local-dune-job:
|
||||
<<: *before_script
|
||||
stage: test
|
||||
version_scheduled_job:
|
||||
stage: versioning
|
||||
script:
|
||||
- scripts/install_vendors_deps.sh
|
||||
- scripts/build_ligo_local.sh
|
||||
- dune runtest
|
||||
- make coverage
|
||||
artifacts:
|
||||
paths:
|
||||
- _coverage_all
|
||||
- scripts/versioning.sh
|
||||
only:
|
||||
- schedules
|
||||
|
||||
.nix:
|
||||
stage: build
|
||||
tags:
|
||||
- nix
|
||||
before_script:
|
||||
- find "$CI_PROJECT_DIR" -path "$CI_PROJECT_DIR/.git" -prune -o "(" -type d -a -not -perm -u=w ")" -exec chmod --verbose u+w {} ";"
|
||||
# - nix-env -f channel:nixos-unstable -iA gnutar gitMinimal
|
||||
- export COMMIT_DATE="$(git show --no-patch --format=%ci)"
|
||||
|
||||
# The binary produced is useless by itself
|
||||
binary:
|
||||
extends: .nix
|
||||
only:
|
||||
- merge_requests
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
|
||||
# Run a docker build without publishing to the registry
|
||||
build-current-docker-image:
|
||||
stage: build_docker
|
||||
dependencies:
|
||||
- build-and-package-debian-10
|
||||
<<: *docker
|
||||
script:
|
||||
- sh scripts/build_docker_image.sh next
|
||||
- sh scripts/test_cli.sh
|
||||
- nix-build nix -A ligo-bin
|
||||
|
||||
doc:
|
||||
extends: .nix
|
||||
only:
|
||||
- merge_requests
|
||||
|
||||
# When a MR/PR is merged to dev
|
||||
# take the previous build and publish it to Docker Hub
|
||||
build-and-publish-latest-docker-image:
|
||||
stage: build_and_deploy
|
||||
<<: *docker
|
||||
dependencies:
|
||||
- build-and-package-debian-10
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
script:
|
||||
- sh scripts/build_docker_image.sh $(if test "$CI_COMMIT_REF_NAME" = "dev"; then echo next; else echo next-attempt; fi)
|
||||
- sh scripts/test_cli.sh
|
||||
- echo ${LIGO_REGISTRY_PASSWORD} | docker login -u ${LIGO_REGISTRY_USER} --password-stdin
|
||||
- docker push ${LIGO_REGISTRY_IMAGE_BUILD:-ligolang/ligo}:$(if test "$CI_COMMIT_REF_NAME" = "dev"; then echo next; else echo next-attempt; fi)
|
||||
- nix-build nix -A ligo-doc
|
||||
- cp -Lr --no-preserve=mode,ownership,timestamps result/share/doc .
|
||||
artifacts:
|
||||
paths:
|
||||
- doc
|
||||
|
||||
test:
|
||||
extends: .nix
|
||||
only:
|
||||
- merge_requests
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
script:
|
||||
- nix-build nix -A ligo-coverage
|
||||
- cat result/share/coverage-all
|
||||
- cp -Lr --no-preserve=mode,ownership,timestamps result/share/coverage .
|
||||
artifacts:
|
||||
paths:
|
||||
- coverage
|
||||
|
||||
xrefcheck:
|
||||
extends: .nix
|
||||
only:
|
||||
- merge_requests
|
||||
script:
|
||||
# Should be replaced with
|
||||
# nix run github:serokell/xrefcheck
|
||||
# Once flakes roll out to stable
|
||||
# - nix run -f https://github.com/serokell/xrefcheck/archive/v0.1.1.2.tar.gz -c 'xrefcheck local-only'
|
||||
- curl -L https://github.com/serokell/xrefcheck/releases/download/v0.1.1/release.tar.gz | tar -zxf - xrefcheck/bin/xrefcheck
|
||||
- xrefcheck/bin/xrefcheck
|
||||
|
||||
# Strange race conditions, disable for now
|
||||
.webide-e2e:
|
||||
extends: .nix
|
||||
only:
|
||||
# Disabled for now unless the branch name contains webide, because a test in this job fails randomly
|
||||
- /.*webide.*/
|
||||
#- merge_requests
|
||||
#- dev
|
||||
#- /^.*-run-dev$/
|
||||
script:
|
||||
- nix-build nix -A ligo-editor.e2e
|
||||
|
||||
docker:
|
||||
extends: .nix
|
||||
only:
|
||||
- merge_requests
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
script:
|
||||
- nix-build nix -A ligo-docker
|
||||
- cp -L result ligo.tar.gz
|
||||
artifacts:
|
||||
paths:
|
||||
- ligo.tar.gz
|
||||
|
||||
docker-push:
|
||||
extends: .docker-image
|
||||
dependencies:
|
||||
- docker
|
||||
needs:
|
||||
- docker
|
||||
rules:
|
||||
# Only deploy docker when from the dev branch AND on the canonical ligolang/ligo repository
|
||||
- if: '$CI_COMMIT_REF_NAME =~ /^(dev|.*-run-dev)$/ && $CI_PROJECT_PATH == "ligolang/ligo"'
|
||||
when: always
|
||||
script:
|
||||
- echo ${LIGO_REGISTRY_PASSWORD} | docker login -u ${LIGO_REGISTRY_USER} --password-stdin
|
||||
- docker load -i=./ligo.tar.gz
|
||||
- export LIGO_REGISTRY_FULL_NAME=${LIGO_REGISTRY_IMAGE_BUILD:-ligolang/ligo}:$(if test "$CI_COMMIT_REF_NAME" = "dev"; then echo next; else echo next-attempt; fi)
|
||||
- docker tag ligo "${LIGO_REGISTRY_FULL_NAME}"
|
||||
- docker push "${LIGO_REGISTRY_FULL_NAME}"
|
||||
|
||||
# It'd be a good idea to generate those jobs dynamically,
|
||||
# based on desired targets
|
||||
build-and-package-debian-9:
|
||||
<<: *docker
|
||||
# To run in sequence and save CPU usage, use stage: build_and_package_binaries
|
||||
stage: test
|
||||
variables:
|
||||
target_os_family: "debian"
|
||||
target_os: "debian"
|
||||
target_os_version: "9"
|
||||
<<: *build_binary
|
||||
only:
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
|
||||
build-and-package-debian-10:
|
||||
<<: *docker
|
||||
# To run in sequence and save CPU usage, use stage: build_and_package_binaries
|
||||
stage: test
|
||||
variables:
|
||||
target_os_family: "debian"
|
||||
target_os: "debian"
|
||||
target_os_version: "10"
|
||||
<<: *build_binary
|
||||
# this one is merge_requests and dev, because the debian 10 binary
|
||||
# is used for build-current-docker-image and for
|
||||
# build-and-publish-latest-docker-image
|
||||
webide-docker:
|
||||
extends: .nix
|
||||
only:
|
||||
- merge_requests
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
script:
|
||||
- nix-build nix -A ligo-editor-docker
|
||||
- cp -L result webide.tar.gz
|
||||
artifacts:
|
||||
paths:
|
||||
- webide.tar.gz
|
||||
|
||||
build-and-package-ubuntu-18-04:
|
||||
<<: *docker
|
||||
# To run in sequence and save CPU usage, use stage: build_and_package_binaries
|
||||
stage: test
|
||||
variables:
|
||||
target_os_family: "debian"
|
||||
target_os: "ubuntu"
|
||||
target_os_version: "18.04"
|
||||
<<: *build_binary
|
||||
only:
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
|
||||
build-and-package-ubuntu-19-04:
|
||||
<<: *docker
|
||||
# To run in sequence and save CPU usage, use stage: build_and_package_binaries
|
||||
stage: test
|
||||
variables:
|
||||
target_os_family: "debian"
|
||||
target_os: "ubuntu"
|
||||
target_os_version: "19.04"
|
||||
<<: *build_binary
|
||||
only:
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
|
||||
# Pages are deployed from dev, be careful not to override 'next'
|
||||
# in case something gets merged into 'dev' while releasing.
|
||||
pages:
|
||||
<<: *website_build
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME == "dev" && $CI_PROJECT_PATH == "ligolang/ligo"'
|
||||
when: always
|
||||
|
||||
pages-attempt:
|
||||
<<: *website_build
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME =~ /^.*-run-dev$/ && $CI_PROJECT_PATH == "ligolang/ligo"'
|
||||
when: always
|
||||
|
||||
# WEBIDE jobs
|
||||
|
||||
run-webide-unit-tests:
|
||||
stage: ide-unit-test
|
||||
webide-push:
|
||||
extends: .docker-image
|
||||
dependencies:
|
||||
- build-and-package-debian-10
|
||||
image: node:12-buster
|
||||
script:
|
||||
- mv $(realpath dist/package/debian-10/*.deb) ligo_deb10.deb
|
||||
- apt-get update && apt-get -y install libev-dev perl pkg-config libgmp-dev libhidapi-dev m4 libcap-dev bubblewrap rsync
|
||||
- dpkg -i ligo_deb10.deb
|
||||
- cd tools/webide/packages/server
|
||||
- npm ci
|
||||
- export LIGO_CMD=/bin/ligo && npm run test
|
||||
- webide-docker
|
||||
needs:
|
||||
- webide-docker
|
||||
rules:
|
||||
- changes:
|
||||
- tools/webide/**
|
||||
# Only deploy docker when from the dev branch AND on the canonical ligolang/ligo repository
|
||||
- if: '$CI_COMMIT_REF_NAME =~ /^(dev|.*-run-dev)$/ && $CI_PROJECT_PATH == "ligolang/ligo"'
|
||||
when: always
|
||||
|
||||
build-publish-ide-image:
|
||||
stage: build_and_deploy
|
||||
<<: *docker
|
||||
script:
|
||||
- ls -F
|
||||
- find dist/
|
||||
- find dist/package/ -name '*ligo_*deb'
|
||||
- mv $(realpath dist/package/debian-10/*.deb) tools/webide/ligo_deb10.deb
|
||||
- cp -r src/test/examples tools/webide/packages/client/examples
|
||||
- cd tools/webide
|
||||
- echo "${CI_BUILD_TOKEN}" | docker login -u gitlab-ci-token --password-stdin registry.gitlab.com
|
||||
- >
|
||||
docker build
|
||||
-t "${WEBIDE_IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}"
|
||||
--build-arg GIT_TAG="${CI_COMMIT_SHA}"
|
||||
--build-arg GIT_COMMIT="${CI_COMMIT_SHORT_SHA}"
|
||||
--build-arg EXAMPLES_DIR_SRC=packages/client/examples
|
||||
.
|
||||
- docker load -i=./webide.tar.gz
|
||||
- docker tag ligo-editor "${WEBIDE_IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}"
|
||||
- docker push "${WEBIDE_IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}"
|
||||
rules:
|
||||
- changes:
|
||||
- tools/webide/**
|
||||
when: always
|
||||
- if: '$CI_COMMIT_REF_NAME == "dev"'
|
||||
when: always
|
||||
|
||||
run-webide-e2e-tests:
|
||||
stage: ide-e2e-test
|
||||
<<: *docker
|
||||
image: tmaier/docker-compose
|
||||
script:
|
||||
- cd tools/webide/packages/e2e
|
||||
- export WEBIDE_IMAGE="${WEBIDE_IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}"
|
||||
- docker-compose run e2e
|
||||
rules:
|
||||
- changes:
|
||||
- tools/webide/**
|
||||
when: always
|
||||
- if: '$CI_COMMIT_REF_NAME == "dev"'
|
||||
when: always
|
||||
|
||||
deploy-handoff:
|
||||
# Handoff deployment duties to private repo
|
||||
@ -280,3 +162,53 @@ deploy-handoff:
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME == "dev"'
|
||||
when: always
|
||||
|
||||
static-binary:
|
||||
extends: .nix
|
||||
only:
|
||||
- merge_requests
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
script:
|
||||
- nix-build nix -A ligo-static
|
||||
# Check that the binary is truly static and has 0 dependencies
|
||||
- test $(nix-store -q --references ./result | wc -l) -eq 0
|
||||
- cp -L result/bin/ligo ligo
|
||||
- chmod +rwx ligo
|
||||
artifacts:
|
||||
paths:
|
||||
- ligo
|
||||
|
||||
.website:
|
||||
extends: .nix
|
||||
script:
|
||||
- nix-build nix -A ligo-website
|
||||
- cp -Lr --no-preserve=mode,ownership,timestamps result/ public
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
|
||||
pages:
|
||||
extends: .website
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME == "dev" && $CI_PROJECT_PATH == "ligolang/ligo"'
|
||||
when: always
|
||||
|
||||
pages-attempt:
|
||||
extends: .website
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*-run-dev$/
|
||||
|
||||
vscode-extension:
|
||||
extends: .nix
|
||||
only:
|
||||
- merge_requests
|
||||
- dev
|
||||
- /^.*-run-dev$/
|
||||
script:
|
||||
- nix-build tools/lsp -A ligo-vscode-extension
|
||||
- cp -Lr --no-preserve=mode,ownership,timestamps result/*.vsix ligo-extension.vsix
|
||||
artifacts:
|
||||
paths:
|
||||
- ligo-extension.vsix
|
||||
|
49
.xrefcheck.yaml
Normal file
@ -0,0 +1,49 @@
|
||||
# SPDX-FileCopyrightText: 2019 Serokell <https://serokell.io>
|
||||
#
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
# Parameters of repository traversal.
|
||||
traversal:
|
||||
# Files and folders which we pretend do not exist
|
||||
# (so they are neither analyzed nor can be referenced).
|
||||
ignored:
|
||||
# Git files
|
||||
- .git
|
||||
- xrefcheck
|
||||
|
||||
# Verification parameters.
|
||||
verification:
|
||||
# On 'anchor not found' error, how much similar anchors should be displayed as
|
||||
# hint. Number should be between 0 and 1, larger value means stricter filter.
|
||||
anchorSimilarityThreshold: 0.5
|
||||
|
||||
# When checking external references, how long to wait on request before
|
||||
# declaring "Response timeout".
|
||||
externalRefCheckTimeout: 60s
|
||||
|
||||
# Prefixes of files, references in which should not be analyzed.
|
||||
notScanned:
|
||||
# GitHub-specific files
|
||||
- .github/pull_request_template.md
|
||||
- .github/issue_template.md
|
||||
- .github/PULL_REQUEST_TEMPLATE
|
||||
- .github/ISSUE_TEMPLATE
|
||||
|
||||
# GitLab-specific files
|
||||
- .gitlab/merge_request_templates/
|
||||
- .gitlab/issue_templates/
|
||||
|
||||
# Glob patterns describing the files which do not physically exist in the
|
||||
# repository but should be treated as existing nevertheless.
|
||||
virtualFiles:
|
||||
# GitHub pages
|
||||
- ../../../issues
|
||||
- ../../../issues/*
|
||||
- ../../../pulls
|
||||
- ../../../pulls/*
|
||||
|
||||
# GitLab pages
|
||||
- ../../issues
|
||||
- ../../issues/*
|
||||
- ../../merge_requests
|
||||
- ../../merge_requests/*
|
@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [Michelson or type] (https://gitlab.com/ligolang/ligo/-/merge_requests/530)
|
||||
### Added
|
||||
- New type michelson_or, will give control over or types instead of relying on LIGO variants.
|
||||
|
||||
## [Support for self] (https://gitlab.com/ligolang/ligo/-/merge_requests/453)
|
||||
### Added
|
||||
- support for `Tezos.self(%Entrypoint)`
|
||||
|
1
debug.cmd
Normal file
@ -0,0 +1 @@
|
||||
(echo '['; sed -ne '/###############################START_OF_JSON/,/###############################END_OF_JSON/{/^###############################.*_OF_JSON/d;p}' < '/home/suzanne/00ligopam/ligo/_build/default/src/test/_build/_tests/'*'/Integration (End to End).001.output'; echo '"end of json"]') > /tmp/js.json
|
@ -1,3 +0,0 @@
|
||||
{ sources ? import ./nix/sources.nix }:
|
||||
let ocaml-overlay = import ./nix/ocaml-overlay.nix { inherit sources; };
|
||||
in import sources.nixpkgs { overlays = [ ocaml-overlay ]; }
|
@ -12,14 +12,14 @@ RUN mkdir /package && mkdir /package/bin && mkdir /package/DEBIAN && mkdir /pack
|
||||
RUN cp /home/opam/.opam/4.07/bin/ligo /package/bin/ligo
|
||||
|
||||
# @TODO: inherit version (and other details) from the ligo opam package definition
|
||||
# In our case we're using the version field to name our package accordingly,
|
||||
# In our case we're using the version field to name our package accordingly,
|
||||
# however this is most likely not ideal
|
||||
# Also, the architecture field should not be 'all' but rather specific instead.
|
||||
RUN echo "Package: ligo\n\
|
||||
Version: $version\n\
|
||||
Architecture: all\n\
|
||||
Maintainer: info@ligolang.org\n\
|
||||
Depends: libev4, libgmp10, libgmpxx4ldbl, cpp\n\
|
||||
Depends: libev4, libgmp10, libgmpxx4ldbl\n\
|
||||
Homepage: http://ligolang.org\n\
|
||||
Description: LIGO is a statically typed high-level smart-contract language that compiles down to Michelson." >> /package/DEBIAN/control
|
||||
|
||||
|
@ -2,7 +2,11 @@ ARG target
|
||||
FROM ocaml/opam2:${target}
|
||||
|
||||
ARG ci_job_id
|
||||
ARG ci_commit_sha
|
||||
ARG commit_date
|
||||
ENV CI_JOB_ID=$ci_job_id
|
||||
ENV CI_COMMIT_SHA=$ci_commit_sha
|
||||
ENV COMMIT_DATE=$commit_date
|
||||
|
||||
RUN opam switch 4.07 && eval $(opam env)
|
||||
|
||||
@ -29,7 +33,7 @@ RUN opam update
|
||||
|
||||
# Install ligo
|
||||
RUN sh scripts/install_vendors_deps.sh
|
||||
RUN opam install -y .
|
||||
RUN opam install -y . || (tail -n +1 ~/.opam/log/* ; false)
|
||||
|
||||
# Use the ligo binary as a default command
|
||||
ENTRYPOINT [ "/home/opam/.opam/4.07/bin/ligo" ]
|
||||
|
@ -16,6 +16,7 @@ services:
|
||||
# - ./website/versioned_sidebars:/app/website/versioned_sidebars
|
||||
# - ./website/versioned_docs:/app/website/versioned_docs
|
||||
- ./website/sidebars.json:/app/website/sidebars.json
|
||||
- ./website/sitemap.xml:/app/website/sitemap.xml
|
||||
- ./website/docusaurus.config.js:/app/website/docusaurus.config.js
|
||||
# - ./website/versions.json:/app/website/versions.json
|
||||
# - ./website/core/AlgoliaSearch.js:/app/website/core/AlgoliaSearch.js
|
||||
|
@ -234,7 +234,7 @@ function deny (const action : parameter; const store : storage) : return is
|
||||
else ((nil : list (operation)), store)
|
||||
```
|
||||
|
||||
> Note that `amount` is *deprecated*.
|
||||
> Note that `amount` is *deprecated*. Please use `Tezos.amount`.
|
||||
|
||||
</Syntax>
|
||||
|
||||
@ -251,7 +251,7 @@ let deny (action, store : parameter * storage) : return =
|
||||
else (([] : operation list), store)
|
||||
```
|
||||
|
||||
> Note that `amount` is *deprecated*.
|
||||
> Note that `amount` is *deprecated*. Please use `Tezos.amount`.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
@ -268,7 +268,7 @@ let deny = ((action, store): (parameter, storage)) : return => {
|
||||
};
|
||||
```
|
||||
|
||||
> Note that `amount` is *deprecated*.
|
||||
> Note that `amount` is *deprecated*. Please use `Tezos.amount`.
|
||||
|
||||
</Syntax>
|
||||
|
||||
@ -289,7 +289,7 @@ function main (const action : parameter; const store : storage) : return is
|
||||
else ((nil : list (operation)), store)
|
||||
```
|
||||
|
||||
> Note that `source` is *deprecated*.
|
||||
> Note that `source` is *deprecated*. Please use `Tezos.source`.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
@ -302,7 +302,7 @@ let main (action, store: parameter * storage) : return =
|
||||
else (([] : operation list), store)
|
||||
```
|
||||
|
||||
> Note that `source` is *deprecated*.
|
||||
> Note that `source` is *deprecated*. Please use `Tezos.source`.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
@ -316,7 +316,7 @@ let main = ((action, store) : (parameter, storage)) : return => {
|
||||
};
|
||||
```
|
||||
|
||||
> Note that `source` is *deprecated*.
|
||||
> Note that `source` is *deprecated*. Please use `Tezos.source`.
|
||||
|
||||
</Syntax>
|
||||
|
||||
@ -466,8 +466,8 @@ let proxy = ((action, store): (parameter, storage)) : return => {
|
||||
| Some (contract) => contract;
|
||||
| None => (failwith ("Contract not found.") : contract (parameter));
|
||||
};
|
||||
(* Reuse the parameter in the subsequent
|
||||
transaction or use another one, `mock_param`. *)
|
||||
/* Reuse the parameter in the subsequent
|
||||
transaction or use another one, `mock_param`. */
|
||||
let mock_param : parameter = Increment (5n);
|
||||
let op : operation = Tezos.transaction (action, 0tez, counter);
|
||||
([op], store)
|
||||
|
70
gitlab-pages/docs/advanced/inline.md
Normal file
@ -0,0 +1,70 @@
|
||||
---
|
||||
id: inline
|
||||
title: Inlining
|
||||
---
|
||||
|
||||
import Syntax from '@theme/Syntax';
|
||||
|
||||
When compiling a contract in LIGO, declarations will get inlined if they are
|
||||
only used once and pure. Inlining often results in larger contracts and is
|
||||
therefore not aggressively done.
|
||||
|
||||
A pure declaration is one that doesn't cause side effects like causing a
|
||||
failure or operation.
|
||||
|
||||
In some cases you might want to override the default behaviour of LIGO and
|
||||
force inlining. The declaration still needs to be pure though.
|
||||
|
||||
## Inline attribute
|
||||
|
||||
To force inlining you can use the inline attribute.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
function fst(const p : nat * nat) : nat is p.0; attributes ["inline"] ;
|
||||
|
||||
function main(const p : nat * nat; const s : nat * nat) : list(operation) * (nat * nat) is
|
||||
((list end : list(operation)), (fst(p.0,p.1), fst(s.1,s.0)))
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let fst (p: (nat * nat)) : nat = p.0 [@@inline]
|
||||
|
||||
let main (p : (nat * nat)) (s : (nat * nat)) : (operation list * (nat * nat)) =
|
||||
(([]: operation list), (fst (p.0, p.1), fst (s.1, s.0)))
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
[@inline]
|
||||
let fst = (p: (nat, nat)) : nat => p[0]
|
||||
|
||||
let main = (p : (nat, nat), s : (nat, nat)) : (list(operation), (nat, nat)) =>
|
||||
(([]: list(operation)), (fst((p[0], p[1])), fst((s[1], s[0]))))
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
Now if we measure the difference between inlining and without inlining, using
|
||||
`ligo measure-contract name_of_contract.ligo <entrypoint>`, we see the
|
||||
following results:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>With inlining</td><td>66 bytes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Without inlining</td><td>170 bytes</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
:::info
|
||||
Note that these results can change due to ongoing work to optimize output of
|
||||
the LIGO compiler.
|
||||
:::
|
730
gitlab-pages/docs/advanced/interop.md
Normal file
@ -0,0 +1,730 @@
|
||||
---
|
||||
id: interop
|
||||
title: Interop
|
||||
---
|
||||
|
||||
import Syntax from '@theme/Syntax';
|
||||
|
||||
LIGO can work together with other smart contract languages on Tezos. However
|
||||
data structures might have different representations in Michelson and not
|
||||
correctly match the standard LIGO types.
|
||||
|
||||
## Michelson types and annotations
|
||||
Michelson types consist of `or`'s and `pair`'s, combined with field annotations.
|
||||
Field annotations add contraints on a Michelson type, for example a pair of
|
||||
`(pair (int %foo) (string %bar))` will only work with the exact equivalence or
|
||||
the same type without the field annotations.
|
||||
|
||||
To clarify:
|
||||
|
||||
```michelson
|
||||
(pair (int %foo) (string %bar))
|
||||
````
|
||||
|
||||
works with
|
||||
|
||||
```michelson
|
||||
(pair (int %foo) (string %bar))
|
||||
```
|
||||
|
||||
works with
|
||||
|
||||
```michelson
|
||||
(pair int string)
|
||||
```
|
||||
|
||||
works not with
|
||||
|
||||
```michelson
|
||||
(pair (int %bar) (string %foo))
|
||||
```
|
||||
|
||||
works not with
|
||||
|
||||
```michelson
|
||||
(pair (string %bar) (int %foo))
|
||||
```
|
||||
|
||||
:::info
|
||||
In the case of annotated entrypoints - the annotated `or` tree directly under
|
||||
`parameter` in a contract - you should annotations, as otherwise it would
|
||||
become unclear which entrypoint you are referring to.
|
||||
:::
|
||||
|
||||
## Entrypoints and annotations
|
||||
It's possible for a contract to have multiple entrypoints, which translates in
|
||||
LIGO to a `parameter` with a variant type as shown here:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type storage is int
|
||||
|
||||
type parameter is
|
||||
| Left of int
|
||||
| Right of int
|
||||
|
||||
function main (const p: parameter; const x: storage): (list(operation) * storage) is
|
||||
((nil: list(operation)), case p of
|
||||
| Left(i) -> x - i
|
||||
| Right(i) -> x + i
|
||||
end)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type storage = int
|
||||
|
||||
type parameter =
|
||||
| Left of int
|
||||
| Right of int
|
||||
|
||||
let main ((p, x): (parameter * storage)): (operation list * storage) =
|
||||
(([]: operation list), (match p with
|
||||
| Left i -> x - i
|
||||
| Right i -> x + i
|
||||
))
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type storage = int
|
||||
|
||||
type parameter =
|
||||
| Left(int)
|
||||
| Right(int)
|
||||
|
||||
let main = ((p, x): (parameter, storage)): (list(operation), storage) => {
|
||||
([]: list(operation), (switch(p) {
|
||||
| Left(i) => x - i
|
||||
| Right(i) => x + i
|
||||
}))
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
This contract can be called by another contract, like this one:
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=get_entrypoint_opt
|
||||
type storage is int
|
||||
|
||||
type parameter is int
|
||||
|
||||
type x is Left of int
|
||||
|
||||
function main (const p: parameter; const s: storage): (list(operation) * storage) is block {
|
||||
const contract: contract(x) =
|
||||
case (Tezos.get_entrypoint_opt("%left", ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx":address)): option(contract(x))) of
|
||||
| Some (c) -> c
|
||||
| None -> (failwith("not a correct contract") : contract(x))
|
||||
end;
|
||||
|
||||
const result: (list(operation) * storage) = ((list [Tezos.transaction(Left(2), 2mutez, contract)]: list(operation)), s)
|
||||
} with result
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=get_entrypoint_opt
|
||||
type storage = int
|
||||
|
||||
type parameter = int
|
||||
|
||||
type x = Left of int
|
||||
|
||||
let main (p, s: parameter * storage): operation list * storage = (
|
||||
let contract: x contract =
|
||||
match ((Tezos.get_entrypoint_opt "%left" ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)): x contract option) with
|
||||
| Some c -> c
|
||||
| None -> (failwith "contract does not match": x contract)
|
||||
in
|
||||
(([
|
||||
Tezos.transaction (Left 2) 2mutez contract;
|
||||
]: operation list), s)
|
||||
)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=get_entrypoint_opt
|
||||
type storage = int;
|
||||
|
||||
type parameter = int;
|
||||
|
||||
type x = Left(int);
|
||||
|
||||
let main = ((p, s): (parameter, storage)): (list(operation), storage) => {
|
||||
let contract: contract(x) =
|
||||
switch (Tezos.get_entrypoint_opt("%left", ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)): option(contract(x))) {
|
||||
| Some c => c
|
||||
| None => (failwith ("contract does not match"): contract(x))
|
||||
};
|
||||
([
|
||||
Tezos.transaction(Left(2), 2mutez, contract)
|
||||
]: list(operation), s);
|
||||
};
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
Notice how we directly use the `%left` entrypoint without mentioning the
|
||||
`%right` entrypoint. This is done with the help of annotations. Without
|
||||
annotations it wouldn't be clear what our `int` would be referring to.
|
||||
|
||||
This currently only works for `or`'s or variant types in LIGO.
|
||||
|
||||
## Interop with Michelson
|
||||
To interop with existing Michelson code or for compatibility with certain
|
||||
development tooling, LIGO has two special interop types: `michelson_or` and
|
||||
`michelson_pair`. These types give the flexibility to model the exact Michelson
|
||||
output, including field annotations.
|
||||
|
||||
Take for example the following Michelson type that we want to interop with:
|
||||
|
||||
```michelson
|
||||
(or
|
||||
(unit %z)
|
||||
(or %other
|
||||
(unit %y)
|
||||
(pair %other
|
||||
(string %x)
|
||||
(pair %other
|
||||
(int %w)
|
||||
(nat %v)))))
|
||||
```
|
||||
|
||||
To reproduce this type we can use the following LIGO code:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type w_and_v is michelson_pair(int, "w", nat, "v")
|
||||
type x_and is michelson_pair(string, "x", w_and_v, "other")
|
||||
type y_or is michelson_or(unit, "y", x_and, "other")
|
||||
type z_or is michelson_or(unit, "z", y_or, "other")
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type w_and_v = (int, "w", nat, "v") michelson_pair
|
||||
type x_and = (string, "x", w_and_v, "other") michelson_pair
|
||||
type y_or = (unit, "y", x_and, "other") michelson_or
|
||||
type z_or = (unit, "z", y_or, "other") michelson_or
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type w_and_v = michelson_pair(int, "w", nat, "v")
|
||||
type x_and = michelson_pair(string, "x", w_and_v, "other")
|
||||
type y_or = michelson_or(unit, "y", x_and, "other")
|
||||
type z_or = michelson_or(unit, "z", y_or, "other")
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
If you don't want to have an annotation, you need to provide an empty string.
|
||||
|
||||
:::info
|
||||
Alternatively, if annotations are not important you can also use plain tuples
|
||||
for pair's instead. Plain tuples don't have any annotations.
|
||||
:::
|
||||
|
||||
To use variables of type `michelson_or` you have to use `M_left` and `M_right`.
|
||||
`M_left` picks the left `or` case while `M_right` picks the right `or` case.
|
||||
For `michelson_pair` you need to use tuples.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
const z: z_or = (M_left (unit) : z_or);
|
||||
|
||||
const y_1: y_or = (M_left (unit): y_or);
|
||||
const y: z_or = (M_right (y_1) : z_or);
|
||||
|
||||
const x_pair: x_and = ("foo", (2, 3n));
|
||||
const x_1: y_or = (M_right (x_pair): y_or);
|
||||
const x: z_or = (M_right (y_1) : z_or);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let z: z_or = (M_left (unit) : z_or)
|
||||
|
||||
let y_1: y_or = (M_left (unit): y_or)
|
||||
let y: z_or = (M_right (y_1) : z_or)
|
||||
|
||||
let x_pair: x_and = ("foo", (2, 3n))
|
||||
let x_1: y_or = (M_right (x_pair): y_or)
|
||||
let x: z_or = (M_right (y_1) : z_or)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let z: z_or = (M_left (unit) : z_or)
|
||||
|
||||
let y_1: y_or = (M_left (unit): y_or)
|
||||
let y: z_or = (M_right (y_1) : z_or)
|
||||
|
||||
let x_pair: x_and = ("foo", (2, 3n))
|
||||
let x_1: y_or = (M_right (x_pair): y_or)
|
||||
let x: z_or = (M_right (y_1) : z_or)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
## Helper functions
|
||||
Converting between different LIGO types and data structures can happen in two
|
||||
ways. The first way is to use the provided layout conversion functions, and the
|
||||
second way is to handle the layout conversion manually.
|
||||
|
||||
:::info
|
||||
In both cases it will increase the size of the smart contract and the
|
||||
conversion will happen when running the smart contract.
|
||||
:::
|
||||
|
||||
### Converting left combed Michelson data structures
|
||||
Here's an example of a left combed Michelson data structure using pairs:
|
||||
|
||||
```michelson
|
||||
(pair %other
|
||||
(pair %other
|
||||
(string %s)
|
||||
(int %w)
|
||||
)
|
||||
(nat %v)
|
||||
)
|
||||
```
|
||||
|
||||
Which could respond with the following record type:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type l_record is record [
|
||||
s: string;
|
||||
w: int;
|
||||
v: nat
|
||||
]
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type l_record = {
|
||||
s: string;
|
||||
w: int;
|
||||
v: nat
|
||||
}
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type l_record = {
|
||||
s: string,
|
||||
w: int,
|
||||
v: nat
|
||||
}
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
If we want to convert from the Michelson type to our record type and vice
|
||||
versa, we can use the following code:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type michelson is michelson_pair_left_comb(l_record)
|
||||
|
||||
function of_michelson (const f: michelson) : l_record is
|
||||
block {
|
||||
const p: l_record = Layout.convert_from_left_comb(f)
|
||||
}
|
||||
with p
|
||||
|
||||
function to_michelson (const f: l_record) : michelson is
|
||||
block {
|
||||
const p: michelson = Layout.convert_to_left_comb ((f: l_record))
|
||||
}
|
||||
with p
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type michelson = l_record michelson_pair_left_comb
|
||||
|
||||
let of_michelson (f: michelson) : l_record =
|
||||
let p: l_record = Layout.convert_from_left_comb f in
|
||||
p
|
||||
|
||||
let to_michelson (f: l_record) : michelson =
|
||||
let p = Layout.convert_to_left_comb (f: l_record) in
|
||||
p
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type michelson = michelson_pair_left_comb(l_record);
|
||||
|
||||
let of_michelson = (f: michelson) : l_record => {
|
||||
let p: l_record = Layout.convert_from_left_comb(f);
|
||||
p
|
||||
};
|
||||
|
||||
let to_michelson = (f: l_record) : michelson => {
|
||||
let p = Layout.convert_to_left_comb(f: l_record);
|
||||
p
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
In the case of a left combed Michelson `or` data structure, that you want to
|
||||
translate to a variant, you can use the `michelson_or_left_comb` type.
|
||||
|
||||
For example:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type vari is
|
||||
| Foo of int
|
||||
| Bar of nat
|
||||
| Other of bool
|
||||
|
||||
type r is michelson_or_left_comb(vari)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type vari =
|
||||
| Foo of int
|
||||
| Bar of nat
|
||||
| Other of bool
|
||||
|
||||
type r = vari michelson_or_left_comb
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type vari =
|
||||
| Foo(int)
|
||||
| Bar(nat)
|
||||
| Other(bool)
|
||||
|
||||
type r = michelson_or_left_comb(vari)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
And then use these types in `Layout.convert_from_left_comb` or
|
||||
`Layout.convert_to_left_comb`, similar to the `pair`s example above, like this:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
function of_michelson_or (const f: r) : vari is
|
||||
block {
|
||||
const p: vari = Layout.convert_from_left_comb(f)
|
||||
}
|
||||
with p
|
||||
|
||||
function to_michelson_or (const f: vari) : r is
|
||||
block {
|
||||
const p: r = Layout.convert_to_left_comb((f: vari))
|
||||
}
|
||||
with p
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let of_michelson_or (f: r) : vari =
|
||||
let p: vari = Layout.convert_from_left_comb f in
|
||||
p
|
||||
|
||||
let to_michelson_or (f: vari) : r =
|
||||
let p = Layout.convert_to_left_comb (f: vari) in
|
||||
p
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let of_michelson_or = (f: r) : vari => {
|
||||
let p: vari = Layout.convert_from_left_comb(f);
|
||||
p
|
||||
};
|
||||
|
||||
let to_michelson_or = (f: vari) : r => {
|
||||
let p = Layout.convert_to_left_comb(f: vari);
|
||||
p
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
### Converting right combed Michelson data structures
|
||||
|
||||
In the case of right combed data structures, like:
|
||||
|
||||
```michelson
|
||||
(pair %other
|
||||
(string %s)
|
||||
(pair %other
|
||||
(int %w)
|
||||
(nat %v)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
you can almost use the same code as that for the left combed data structures,
|
||||
but with `michelson_or_right_comb`, `michelson_pair_right_comb`,
|
||||
`Layout.convert_from_right_comb`, and `Layout.convert_to_left_comb`
|
||||
respectively.
|
||||
|
||||
### Manual data structure conversion
|
||||
If you want to get your hands dirty, it's also possible to do manual data
|
||||
structure conversion.
|
||||
|
||||
The following code can be used as inspiration:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=helper_functions
|
||||
type z_to_v is
|
||||
| Z
|
||||
| Y
|
||||
| X
|
||||
| W
|
||||
| V
|
||||
|
||||
type w_or_v is michelson_or(unit, "w", unit, "v")
|
||||
type x_or is michelson_or(unit, "x", w_or_v, "other")
|
||||
type y_or is michelson_or(unit, "y", x_or, "other")
|
||||
type z_or is michelson_or(unit, "z", y_or, "other")
|
||||
|
||||
type test is record [
|
||||
z: string;
|
||||
y: int;
|
||||
x: string;
|
||||
w: bool;
|
||||
v: int;
|
||||
]
|
||||
|
||||
function make_concrete_sum (const r: z_to_v) : z_or is block {
|
||||
const z: z_or = (M_left (unit) : z_or);
|
||||
|
||||
const y_1: y_or = (M_left (unit): y_or);
|
||||
const y: z_or = (M_right (y_1) : z_or);
|
||||
|
||||
const x_2: x_or = (M_left (unit): x_or);
|
||||
const x_1: y_or = (M_right (x_2): y_or);
|
||||
const x: z_or = (M_right (x_1) : z_or);
|
||||
|
||||
const w_3: w_or_v = (M_left (unit): w_or_v);
|
||||
const w_2: x_or = (M_right (w_3): x_or);
|
||||
const w_1: y_or = (M_right (w_2): y_or);
|
||||
const w: z_or = (M_right (w_1) : z_or);
|
||||
|
||||
const v_3: w_or_v = (M_right (unit): w_or_v);
|
||||
const v_2: x_or = (M_right (v_3): x_or);
|
||||
const v_1: y_or = (M_right (v_2): y_or);
|
||||
const v: z_or = (M_right (v_1) : z_or);
|
||||
}
|
||||
with (case r of
|
||||
| Z -> z
|
||||
| Y -> y
|
||||
| X -> x
|
||||
| W -> w
|
||||
| V -> v
|
||||
end)
|
||||
|
||||
|
||||
function make_concrete_record (const r: test) : (string * int * string * bool * int) is
|
||||
(r.z, r.y, r.x, r.w, r.v)
|
||||
|
||||
function make_abstract_sum (const z_or: z_or) : z_to_v is
|
||||
(case z_or of
|
||||
| M_left (n) -> Z
|
||||
| M_right (y_or) ->
|
||||
(case y_or of
|
||||
| M_left (n) -> Y
|
||||
| M_right (x_or) ->
|
||||
(case x_or of
|
||||
| M_left (n) -> X
|
||||
| M_right (w_or) ->
|
||||
(case (w_or) of
|
||||
| M_left (n) -> W
|
||||
| M_right (n) -> V
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
function make_abstract_record (const z: string; const y: int; const x: string; const w: bool; const v: int) : test is
|
||||
record [ z = z; y = y; x = x; w = w; v = v ]
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=helper_functions
|
||||
type z_to_v =
|
||||
| Z
|
||||
| Y
|
||||
| X
|
||||
| W
|
||||
| V
|
||||
|
||||
type w_or_v = (unit, "w", unit, "v") michelson_or
|
||||
type x_or = (unit, "x", w_or_v, "other") michelson_or
|
||||
type y_or = (unit, "y", x_or, "other") michelson_or
|
||||
type z_or = (unit, "z", y_or, "other") michelson_or
|
||||
|
||||
type test = {
|
||||
z: string;
|
||||
y: int;
|
||||
x: string;
|
||||
w: bool;
|
||||
v: int;
|
||||
}
|
||||
|
||||
let make_concrete_sum (r: z_to_v) : z_or =
|
||||
match r with
|
||||
| Z -> (M_left (unit) : z_or)
|
||||
| Y -> (M_right (M_left (unit): y_or) : z_or )
|
||||
| X -> (M_right (M_right (M_left (unit): x_or): y_or) : z_or )
|
||||
| W -> (M_right (M_right (M_right (M_left (unit): w_or_v): x_or): y_or) : z_or )
|
||||
| V -> (M_right (M_right (M_right (M_right (unit): w_or_v): x_or): y_or) : z_or )
|
||||
|
||||
let make_concrete_record (r: test) : (string * int * string * bool * int) =
|
||||
(r.z, r.y, r.x, r.w, r.v)
|
||||
|
||||
let make_abstract_sum (z_or: z_or) : z_to_v =
|
||||
match z_or with
|
||||
| M_left n -> Z
|
||||
| M_right y_or ->
|
||||
(match y_or with
|
||||
| M_left n -> Y
|
||||
| M_right x_or -> (
|
||||
match x_or with
|
||||
| M_left n -> X
|
||||
| M_right w_or -> (
|
||||
match w_or with
|
||||
| M_left n -> W
|
||||
| M_right n -> V)))
|
||||
|
||||
|
||||
let make_abstract_record (z: string) (y: int) (x: string) (w: bool) (v: int) : test =
|
||||
{ z = z; y = y; x = x; w = w; v = v }
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=helper_functions
|
||||
type z_to_v =
|
||||
| Z
|
||||
| Y
|
||||
| X
|
||||
| W
|
||||
| V
|
||||
|
||||
type w_or_v = michelson_or(unit, "w", unit, "v")
|
||||
type x_or = michelson_or(unit, "x", w_or_v, "other")
|
||||
type y_or = michelson_or(unit, "y", x_or, "other")
|
||||
type z_or = michelson_or(unit, "z", y_or, "other")
|
||||
|
||||
type test = {
|
||||
z: string,
|
||||
y: int,
|
||||
x: string,
|
||||
w: bool,
|
||||
v: int
|
||||
}
|
||||
|
||||
let make_concrete_sum = (r: z_to_v) : z_or =>
|
||||
switch(r){
|
||||
| Z => (M_left (unit) : z_or)
|
||||
| Y => (M_right (M_left (unit): y_or) : z_or )
|
||||
| X => (M_right (M_right (M_left (unit): x_or): y_or) : z_or )
|
||||
| W => (M_right (M_right (M_right (M_left (unit): w_or_v): x_or): y_or) : z_or )
|
||||
| V => (M_right (M_right (M_right (M_right (unit): w_or_v): x_or): y_or) : z_or )
|
||||
}
|
||||
|
||||
let make_concrete_record = (r: test) : (string, int, string, bool, int) =>
|
||||
(r.z, r.y, r.x, r.w, r.v)
|
||||
|
||||
let make_abstract_sum = (z_or: z_or) : z_to_v =>
|
||||
switch (z_or) {
|
||||
| M_left n => Z
|
||||
| M_right y_or => (
|
||||
switch (y_or) {
|
||||
| M_left n => Y
|
||||
| M_right x_or => (
|
||||
switch (x_or) {
|
||||
| M_left n => X
|
||||
| M_right w_or => (
|
||||
switch (w_or) {
|
||||
| M_left n => W
|
||||
| M_right n => V
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
let make_abstract_record = (z: string, y: int, x: string, w: bool, v: int) : test =>
|
||||
{ z : z, y, x, w, v }
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
## Amendment
|
||||
With the upcoming 007 amendment to Tezos this will change though, and also
|
||||
`pair`'s can be ordered differently.
|
@ -11,13 +11,13 @@ LIGO features timestamps, as Michelson does, while bakers baking the
|
||||
block (including the transaction in a block) are responsible for
|
||||
providing the given current timestamp for the contract.
|
||||
|
||||
### Current Time
|
||||
### Starting time of the current block
|
||||
|
||||
You can obtain the current time using the built-in syntax specific
|
||||
expression, please be aware that it is up to the baker to set the
|
||||
You can obtain the starting time of the current block using the
|
||||
built-in `Tezos.now`. This timestamp does not change during the execution
|
||||
of the contract. Please be aware that it is up to the baker to set the
|
||||
current timestamp value.
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=a
|
||||
@ -62,20 +62,20 @@ constraints on your smart contracts. Consider the following scenarios.
|
||||
|
||||
```pascaligo group=b
|
||||
const today : timestamp = Tezos.now
|
||||
const one_day : int = 86400
|
||||
const one_day : int = 86_400
|
||||
const in_24_hrs : timestamp = today + one_day
|
||||
const some_date : timestamp = ("2000-01-01T10:10:10Z" : timestamp)
|
||||
const one_day_later : timestamp = some_date + one_day
|
||||
```
|
||||
|
||||
> Note that `now` is *deprecated*.
|
||||
> Note that `now` is *deprecated*. Please use `Tezos.now`.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=b
|
||||
let today : timestamp = Tezos.now
|
||||
let one_day : int = 86400
|
||||
let one_day : int = 86_400
|
||||
let in_24_hrs : timestamp = today + one_day
|
||||
let some_date : timestamp = ("2000-01-01t10:10:10Z" : timestamp)
|
||||
let one_day_later : timestamp = some_date + one_day
|
||||
@ -88,7 +88,7 @@ let one_day_later : timestamp = some_date + one_day
|
||||
|
||||
```reasonligo group=b
|
||||
let today : timestamp = Tezos.now;
|
||||
let one_day : int = 86400;
|
||||
let one_day : int = 86_400;
|
||||
let in_24_hrs : timestamp = today + one_day;
|
||||
let some_date : timestamp = ("2000-01-01t10:10:10Z" : timestamp);
|
||||
let one_day_later : timestamp = some_date + one_day;
|
||||
@ -110,7 +110,7 @@ const one_day : int = 86400
|
||||
const in_24_hrs : timestamp = today - one_day
|
||||
```
|
||||
|
||||
> Note that `now` is *deprecated*.
|
||||
> Note that `now` is *deprecated*. Please use `Tezos.now`.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
@ -149,7 +149,7 @@ applying to numbers.
|
||||
const not_tommorow : bool = (Tezos.now = in_24_hrs)
|
||||
```
|
||||
|
||||
> Note that `now` is *deprecated*.
|
||||
> Note that `now` is *deprecated*. Please use `Tezos.now`.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
@ -3,7 +3,7 @@ id: cli-commands
|
||||
title: CLI Commands
|
||||
---
|
||||
|
||||
Contracts written in Ligo can be compiled using the `ligo` executable.
|
||||
Contracts written in LIGO can be compiled using the `ligo` executable.
|
||||
|
||||
|
||||
## Compiling a contract
|
||||
|
@ -6,7 +6,7 @@ title: Documentation and releases
|
||||
|
||||
## Documentation
|
||||
|
||||
If you'd like to contribute to the docs you can find them at [`gitlab-pages/docs`]() in raw markdown form.
|
||||
If you'd like to contribute to the docs you can find them at `gitlab-pages/docs` in raw markdown form.
|
||||
Deployment of the docs/website for LIGO is taken care of within the CI, from `dev` and `master` branches.
|
||||
|
||||
## Releases & versioning
|
||||
|
@ -7,7 +7,7 @@ Bonus: you'll become more familiar with LIGO in the process!
|
||||
Tests are written in OCaml, as LIGO doesn't (yet) have a good way to do automated testing. Thankfully the test code is typically less demanding than the features being tested.
|
||||
|
||||
Tests are currently contained in [src/test](https://gitlab.com/ligolang/ligo/tree/dev/src/test), but most are integration tests which rely on test contracts kept in [src/test/contracts](https://gitlab.com/ligolang/ligo/tree/dev/src/test/contracts). If you're new to LIGO, reading these contracts can be a useful introduction to a particular LIGO syntax. In the future we plan
|
||||
to have detailed documentation for each syntax, but at the moment we only have a reference manual for [PascaLIGO](https://gitlab.com/ligolang/ligo/blob/dev/src/passes/1-parser/pascaligo/Doc/pascaligo.md)
|
||||
to have detailed documentation for each syntax, but at the moment we only have a reference manual for [PascaLIGO](https://gitlab.com/ligolang/ligo/blob/dev/src/passes/01-parsing/pascaligo/Doc/pascaligo.md)
|
||||
|
||||
## How To Find Good Test Cases
|
||||
|
||||
@ -23,7 +23,7 @@ LIGO is divided into two parts
|
||||
- the **front end** handles syntax
|
||||
- the **backend** optimizes and compiles a core language shared between syntaxes
|
||||
|
||||
You can find basic test cases for a particular LIGO syntax by studying its parser. You will find the parser under [src/passes/1-parser](https://gitlab.com/ligolang/ligo/tree/dev/src/passes/1-parser).
|
||||
You can find basic test cases for a particular LIGO syntax by studying its parser. You will find the parser under [src/passes/1-parser](https://gitlab.com/ligolang/ligo/tree/dev/src/passes/01-parsing).
|
||||
|
||||
### Two Useful Test Cases Using LIGO
|
||||
|
||||
@ -102,7 +102,7 @@ What's going on is similar to the last program: `expect_eq_evaluate` runs a prog
|
||||
|
||||
For example, once the program stops running the value of `address` is `"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"`. The *comparison*, however, is made to a constructed expression.
|
||||
|
||||
Remember that we're testing from OCaml, but the program is written and evaluated as LIGO. In order to provide a proper comparison, we convert our expected test values into LIGO expressions and data. Constructors such as `e_list` and `e_address` provide a bridge between LIGO and OCaml. Their definitions can be found in files such as [src/stages/ast_core/combinators.ml](https://gitlab.com/ligolang/ligo/blob/dev/src/stages/ast_core/combinators.ml), or using [Merlin's definition point finder](https://github.com/ocaml/merlin/wiki). These same functions are used during the simplification stage of LIGO compilation, so becoming familiar with them will help prepare you to work on the [front end](contributors/big-picture/front-end/).
|
||||
Remember that we're testing from OCaml, but the program is written and evaluated as LIGO. In order to provide a proper comparison, we convert our expected test values into LIGO expressions and data. Constructors such as `e_list` and `e_address` provide a bridge between LIGO and OCaml. Their definitions can be found in files such as [src/stages/ast_core/combinators.ml](https://gitlab.com/ligolang/ligo/blob/dev/src/stages/ast_core/combinators.ml), or using [Merlin's definition point finder](https://github.com/ocaml/merlin/wiki). These same functions are used during the simplification stage of LIGO compilation, so becoming familiar with them will help prepare you to work on the [front end](big-picture/front-end.md).
|
||||
|
||||
## How To Write A Test For LIGO
|
||||
|
||||
|
170
gitlab-pages/docs/demo/ligo-snippet.md
Normal file
@ -0,0 +1,170 @@
|
||||
---
|
||||
id: ligo-snippets-demo
|
||||
title: Ligo-Snippets Demo
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
“ligo-snippets” (https://www.npmjs.com/package/@ligolang/ligo-snippets) is a React component that can be included on any webpage to display Ligo source code to users.
|
||||
|
||||
The user will see Ligo code with syntax highlighting, and an action button allowing the user to open the source code in the Ligo Web IDE (https://ide.ligolang.org).
|
||||
|
||||
Each code snippet can have preset Ligo Web IDE configurations (e.g. entrypoint, parameters or storage). These configurations are optional and will be passed onto the Ligo Web IDE when present. This will allow examples to provide the proper configurations for the reader to experiment with.
|
||||
|
||||
The “ligo-snippets” React component uses the CodeJar editor (https://github.com/antonmedv/codejar), which is extremely lightweight (only 2kB). It currently supports syntax highlighting for PascaLigo, CameLigo and ReasonLigo. Additionally, it has both a light and dark theme mode.
|
||||
|
||||
|
||||
|
||||
<Tabs
|
||||
defaultValue="pascaligo"
|
||||
values={[
|
||||
{ label: 'PascaLIGO', value: 'pascaligo', },
|
||||
{ label: 'CameLIGO', value: 'cameligo', },
|
||||
{ label: 'ReasonLIGO', value: 'reasonligo', },
|
||||
]
|
||||
}>
|
||||
<TabItem value="pascaligo">
|
||||
|
||||
```pascaligo {"name": "Ligo Introduction Example", "editor": true}
|
||||
(*_*
|
||||
name: PascaLIGO Contract
|
||||
language: pascaligo
|
||||
compile:
|
||||
entrypoint: main
|
||||
dryRun:
|
||||
entrypoint: main
|
||||
parameters: Increment (1)
|
||||
storage: 999
|
||||
deploy:
|
||||
entrypoint: main
|
||||
storage: 999
|
||||
evaluateValue:
|
||||
entrypoint: ""
|
||||
evaluateFunction:
|
||||
entrypoint: add
|
||||
parameters: (5, 6)
|
||||
generateDeployScript:
|
||||
entrypoint: main
|
||||
storage: 999
|
||||
*_*)
|
||||
// variant defining pseudo multi-entrypoint actions
|
||||
type action is
|
||||
| Increment of int
|
||||
| Decrement of int
|
||||
|
||||
function add (const a : int ; const b : int) : int is
|
||||
block { skip } with a + b
|
||||
|
||||
function subtract (const a : int ; const b : int) : int is
|
||||
block { skip } with a - b
|
||||
|
||||
// real entrypoint that re-routes the flow based
|
||||
// on the action provided
|
||||
function main (const p : action ; const s : int) :
|
||||
(list(operation) * int) is
|
||||
block { skip } with ((nil : list(operation)),
|
||||
case p of
|
||||
| Increment(n) -> add(s, n)
|
||||
| Decrement(n) -> subtract(s, n)
|
||||
end)
|
||||
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cameligo">
|
||||
|
||||
```cameligo {"name": "Ligo Introduction Example", "editor": true}
|
||||
(*_*
|
||||
name: CameLIGO Contract
|
||||
language: cameligo
|
||||
compile:
|
||||
entrypoint: main
|
||||
dryRun:
|
||||
entrypoint: main
|
||||
parameters: Increment 1
|
||||
storage: 999
|
||||
deploy:
|
||||
entrypoint: main
|
||||
storage: 999
|
||||
evaluateValue:
|
||||
entrypoint: ""
|
||||
evaluateFunction:
|
||||
entrypoint: add
|
||||
parameters: 5, 6
|
||||
generateDeployScript:
|
||||
entrypoint: main
|
||||
storage: 999
|
||||
*_*)
|
||||
type storage = int
|
||||
|
||||
(* variant defining pseudo multi-entrypoint actions *)
|
||||
|
||||
type action =
|
||||
| Increment of int
|
||||
| Decrement of int
|
||||
|
||||
let add (a,b: int * int) : int = a + b
|
||||
let sub (a,b: int * int) : int = a - b
|
||||
|
||||
(* real entrypoint that re-routes the flow based on the action provided *)
|
||||
|
||||
let main (p,s: action * storage) =
|
||||
let storage =
|
||||
match p with
|
||||
| Increment n -> add (s, n)
|
||||
| Decrement n -> sub (s, n)
|
||||
in ([] : operation list), storage
|
||||
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="reasonligo">
|
||||
|
||||
```reasonligo {"name": "Ligo Introduction Example", "editor": true}
|
||||
(*_*
|
||||
name: ReasonLIGO Contract
|
||||
language: reasonligo
|
||||
compile:
|
||||
entrypoint: main
|
||||
dryRun:
|
||||
entrypoint: main
|
||||
parameters: Increment (1)
|
||||
storage: 999
|
||||
deploy:
|
||||
entrypoint: main
|
||||
storage: 999
|
||||
evaluateValue:
|
||||
entrypoint: ""
|
||||
evaluateFunction:
|
||||
entrypoint: add
|
||||
parameters: (5, 6)
|
||||
generateDeployScript:
|
||||
entrypoint: main
|
||||
storage: 999
|
||||
*_*)
|
||||
type storage = int;
|
||||
|
||||
/* variant defining pseudo multi-entrypoint actions */
|
||||
|
||||
type action =
|
||||
| Increment(int)
|
||||
| Decrement(int);
|
||||
|
||||
let add = ((a,b): (int, int)): int => a + b;
|
||||
let sub = ((a,b): (int, int)): int => a - b;
|
||||
|
||||
/* real entrypoint that re-routes the flow based on the action provided */
|
||||
|
||||
let main = ((p,storage): (action, storage)) => {
|
||||
let storage =
|
||||
switch (p) {
|
||||
| Increment(n) => add((storage, n))
|
||||
| Decrement(n) => sub((storage, n))
|
||||
};
|
||||
([]: list(operation), storage);
|
||||
};
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
@ -3,26 +3,28 @@ id: installation
|
||||
title: Installation
|
||||
---
|
||||
|
||||
There are currently two ways to get started with Ligo. You can choose to use a Docker image, or to install packages for your Debian Linux distribution.
|
||||
There are currently three ways to get started with LIGO. You can choose to use a Docker image, a static Linux binary or to install packages for your Debian Linux distribution.
|
||||
|
||||
## Dockerized installation (recommended)
|
||||
|
||||
> 🐳 You can find instructions on how to install Docker [here](https://docs.docker.com/install/).
|
||||
|
||||
It's easiest to use LIGO through one of its Docker images. You have two options:
|
||||
* Use our installation script to set up a globally available LIGO
|
||||
* Use our installation script to set up a globally available `ligo`
|
||||
executable (see below). This manages the Docker bits for you.
|
||||
* Use the Docker image available at [Docker Hub](https://hub.docker.com/r/ligolang/ligo).
|
||||
This lets you run multiple versions and keep your installation(s) self contained, but requires more familiarity with Docker.
|
||||
This lets you run multiple versions and keep your installation(s) self-contained but requires more familiarity with Docker.
|
||||
|
||||
Sources for the image can be found on [GitLab](https://gitlab.com/ligolang/ligo/blob/master/docker/Dockerfile).
|
||||
If this is your first time using Docker, you probably want to set up a global LIGO executable as shown below.
|
||||
If this is your first time using Docker, you probably want to set up a global `ligo` executable as shown below.
|
||||
|
||||
### Setting up a globally available `ligo` executable
|
||||
|
||||
> You can install additional ligo versions by replacing `next` with the desired version number
|
||||
<!--
|
||||
> You can install additional LIGO versions by replacing `next` with the desired version number
|
||||
-->
|
||||
|
||||
Download the latest binaries here: https://gitlab.com/ligolang/ligo/pipelines/85536879/builds or get the latest pre-release:
|
||||
Get the latest pre-release:
|
||||
|
||||
```zsh
|
||||
# next (pre-release)
|
||||
@ -35,25 +37,36 @@ curl https://gitlab.com/ligolang/ligo/raw/master/scripts/installer.sh | bash -s
|
||||
```
|
||||
-->
|
||||
|
||||
**Verify your ligo installation by running:**
|
||||
**Verify your LIGO installation by running:**
|
||||
```zsh
|
||||
ligo --help
|
||||
```
|
||||
|
||||
## Static Linux binary
|
||||
|
||||
The `ligo` executable is statically linked. It should run on most modern Linux distributions.
|
||||
|
||||
To use it, get it [here](https://ligolang.org/bin/linux/ligo), make it executable, you're done!
|
||||
|
||||
```zsh
|
||||
wget https://ligolang.org/bin/linux/ligo
|
||||
chmod +x ./ligo
|
||||
```
|
||||
|
||||
Optionally, you can put it somewhere in your `PATH` for easy access:
|
||||
|
||||
```zsh
|
||||
sudo cp ./ligo /usr/local/bin
|
||||
```
|
||||
|
||||
## Debian Linux package installation
|
||||
|
||||
We have produced .deb packages for a few Debian Linux versions. They will install a global `ligo` executable.
|
||||
First download one of the packages below, and then install using:
|
||||
A `.deb` package containing the static `ligo` executable is also available.
|
||||
First, download [the package](https://ligolang.org/deb/ligo.deb), and then install using:
|
||||
|
||||
```zsh
|
||||
sudo apt install ./ligo.deb
|
||||
```
|
||||
sudo apt install ./<package_name_here>.deb
|
||||
```
|
||||
|
||||
- [Ubuntu 18.04](/deb/ligo_ubuntu-18.04.deb)
|
||||
- [Ubuntu 19.04](/deb/ligo_ubuntu-19.04.deb)
|
||||
- [Debian 9](/deb/ligo_debian-9.deb)
|
||||
- [Debian 10](/deb/ligo_debian-10.deb)
|
||||
|
||||
## Release schedule
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
id: introduction
|
||||
title: Introduction To LIGO
|
||||
title: Introduction to LIGO
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
@ -9,13 +9,13 @@ import TabItem from '@theme/TabItem';
|
||||
LIGO is a programming language for writing [Tezos](https://tezos.com/) smart contracts.
|
||||
Smart contracts are a unique domain with extreme resource constraints and even
|
||||
more extreme security risks. Unlike desktop, mobile, or web
|
||||
application development smart contracts cannot rely on cheap CPU time and memory.
|
||||
application development, smart contracts cannot rely on cheap CPU time and memory.
|
||||
All resources used by contracts are expensive, and tracked as 'gas costs'. Smart
|
||||
contracts often directly control money or assets, which if stolen could rack up to
|
||||
a large financial loss to the contracts controllers and users. Tezos smart contracts
|
||||
live on the blockchain forever, if there's a bug in them they can't be patched or
|
||||
amended. Naturally under these conditions it's not possible to develop smart contracts
|
||||
the way we're used to developing user facing applications.
|
||||
amended. Naturally, under these conditions, it's not possible to develop smart contracts
|
||||
the way we're used to developing user-facing applications.
|
||||
|
||||
LIGO is designed with these problems in mind. The design philosophy can be
|
||||
described in a few bullet points:
|
||||
@ -29,7 +29,7 @@ compiled output using a project like [Mi-Cho-Coq](https://gitlab.com/nomadic-lab
|
||||
|
||||
4. Significantly reduce the risk that your smart contract will lose its balance to an [avoidable exploit](https://www.wired.com/2016/06/50-million-hack-just-showed-dao-human/).
|
||||
|
||||
LIGO is a functional language designed to include the features you need, while
|
||||
LIGO is a functional language designed to include the features you need while
|
||||
avoiding patterns that make formal verification hard. Most useful smart contracts
|
||||
can express their core functionality in under a thousand lines of code. This makes
|
||||
them a good target for formal methods, and what can't be easily proven can at least
|
||||
@ -41,11 +41,11 @@ LIGO currently offers three syntaxes:
|
||||
- **PascaLIGO**, a syntax inspired by Pascal which provides an
|
||||
imperative developer experience.
|
||||
|
||||
- **CameLIGO**, an [OCaml]((https://ocaml.org/)) inspired
|
||||
- **CameLIGO**, an [OCaml](https://ocaml.org/) inspired
|
||||
syntax that allows you to write in a functional style.
|
||||
|
||||
- **ReasonLIGO**, an [ReasonML]((https://reasonml.github.io/)) inspired syntax
|
||||
that builds on the strong points of OCaml. It aims to be familiar for those
|
||||
- **ReasonLIGO**, a [ReasonML](https://reasonml.github.io/) inspired syntax
|
||||
that builds on the strong points of OCaml. It aims to be familiar to those
|
||||
coming from JavaScript.
|
||||
|
||||
Let's define some LIGO contract in the three flavours above. Do
|
||||
@ -134,20 +134,19 @@ This LIGO contract accepts the following LIGO expressions:
|
||||
|
||||
---
|
||||
|
||||
## Runnable code snippets & exercises
|
||||
## Runnable code snippets
|
||||
|
||||
Some of the sections in this documentation will include runnable code snippets and exercises. Sources for those are available at
|
||||
Some of the sections in this documentation will include runnable code snippets. Sources for those are available at
|
||||
the [LIGO Gitlab repository](https://gitlab.com/ligolang/ligo).
|
||||
|
||||
### Snippets
|
||||
|
||||
For example **code snippets** for the *Types* subsection of this doc, can be found here:
|
||||
`gitlab-pages/docs/language-basics/src/types/**`
|
||||
|
||||
### Exercises
|
||||
Solutions to exercises can be found e.g. here: `gitlab-pages/docs/language-basics/exercises/types/**/solutions/**`
|
||||
### Running snippets
|
||||
|
||||
### Running snippets / exercise solutions
|
||||
In certain cases it makes sense to be able to run/evaluate the given snippet or a solution, usually there'll be an example command which you can use, such as:
|
||||
In certain cases it makes sense to be able to run/evaluate the given snippet. Usually there'll be an example command which you can use, such as:
|
||||
|
||||
```shell
|
||||
ligo evaluate-value -s pascaligo gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo age
|
||||
|
@ -36,6 +36,373 @@ let b : bool = false;
|
||||
|
||||
</Syntax>
|
||||
|
||||
Common operations:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
<div className="boolean-example-table">
|
||||
<div className="operation">
|
||||
and
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical and
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const logical_and: bool = True and True;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
or
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical or
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const logical_or: bool = False or True;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
not
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical not
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const logical_not: bool = not False;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
=
|
||||
</div>
|
||||
<div className="description">
|
||||
Equals
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const eq: bool = 2 = 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
=/=
|
||||
</div>
|
||||
<div className="description">
|
||||
Not equals
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const not_eq: bool = 2 =/= 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
>
|
||||
</div>
|
||||
<div className="description">
|
||||
Greater than
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const gt: bool = 4 > 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
<
|
||||
</div>
|
||||
<div className="description">
|
||||
Less than
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const lt: bool = 4 < 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
>=
|
||||
</div>
|
||||
<div className="description">
|
||||
Greater than or equal to
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const gte: bool = 4 >= 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
<=
|
||||
</div>
|
||||
<div className="description">
|
||||
Less than or equal to
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```pascaligo
|
||||
const lte: bool = 4 <= 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="cameligo">
|
||||
<div className="boolean-example-table">
|
||||
<div className="operation">
|
||||
&&
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical and
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let logical_and: bool = true && true
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
||
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical or
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let logical_or: bool = false || true
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
!
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical not
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let logical_not: bool = not false
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
=
|
||||
</div>
|
||||
<div className="description">
|
||||
Equals
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let eq: bool = 2 = 3
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
<>
|
||||
</div>
|
||||
<div className="description">
|
||||
Not equals
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let not_eq: bool = 2 <> 3
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
>
|
||||
</div>
|
||||
<div className="description">
|
||||
Greater than
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let gt: bool = 4 > 3
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
<
|
||||
</div>
|
||||
<div className="description">
|
||||
Less than
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let lt: bool = 4 < 3
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
>=
|
||||
</div>
|
||||
<div className="description">
|
||||
Greater than or equal to
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let gte: bool = 4 >= 3
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
<=
|
||||
</div>
|
||||
<div className="description">
|
||||
Less than or equal to
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```cameligo
|
||||
let lte: bool = 4 <= 3
|
||||
```
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="reasonligo">
|
||||
<div className="boolean-example-table">
|
||||
<div className="operation">
|
||||
&&
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical and
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let logical_and: bool = true && true;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
||
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical or
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let logical_or: bool = false || true;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
!
|
||||
</div>
|
||||
<div className="description">
|
||||
Logical not
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let logical_not: bool = !false;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
==
|
||||
</div>
|
||||
<div className="description">
|
||||
Equals
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let eq: bool = 2 == 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
!=
|
||||
</div>
|
||||
<div className="description">
|
||||
Not equals
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let not_eq: bool = 2 != 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
>
|
||||
</div>
|
||||
<div className="description">
|
||||
Greater than
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let gt: bool = 4 > 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
<
|
||||
</div>
|
||||
<div className="description">
|
||||
Less than
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let lt: bool = 4 < 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
>=
|
||||
</div>
|
||||
<div className="description">
|
||||
Greater than or equal to
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let gte: bool = 4 >= 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
<div className="operation">
|
||||
<=
|
||||
</div>
|
||||
<div className="description">
|
||||
Less than or equal to
|
||||
</div>
|
||||
<div className="example">
|
||||
|
||||
```reasonligo
|
||||
let lte: bool = 4 <= 3;
|
||||
```
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Syntax>
|
||||
|
||||
## Comparing Values
|
||||
|
||||
@ -152,6 +519,7 @@ let c : bool = (a = b) // false
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=d
|
||||
let a : tez = 5mutez;
|
||||
let b : tez = 10mutez;
|
||||
@ -181,7 +549,7 @@ You can run the `compare` function defined above using the LIGO compiler
|
||||
like this:
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/boolean-if-else/cond.ligo compare 21n'
|
||||
gitlab-pages/docs/language-basics/src/boolean-if-else/cond.ligo compare '21n'
|
||||
# Outputs: Large(Unit)
|
||||
```
|
||||
|
||||
@ -222,7 +590,7 @@ You can run the `compare` function defined above using the LIGO compiler
|
||||
like this:
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/boolean-if-else/cond.mligo compare 21n'
|
||||
gitlab-pages/docs/language-basics/src/boolean-if-else/cond.mligo compare '21n'
|
||||
# Outputs: Large
|
||||
```
|
||||
|
||||
@ -245,7 +613,7 @@ You can run the `compare` function defined above using the LIGO compiler
|
||||
like this:
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/boolean-if-else/cond.religo compare 21n'
|
||||
gitlab-pages/docs/language-basics/src/boolean-if-else/cond.religo compare '21n'
|
||||
# Outputs: Large
|
||||
```
|
||||
|
||||
|
@ -127,7 +127,7 @@ in CameLIGO. While this approach is faithful to the original OCaml,
|
||||
it is costlier in Michelson than naive function execution accepting
|
||||
multiple arguments. Instead, for most functions with more than one
|
||||
parameter, we should gather the arguments in a
|
||||
[tuple](language-basics/sets-lists-tuples.md) and pass the tuple in as
|
||||
[tuple](sets-lists-tuples.md) and pass the tuple in as
|
||||
a single parameter.
|
||||
|
||||
Here is how you define a basic function that accepts two integers and
|
||||
@ -342,7 +342,7 @@ At the moment, recursive function are limited to one (possibly tupled) parameter
|
||||
limited to tail recursion (i.e the recursive call should be the last expression of the function)
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
In PascaLigo recursive functions are defined using the `recursive` keyword
|
||||
In PascaLIGO recursive functions are defined using the `recursive` keyword
|
||||
|
||||
```pascaligo group=d
|
||||
recursive function sum (const n : int; const acc: int) : int is
|
||||
@ -353,7 +353,7 @@ recursive function fibo (const n: int; const n_1: int; const n_0 :int) : int is
|
||||
```
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
In CameLigo recursive functions are defined using the `rec` keyword
|
||||
In CameLIGO recursive functions are defined using the `rec` keyword
|
||||
|
||||
```cameligo group=d
|
||||
let rec sum ((n,acc):int * int) : int =
|
||||
@ -364,7 +364,7 @@ let rec fibo ((n,n_1,n_0):int*int*int) : int =
|
||||
```
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
In ReasonLigo recursive functions are defined using the `rec` keyword
|
||||
In ReasonLIGO recursive functions are defined using the `rec` keyword
|
||||
|
||||
```reasonligo group=d
|
||||
let rec sum = ((n, acc) : (int,int)): int =>
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
id: loops
|
||||
title: Loops
|
||||
title: Iteration
|
||||
---
|
||||
|
||||
import Syntax from '@theme/Syntax';
|
||||
@ -110,6 +110,7 @@ let gcd = ((x,y) : (nat, nat)) : nat => {
|
||||
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
## Bounded Loops
|
||||
|
||||
@ -212,3 +213,5 @@ gitlab-pages/docs/language-basics/src/loops/collection.ligo sum_map
|
||||
'map ["1"->1; "2"->2; "3"->3]'
|
||||
# Outputs: ( "123", 6 )
|
||||
```
|
||||
|
||||
</Syntax>
|
@ -5,20 +5,18 @@ title: Records and Maps
|
||||
|
||||
import Syntax from '@theme/Syntax';
|
||||
|
||||
So far we have seen pretty basic data types. LIGO also offers more
|
||||
So far, we have seen pretty basic data types. LIGO also offers more
|
||||
complex built-in constructs, such as *records* and *maps*.
|
||||
|
||||
## Records
|
||||
|
||||
Records are one way data of different types can be packed into a
|
||||
Records are one-way data of different types can be packed into a
|
||||
single type. A record is made of a set of *fields*, which are made of
|
||||
a *field name* and a *field type*. Given a value of a record type, the
|
||||
value bound to a field can be accessed by giving its field name to a
|
||||
special operator (`.`).
|
||||
|
||||
Let us first consider and example of record type declaration.
|
||||
|
||||
|
||||
Let us first consider an example of record type declaration.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
@ -55,10 +53,8 @@ type user = {
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
And here is how a record value is defined:
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=records1
|
||||
@ -138,13 +134,11 @@ updated record.
|
||||
Let us consider defining a function that translates three-dimensional
|
||||
points on a plane.
|
||||
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
In PascaLIGO, the shape of that expression is
|
||||
`<record variable> with <record value>`.
|
||||
The record variable is the record to update and the
|
||||
In PascaLIGO, the shape of that expression is
|
||||
`<record variable> with <record value>`.
|
||||
The record variable is the record to update, and the
|
||||
record value is the update itself.
|
||||
|
||||
```pascaligo group=records2
|
||||
@ -162,13 +156,13 @@ following command of the shell:
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/src/maps-records/record_update.ligo
|
||||
translate "(record [x=2;y=3;z=1], record [dx=3;dy=4])"
|
||||
xy_translate "(record [x=2;y=3;z=1], record [dx=3;dy=4])"
|
||||
# Outputs: {z = 1 , y = 7 , x = 5}
|
||||
```
|
||||
|
||||
You have to understand that `p` has not been changed by the functional
|
||||
update: a namless new version of it has been created and returned by
|
||||
the blockless function.
|
||||
update: a nameless new version of it has been created and returned by
|
||||
the block-less function.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
@ -188,6 +182,7 @@ let xy_translate (p, vec : point * vector) : point =
|
||||
|
||||
You can call the function `xy_translate` defined above by running the
|
||||
following command of the shell:
|
||||
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/src/maps-records/record_update.mligo
|
||||
@ -220,6 +215,7 @@ let xy_translate = ((p, vec) : (point, vector)) : point =>
|
||||
|
||||
You can call the function `xy_translate` defined above by running the
|
||||
following command of the shell:
|
||||
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/src/maps-records/record_update.religo
|
||||
@ -230,10 +226,119 @@ xy_translate "({x:2,y:3,z:1}, {dx:3,dy:4})"
|
||||
You have to understand that `p` has not been changed by the functional
|
||||
update: a nameless new version of it has been created and returned.
|
||||
|
||||
#### Nested updates
|
||||
|
||||
A unique feature of LIGO is the ability to perform nested updates on records.
|
||||
|
||||
For example if you have the following record structure:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type color is
|
||||
| Blue
|
||||
| Green
|
||||
|
||||
type preferences is record [
|
||||
color : color;
|
||||
other : int;
|
||||
]
|
||||
|
||||
type account is record [
|
||||
id : int;
|
||||
preferences : preferences;
|
||||
]
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type color =
|
||||
Blue
|
||||
| Green
|
||||
|
||||
type preferences = {
|
||||
color : color;
|
||||
other : int;
|
||||
}
|
||||
|
||||
type account = {
|
||||
id: int;
|
||||
preferences: preferences;
|
||||
}
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type color =
|
||||
Blue
|
||||
| Green;
|
||||
|
||||
type preferences = {
|
||||
color : color,
|
||||
other : int
|
||||
}
|
||||
|
||||
type account = {
|
||||
id : int,
|
||||
preferences : preferences
|
||||
}
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
You can update the nested record with the following code:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
|
||||
function change_color_preference (const account : account; const color : color ) : account is
|
||||
block {
|
||||
account := account with record [preferences.color = color]
|
||||
} with account
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let change_color_preference (account : account) (color : color) : account =
|
||||
{ account with preferences.color = color }
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let change_color_preference = (account : account, color : color): account =>
|
||||
{ ...account, preferences.color: color };
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
Note that all the records in the path will get updated. In this example that's
|
||||
`account` and `preferences`.
|
||||
|
||||
You can call the function `change_color_preference` defined above by running the
|
||||
following command:
|
||||
|
||||
```shell
|
||||
ligo run-function gitlab-pages/docs/language-basics/src/maps-records/record_nested_update.ligo
|
||||
change_color_preference "(record [id=1001; preferences=record [color=Blue; other=1]], Green)"
|
||||
# Outputs: record[id -> 1001 , preferences -> record[color -> Green(unit) , other -> 1]]
|
||||
```
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
### Record Patches
|
||||
|
||||
Another way to understand what it means to update a record value is to
|
||||
make sure that any further reference to the value afterwards will
|
||||
make sure that any further reference to the value afterward will
|
||||
exhibit the modification. This is called a `patch` and this is only
|
||||
possible in PascaLIGO, because a patch is an *instruction*, therefore
|
||||
we can only use it in a block. Similarly to a *functional update*, a
|
||||
@ -248,8 +353,6 @@ points on a plane.
|
||||
type point is record [x : int; y : int; z : int]
|
||||
type vector is record [dx : int; dy : int]
|
||||
|
||||
const origin : point = record [x = 0; y = 0; z = 0]
|
||||
|
||||
function xy_translate (var p : point; const vec : vector) : point is
|
||||
block {
|
||||
patch p with record [x = p.x + vec.dx];
|
||||
@ -259,6 +362,7 @@ function xy_translate (var p : point; const vec : vector) : point is
|
||||
|
||||
You can call the function `xy_translate` defined above by running the
|
||||
following command of the shell:
|
||||
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/src/maps-records/record_patch.ligo
|
||||
@ -274,8 +378,6 @@ the value of `p` indeed changed. So, a shorter version would be
|
||||
type point is record [x : int; y : int; z : int]
|
||||
type vector is record [dx : int; dy : int]
|
||||
|
||||
const origin : point = record [x = 0; y = 0; z = 0]
|
||||
|
||||
function xy_translate (var p : point; const vec : vector) : point is
|
||||
block {
|
||||
patch p with record [x = p.x + vec.dx; y = p.y + vec.dy]
|
||||
@ -284,6 +386,7 @@ function xy_translate (var p : point; const vec : vector) : point is
|
||||
|
||||
You can call the new function `xy_translate` defined above by running the
|
||||
following command of the shell:
|
||||
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/src/maps-records/record_patch2.ligo
|
||||
@ -299,8 +402,6 @@ one we want to update* and use a functional update, like so:
|
||||
type point is record [x : int; y : int; z : int]
|
||||
type vector is record [dx : int; dy : int]
|
||||
|
||||
const origin : point = record [x = 0; y = 0; z = 0]
|
||||
|
||||
function xy_translate (var p : point; const vec : vector) : point is
|
||||
block {
|
||||
const p : point = p with record [x = p.x + vec.dx; y = p.y + vec.dy]
|
||||
@ -309,6 +410,7 @@ function xy_translate (var p : point; const vec : vector) : point is
|
||||
|
||||
You can call the new function `xy_translate` defined above by running the
|
||||
following command of the shell:
|
||||
|
||||
```shell
|
||||
ligo run-function
|
||||
gitlab-pages/docs/language-basics/src/maps-records/record_simu.ligo
|
||||
@ -318,6 +420,8 @@ xy_translate "(record [x=2;y=3;z=1], record [dx=3;dy=4])"
|
||||
|
||||
The hiding of a variable by another (here `p`) is called `shadowing`.
|
||||
|
||||
</Syntax>
|
||||
|
||||
## Maps
|
||||
|
||||
*Maps* are a data structure which associate values of the same type to
|
||||
@ -331,8 +435,6 @@ sense.
|
||||
Here is how a custom map from addresses to a pair of integers is
|
||||
defined.
|
||||
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=maps
|
||||
@ -586,8 +688,8 @@ let assign = (m : register) : register =>
|
||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), Some ((4,9)), m);
|
||||
```
|
||||
|
||||
Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had
|
||||
use `None` instead, that would have meant that the binding is removed.
|
||||
Notice the optional value `Some (4,9)` instead of `(4,9)`. If we used
|
||||
`None` instead that would have meant that the binding is removed.
|
||||
|
||||
As a particular case, we can only add a key and its associated value.
|
||||
|
||||
@ -599,7 +701,6 @@ let add = (m : register) : register =>
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
To remove a binding from a map, we need its key.
|
||||
|
||||
|
||||
@ -654,8 +755,8 @@ There are three kinds of functional iterations over LIGO maps: the
|
||||
|
||||
The first, the *iterated operation*, is an iteration over the map with
|
||||
no return value: its only use is to produce side-effects. This can be
|
||||
useful if for example you would like to check that each value inside
|
||||
of a map is within a certain range, and fail with an error otherwise.
|
||||
useful if, for example you would like to check that each value inside
|
||||
of a map is within a certain range and fail with an error otherwise.
|
||||
|
||||
The predefined functional iterator implementing the iterated operation
|
||||
over maps is called `Map.iter`. In the following example, the register
|
||||
@ -891,7 +992,7 @@ let moves : register =
|
||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
||||
```
|
||||
|
||||
The predefind function `Big_map.literal` constructs a big map from a
|
||||
The predefined function `Big_map.literal` constructs a big map from a
|
||||
list of key-value pairs `(<key>, <value>)`. Note also the semicolon
|
||||
separating individual map entries. The annotated value `("<string>
|
||||
value>" : address)` means that we cast a string into an address.
|
||||
@ -906,7 +1007,7 @@ let moves : register =
|
||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||
```
|
||||
|
||||
The predefind function `Big_map.literal` constructs a big map from a
|
||||
The predefined function `Big_map.literal` constructs a big map from a
|
||||
list of key-value pairs `(<key>, <value>)`. Note also the semicolon
|
||||
separating individual map entries. The annotated value `("<string>
|
||||
value>" : address)` means that we cast a string into an address.
|
||||
@ -959,12 +1060,23 @@ The values of a PascaLIGO big map can be updated using the
|
||||
assignment syntax for ordinary maps
|
||||
|
||||
```pascaligo group=big_maps
|
||||
function add (var m : register) : register is
|
||||
function assign (var m : register) : register is
|
||||
block {
|
||||
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
||||
} with m
|
||||
```
|
||||
|
||||
const updated_map : register = add (moves)
|
||||
If multiple bindings need to be updated, PascaLIGO offers a *patch
|
||||
instruction* for maps, similar to that for records.
|
||||
|
||||
```pascaligo group=big_maps
|
||||
function assignments (var m : register) : register is
|
||||
block {
|
||||
patch m with map [
|
||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (4,9);
|
||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) -> (1,2)
|
||||
]
|
||||
} with m
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
@ -1038,4 +1150,3 @@ let updated_map : register =
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
@ -25,7 +25,7 @@ Like records, tuple components can be of arbitrary types.
|
||||
|
||||
### Defining Tuples
|
||||
|
||||
Unlike [a record](language-basics/maps-records.md), tuple types do not
|
||||
Unlike [a record](maps-records.md), tuple types do not
|
||||
have to be defined before they can be used. However below we will give
|
||||
them names by *type aliasing*.
|
||||
|
||||
@ -59,12 +59,58 @@ let full_name : full_name = ("Alice", "Johnson");
|
||||
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
### Destructuring
|
||||
|
||||
If we want to get the first and last name of the `full_name` type, we can use
|
||||
destructuring. Destructuring a tuple allows you to give names to the elements
|
||||
inside the tuple.
|
||||
|
||||
```cameligo group=tuple
|
||||
let (first_name, last_name) : full_name = full_name
|
||||
```
|
||||
|
||||
This also works in functions:
|
||||
|
||||
```cameligo group=tuple
|
||||
let first_name ((first_name, _): full_name) = first_name
|
||||
let alice = first_name full_name
|
||||
```
|
||||
|
||||
Notice that we use the underscore to indicate that we ignore the last element
|
||||
of the tuple.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
### Destructuring
|
||||
|
||||
If we want to get the first and last name of the `full_name` type, we can use
|
||||
destructuring. Destructuring a tuple allows you to give names to the elements
|
||||
inside the tuple.
|
||||
|
||||
```reasonligo group=tuple
|
||||
let (first_name, last_name) : full_name = full_name
|
||||
```
|
||||
|
||||
This also works in functions:
|
||||
|
||||
```reasonligo group=tuple
|
||||
let first_name = ((first_name, _): full_name) => first_name
|
||||
let alice = first_name(full_name)
|
||||
```
|
||||
|
||||
Notice that we use the underscore to indicate that we ignore the last element
|
||||
of the tuple.
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
### Accessing Components
|
||||
|
||||
Accessing the components of a tuple in OCaml is achieved by
|
||||
[pattern matching](language-basics/unit-option-pattern-matching.md). LIGO
|
||||
[pattern matching](unit-option-pattern-matching.md). LIGO
|
||||
currently supports tuple patterns only in the parameters of functions,
|
||||
not in pattern matching. However, we can access components by their
|
||||
position in their tuple, which cannot be done in OCaml. *Tuple
|
||||
|
@ -71,16 +71,17 @@ let full_greeting : string = greeting ++ " " ++ name;
|
||||
|
||||
|
||||
|
||||
## Slicing Strings
|
||||
|
||||
Strings can be sliced using a built-in function:
|
||||
## Extracting Subtrings
|
||||
|
||||
Substrings can be extracted using the predefined function
|
||||
`String.sub`. The first character has index 0 and the interval of
|
||||
indices for the substring has inclusive bounds.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=b
|
||||
const name : string = "Alice"
|
||||
const slice : string = String.slice (0n, 1n, name)
|
||||
const slice : string = String.sub (0n, 1n, name)
|
||||
```
|
||||
|
||||
> Note that `string_slide` is *deprecated*.
|
||||
@ -90,17 +91,21 @@ const slice : string = String.slice (0n, 1n, name)
|
||||
|
||||
```cameligo group=b
|
||||
let name : string = "Alice"
|
||||
let slice : string = String.slice 0n 1n name
|
||||
let slice : string = String.sub 0n 1n name
|
||||
```
|
||||
|
||||
> Note that `String.slice` is *deprecated*.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=b
|
||||
let name : string = "Alice";
|
||||
let slice : string = String.slice (0n, 1n, name);
|
||||
let slice : string = String.sub (0n, 1n, name);
|
||||
```
|
||||
|
||||
> Note that `String.slice` is *deprecated*.
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
@ -119,23 +124,27 @@ const name : string = "Alice"
|
||||
const length : nat = String.length (name) // length = 5
|
||||
```
|
||||
|
||||
> Note that `size` is *deprecated*.
|
||||
> Note that `size` is *deprecated*.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=c
|
||||
let name : string = "Alice"
|
||||
let length : nat = String.size name // length = 5
|
||||
let length : nat = String.length name // length = 5
|
||||
```
|
||||
|
||||
> Note that `String.size` is *deprecated*.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=c
|
||||
let name : string = "Alice";
|
||||
let length : nat = String.size (name); // length == 5
|
||||
let length : nat = String.length (name); // length == 5
|
||||
```
|
||||
|
||||
> Note that `String.size` is *deprecated*.
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
@ -11,10 +11,11 @@ functions. This page will tell you about them.
|
||||
|
||||
## Pack and Unpack
|
||||
|
||||
Michelson provides the `PACK` and `UNPACK` instructions for data
|
||||
serialization. The former converts Michelson data structures into a
|
||||
binary format, and the latter reverses that transformation. This
|
||||
functionality can be accessed from within LIGO.
|
||||
As Michelson provides the `PACK` and `UNPACK` instructions for data
|
||||
serialization, so does LIGO with `Bytes.pack` and `Bytes.unpack`. The
|
||||
former serializes Michelson data structures into a binary format, and
|
||||
the latter reverses that transformation. Unpacking may fail, so the
|
||||
return type of `Byte.unpack` is an option that needs to be annotated.
|
||||
|
||||
> ⚠️ `PACK` and `UNPACK` are Michelson instructions that are intended
|
||||
> to be used by people that really know what they are doing. There are
|
||||
@ -28,11 +29,11 @@ functionality can be accessed from within LIGO.
|
||||
|
||||
```pascaligo group=a
|
||||
function id_string (const p : string) : option (string) is block {
|
||||
const packed : bytes = bytes_pack (p)
|
||||
const packed : bytes = Bytes.pack (p)
|
||||
} with (Bytes.unpack (packed) : option (string))
|
||||
```
|
||||
|
||||
> Note that `bytes_unpack` is *deprecated*.
|
||||
> Note that `bytes_pack` and `bytes_unpack` are *deprecated*.
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
@ -72,18 +73,21 @@ a predefined functions returning a value of type `key_hash`.
|
||||
function check_hash_key (const kh1 : key_hash; const k2 : key) : bool * key_hash is
|
||||
block {
|
||||
var ret : bool := False;
|
||||
var kh2 : key_hash := crypto_hash_key (k2);
|
||||
var kh2 : key_hash := Crypto.hash_key (k2);
|
||||
if kh1 = kh2 then ret := True else skip
|
||||
} with (ret, kh2)
|
||||
```
|
||||
|
||||
> Note that `hash_key` is *deprecated*. Please use `Crypto.hash_key`.
|
||||
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=b
|
||||
let check_hash_key (kh1, k2 : key_hash * key) : bool * key_hash =
|
||||
let kh2 : key_hash = Crypto.hash_key k2 in
|
||||
if kh1 = kh2 then true, kh2 else false, kh2
|
||||
let kh2 : key_hash = Crypto.hash_key k2 in
|
||||
(kh1 = kh2), kh2
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
@ -92,7 +96,7 @@ let check_hash_key (kh1, k2 : key_hash * key) : bool * key_hash =
|
||||
```reasonligo group=b
|
||||
let check_hash_key = ((kh1, k2) : (key_hash, key)) : (bool, key_hash) => {
|
||||
let kh2 : key_hash = Crypto.hash_key (k2);
|
||||
if (kh1 == kh2) { (true, kh2); } else { (false, kh2); }
|
||||
((kh1 == kh2), kh2);
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -8,53 +8,13 @@ hide_table_of_contents: true
|
||||
import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
A lazily deserialized map that's intended to store large amounts of data.
|
||||
A lazily deserialized map that's intended to store large amounts of data.
|
||||
Lazily means that storage is read or written per key on demand. Therefore
|
||||
there are no `map`, `fold`, and `iter` operations as in
|
||||
[Map](map.md).
|
||||
|
||||
The gast costs of deserialized maps are higher than standard maps as data is lazily deserialized.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type big_map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type ('key, 'value) big_map
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type big_map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
The type of a big map from values of type `key` to
|
||||
values of type `value` is `big_map (key, value)`.
|
||||
|
||||
```pascaligo group=big_map
|
||||
type move is int * int
|
||||
type register is big_map (address, move)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
The type of a big map from values of type `key` to values
|
||||
of type `value` is `(key, value) big_map`.
|
||||
|
||||
```cameligo group=big_map
|
||||
type move = int * int
|
||||
type register = (address, move) big_map
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
The type of a big map from values of type `key` to
|
||||
values of type `value` is `big_map (key, value)`.
|
||||
|
||||
```reasonligo group=big_map
|
||||
type move = (int, int);
|
||||
type register = big_map (address, move);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
The gas costs of big maps are higher than standard maps as data is lazily
|
||||
deserialized.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function empty : big_map ('key, 'value)
|
||||
@ -63,7 +23,7 @@ function empty : big_map ('key, 'value)
|
||||
val empty : ('key, 'value) big_map
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let empty: big_map ('key, 'value)
|
||||
let empty: big_map('key, 'value)
|
||||
</SyntaxTitle>
|
||||
|
||||
Create an empty big_map.
|
||||
@ -71,6 +31,9 @@ Create an empty big_map.
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=big_map
|
||||
type move is int * int
|
||||
type register is big_map (address, move)
|
||||
|
||||
const empty : register = Big_map.empty
|
||||
```
|
||||
|
||||
@ -84,6 +47,9 @@ const empty_alternative : register = big_map []
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=big_map
|
||||
type move = int * int
|
||||
type register = (address, move) big_map
|
||||
|
||||
let empty : register = Big_map.empty
|
||||
```
|
||||
|
||||
@ -91,7 +57,10 @@ let empty : register = Big_map.empty
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=big_map
|
||||
let empty : register = Big_map.empty
|
||||
type move = (int, int);
|
||||
type register = big_map(address, move);
|
||||
|
||||
let empty: register = Big_map.empty
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
@ -141,7 +110,7 @@ let moves : register =
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=big_map
|
||||
let moves : register =
|
||||
let moves: register =
|
||||
Big_map.literal ([
|
||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||
@ -156,7 +125,7 @@ function find_opt : 'key -> big_map ('key, 'value) -> option 'value
|
||||
val find_opt : 'key -> ('key, 'value) big_map -> 'value option
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let find_opt : ('key, big_map ('key, 'value)) => option ('value)
|
||||
let find_opt: ('key, big_map ('key, 'value)) => option ('value)
|
||||
</SyntaxTitle>
|
||||
|
||||
Retrieve a value from a big map with the given key.
|
||||
@ -191,8 +160,8 @@ let my_balance : move option =
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=big_map
|
||||
let my_balance : option (move) =
|
||||
Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, moves);
|
||||
let my_balance: option (move) =
|
||||
Big_map.find_opt("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, moves);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
@ -204,7 +173,7 @@ function update : 'key -> option 'value -> big_map ('key, 'value) -> big_map ('k
|
||||
val update: 'key -> 'value option -> ('key, 'value) big_map -> ('key, 'value) big_map
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let update: ('key, option('value), big_map ('key, 'value)) => big_map ('key, 'value)
|
||||
let update: ('key, option('value), big_map('key, 'value)) => big_map('key, 'value)
|
||||
</SyntaxTitle>
|
||||
|
||||
Note: when `None` is used as a value, the value is removed from the big_map.
|
||||
@ -255,9 +224,9 @@ let updated_map : register =
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=big_map
|
||||
let updated_map : register =
|
||||
let updated_map: register =
|
||||
Big_map.update
|
||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some ((4,9)), moves);
|
||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some((4,9)), moves);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
@ -292,7 +261,7 @@ let add (m : register) : register =
|
||||
```reasonligo group=big_map
|
||||
let add = (m: register): register =>
|
||||
Big_map.add
|
||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (4,9), m);
|
||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), (4,9), m);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
@ -305,7 +274,7 @@ function remove: 'key -> big_map ('key, 'value) -> big_map ('key, 'value)
|
||||
val remove: 'key -> ('key, 'value) big_map -> ('key, 'value) big_map
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let remove: ('key, big_map ('key, 'value)) => big_map ('key, 'value)
|
||||
let remove: ('key, big_map('key, 'value)) => big_map('key, 'value)
|
||||
</SyntaxTitle>
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
@ -340,8 +309,8 @@ let updated_map : register =
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=big_map
|
||||
let updated_map : register =
|
||||
Big_map.remove (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), moves)
|
||||
let updated_map: register =
|
||||
Big_map.remove(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), moves)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
@ -9,17 +9,42 @@ import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function and : nat -> nat -> nat
|
||||
function and : 'a -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val and : nat -> nat -> nat
|
||||
val and : 'a -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let and: (nat, nat) -> nat
|
||||
let and: ('a, nat) => nat
|
||||
</SyntaxTitle>
|
||||
|
||||
`'a` can either be an `int` or `nat`.
|
||||
|
||||
A bitwise `and` operation.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
const zero: nat = Bitwise.and(2n, 1n)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let zero: nat = Bitwise.and 2n 1n
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let zero: nat = Bitwise.and(2n, 1n);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function or : nat -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
@ -27,11 +52,33 @@ function or : nat -> nat -> nat
|
||||
val or : nat -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let or: (nat, nat) -> nat
|
||||
let or: (nat, nat) => nat
|
||||
</SyntaxTitle>
|
||||
|
||||
A bitwise `or` operation.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
const three: nat = Bitwise.or(2n, 1n)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let three: nat = Bitwise.or 2n 1n
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let three: nat = Bitwise.or(2n, 1n);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function xor : nat -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
@ -39,11 +86,33 @@ function xor : nat -> nat -> nat
|
||||
val xor : nat -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let xor: (nat, nat) -> nat
|
||||
let xor: (nat, nat) => nat
|
||||
</SyntaxTitle>
|
||||
|
||||
A bitwise `xor` operation.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
const three: nat = Bitwise.xor(2n, 1n)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let three: nat = Bitwise.xor 2n 1n
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let three: nat = Bitwise.xor(2n, 1n);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function shift_left : nat -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
@ -51,11 +120,33 @@ function shift_left : nat -> nat -> nat
|
||||
val shift_left : nat -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let shift_left: (nat, nat) -> nat
|
||||
let shift_left: (nat, nat) => nat
|
||||
</SyntaxTitle>
|
||||
|
||||
A bitwise shift left operation.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
const four: nat = Bitwise.shift_left(2n, 1n)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let four: nat = Bitwise.shift_left 2n 1n
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let four: nat = Bitwise.shift_left(2n, 1n);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function shift_right : nat -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
@ -63,7 +154,29 @@ function shift_right : nat -> nat -> nat
|
||||
val shift_right : nat -> nat -> nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let shift_right: (nat, nat) -> nat
|
||||
let shift_right: (nat, nat) => nat
|
||||
</SyntaxTitle>
|
||||
|
||||
A bitwise shift right operation.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
const one: nat = Bitwise.shift_right(2n, 1n)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let one: nat = Bitwise.shift_right 2n 1n
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let one: nat = Bitwise.shift_right(2n, 1n);
|
||||
```
|
||||
|
||||
</Syntax>
|
@ -8,16 +8,6 @@ hide_table_of_contents: true
|
||||
import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type bytes
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type bytes
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type bytes
|
||||
</SyntaxTitle>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function concat : bytes -> bytes -> bytes
|
||||
</SyntaxTitle>
|
||||
@ -65,8 +55,8 @@ val sub : nat -> nat -> bytes -> bytes
|
||||
let sub : (nat, nat, bytes) => bytes
|
||||
</SyntaxTitle>
|
||||
|
||||
Extract the bytes between `pos1` and `pos2`. **Positions are zero indexed and
|
||||
inclusive**. For example if you gave the input "ff7a7aff" to the following:
|
||||
Extract bytes from `start` to `length`. For example if you gave the
|
||||
input "ff7a7aff" to the following function:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
@ -96,7 +86,7 @@ let slice_op = (s: bytes): bytes => Bytes.sub(1n, 2n, s);
|
||||
|
||||
</Syntax>
|
||||
|
||||
It would return "7a7a" rather than "ff7a" or "ff" or "7a".
|
||||
It would return "7a7a".
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function pack : 'a -> bytes
|
||||
|
@ -8,42 +8,6 @@ hide_table_of_contents: true
|
||||
import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type key
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type key
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type key
|
||||
</SyntaxTitle>
|
||||
|
||||
A public cryptographic key.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type key_hash
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type key_hash
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type key_hash
|
||||
</SyntaxTitle>
|
||||
|
||||
The hash of a public cryptographic key.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type signature
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type signature
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type signature
|
||||
</SyntaxTitle>
|
||||
|
||||
A cryptographic signature.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function blake2b : bytes -> bytes
|
||||
</SyntaxTitle>
|
||||
|
@ -9,93 +9,17 @@ import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type timestamp
|
||||
function balance : tez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type timestamp
|
||||
val balance : tez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type timestamp
|
||||
</SyntaxTitle>
|
||||
|
||||
A date in the real world.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type mutez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type mutez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type mutez
|
||||
</SyntaxTitle>
|
||||
|
||||
A specific type for tokens.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type address
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type address
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type address
|
||||
</SyntaxTitle>
|
||||
|
||||
An untyped address which can refer to a smart contract or account.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type contract('parameter)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type 'parameter contract
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type contract('parameter)
|
||||
</SyntaxTitle>
|
||||
|
||||
A typed contract.
|
||||
|
||||
Use `unit` as `parameter` to indicate an implicit account.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type operation
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type operation
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type operation
|
||||
</SyntaxTitle>
|
||||
|
||||
An operation emitted by the contract
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type chain_id
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type chain_id
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type chain_id
|
||||
</SyntaxTitle>
|
||||
|
||||
The identifier of a chain, used to indicate test or main chains.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function balance : mutez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val balance : mutez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let balance: mutez
|
||||
let balance: tez
|
||||
</SyntaxTitle>
|
||||
|
||||
Get the balance for the contract.
|
||||
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
@ -263,13 +187,13 @@ let not_tomorrow: bool = (Tezos.now == in_24_hrs);
|
||||
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function amount : mutez
|
||||
function amount : tez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val amount : mutez
|
||||
val amount : tez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let amount: mutez
|
||||
let amount: tez
|
||||
</SyntaxTitle>
|
||||
|
||||
Get the amount of tez provided by the sender to complete this
|
||||
@ -598,48 +522,17 @@ let main = (p : unit) : address => Tezos.source;
|
||||
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function failwith : string -> unit
|
||||
function failwith : 'a -> unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
function failwith : string -> unit
|
||||
function failwith : 'a -> unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
function failwith : string -> unit
|
||||
function failwith: 'a -> unit
|
||||
</SyntaxTitle>
|
||||
|
||||
Cause the contract to fail with an error message.
|
||||
[See `failwith`](toplevel.md#failwith)
|
||||
|
||||
> ⚠ Using this currently requires in general a type annotation on the
|
||||
> `failwith` call.
|
||||
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
function main (const p : int; const s : unit) : list (operation) * unit is
|
||||
block {
|
||||
if p > 10 then failwith ("Failure.") else skip
|
||||
}
|
||||
with ((nil : list (operation)), s)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let main (p,s : int * unit) = if p > 10 then failwith "Failure."
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let main = ((p,s) : (int, unit)) =>
|
||||
if (p > 10) { failwith ("Failure."); };
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function chain_id : chain_id
|
||||
@ -713,10 +606,19 @@ val transaction : 'parameter -> mutez -> 'parameter contract -> operation
|
||||
let transaction: 'parameter -> mutez -> contract('parameter) -> operation
|
||||
</SyntaxTitle>
|
||||
|
||||
Create a transaction to a contract or account.
|
||||
Transfer `tez` to an account, or run code of another smart contract.
|
||||
|
||||
To indicate an account, use `unit` as `parameter`.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
Note that `transaction` is deprecated. Please use `Tezos.transaction` instead.
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
Note that `transaction` is deprecated. Please use `Tezos.transaction` instead.
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
Note that `transaction` is deprecated. Please use `Tezos.transaction` instead.
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function set_delegate : option(key_hash) -> operation
|
||||
@ -728,9 +630,26 @@ val set_delegate : key_hash option -> operation
|
||||
let set_delegate: option(key_hash) => operation
|
||||
</SyntaxTitle>
|
||||
|
||||
Create a delegation.
|
||||
Modify the [delegate](http://tezos.gitlab.io/user/glossary.html?highlight=delegate#delegate) of the current contract.
|
||||
|
||||
See also: http://tezos.gitlab.io/user/glossary.html?highlight=delegate#delegate
|
||||
The operation fails when:
|
||||
- the delegate is the same as current delegate
|
||||
- the keyhash is not of a registered delegate
|
||||
|
||||
Use `None` to withdraw the current delegate.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
Note that `set_delegate` is deprecated. Please use `Tezos.set_delegate`
|
||||
instead.
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
Note that `Operation.set_delegate` is deprecated. Please use
|
||||
`Tezos.set_delegate` instead.
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
Note that `Operation.set_delegate` is deprecated. Please use
|
||||
`Tezos.set_delegate` instead.
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function get_contract_opt : address -> option(contract('parameter))
|
||||
@ -747,6 +666,19 @@ Get a contract from an address.
|
||||
When no contract is found or the contract doesn't match the type,
|
||||
`None` is returned.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
Note that `get_contract` and `get_contract_opt` are deprecated. Please use
|
||||
`Tezos.get_contract_opt` instead.
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
Note that `Operation.get_contract` and `Operation.get_contract_opt` are
|
||||
deprecated. Please use `Tezos.get_contract_opt` instead.
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
Note that `Operation.get_contract` and `Operation.get_contract_opt` are
|
||||
deprecated. Please use `Tezos.get_contract_opt` instead.
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function get_entrypoint_opt : string -> address -> option(contract('parameter))
|
||||
</SyntaxTitle>
|
||||
@ -763,3 +695,18 @@ Entrypoints are written in the form of: `%entrypoint`.
|
||||
|
||||
When no contract is found or the contract doesn't match the type,
|
||||
`None` is returned.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
Note that `get_entrypoint` and `get_entrypoint_opt` are deprecated. Please use
|
||||
`Tezos.get_entrypoint_opt` instead.
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="cameligo">
|
||||
Note that `Operation.get_entrypoint` and `Operation.get_entrypoint_opt` are
|
||||
deprecated. Please use `Tezos.get_entrypoint_opt` instead.
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="reasonligo">
|
||||
Note that `Operation.get_entrypoint` and `Operation.get_entrypoint_opt` are
|
||||
deprecated. Please use `Tezos.get_entrypoint_opt` instead.
|
||||
</Syntax>
|
@ -8,18 +8,6 @@ hide_table_of_contents: true
|
||||
import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type list ('t)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type 't list
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type list('t)
|
||||
</SyntaxTitle>
|
||||
|
||||
A sequence of elements of the same type.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function length : nat
|
||||
</SyntaxTitle>
|
||||
@ -155,7 +143,7 @@ val fold : ('accumulator -> 'item -> 'accumulator) -> 'item list -> 'accumulator
|
||||
let fold: ((('accumulator, 'item) => 'accumulator), list('item), 'accumulator) => 'accumulator
|
||||
</SyntaxTitle>
|
||||
|
||||
[Fold over items in a list](../language-basics/sets-lists-tuples#folded-operation-over-lists);
|
||||
[Fold over items in a list](../language-basics/sets-lists-tuples.md#folded-operation-over-lists);
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
|
@ -8,50 +8,6 @@ hide_table_of_contents: true
|
||||
import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type ('key, 'value) map
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
The type of a map from values of type `key` to
|
||||
values of type `value` is `map (key, value)`.
|
||||
|
||||
```pascaligo group=maps
|
||||
type move is int * int
|
||||
type register is map (address, move)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
The type of a map from values of type `key` to values
|
||||
of type `value` is `(key, value) map`.
|
||||
|
||||
```cameligo group=maps
|
||||
type move = int * int
|
||||
type register = (address, move) map
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
The type of a map from values of type `key` to
|
||||
values of type `value` is `map (key, value)`.
|
||||
|
||||
```reasonligo group=maps
|
||||
type move = (int, int);
|
||||
type register = map (address, move);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function empty : map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
@ -67,6 +23,9 @@ Create an empty map.
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=maps
|
||||
type move is int * int
|
||||
type register is map (address, move)
|
||||
|
||||
const empty : register = Map.empty
|
||||
```
|
||||
|
||||
@ -80,6 +39,9 @@ const empty : register = map []
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=maps
|
||||
type move = int * int
|
||||
type register = (address, move) map
|
||||
|
||||
let empty : register = Map.empty
|
||||
```
|
||||
|
||||
@ -87,6 +49,9 @@ let empty : register = Map.empty
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=maps
|
||||
type move = (int, int);
|
||||
type register = map (address, move);
|
||||
|
||||
let empty : register = Map.empty
|
||||
```
|
||||
|
||||
|
@ -10,16 +10,6 @@ import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
Sets are unordered collections of unique values of the same type.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type set ('value)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type 'value set
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type set('value)
|
||||
</SyntaxTitle>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function empty : set('value)
|
||||
</SyntaxTitle>
|
||||
@ -258,7 +248,7 @@ val fold : ('accumulator -> 'item -> 'accumulator) -> 'set list -> 'accumulator
|
||||
let fold: ((('accumulator, 'item) => 'accumulator), set('item), 'accumulator) => 'accumulator
|
||||
</SyntaxTitle>
|
||||
|
||||
[Fold over values in a set](../language-basics/sets-lists-tuples#folded-operation)
|
||||
[Fold over values in a set](../language-basics/sets-lists-tuples.md#folded-operation)
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
@ -8,18 +8,6 @@ hide_table_of_contents: true
|
||||
import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type string
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type string
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type string
|
||||
</SyntaxTitle>
|
||||
|
||||
A sequence of characters.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function length : string -> nat
|
||||
</SyntaxTitle>
|
||||
@ -73,8 +61,8 @@ val sub : nat -> nat -> string -> string
|
||||
let sub: (nat, nat, string) => string
|
||||
</SyntaxTitle>
|
||||
|
||||
Get the substring of `s` between `pos1` inclusive and `pos2` inclusive. For example
|
||||
the string "tata" given to the function below would return "at".
|
||||
Extract a substring from a string based on the given offset and length. For
|
||||
example the string "abcd" given to the function below would return "bc".
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
461
gitlab-pages/docs/reference/toplevel.md
Normal file
@ -0,0 +1,461 @@
|
||||
---
|
||||
id: toplevel
|
||||
title: Top-Level
|
||||
description: Available functions at the top level
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
import Syntax from '@theme/Syntax';
|
||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||
|
||||
These types and functions are available without any needed prefix.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type address
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type address
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type address
|
||||
</SyntaxTitle>
|
||||
|
||||
An untyped address which can refer to a smart contract or account.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type big_map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type ('key, 'value) big_map
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type big_map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
The type of a big map from values of type `key` to
|
||||
values of type `value` is `big_map (key, value)`.
|
||||
|
||||
```pascaligo group=big_map
|
||||
type move is int * int
|
||||
type register is big_map (address, move)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
The type of a big map from values of type `key` to values
|
||||
of type `value` is `(key, value) big_map`.
|
||||
|
||||
```cameligo group=big_map
|
||||
type move = int * int
|
||||
type register = (address, move) big_map
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
The type of a big map from values of type `key` to
|
||||
values of type `value` is `big_map(key, value)`.
|
||||
|
||||
```reasonligo group=big_map
|
||||
type move = (int, int);
|
||||
type register = big_map(address, move);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
Be aware that a `big_map` cannot appear inside another `big_map`.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type bool
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type bool
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type bool
|
||||
</SyntaxTitle>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type bytes
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type bytes
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type bytes
|
||||
</SyntaxTitle>
|
||||
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type contract('parameter)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type 'parameter contract
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type contract('parameter)
|
||||
</SyntaxTitle>
|
||||
|
||||
A typed contract.
|
||||
|
||||
Use `unit` as `parameter` to indicate an implicit account.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type chain_id
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type chain_id
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type chain_id
|
||||
</SyntaxTitle>
|
||||
|
||||
The identifier of a chain, used to indicate test or main chains.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type int
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type int
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type int
|
||||
</SyntaxTitle>
|
||||
|
||||
An integer.
|
||||
|
||||
The only size limit to integers is gas.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type key
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type key
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type key
|
||||
</SyntaxTitle>
|
||||
|
||||
A public cryptographic key.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type key_hash
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type key_hash
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type key_hash
|
||||
</SyntaxTitle>
|
||||
|
||||
The hash of a public cryptographic key.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type list ('t)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type 't list
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type list('t)
|
||||
</SyntaxTitle>
|
||||
|
||||
A sequence of elements of the same type.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type ('key, 'value) map
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type map ('key, 'value)
|
||||
</SyntaxTitle>
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
The type of a map from values of type `key` to
|
||||
values of type `value` is `map (key, value)`.
|
||||
|
||||
```pascaligo group=maps
|
||||
type move is int * int
|
||||
type register is map (address, move)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
The type of a map from values of type `key` to values
|
||||
of type `value` is `(key, value) map`.
|
||||
|
||||
```cameligo group=maps
|
||||
type move = int * int
|
||||
type register = (address, move) map
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
The type of a map from values of type `key` to
|
||||
values of type `value` is `map (key, value)`.
|
||||
|
||||
```reasonligo group=maps
|
||||
type move = (int, int);
|
||||
type register = map (address, move);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type nat
|
||||
</SyntaxTitle>
|
||||
|
||||
A natural number.
|
||||
|
||||
The only size limit to natural numbers is gas.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type operation
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type operation
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type operation
|
||||
</SyntaxTitle>
|
||||
|
||||
An operation emitted by the contract
|
||||
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type set ('value)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type 'value set
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type set('value)
|
||||
</SyntaxTitle>
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type signature
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type signature
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type signature
|
||||
</SyntaxTitle>
|
||||
|
||||
A cryptographic signature.
|
||||
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type string
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type string
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type string
|
||||
</SyntaxTitle>
|
||||
|
||||
A sequence of characters.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type tez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type tez
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type tez
|
||||
</SyntaxTitle>
|
||||
|
||||
A specific type for tokens.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type timestamp
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type timestamp
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type timestamp
|
||||
</SyntaxTitle>
|
||||
|
||||
A date in the real world.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
type unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
type unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
type unit
|
||||
</SyntaxTitle>
|
||||
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function is_nat: int -> option(nat)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val is_nat: int -> nat option
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let is_nat: int => option(nat)
|
||||
</SyntaxTitle>
|
||||
|
||||
Convert an `int` to a `nat` if possible.
|
||||
|
||||
Note that `Michelson.is_nat` is deprecated. Please use `is_nat` instead.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function abs: int -> nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val abs: int -> nat
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let abs: int => nat
|
||||
</SyntaxTitle>
|
||||
|
||||
Cast an `int` to `nat`.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function int: nat -> int
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val int: nat -> int
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let int: nat => int
|
||||
</SyntaxTitle>
|
||||
|
||||
Cast an `nat` to `int`.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
const unit: unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val unit: unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let (): unit
|
||||
</SyntaxTitle>
|
||||
|
||||
A helper to create a unit.
|
||||
|
||||
<a name="failwith"></a>
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function failwith : 'a -> unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val failwith : 'a -> unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let failwith: 'a => unit
|
||||
</SyntaxTitle>
|
||||
|
||||
Cause the contract to fail with an error message or integer. Other types are
|
||||
not supported at the moment.
|
||||
|
||||
Using this currently requires in general a type annotation on the
|
||||
`failwith` call.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
function main (const p : int; const s : unit) : list (operation) * unit is
|
||||
block {
|
||||
if p > 10 then failwith ("Failure.") else skip
|
||||
}
|
||||
with ((nil : list (operation)), s)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let main (p,s : int * unit) = if p > 10 then failwith "Failure."
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let main = ((p,s) : (int, unit)) =>
|
||||
if (p > 10) { failwith ("Failure."); };
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
`Current.failwith` is deprecated. Use `Tezos.failwith` or `failwith` instead.
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
`Current.failwith` is deprecated. Use `Tezos.failwith` or `failwith` instead.
|
||||
</Syntax>
|
||||
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function assert : bool -> unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val assert : bool -> unit
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let assert: bool => unit
|
||||
</SyntaxTitle>
|
||||
|
||||
Check if a certain condition has been met. If not the contract will fail.
|
||||
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function ediv : int -> int -> option (int * nat)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function ediv : mutez -> nat -> option (mutez * mutez)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function ediv : mutez -> mutez -> option (nat * mutez)
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="pascaligo">
|
||||
function ediv : nat -> nat -> option (nat * nat)
|
||||
</SyntaxTitle>
|
||||
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val ediv : int -> int -> (int * nat) option
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val ediv : mutez -> nat -> (mutez * mutez) option
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val ediv : mutez -> mutez -> (nat * mutez) option
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="cameligo">
|
||||
val ediv : nat -> nat -> (nat * nat) option
|
||||
</SyntaxTitle>
|
||||
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let ediv: (int, int) => option((int, nat))
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let ediv: (mutez, nat) => option((mutez, mutez))
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let ediv: (mutez, mutez) => option((nat, mutez))
|
||||
</SyntaxTitle>
|
||||
<SyntaxTitle syntax="reasonligo">
|
||||
let ediv: (nat, nat) => option((nat, nat))
|
||||
</SyntaxTitle>
|
||||
|
||||
Compiles to Michelson `EDIV`, one operation to get both the quotient and remainder of a division. `ediv x y` returns None if `y` is zero, otherwise returns `Some (quotient, remainder)` such that `x = (quotient * y) + remainder` and `0 <= remainder < abs(y)`.
|
@ -34,13 +34,21 @@ function buy_taco (const taco_kind_index : nat; var taco_shop_storage : taco_sho
|
||||
// Update the storage with the refreshed taco_kind
|
||||
taco_shop_storage[taco_kind_index] := taco_kind;
|
||||
|
||||
const receiver : contract (unit) = get_contract (ownerAddress);
|
||||
const donationReceiver : contract (unit) = get_contract (donationAddress);
|
||||
const receiver : contract (unit) =
|
||||
case (Tezos.get_contract_opt (ownerAddress): option(contract (unit))) of
|
||||
Some (contract) -> contract
|
||||
| None -> (failwith ("Not a contract") : contract (unit))
|
||||
end;
|
||||
const donationReceiver : contract (unit) =
|
||||
case (Tezos.get_contract_opt (donationAddress): option(contract (unit))) of
|
||||
Some (contract) -> contract
|
||||
| None -> (failwith ("Not a contract") : contract (unit))
|
||||
end;
|
||||
|
||||
const donationAmount : tez = amount / 10n;
|
||||
|
||||
const operations : list (operation) = list [
|
||||
transaction (unit, amount - donationAmount, receiver);
|
||||
transaction (unit, donationAmount, donationReceiver);
|
||||
Tezos.transaction (unit, amount - donationAmount, receiver);
|
||||
Tezos.transaction (unit, donationAmount, donationReceiver);
|
||||
]
|
||||
} with (operations, taco_shop_storage)
|
||||
|
@ -4,7 +4,7 @@ title: Paying out profits from the Taco Shop
|
||||
---
|
||||
|
||||
In the
|
||||
[previous tutorial](tutorials/get-started/tezos-taco-shop-smart-contract.md)
|
||||
[previous tutorial](tezos-taco-shop-smart-contract.md)
|
||||
we have learnt how to setup & interact with the LIGO CLI. Followed an
|
||||
implementation of a simple Taco Shop smart contract for our
|
||||
entrepreneur Pedro.
|
||||
@ -72,7 +72,7 @@ const current_purchase_price : tez =
|
||||
### Replacing *spendable* Smart Contracts
|
||||
|
||||
However, due to the
|
||||
[recent protocol upgrade](http://tezos.gitlab.io/mainnet/protocols/004_Pt24m4xi.html)
|
||||
[recent protocol upgrade](http://tezos.gitlab.io/protocols/004_Pt24m4xi.html)
|
||||
of the Tezos `mainnet`, Pedro cannot access the tokens stored in his
|
||||
shop's contract directly. This was previously possible via *spendable
|
||||
smart contracts*, which are no longer available in the new
|
||||
@ -105,7 +105,11 @@ contract with no parameters, or an implicit account.
|
||||
|
||||
```pascaligo group=ex1
|
||||
const ownerAddress : address = ("tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV" : address);
|
||||
const receiver : contract (unit) = get_contract (ownerAddress);
|
||||
const receiver : contract (unit) =
|
||||
case (Tezos.get_contract_opt (ownerAddress): option(contract(unit))) of
|
||||
Some (contract) -> contract
|
||||
| None -> (failwith ("Not a contract") : (contract(unit)))
|
||||
end;
|
||||
```
|
||||
|
||||
> Would you like to learn more about addresses, contracts and
|
||||
@ -120,7 +124,7 @@ receiver)` within a list of operations returned at the end of our
|
||||
contract.
|
||||
|
||||
```pascaligo group=ex1
|
||||
const payoutOperation : operation = transaction (unit, amount, receiver) ;
|
||||
const payoutOperation : operation = Tezos.transaction (unit, amount, receiver) ;
|
||||
const operations : list (operation) = list [payoutOperation];
|
||||
```
|
||||
|
||||
@ -166,10 +170,15 @@ function buy_taco (const taco_kind_index : nat ; var taco_shop_storage : taco_sh
|
||||
// Update the storage with the refreshed taco_kind
|
||||
taco_shop_storage[taco_kind_index] := taco_kind;
|
||||
|
||||
const receiver : contract(unit) = get_contract (ownerAddress);
|
||||
const payoutOperation : operation = transaction (unit, amount, receiver);
|
||||
const receiver : contract (unit) =
|
||||
case (Tezos.get_contract_opt (ownerAddress): option(contract(unit))) of
|
||||
Some (contract) -> contract
|
||||
| None -> (failwith ("Not a contract") : (contract(unit)))
|
||||
end;
|
||||
|
||||
const payoutOperation : operation = Tezos.transaction (unit, amount, receiver);
|
||||
const operations : list(operation) = list [payoutOperation]
|
||||
} with ((nil : list (operation)), taco_shop_storage)
|
||||
} with ((operations : list (operation)), taco_shop_storage)
|
||||
```
|
||||
|
||||
### Dry-run the Contract
|
||||
@ -214,8 +223,16 @@ sum from each taco purchase.
|
||||
const ownerAddress : address = ("tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV" : address);
|
||||
const donationAddress : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address);
|
||||
|
||||
const receiver : contract (unit) = get_contract (ownerAddress);
|
||||
const donationReceiver : contract(unit) = get_contract (donationAddress);
|
||||
const receiver : contract (unit) =
|
||||
case (Tezos.get_contract_opt (ownerAddress) : option(contract(unit))) of
|
||||
Some (contract) -> contract
|
||||
| None -> (failwith ("Not a contract") : contract (unit))
|
||||
end;
|
||||
const donationReceiver : contract (unit) =
|
||||
case (Tezos.get_contract_opt (donationAddress) : option(contract(unit))) of
|
||||
Some (contract) -> contract
|
||||
| None -> (failwith ("Not a contract") : contract (unit))
|
||||
end;
|
||||
|
||||
const donationAmount : tez = amount / 10n;
|
||||
|
||||
|
@ -67,7 +67,7 @@ current_purchase_price = max_price / available_stock
|
||||
|
||||
In this tutorial, we will use LIGO's dockerized version, for the sake
|
||||
of simplicity. You can find the installation instructions
|
||||
[here](intro/installation.md#dockerized-installation-recommended).
|
||||
[here](../../intro/installation.md#dockerized-installation-recommended).
|
||||
|
||||
The best way to install the dockerized LIGO is as a **global
|
||||
executable** through the installation script, as shown in the
|
||||
@ -203,7 +203,7 @@ function main (const parameter : unit; const taco_shop_storage : taco_shop_stor
|
||||
When dry-running a contract, it is crucial to provide a correct
|
||||
initial storage value. In our case the storage is type-checked as
|
||||
`taco_shop_storage`. Reflecting
|
||||
[Pedro's daily offer](tutorials/get-started/tezos-taco-shop-smart-contract.md#daily-offer),
|
||||
[Pedro's daily offer](tezos-taco-shop-smart-contract.md#daily-offer),
|
||||
our storage's value will be defined as follows:
|
||||
|
||||
**Storage value**
|
||||
@ -340,7 +340,7 @@ accessible within LIGO as `amount`.
|
||||
To make sure we get paid, we will:
|
||||
|
||||
- calculate a `current_purchase_price` based on the
|
||||
[equation specified earlier](tutorials/get-started/tezos-taco-shop-smart-contract.md#calculating-the-current-purchase-price)
|
||||
[equation specified earlier](tezos-taco-shop-smart-contract.md#calculating-the-current-purchase-price)
|
||||
- check if the sent `amount` matches the `current_purchase_price`:
|
||||
- if not, then our contract will fail (`failwith`)
|
||||
- otherwise, stock for the given `taco_kind` will be decreased and
|
||||
|
@ -113,9 +113,14 @@ const siteConfig = {
|
||||
// template. For example, if you need your repo's URL...
|
||||
// repoUrl: repoUrl,
|
||||
plugins: [
|
||||
'@ligo/syntax', {
|
||||
require.resolve('@ligo/syntax', {
|
||||
|
||||
}
|
||||
},
|
||||
'@docusaurus/plugin-sitemap', {
|
||||
cacheTime: 600 * 1000, // 600 sec - cache purge period
|
||||
changefreq: 'weekly',
|
||||
priority: 0.5,
|
||||
})
|
||||
],
|
||||
|
||||
presets: [
|
||||
@ -151,17 +156,18 @@ const siteConfig = {
|
||||
srcDark: 'img/logo-night.svg'
|
||||
},
|
||||
links: [
|
||||
{ href: 'https://ide.ligolang.org/', label: 'Try Online' },
|
||||
{ to: 'docs/intro/installation', label: 'Install' },
|
||||
{ to: 'docs/intro/introduction', label: 'Docs' },
|
||||
{ href: 'https://ide.ligolang.org/', label: 'Try Online', position: 'left', target: '_self' },
|
||||
{ to: 'docs/intro/installation', label: 'Install', position: 'left' },
|
||||
{ to: 'docs/intro/introduction', label: 'Docs', position: 'left' },
|
||||
{
|
||||
to: 'docs/tutorials/get-started/tezos-taco-shop-smart-contract',
|
||||
label: 'Tutorials'
|
||||
label: 'Tutorials',
|
||||
position: 'left'
|
||||
},
|
||||
{ href: 'https://forum.tezosagora.org/tag/ligo', label: 'Blog' },
|
||||
{ href: 'https://forum.tezosagora.org/tag/ligo', label: 'Blog', position: 'left' },
|
||||
// TODO: { href: "/odoc", label: "API" },
|
||||
// { doc: 'contributors/origin', label: 'Contribute' },
|
||||
{ to: '/contact', label: 'Ask Questions' }
|
||||
{ to: '/contact', label: 'Ask Questions', position: 'left' }
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
@ -171,28 +177,28 @@ const siteConfig = {
|
||||
items: [
|
||||
{ to: 'docs/intro/installation', label: 'Install' },
|
||||
{ to: 'docs/api/cli-commands', label: 'CLI Commands' },
|
||||
{ to: 'docs/contributors/origin', label: 'Contribute' },
|
||||
{ to: '/odoc', label: 'API Documentation' }
|
||||
{ to: 'docs/api/cheat-sheet', label: 'Cheat Sheet' },
|
||||
{ href: 'https://ligolang.org/odoc/', label: 'API Documentation' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
items: [
|
||||
{
|
||||
href: 'https://forum.tezosagora.org/tag/ligo',
|
||||
label: 'Tezos Agora Forum'
|
||||
},
|
||||
{
|
||||
href: 'https://tezos.stackexchange.com/questions/tagged/ligo',
|
||||
label: 'Tezos Stack Exchange'
|
||||
},
|
||||
{
|
||||
href: 'https://discord.gg/9rhYaEt',
|
||||
label: 'Discord'
|
||||
},
|
||||
{
|
||||
href: 'https://t.me/LigoLang',
|
||||
label: 'Telegram'
|
||||
},
|
||||
{
|
||||
href: 'https://discord.gg/9rhYaEt',
|
||||
label: 'Discord'
|
||||
href: 'https://riot.im/app/#/room/#ligo-public:matrix.org',
|
||||
label: 'Riot'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -203,9 +209,17 @@ const siteConfig = {
|
||||
label: 'Tutorials',
|
||||
to: 'docs/tutorials/get-started/tezos-taco-shop-smart-contract'
|
||||
},
|
||||
{
|
||||
href: 'https://forum.tezosagora.org/tag/ligo',
|
||||
label: 'Blog'
|
||||
},
|
||||
{
|
||||
label: 'GitLab',
|
||||
href: repoUrl
|
||||
},
|
||||
{
|
||||
label: 'Contribute',
|
||||
to: 'docs/contributors/origin'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
14760
gitlab-pages/website/package-lock.json
generated
@ -1,4 +1,6 @@
|
||||
{
|
||||
"name": "ligo-website",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"start": "docusaurus start --host 0.0.0.0 --port 3000",
|
||||
"build": "docusaurus build",
|
||||
@ -6,8 +8,8 @@
|
||||
"deploy": "docusaurus deploy"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/core": "^2.0.0-alpha.43",
|
||||
"@docusaurus/preset-classic": "^2.0.0-alpha.43",
|
||||
"@docusaurus/core": "^2.0.0-alpha.56",
|
||||
"@docusaurus/preset-classic": "^2.0.0-alpha.56",
|
||||
"classnames": "^2.2.6",
|
||||
"react": "^16.13.0",
|
||||
"react-dom": "^16.13.0",
|
||||
@ -26,6 +28,11 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@ligo/syntax": "file:src/@ligo/syntax"
|
||||
"@docusaurus/plugin-sitemap": "^2.0.0-alpha.56",
|
||||
"@ligo/syntax": "file:src/@ligo/syntax",
|
||||
"@ligolang/ligo-snippets": "^1.0.1",
|
||||
"axios": "^0.19.2",
|
||||
"react-codejar": "^1.0.1",
|
||||
"yaml": "^1.10.0"
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,16 @@
|
||||
"advanced/entrypoints-contracts",
|
||||
"advanced/include",
|
||||
"advanced/first-contract",
|
||||
"advanced/michelson-and-ligo"
|
||||
"advanced/michelson-and-ligo",
|
||||
"advanced/inline",
|
||||
"advanced/interop"
|
||||
],
|
||||
"Reference": [
|
||||
"api/cli-commands",
|
||||
"api/cheat-sheet"
|
||||
],
|
||||
"API":[
|
||||
"reference/toplevel",
|
||||
"reference/big-map-reference",
|
||||
"reference/bitwise-reference",
|
||||
"reference/bytes-reference",
|
||||
|
1
gitlab-pages/website/sitemap.xml
Normal file
@ -2,15 +2,15 @@ import React from 'react';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
function SyntaxSwitch(props) {
|
||||
return React.createElement("select", {
|
||||
return /*#__PURE__*/React.createElement("select", {
|
||||
className: styles.syntaxSwitch,
|
||||
defaultValue: props.syntax,
|
||||
onChange: e => props.onSyntaxChange(e.target.value)
|
||||
}, React.createElement("option", {
|
||||
}, /*#__PURE__*/React.createElement("option", {
|
||||
value: "pascaligo"
|
||||
}, "PascaLIGO"), React.createElement("option", {
|
||||
}, "PascaLIGO"), /*#__PURE__*/React.createElement("option", {
|
||||
value: "cameligo"
|
||||
}, "CameLIGO"), React.createElement("option", {
|
||||
}, "CameLIGO"), /*#__PURE__*/React.createElement("option", {
|
||||
value: "reasonligo"
|
||||
}, "ReasonLIGO"));
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ import React from 'react';
|
||||
import SyntaxContext from './SyntaxContext';
|
||||
|
||||
function Syntax(props) {
|
||||
return React.createElement(SyntaxContext.Consumer, null, syntax => {
|
||||
return /*#__PURE__*/React.createElement(SyntaxContext.Consumer, null, syntax => {
|
||||
if (syntax === props.syntax) {
|
||||
return props.children;
|
||||
} else {
|
||||
return React.createElement(React.Fragment, null);
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
.syntaxSwitch option {
|
||||
color: var(--color-primary-text);
|
||||
font-weight:normal;
|
||||
background-color: var(--ifm-navbar-background-color);
|
||||
}
|
||||
|
||||
|
@ -72,9 +72,9 @@ function SyntaxTitle(props) {
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
return React.createElement(SyntaxContext.Consumer, null, syntax => {
|
||||
return /*#__PURE__*/React.createElement(SyntaxContext.Consumer, null, syntax => {
|
||||
if (syntax === props.syntax) {
|
||||
return React.createElement(Highlight, _extends({}, defaultProps, {
|
||||
return /*#__PURE__*/React.createElement(Highlight, _extends({}, defaultProps, {
|
||||
key: mounted,
|
||||
language: props.syntax,
|
||||
code: props.children,
|
||||
@ -85,7 +85,7 @@ function SyntaxTitle(props) {
|
||||
tokens,
|
||||
getLineProps,
|
||||
getTokenProps
|
||||
}) => React.createElement("pre", {
|
||||
}) => /*#__PURE__*/React.createElement("pre", {
|
||||
className: className,
|
||||
style: {
|
||||
backgroundColor: 'var(--ifm-background-color)',
|
||||
@ -95,15 +95,15 @@ function SyntaxTitle(props) {
|
||||
whiteSpace: 'break-spaces',
|
||||
marginTop: '3rem'
|
||||
}
|
||||
}, tokens.map((line, i) => React.createElement("div", getLineProps({
|
||||
}, tokens.map((line, i) => /*#__PURE__*/React.createElement("div", getLineProps({
|
||||
line,
|
||||
key: i
|
||||
}), line.map((token, key) => React.createElement("span", getTokenProps({
|
||||
}), line.map((token, key) => /*#__PURE__*/React.createElement("span", getTokenProps({
|
||||
token,
|
||||
key
|
||||
})))))));
|
||||
} else {
|
||||
return React.createElement("div", null);
|
||||
return /*#__PURE__*/React.createElement("div", null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
.syntaxSwitch option {
|
||||
color: var(--color-primary-text);
|
||||
font-weight:normal;
|
||||
background-color: var(--ifm-navbar-background-color);
|
||||
}
|
||||
|
||||
|
@ -6,15 +6,22 @@ const TEAM = [
|
||||
{
|
||||
firstName: 'Christian',
|
||||
lastName: 'Rinderknecht',
|
||||
image: 'img/christian.jpeg',
|
||||
image: 'img/christian.jpg',
|
||||
link: 'https://github.com/rinderknecht',
|
||||
pinned: true
|
||||
},
|
||||
{
|
||||
firstName: 'Brice',
|
||||
lastName: 'Aldrich',
|
||||
image: 'img/brice.jpeg',
|
||||
link: 'https://github.com/DefinitelyNotAGoat',
|
||||
firstName: 'Eowyn',
|
||||
lastName: 'Dean',
|
||||
image: 'img/eowyn.jpg',
|
||||
link: 'https://gitlab.com/dernhelm7',
|
||||
pinned: true
|
||||
},
|
||||
{
|
||||
firstName: 'Francis',
|
||||
lastName: 'Brunelle',
|
||||
image: 'img/francis.jpg',
|
||||
link: 'https://github.com/frabrunelle',
|
||||
pinned: true
|
||||
},
|
||||
{
|
||||
@ -25,10 +32,10 @@ const TEAM = [
|
||||
pinned: true
|
||||
},
|
||||
{
|
||||
firstName: 'Matej',
|
||||
lastName: 'Sima',
|
||||
image: 'img/matej.jpeg',
|
||||
link: 'https://github.com/maht0rz',
|
||||
firstName: 'Pierre-Emmanuel',
|
||||
lastName: 'Wolfman',
|
||||
image: 'img/pierre-emmanuel.jpg',
|
||||
link: 'https://gitlab.com/Popu-sama',
|
||||
pinned: true
|
||||
},
|
||||
{
|
||||
@ -41,27 +48,32 @@ const TEAM = [
|
||||
{
|
||||
firstName: 'Suzanne',
|
||||
lastName: 'Dupéron',
|
||||
image: 'img/suzanne.jpeg',
|
||||
image: 'img/suzanne.jpg',
|
||||
link: 'https://gitlab.com/suzanne.duperon',
|
||||
pinned: true
|
||||
}
|
||||
];
|
||||
|
||||
const COMMUNICATION_CHANNELS = [
|
||||
{
|
||||
link: 'https://discord.gg/9rhYaEt',
|
||||
icon: 'img/discord.svg',
|
||||
description: "Join our Discord server. We're here to help."
|
||||
},
|
||||
{
|
||||
link: 'https://t.me/LigoLang',
|
||||
icon: 'img/telegram.svg',
|
||||
description: "We're here to help. Ask us anything"
|
||||
description: "We're also on Telegram. Ask us anything!"
|
||||
},
|
||||
{
|
||||
link: 'https://gitlab.com/ligolang/ligo/issues',
|
||||
icon: 'img/gitlab.svg',
|
||||
description: 'Need a fix? Create an issue on GitLab'
|
||||
description: 'Need a fix? Create an issue on GitLab.'
|
||||
},
|
||||
{
|
||||
link: 'https://twitter.com/ligolang',
|
||||
icon: 'img/twitter.svg',
|
||||
description: 'Join the latest chit-chat'
|
||||
description: 'Join the latest chit-chat and follow us on Twitter!'
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -88,7 +88,7 @@ const FEATURES = [
|
||||
{
|
||||
image: 'img/easy-integration.svg',
|
||||
title: 'Easy Integration',
|
||||
content: 'You can use LIGO as a NodeJS library with Granary'
|
||||
content: 'You can use LIGO as a Node.js library with Truffle.'
|
||||
}
|
||||
];
|
||||
|
||||
@ -100,9 +100,9 @@ const PARTNERS = [
|
||||
pinned: true
|
||||
},
|
||||
{
|
||||
name: 'Tocqueville Group',
|
||||
name: 'TQ Tezos',
|
||||
image: 'img/tq-logo.svg',
|
||||
link: 'https://tqgroup.io/',
|
||||
link: 'https://tqtezos.com/',
|
||||
pinned: true
|
||||
},
|
||||
{
|
||||
|
@ -1,14 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React, {useEffect, useState, useRef} from 'react';
|
||||
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
|
||||
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Highlight, {defaultProps} from 'prism-react-renderer';
|
||||
const {Prism} = require("prism-react-renderer");
|
||||
import Highlight, { defaultProps } from 'prism-react-renderer';
|
||||
|
||||
import Prism from 'prism-react-renderer/prism';
|
||||
|
||||
Prism.languages = {
|
||||
...Prism.languages,
|
||||
pascaligo: {
|
||||
@ -58,33 +62,107 @@ Prism.languages = {
|
||||
],
|
||||
'punctuation': /\(\.|\.\)|[()\[\]:;,.]/
|
||||
},
|
||||
reasonligo:
|
||||
{...Prism.languages.reason,
|
||||
reasonligo:
|
||||
{
|
||||
...Prism.languages.reason,
|
||||
'comment': [
|
||||
/(^|[^\\])\/\*[\s\S]*?\*\//,
|
||||
/\(\*[\s\S]*?\*\)/,
|
||||
/\/\/.*/
|
||||
/\(\*[\s\S]*?\*\)/,
|
||||
/\/\/.*/
|
||||
]
|
||||
|
||||
|
||||
},
|
||||
cameligo: {...Prism.languages.ocaml,
|
||||
'comment': [
|
||||
cameligo: {
|
||||
...Prism.languages.ocaml,
|
||||
'comment': [
|
||||
/(^|[^\\])\/\*[\s\S]*?\*\//,
|
||||
/\(\*[\s\S]*?\*\)/,
|
||||
/\/\/.*/
|
||||
]}
|
||||
/\(\*[\s\S]*?\*\)/,
|
||||
/\/\/.*/
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
import defaultTheme from 'prism-react-renderer/themes/palenight';
|
||||
import Clipboard from 'clipboard';
|
||||
import rangeParser from 'parse-numeric-range';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import useThemeContext from '@theme/hooks/useThemeContext';
|
||||
import { LigoSnippet } from '@ligolang/ligo-snippets'
|
||||
|
||||
import styles from './styles.module.css';
|
||||
|
||||
const highlightLinesRangeRegex = /{([\d,-]+)}/;
|
||||
const getHighlightDirectiveRegex = (
|
||||
languages = ['js', 'jsBlock', 'jsx', 'python', 'html'],
|
||||
) => {
|
||||
// supported types of comments
|
||||
const comments = {
|
||||
js: {
|
||||
start: '\\/\\/',
|
||||
end: '',
|
||||
},
|
||||
jsBlock: {
|
||||
start: '\\/\\*',
|
||||
end: '\\*\\/',
|
||||
},
|
||||
jsx: {
|
||||
start: '\\{\\s*\\/\\*',
|
||||
end: '\\*\\/\\s*\\}',
|
||||
},
|
||||
python: {
|
||||
start: '#',
|
||||
end: '',
|
||||
},
|
||||
html: {
|
||||
start: '<!--',
|
||||
end: '-->',
|
||||
},
|
||||
};
|
||||
// supported directives
|
||||
const directives = [
|
||||
'highlight-next-line',
|
||||
'highlight-start',
|
||||
'highlight-end',
|
||||
].join('|');
|
||||
// to be more reliable, the opening and closing comment must match
|
||||
const commentPattern = languages
|
||||
.map(
|
||||
(lang) =>
|
||||
`(?:${comments[lang].start}\\s*(${directives})\\s*${comments[lang].end})`,
|
||||
)
|
||||
.join('|');
|
||||
// white space is allowed, but otherwise it should be on it's own line
|
||||
return new RegExp(`^\\s*(?:${commentPattern})\\s*$`);
|
||||
};
|
||||
// select comment styles based on language
|
||||
const highlightDirectiveRegex = (lang) => {
|
||||
switch (lang) {
|
||||
case 'js':
|
||||
case 'javascript':
|
||||
case 'ts':
|
||||
case 'typescript':
|
||||
return getHighlightDirectiveRegex(['js', 'jsBlock']);
|
||||
|
||||
case 'jsx':
|
||||
case 'tsx':
|
||||
return getHighlightDirectiveRegex(['js', 'jsBlock', 'jsx']);
|
||||
|
||||
case 'html':
|
||||
return getHighlightDirectiveRegex(['js', 'jsBlock', 'html']);
|
||||
|
||||
case 'python':
|
||||
case 'py':
|
||||
return getHighlightDirectiveRegex(['python']);
|
||||
|
||||
default:
|
||||
// all comment types
|
||||
return getHighlightDirectiveRegex();
|
||||
}
|
||||
};
|
||||
const codeBlockTitleRegex = /title=".*"/;
|
||||
|
||||
export default ({ children, className: languageClassName, metastring }) => {
|
||||
|
||||
export default ({children, className: languageClassName, metastring}) => {
|
||||
const {
|
||||
siteConfig: {
|
||||
themeConfig: {prism = {}},
|
||||
@ -107,6 +185,7 @@ export default ({children, className: languageClassName, metastring}) => {
|
||||
const target = useRef(null);
|
||||
const button = useRef(null);
|
||||
let highlightLines = [];
|
||||
let codeBlockTitle = '';
|
||||
|
||||
const {isDarkTheme} = useThemeContext();
|
||||
const lightModeTheme = prism.theme || defaultTheme;
|
||||
@ -115,7 +194,16 @@ export default ({children, className: languageClassName, metastring}) => {
|
||||
|
||||
if (metastring && highlightLinesRangeRegex.test(metastring)) {
|
||||
const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1];
|
||||
highlightLines = rangeParser.parse(highlightLinesRange).filter(n => n > 0);
|
||||
highlightLines = rangeParser
|
||||
.parse(highlightLinesRange)
|
||||
.filter((n) => n > 0);
|
||||
}
|
||||
|
||||
if (metastring && codeBlockTitleRegex.test(metastring)) {
|
||||
codeBlockTitle = metastring
|
||||
.match(codeBlockTitleRegex)[0]
|
||||
.split('title=')[1]
|
||||
.replace(/"+/g, '');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@ -141,6 +229,50 @@ export default ({children, className: languageClassName, metastring}) => {
|
||||
language = prism.defaultLanguage;
|
||||
}
|
||||
|
||||
// only declaration OR directive highlight can be used for a block
|
||||
let code = children.replace(/\n$/, '');
|
||||
if (highlightLines.length === 0 && language !== undefined) {
|
||||
let range = '';
|
||||
const directiveRegex = highlightDirectiveRegex(language);
|
||||
// go through line by line
|
||||
const lines = children.replace(/\n$/, '').split('\n');
|
||||
let blockStart;
|
||||
// loop through lines
|
||||
for (let index = 0; index < lines.length; ) {
|
||||
const line = lines[index];
|
||||
// adjust for 0-index
|
||||
const lineNumber = index + 1;
|
||||
const match = line.match(directiveRegex);
|
||||
if (match !== null) {
|
||||
const directive = match
|
||||
.slice(1)
|
||||
.reduce((final, item) => final || item, undefined);
|
||||
switch (directive) {
|
||||
case 'highlight-next-line':
|
||||
range += `${lineNumber},`;
|
||||
break;
|
||||
|
||||
case 'highlight-start':
|
||||
blockStart = lineNumber;
|
||||
break;
|
||||
|
||||
case 'highlight-end':
|
||||
range += `${blockStart}-${lineNumber - 1},`;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
lines.splice(index, 1);
|
||||
} else {
|
||||
// lines without directives are unchanged
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
highlightLines = rangeParser.parse(range);
|
||||
code = lines.join('\n');
|
||||
}
|
||||
|
||||
const handleCopyCode = () => {
|
||||
window.getSelection().empty();
|
||||
setShowCopied(true);
|
||||
@ -148,46 +280,88 @@ export default ({children, className: languageClassName, metastring}) => {
|
||||
setTimeout(() => setShowCopied(false), 2000);
|
||||
};
|
||||
|
||||
// ligo-snippets - begin
|
||||
if (metastring) {
|
||||
const theme = isDarkTheme ? 'dark' : 'light';
|
||||
let isObject = true
|
||||
let metadata
|
||||
|
||||
try {
|
||||
metadata = JSON.parse(metastring)
|
||||
} catch (e) {
|
||||
isObject = false
|
||||
}
|
||||
|
||||
if (isObject) {
|
||||
const snippetData = {
|
||||
"language": language,
|
||||
"name": metadata.name,
|
||||
"code": children,
|
||||
"theme": theme,
|
||||
"height": "" // Optional
|
||||
}
|
||||
|
||||
if (metadata.editor) {
|
||||
return <LigoSnippet data={snippetData} />
|
||||
}
|
||||
}
|
||||
}
|
||||
// ligo-snippets - end
|
||||
|
||||
return (
|
||||
<Highlight
|
||||
{...defaultProps}
|
||||
key={mounted}
|
||||
theme={prismTheme}
|
||||
code={children.trim()}
|
||||
code={code}
|
||||
language={language}>
|
||||
{({className, style, tokens, getLineProps, getTokenProps}) => (
|
||||
<pre className={classnames(className, styles.codeBlock)}>
|
||||
<button
|
||||
ref={button}
|
||||
type="button"
|
||||
aria-label="Copy code to clipboard"
|
||||
className={styles.copyButton}
|
||||
onClick={handleCopyCode}>
|
||||
{showCopied ? 'Copied' : 'Copy'}
|
||||
</button>
|
||||
<>
|
||||
{codeBlockTitle && (
|
||||
<div style={style} className={styles.codeBlockTitle}>
|
||||
{codeBlockTitle}
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.codeBlockContent}>
|
||||
<button
|
||||
ref={button}
|
||||
type="button"
|
||||
aria-label="Copy code to clipboard"
|
||||
className={classnames(styles.copyButton, {
|
||||
[styles.copyButtonWithTitle]: codeBlockTitle,
|
||||
})}
|
||||
onClick={handleCopyCode}>
|
||||
{showCopied ? 'Copied' : 'Copy'}
|
||||
</button>
|
||||
<div
|
||||
tabIndex="0"
|
||||
className={classnames(className, styles.codeBlock, {
|
||||
[styles.codeBlockWithTitle]: codeBlockTitle,
|
||||
})}>
|
||||
<div ref={target} className={styles.codeBlockLines} style={style}>
|
||||
{tokens.map((line, i) => {
|
||||
if (line.length === 1 && line[0].content === '') {
|
||||
line[0].content = '\n'; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
|
||||
<code ref={target} className={styles.codeBlockLines} style={style}>
|
||||
{tokens.map((line, i) => {
|
||||
if (line.length === 1 && line[0].content === '') {
|
||||
line[0].content = '\n'; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
const lineProps = getLineProps({line, key: i});
|
||||
|
||||
const lineProps = getLineProps({line, key: i});
|
||||
if (highlightLines.includes(i + 1)) {
|
||||
lineProps.className = `${lineProps.className} docusaurus-highlight-code-line`;
|
||||
}
|
||||
|
||||
if (highlightLines.includes(i + 1)) {
|
||||
lineProps.className = `${lineProps.className} docusaurus-highlight-code-line`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={i} {...lineProps}>
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({token, key})} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</code>
|
||||
</pre>
|
||||
return (
|
||||
<div key={i} {...lineProps}>
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({token, key})} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Highlight>
|
||||
);
|
||||
|
@ -1,44 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.codeBlockContent {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.codeBlockTitle {
|
||||
border-top-left-radius: var(--ifm-global-radius);
|
||||
border-top-right-radius: var(--ifm-global-radius);
|
||||
border-bottom: 1px solid var(--ifm-color-emphasis-200);
|
||||
font-family: var(--ifm-font-family-monospace);
|
||||
font-weight: bold;
|
||||
padding: 0.75rem var(--ifm-pre-padding);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.codeBlock {
|
||||
overflow: auto;
|
||||
display: block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-radius: var(--ifm-global-radius);
|
||||
}
|
||||
|
||||
.codeBlockWithTitle {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.copyButton {
|
||||
background: rgb(1, 22, 39);
|
||||
border: 1px solid rgb(214, 222, 235);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border: none;
|
||||
border-radius: var(--ifm-global-radius);
|
||||
color: rgb(214, 222, 235);
|
||||
color: var(--ifm-color-white);
|
||||
cursor: pointer;
|
||||
line-height: 12px;
|
||||
opacity: 0;
|
||||
outline: none;
|
||||
padding: 4px 8px;
|
||||
padding: 0.4rem 0.5rem;
|
||||
position: absolute;
|
||||
right: var(--ifm-pre-padding);
|
||||
top: var(--ifm-pre-padding);
|
||||
right: calc(var(--ifm-pre-padding) / 2);
|
||||
top: calc(var(--ifm-pre-padding) / 2);
|
||||
visibility: hidden;
|
||||
transition: opacity 200ms ease-in-out, visibility 200ms ease-in-out,
|
||||
bottom 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.codeBlock:hover > .copyButton {
|
||||
.codeBlockTitle:hover + .codeBlockContent .copyButton,
|
||||
.codeBlockContent:hover > .copyButton {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.codeBlockLines {
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
margin-bottom: 0;
|
||||
font-family: var(--ifm-font-family-monospace);
|
||||
font-size: inherit;
|
||||
line-height: var(--ifm-pre-line-height);
|
||||
white-space: pre;
|
||||
float: left;
|
||||
min-width: 100%;
|
||||
padding: var(--ifm-pre-padding);
|
||||
|
217
gitlab-pages/website/src/theme/DocItem/index.js
Normal file
@ -0,0 +1,217 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Head from '@docusaurus/Head';
|
||||
import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
import DocPaginator from '@theme/DocPaginator';
|
||||
import useTOCHighlight from '@theme/hooks/useTOCHighlight';
|
||||
|
||||
import classnames from 'classnames';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
const LINK_CLASS_NAME = 'table-of-contents__link';
|
||||
const ACTIVE_LINK_CLASS_NAME = 'table-of-contents__link--active';
|
||||
const TOP_OFFSET = 100;
|
||||
|
||||
function DocTOC({headings}) {
|
||||
useTOCHighlight(LINK_CLASS_NAME, ACTIVE_LINK_CLASS_NAME, TOP_OFFSET);
|
||||
return (
|
||||
<div className="col col--3">
|
||||
<div className={styles.tableOfContents}>
|
||||
<Headings headings={headings} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* eslint-disable jsx-a11y/control-has-associated-label */
|
||||
function Headings({headings, isChild}) {
|
||||
if (!headings.length) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<ul
|
||||
className={
|
||||
isChild ? '' : 'table-of-contents table-of-contents__left-border'
|
||||
}>
|
||||
{headings.map((heading) => (
|
||||
<li key={heading.id}>
|
||||
<a
|
||||
href={`#${heading.id}`}
|
||||
className={LINK_CLASS_NAME}
|
||||
dangerouslySetInnerHTML={{__html: heading.value}}
|
||||
/>
|
||||
<Headings isChild headings={heading.children} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
function DocItem(props) {
|
||||
const {siteConfig = {}} = useDocusaurusContext();
|
||||
const {url: siteUrl, title: siteTitle} = siteConfig;
|
||||
const {content: DocContent} = props;
|
||||
const {metadata} = DocContent;
|
||||
const {
|
||||
description,
|
||||
title,
|
||||
permalink,
|
||||
editUrl,
|
||||
lastUpdatedAt,
|
||||
lastUpdatedBy,
|
||||
version,
|
||||
} = metadata;
|
||||
const {
|
||||
frontMatter: {
|
||||
image: metaImage,
|
||||
keywords,
|
||||
hide_title: hideTitle,
|
||||
hide_table_of_contents: hideTableOfContents,
|
||||
},
|
||||
} = DocContent;
|
||||
|
||||
const metaTitle = title ? `${title} | ${siteTitle}` : siteTitle;
|
||||
let metaImageUrl = siteUrl + useBaseUrl(metaImage);
|
||||
if (!isInternalUrl(metaImage)) {
|
||||
metaImageUrl = metaImage;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{metaTitle}</title>
|
||||
<meta property="og:title" content={metaTitle} />
|
||||
{description && <meta name="description" content={description} />}
|
||||
{description && (
|
||||
<meta property="og:description" content={description} />
|
||||
)}
|
||||
{keywords && keywords.length && (
|
||||
<meta name="keywords" content={keywords.join(',')} />
|
||||
)}
|
||||
{metaImage && <meta property="og:image" content={metaImageUrl} />}
|
||||
{metaImage && <meta property="twitter:image" content={metaImageUrl} />}
|
||||
{metaImage && (
|
||||
<meta name="twitter:image:alt" content={`Image for ${title}`} />
|
||||
)}
|
||||
{permalink && <meta property="og:url" content={siteUrl + permalink} />}
|
||||
{permalink && <link rel="canonical" href={siteUrl + permalink} />}
|
||||
</Head>
|
||||
<div
|
||||
className={classnames(
|
||||
'container padding-vert--lg',
|
||||
styles.docItemWrapper,
|
||||
)}>
|
||||
<div className="row">
|
||||
<div
|
||||
className={classnames('col', {
|
||||
[styles.docItemCol]: !hideTableOfContents,
|
||||
})}>
|
||||
<div className={styles.docItemContainer}>
|
||||
<article>
|
||||
{version && (
|
||||
<div>
|
||||
<span className="badge badge--secondary">
|
||||
Version: {version}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{!hideTitle && (
|
||||
<header>
|
||||
<h1 className={styles.docTitle}>{title}</h1>
|
||||
</header>
|
||||
)}
|
||||
<div className="markdown">
|
||||
<DocContent />
|
||||
</div>
|
||||
</article>
|
||||
{(editUrl || lastUpdatedAt || lastUpdatedBy) && (
|
||||
<div className="margin-vert--xl">
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
{editUrl && (
|
||||
<a
|
||||
href={editUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener">
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1.2em"
|
||||
width="1.2em"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
viewBox="0 0 40 40"
|
||||
style={{
|
||||
marginRight: '0.3em',
|
||||
verticalAlign: 'sub',
|
||||
}}>
|
||||
<g>
|
||||
<path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z" />
|
||||
</g>
|
||||
</svg>
|
||||
Edit this page
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
{(lastUpdatedAt || lastUpdatedBy) && (
|
||||
<div className="col text--right">
|
||||
<em>
|
||||
<small>
|
||||
Last updated{' '}
|
||||
{lastUpdatedAt && (
|
||||
<>
|
||||
on{' '}
|
||||
<time
|
||||
dateTime={new Date(
|
||||
lastUpdatedAt * 1000,
|
||||
).toISOString()}
|
||||
className={styles.docLastUpdatedAt}>
|
||||
{new Date(
|
||||
lastUpdatedAt * 1000,
|
||||
).toLocaleDateString()}
|
||||
</time>
|
||||
{lastUpdatedBy && ' '}
|
||||
</>
|
||||
)}
|
||||
{lastUpdatedBy && (
|
||||
<>
|
||||
by <strong>{lastUpdatedBy}</strong>
|
||||
</>
|
||||
)}
|
||||
{process.env.NODE_ENV === 'development' && (
|
||||
<div>
|
||||
<small>
|
||||
{' '}
|
||||
(Simulated during dev for better perf)
|
||||
</small>
|
||||
</div>
|
||||
)}
|
||||
</small>
|
||||
</em>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="margin-vert--lg">
|
||||
<DocPaginator metadata={metadata} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{!hideTableOfContents && DocContent.rightToc && (
|
||||
<DocTOC headings={DocContent.rightToc} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default DocItem;
|
70
gitlab-pages/website/src/theme/DocItem/styles.module.css
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.docTitle {
|
||||
font-size: 3rem;
|
||||
margin-bottom: calc(var(--ifm-leading-desktop) * var(--ifm-leading));
|
||||
}
|
||||
|
||||
.docItemContainer {
|
||||
margin: 0 auto;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 997px) {
|
||||
.docItemCol {
|
||||
max-width: 75% !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 997px) and (max-width: 1320px) {
|
||||
.docItemWrapper {
|
||||
max-width: calc(
|
||||
var(--ifm-container-width) - 300px - var(--ifm-spacing-horizontal) * 2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
.tableOfContents {
|
||||
display: inherit;
|
||||
max-height: calc(100vh - (var(--ifm-navbar-height) + 2rem));
|
||||
overflow-y: auto;
|
||||
position: sticky;
|
||||
top: calc(var(--ifm-navbar-height) + 2rem);
|
||||
}
|
||||
|
||||
.tableOfContents::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.tableOfContents::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.tableOfContents::-webkit-scrollbar-thumb {
|
||||
background: #888;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.tableOfContents::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 996px) {
|
||||
.tableOfContents {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.docItemContainer {
|
||||
padding: 0 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.docLastUpdatedAt {
|
||||
font-weight: bold;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@ -11,6 +11,7 @@ import {MDXProvider} from '@mdx-js/react';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import renderRoutes from '@docusaurus/renderRoutes';
|
||||
import Layout from '@theme/Layout';
|
||||
import DocItem from '@theme/DocItem';
|
||||
import DocSidebar from '@theme/DocSidebar';
|
||||
import MDXComponents from '@theme/MDXComponents';
|
||||
import NotFound from '@theme/NotFound';
|
||||
@ -21,20 +22,29 @@ import styles from './styles.module.css';
|
||||
import SyntaxContext from '@theme/Syntax/SyntaxContext';
|
||||
|
||||
function DocPage(props) {
|
||||
const {route: baseRoute, docsMetadata, location} = props;
|
||||
|
||||
// case-sensitive route such as it is defined in the sidebar
|
||||
const currentRoute =
|
||||
baseRoute.routes.find(route => {
|
||||
return matchPath(location.pathname, route);
|
||||
}) || {};
|
||||
const {permalinkToSidebar, docsSidebars, version} = docsMetadata;
|
||||
const sidebar = permalinkToSidebar[currentRoute.path];
|
||||
const {route: baseRoute, docsMetadata, location, content} = props;
|
||||
const {
|
||||
siteConfig: {themeConfig = {}} = {},
|
||||
permalinkToSidebar,
|
||||
docsSidebars,
|
||||
version,
|
||||
isHomePage,
|
||||
homePagePath,
|
||||
} = docsMetadata;
|
||||
|
||||
// Get case-sensitive route such as it is defined in the sidebar.
|
||||
const currentRoute = !isHomePage
|
||||
? baseRoute.routes.find((route) => {
|
||||
return matchPath(location.pathname, route);
|
||||
}) || {}
|
||||
: {};
|
||||
|
||||
const sidebar = isHomePage
|
||||
? content.metadata.sidebar
|
||||
: permalinkToSidebar[currentRoute.path];
|
||||
const {
|
||||
siteConfig: {themeConfig: {sidebarCollapsible = true} = {}} = {},
|
||||
isClient,
|
||||
} = useDocusaurusContext();
|
||||
const {sidebarCollapsible = true} = themeConfig;
|
||||
|
||||
let defaultSyntax = 'pascaligo';
|
||||
if (isClient) {
|
||||
@ -42,8 +52,8 @@ function DocPage(props) {
|
||||
}
|
||||
|
||||
const [syntax, setSyntax] = useState(defaultSyntax);
|
||||
|
||||
if (Object.keys(currentRoute).length === 0) {
|
||||
|
||||
if (!isHomePage && Object.keys(currentRoute).length === 0) {
|
||||
return <NotFound {...props} />;
|
||||
}
|
||||
|
||||
@ -55,7 +65,7 @@ function DocPage(props) {
|
||||
<div className={styles.docSidebarContainer}>
|
||||
<DocSidebar
|
||||
docsSidebars={docsSidebars}
|
||||
path={currentRoute.path}
|
||||
path={isHomePage ? homePagePath : currentRoute.path}
|
||||
sidebar={sidebar}
|
||||
sidebarCollapsible={sidebarCollapsible}
|
||||
syntax={syntax}
|
||||
@ -68,7 +78,11 @@ function DocPage(props) {
|
||||
)}
|
||||
<main className={styles.docMainContainer}>
|
||||
<MDXProvider components={MDXComponents}>
|
||||
{renderRoutes(baseRoute.routes)}
|
||||
{isHomePage ? (
|
||||
<DocItem content={content} />
|
||||
) : (
|
||||
renderRoutes(baseRoute.routes)
|
||||
)}
|
||||
</MDXProvider>
|
||||
</main>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@ -10,11 +10,11 @@
|
||||
}
|
||||
|
||||
.docSidebarContainer {
|
||||
border-right: 1px solid var(--ifm-contents-border-color);
|
||||
border-right: 1px solid var(--ifm-toc-border-color);
|
||||
box-sizing: border-box;
|
||||
width: 300px;
|
||||
position: relative;
|
||||
top: calc(-1 * var(--ifm-navbar-height));
|
||||
margin-top: calc(-1 * var(--ifm-navbar-height));
|
||||
}
|
||||
|
||||
.docMainContainer {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@ -8,19 +8,24 @@
|
||||
import React, {useState, useCallback} from 'react';
|
||||
import classnames from 'classnames';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
import useLockBodyScroll from '@theme/hooks/useLockBodyScroll';
|
||||
import useLogo from '@theme/hooks/useLogo';
|
||||
import Link from '@docusaurus/Link';
|
||||
import isInternalUrl from '@docusaurus/utils'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||
|
||||
import styles from './styles.module.css';
|
||||
|
||||
import SyntaxSwitch from '@theme/Syntax/SyntaxSwitch';
|
||||
|
||||
|
||||
const MOBILE_TOGGLE_SIZE = 24;
|
||||
|
||||
function DocSidebarItem({item, onItemClick, collapsible}) {
|
||||
function DocSidebarItem({
|
||||
item,
|
||||
onItemClick,
|
||||
collapsible,
|
||||
activePath,
|
||||
...props
|
||||
}) {
|
||||
const {items, href, label, type} = item;
|
||||
const [collapsed, setCollapsed] = useState(item.collapsed);
|
||||
const [prevCollapsedProp, setPreviousCollapsedProp] = useState(null);
|
||||
@ -33,9 +38,10 @@ function DocSidebarItem({item, onItemClick, collapsible}) {
|
||||
setCollapsed(item.collapsed);
|
||||
}
|
||||
|
||||
const handleItemClick = useCallback(e => {
|
||||
const handleItemClick = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
setCollapsed(state => !state);
|
||||
e.target.blur();
|
||||
setCollapsed((state) => !state);
|
||||
});
|
||||
|
||||
switch (type) {
|
||||
@ -53,16 +59,19 @@ function DocSidebarItem({item, onItemClick, collapsible}) {
|
||||
'menu__link--active': collapsible && !item.collapsed,
|
||||
})}
|
||||
href="#!"
|
||||
onClick={collapsible ? handleItemClick : undefined}>
|
||||
onClick={collapsible ? handleItemClick : undefined}
|
||||
{...props}>
|
||||
{label}
|
||||
</a>
|
||||
<ul className="menu__list">
|
||||
{items.map(childItem => (
|
||||
{items.map((childItem) => (
|
||||
<DocSidebarItem
|
||||
tabIndex={collapsed ? '-1' : '0'}
|
||||
key={childItem.label}
|
||||
item={childItem}
|
||||
onItemClick={onItemClick}
|
||||
collapsible={collapsible}
|
||||
activePath={activePath}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
@ -75,18 +84,21 @@ function DocSidebarItem({item, onItemClick, collapsible}) {
|
||||
return (
|
||||
<li className="menu__list-item" key={label}>
|
||||
<Link
|
||||
className="menu__link"
|
||||
className={classnames('menu__link', {
|
||||
'menu__link--active': href === activePath,
|
||||
})}
|
||||
to={href}
|
||||
{...(isInternalUrl(href)
|
||||
? {
|
||||
activeClassName: 'menu__link--active',
|
||||
isNavLink: true,
|
||||
exact: true,
|
||||
onClick: onItemClick,
|
||||
}
|
||||
: {
|
||||
target: '_blank',
|
||||
rel: 'noreferrer noopener',
|
||||
})}>
|
||||
})}
|
||||
{...props}>
|
||||
{label}
|
||||
</Link>
|
||||
</li>
|
||||
@ -102,8 +114,8 @@ function mutateSidebarCollapsingState(item, path) {
|
||||
case 'category': {
|
||||
const anyChildItemsActive =
|
||||
items
|
||||
.map(childItem => mutateSidebarCollapsingState(childItem, path))
|
||||
.filter(val => val).length > 0;
|
||||
.map((childItem) => mutateSidebarCollapsingState(childItem, path))
|
||||
.filter((val) => val).length > 0;
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
item.collapsed = !anyChildItemsActive;
|
||||
return anyChildItemsActive;
|
||||
@ -118,9 +130,12 @@ function mutateSidebarCollapsingState(item, path) {
|
||||
function DocSidebar(props) {
|
||||
const [showResponsiveSidebar, setShowResponsiveSidebar] = useState(false);
|
||||
const {
|
||||
siteConfig: {themeConfig: {navbar: {title, logo = {}} = {}}} = {}, isClient
|
||||
siteConfig: {
|
||||
themeConfig: {navbar: {title, hideOnScroll = false} = {}},
|
||||
} = {},
|
||||
isClient,
|
||||
} = useDocusaurusContext();
|
||||
const logoUrl = useBaseUrl(logo.src);
|
||||
const {logoLink, logoLinkProps, logoImageUrl, logoAlt} = useLogo();
|
||||
|
||||
const {
|
||||
docsSidebars,
|
||||
@ -144,21 +159,29 @@ function DocSidebar(props) {
|
||||
}
|
||||
|
||||
if (sidebarCollapsible) {
|
||||
sidebarData.forEach(sidebarItem =>
|
||||
sidebarData.forEach((sidebarItem) =>
|
||||
mutateSidebarCollapsingState(sidebarItem, path),
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.sidebar}>
|
||||
<div className={styles.sidebarLogo}>
|
||||
{logo != null && <img src={logoUrl} alt={logo.alt} />}
|
||||
{title != null && <strong>{title}</strong>}
|
||||
</div>
|
||||
{hideOnScroll && (
|
||||
<Link
|
||||
tabIndex="-1"
|
||||
className={styles.sidebarLogo}
|
||||
to={logoLink}
|
||||
{...logoLinkProps}>
|
||||
{logoImageUrl != null && (
|
||||
<img key={isClient} src={logoImageUrl} alt={logoAlt} />
|
||||
)}
|
||||
{title != null && <strong>{title}</strong>}
|
||||
</Link>
|
||||
)}
|
||||
{isClient && document.location.pathname.startsWith('/docs') && !showResponsiveSidebar ?
|
||||
<div className={styles.switchContainer}>
|
||||
Display syntax: <SyntaxSwitch syntax={props.syntax} onSyntaxChange={s => props.onSyntaxChange(s)} />
|
||||
</div>
|
||||
<div className={styles.switchContainer}>
|
||||
Display syntax: <SyntaxSwitch syntax={props.syntax} onSyntaxChange={s => props.onSyntaxChange(s)} />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
@ -168,14 +191,14 @@ function DocSidebar(props) {
|
||||
})}>
|
||||
{isClient && document.location.pathname.startsWith('/docs') && showResponsiveSidebar ?
|
||||
<div className={styles.switchContainerResponsive}>
|
||||
Display syntax:
|
||||
<SyntaxSwitch syntax={props.syntax} onSyntaxChange={s => props.onSyntaxChange(s)} />
|
||||
Display syntax: <SyntaxSwitch syntax={props.syntax} onSyntaxChange={s => props.onSyntaxChange(s)} />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
:
|
||||
null
|
||||
}
|
||||
<button
|
||||
aria-label={showResponsiveSidebar ? 'Close Menu' : 'Open Menu'}
|
||||
aria-haspopup="true"
|
||||
className="button button--secondary button--sm menu__button"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
@ -191,6 +214,7 @@ function DocSidebar(props) {
|
||||
</span>
|
||||
) : (
|
||||
<svg
|
||||
aria-label="Menu"
|
||||
className={styles.sidebarMenuIcon}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height={MOBILE_TOGGLE_SIZE}
|
||||
@ -210,14 +234,16 @@ function DocSidebar(props) {
|
||||
)}
|
||||
</button>
|
||||
<ul className="menu__list">
|
||||
{sidebarData.map(item => (
|
||||
{sidebarData.map((item) => (
|
||||
<DocSidebarItem
|
||||
key={item.label}
|
||||
item={item}
|
||||
onItemClick={() => {
|
||||
onItemClick={(e) => {
|
||||
e.target.blur();
|
||||
setShowResponsiveSidebar(false);
|
||||
}}
|
||||
collapsible={sidebarCollapsible}
|
||||
activePath={path}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@ -39,6 +39,8 @@
|
||||
top: 0;
|
||||
margin: 0 var(--ifm-navbar-padding-horizontal);
|
||||
height: var(--ifm-navbar-height);
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.sidebarLogo img {
|
||||
|
@ -1,201 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React, {useCallback, useState} from 'react';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
|
||||
import SearchBar from '@theme/SearchBar';
|
||||
import Toggle from '@theme/Toggle';
|
||||
|
||||
import classnames from 'classnames';
|
||||
|
||||
import useThemeContext from '@theme/hooks/useThemeContext';
|
||||
import useHideableNavbar from '@theme/hooks/useHideableNavbar';
|
||||
import useLockBodyScroll from '@theme/hooks/useLockBodyScroll';
|
||||
|
||||
import styles from './styles.module.css';
|
||||
|
||||
function NavLink({to, href, label, position, ...props}) {
|
||||
const toUrl = useBaseUrl(to);
|
||||
return (
|
||||
<Link
|
||||
className="navbar__item navbar__link"
|
||||
{...(href
|
||||
? {
|
||||
target: '_blank',
|
||||
rel: 'noopener noreferrer',
|
||||
href,
|
||||
}
|
||||
: {
|
||||
activeClassName: 'navbar__link--active',
|
||||
to: toUrl,
|
||||
})}
|
||||
{...props}>
|
||||
{label}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
function Navbar(props) {
|
||||
const context = useDocusaurusContext();
|
||||
const {siteConfig = {}} = context;
|
||||
const {baseUrl, themeConfig = {}} = siteConfig;
|
||||
const {navbar = {}, disableDarkMode = false} = themeConfig;
|
||||
const {title, logo = {}, links = [], hideOnScroll = false} = navbar;
|
||||
|
||||
const [sidebarShown, setSidebarShown] = useState(false);
|
||||
const [isSearchBarExpanded, setIsSearchBarExpanded] = useState(false);
|
||||
|
||||
const {isDarkTheme, setLightTheme, setDarkTheme} = useThemeContext();
|
||||
const {navbarRef, isNavbarVisible} = useHideableNavbar(hideOnScroll);
|
||||
|
||||
useLockBodyScroll(sidebarShown);
|
||||
|
||||
const showSidebar = useCallback(() => {
|
||||
setSidebarShown(true);
|
||||
}, [setSidebarShown]);
|
||||
const hideSidebar = useCallback(() => {
|
||||
setSidebarShown(false);
|
||||
}, [setSidebarShown]);
|
||||
|
||||
const onToggleChange = useCallback(
|
||||
e => (e.target.checked ? setDarkTheme() : setLightTheme()),
|
||||
[setLightTheme, setDarkTheme],
|
||||
);
|
||||
|
||||
const logoLink = logo.href || baseUrl;
|
||||
const isExternalLogoLink = /http/.test(logoLink);
|
||||
const logoLinkProps = isExternalLogoLink
|
||||
? {
|
||||
rel: 'noopener noreferrer',
|
||||
target: '_blank',
|
||||
}
|
||||
: null;
|
||||
const logoSrc = logo.srcDark && isDarkTheme ? logo.srcDark : logo.src;
|
||||
const logoImageUrl = useBaseUrl(logoSrc);
|
||||
return (
|
||||
<nav
|
||||
ref={navbarRef}
|
||||
className={classnames('navbar', 'navbar--light', 'navbar--fixed-top', {
|
||||
'navbar-sidebar--show': sidebarShown,
|
||||
[styles.navbarHideable]: hideOnScroll,
|
||||
[styles.navbarHidden]: !isNavbarVisible,
|
||||
})}>
|
||||
<div className="navbar__inner">
|
||||
<div className="navbar__items">
|
||||
<div
|
||||
aria-label="Navigation bar toggle"
|
||||
className="navbar__toggle"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={showSidebar}
|
||||
onKeyDown={showSidebar}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 30 30"
|
||||
role="img"
|
||||
focusable="false">
|
||||
<title>Menu</title>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeMiterlimit="10"
|
||||
strokeWidth="2"
|
||||
d="M4 7h22M4 15h22M4 23h22"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<Link className="navbar__brand" to={logoLink} {...logoLinkProps}>
|
||||
{logo != null && (
|
||||
<img className="navbar__logo" src={logoImageUrl} alt={logo.alt} />
|
||||
)}
|
||||
{title != null && (
|
||||
<strong
|
||||
className={isSearchBarExpanded ? styles.hideLogoText : ''}>
|
||||
{title}
|
||||
</strong>
|
||||
)}
|
||||
</Link>
|
||||
{links
|
||||
.filter(linkItem => linkItem.position !== 'right')
|
||||
.map((linkItem, i) => (
|
||||
<NavLink {...linkItem} key={i} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
|
||||
<div className="navbar__items navbar__items--right">
|
||||
{links
|
||||
.filter(linkItem => linkItem.position === 'right')
|
||||
.map((linkItem, i) => (
|
||||
<NavLink {...linkItem} key={i} />
|
||||
))}
|
||||
{!disableDarkMode && (
|
||||
<Toggle
|
||||
className={styles.displayOnlyInLargeViewport}
|
||||
aria-label="Dark mode toggle"
|
||||
checked={isDarkTheme}
|
||||
onChange={onToggleChange}
|
||||
/>
|
||||
)}
|
||||
<SearchBar
|
||||
handleSearchBarToggle={setIsSearchBarExpanded}
|
||||
isSearchBarExpanded={isSearchBarExpanded}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
role="presentation"
|
||||
className="navbar-sidebar__backdrop"
|
||||
onClick={hideSidebar}
|
||||
/>
|
||||
<div className="navbar-sidebar">
|
||||
<div className="navbar-sidebar__brand">
|
||||
<Link
|
||||
className="navbar__brand"
|
||||
onClick={hideSidebar}
|
||||
to={logoLink}
|
||||
{...logoLinkProps}>
|
||||
{logo != null && (
|
||||
<img className="navbar__logo" src={logoImageUrl} alt={logo.alt} />
|
||||
)}
|
||||
{title != null && <strong>{title}</strong>}
|
||||
</Link>
|
||||
{!disableDarkMode && sidebarShown && (
|
||||
<Toggle
|
||||
aria-label="Dark mode toggle in sidebar"
|
||||
checked={isDarkTheme}
|
||||
onChange={onToggleChange}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="navbar-sidebar__items">
|
||||
<div className="menu">
|
||||
<ul className="menu__list">
|
||||
{links.map((linkItem, i) => (
|
||||
<li className="menu__list-item" key={i}>
|
||||
<NavLink
|
||||
className="menu__link"
|
||||
{...linkItem}
|
||||
onClick={hideSidebar}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
export default Navbar;
|
@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
@media screen and (max-width: 997px) {
|
||||
.displayOnlyInLargeViewport {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.hideLogoText {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.navbarHideable {
|
||||
transition: top 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.navbarHidden {
|
||||
top: calc(var(--ifm-navbar-height) * -1) !important;
|
||||
}
|
@ -50,6 +50,7 @@
|
||||
html[data-theme='dark'] {
|
||||
--color-primary-text: white;
|
||||
--blockquote-color: var(--ifm-navbar-background-color);
|
||||
--light-blue: var(--ifm-navbar-background-color);
|
||||
}
|
||||
|
||||
html {
|
||||
@ -241,6 +242,10 @@ p {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.tabs .tabs__item {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.tabs .nav-tabs > div {
|
||||
font-size: 1em;
|
||||
font-weight: normal;
|
||||
@ -506,7 +511,6 @@ a:hover {
|
||||
|
||||
#contactPage,
|
||||
#pageNotFoundPage {
|
||||
font-weight: lighter;
|
||||
margin-top: 80px;
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
@ -691,7 +695,7 @@ a:hover {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1.25em;
|
||||
font-size: 0.85em;
|
||||
font-weight: normal;
|
||||
color: white;
|
||||
}
|
||||
@ -734,6 +738,8 @@ a:hover {
|
||||
cursor: pointer;
|
||||
background-color: var(--lighter-blue);
|
||||
border-left: 6px solid var(--blue);
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#contactPage #message .communicationOptions .option .icon {
|
||||
@ -989,21 +995,79 @@ a:hover {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ReasonLIGO specific syntax highlighting */
|
||||
.language-reasonligo .hljs-operator {
|
||||
color: #a626a4;
|
||||
}
|
||||
.language-reasonligo .hljs-character {
|
||||
color: #50a14f;
|
||||
}
|
||||
.language-reasonligo .hljs-module-identifier {
|
||||
color: #00f;
|
||||
}
|
||||
.language-reasonligo .hljs-constructor {
|
||||
color: #a31515;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.codeTable {
|
||||
display: grid;
|
||||
grid-template-columns: 30% 70%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.codeTable > .primitive {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
text-align: right;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
|
||||
.codeTable > div:nth-child(4n+1) {
|
||||
background-color: var(--ifm-table-stripe-background);
|
||||
}
|
||||
|
||||
.codeTable > div:nth-child(4n+2) {
|
||||
background-color: var(--ifm-table-stripe-background);
|
||||
}
|
||||
|
||||
|
||||
.codeTable > .example {
|
||||
padding-top: var(--ifm-leading);
|
||||
}
|
||||
|
||||
.codeTable > .example pre,
|
||||
.codeTable > .example .codeBlockLines_src-theme-CodeBlock- {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.boolean-example-table {
|
||||
display: grid;
|
||||
grid-template-columns: 10% 30% 60%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.boolean-example-table .operation{
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.boolean-example-table .description {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.boolean-example-table > div:nth-child(6n+1),
|
||||
.boolean-example-table > div:nth-child(6n+2),
|
||||
.boolean-example-table > div:nth-child(6n+3) {
|
||||
background-color: var(--ifm-table-stripe-background);
|
||||
}
|
||||
|
||||
.boolean-example-table > .example pre,
|
||||
.boolean-example-table > .example .codeBlockLines_src-theme-CodeBlock- {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.compactLigoIde {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.compactLigoIde pre {
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 32 KiB |
BIN
gitlab-pages/website/static/img/christian.jpg
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
gitlab-pages/website/static/img/eowyn.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
gitlab-pages/website/static/img/francis.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 33 KiB |
BIN
gitlab-pages/website/static/img/pierre-emmanuel.jpg
Normal file
After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 24 KiB |
BIN
gitlab-pages/website/static/img/suzanne.jpg
Normal file
After Width: | Height: | Size: 29 KiB |
@ -1,6 +1,6 @@
|
||||
name: "ligo"
|
||||
opam-version: "2.0"
|
||||
maintainer: "ligolang@gmail.com"
|
||||
maintainer: "Galfour <contact@ligolang.org>"
|
||||
authors: [ "Galfour" ]
|
||||
homepage: "https://gitlab.com/ligolang/tezos"
|
||||
bug-reports: "https://gitlab.com/ligolang/tezos/issues"
|
||||
@ -23,6 +23,8 @@ depends: [
|
||||
"getopt"
|
||||
"terminal_size"
|
||||
"pprint"
|
||||
"UnionFind"
|
||||
"RedBlackTrees"
|
||||
# work around upstream in-place update
|
||||
"ocaml-migrate-parsetree" { = "1.4.0" }
|
||||
]
|
||||
|
30
nix/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# Nix expressions for building LIGO
|
||||
|
||||
Nix is a declarative package manager. Get it here: https://nixos.org/nix
|
||||
|
||||
These expressions are used on CI to reproducibly build the LIGO compiler, as well as WebIDE and https://ligolang.org .
|
||||
|
||||
If you wish to build it yourself, do `nix build -f. $thing`, where `$thing` is
|
||||
|
||||
- `ligo`: executables, libraries, documentation, coverage reports
|
||||
- `ligo-bin`: a dynamically linked binary (Linux, Mac)
|
||||
- `ligo-static`: a statically linked binary (Linux only)
|
||||
- `ligo-doc`: documentation generated by odoc
|
||||
- `ligo-editor`: WebIDE, it can be started with `result/bin/ligo-editor`
|
||||
- `ligo-website`: the website, website root is `result`
|
||||
- `ligo-docker`: a docker image with LIGO binaries
|
||||
- `ligo-editor-docker`: a docker image with webide
|
||||
- `ligo-deb`: debian package with static binaries
|
||||
|
||||
The output of `nix build` can be found in `result` directory.
|
||||
|
||||
## Quick maintenance guide
|
||||
|
||||
- `opam-repository` and `tezos-opam-repository` are pinned. To update them when required, run `niv update` (you can get niv with `nix shell 'nixpkgs#niv'`)
|
||||
- `ocaml` version is pinned in `ocaml-overlay.nix`. If you want to update it, go there and change the version.
|
||||
- If something fails, `nix repl pkgs.nix` can be very useful to investigate it.
|
||||
|
||||
## Known caveats
|
||||
|
||||
- This is not a [nix flake](https://gist.github.com/edolstra/40da6e3a4d4ee8fd019395365e0772e7). This will never be a flake if we want to keep this low-maintenance, because of the way `opam` sources are defined. Sometimes, the checksum is omitted there, so we have to use `fetchTarball` without the checksum, which won't work in restricted mode (which is required for flakes). The only solution would be to generate nix expressions for opam-repository separately, but it means a manual step in the process (and it's also impossible to make this work as a flake).
|
||||
- For the same reason as above, evaluation can take a while because we need to download all the sources every `tarball-ttl` seconds. This can be mitigated by setting `tarball-ttl` to a high value.
|
9
nix/default.nix
Normal file
@ -0,0 +1,9 @@
|
||||
{ sources ? import ./sources.nix }@args:
|
||||
let pkgs = import ./pkgs.nix args;
|
||||
in {
|
||||
inherit (pkgs)
|
||||
ligo ligo-tests ligo-doc ligo-coverage
|
||||
ligo-bin ligo-static ligo-docker ligo-deb
|
||||
ligo-editor ligo-editor-docker
|
||||
ligo-website;
|
||||
}
|
8
nix/docker.nix
Normal file
@ -0,0 +1,8 @@
|
||||
{ dockerTools, writeShellScriptBin, runCommand, mcpp, bash, coreutils, ligo
|
||||
, name ? "ligo", extraContents ? [ ] }:
|
||||
dockerTools.buildLayeredImage {
|
||||
inherit name;
|
||||
tag = "latest";
|
||||
contents = [ ligo bash ] ++ extraContents;
|
||||
config.Entrypoint = name;
|
||||
}
|
84
nix/lib.nix
@ -1,84 +0,0 @@
|
||||
pkgs:
|
||||
let
|
||||
findOpamFile = src:
|
||||
let
|
||||
opamFiles = (builtins.filter (x: !isNull (builtins.match ".*.opam" x))
|
||||
(builtins.attrNames (builtins.readDir src)));
|
||||
in if builtins.length opamFiles == 1 then
|
||||
builtins.head opamFiles
|
||||
else
|
||||
builtins.throw "Unable to determine a single opam file in ${src} (${
|
||||
toString opamFiles
|
||||
}), unable to proceed" "";
|
||||
in rec {
|
||||
opam-parser = pkgs.stdenv.mkDerivation {
|
||||
name = "opam-parser";
|
||||
src = ./opam-parser.hs;
|
||||
unpackPhase = "true";
|
||||
buildInputs = [ pkgs.ghc ];
|
||||
buildPhase = "ghc -o $out $src";
|
||||
phases = [ "buildPhase" ];
|
||||
};
|
||||
|
||||
# Generate a nix file from an opam file
|
||||
opam2nix =
|
||||
{ src, opamFile ? findOpamFile src, name ? opamFile + ".nix", ... }:
|
||||
pkgs.runCommandNoCC name { }
|
||||
"cat ${src}/${opamFile} | ${pkgs.glibc.bin}/bin/iconv -c -f utf-8 -t ascii | ${opam-parser} > $out";
|
||||
|
||||
# Traverse OPAM repository, producing an extension to
|
||||
# ocamlPackages than includes all the packages in the repo.
|
||||
traverseOPAMRepo = repo: self: super:
|
||||
let
|
||||
pkgNames = builtins.readDir "${repo}/packages";
|
||||
parseVersion = n: builtins.head (builtins.match "[^.]*.(.*)" n);
|
||||
versions = pkg:
|
||||
map parseVersion
|
||||
(builtins.attrNames (builtins.readDir "${repo}/packages/${pkg}"));
|
||||
latestVersion = builtins.foldl'
|
||||
(x: acc: if builtins.compareVersions x acc == 1 then x else acc) "";
|
||||
opamPkgs = builtins.mapAttrs (name: _:
|
||||
let
|
||||
file = version:
|
||||
opam2nix {
|
||||
src = "${repo}/packages/${name}/${name}.${version}";
|
||||
opamFile = "opam";
|
||||
name = "${name}.nix";
|
||||
};
|
||||
package = version:
|
||||
self.callPackage (file version) {
|
||||
extraArgs = {
|
||||
pname = name;
|
||||
inherit version;
|
||||
};
|
||||
};
|
||||
latest = package (latestVersion (versions name));
|
||||
others = map package (versions name);
|
||||
in latest // {
|
||||
versions = builtins.listToAttrs (map (p: {
|
||||
name = p.version;
|
||||
value = p;
|
||||
}) others);
|
||||
}) pkgNames;
|
||||
in opamPkgs;
|
||||
|
||||
# Same as traverseOPAMRepo, but packages in super take precedence over packages from the new repo.
|
||||
traverseOPAMRepo' = repo: self: super:
|
||||
let traversed = traverseOPAMRepo repo self super;
|
||||
in traversed // builtins.mapAttrs (name: v:
|
||||
v // {
|
||||
versions = (traversed.${name} or { versions = { }; }).versions;
|
||||
}) super;
|
||||
|
||||
# Extension that adds callOPAMPackage to the package set
|
||||
callOPAMPackage = self: super: {
|
||||
callOPAMPackage = src: extraArgs: overrides:
|
||||
(self.callPackage (opam2nix (extraArgs // { inherit src; }))
|
||||
(overrides // { inherit extraArgs; })).overrideAttrs ({ buildInputs, ... }@args: {
|
||||
inherit src;
|
||||
buildInputs = buildInputs ++ extraArgs.extraBuildInputs or [ ];
|
||||
propagatedBuildInputs = buildInputs
|
||||
++ extraArgs.extraBuildInputs or [ ];
|
||||
});
|
||||
};
|
||||
}
|
77
nix/ligo-editor.nix
Normal file
@ -0,0 +1,77 @@
|
||||
{ stdenv, lib, mkYarnPackage, nodejs, python2, ligo-bin, coreutils
|
||||
, writeShellScriptBin, makeFontsConf, buildEnv, rsync, sources
|
||||
, chromium ? null }:
|
||||
let
|
||||
# Use a common yarn.lock for everything
|
||||
yarnLock = ../tools/webide/yarn.lock;
|
||||
|
||||
installPhase = "mkdir $out; cp -Lr node_modules $out/node_modules";
|
||||
|
||||
# node_modules of the server
|
||||
server = mkYarnPackage {
|
||||
name = "webide-server";
|
||||
src = ../tools/webide/packages/server;
|
||||
buildPhase = ''
|
||||
cp ${../tools/webide/tsconfig.json} tsconfig.json
|
||||
yarn --offline run build
|
||||
rm node_modules/server/server
|
||||
'';
|
||||
doCheck = true;
|
||||
checkPhase = "DATA_DIR=/tmp LIGO_CMD=${ligo-bin}/bin/ligo yarn --offline jest";
|
||||
distPhase = "true";
|
||||
inherit yarnLock installPhase;
|
||||
};
|
||||
|
||||
# node_modules of the client
|
||||
client = mkYarnPackage rec {
|
||||
name = "webide-client";
|
||||
src = ../tools/webide/packages/client;
|
||||
buildPhase = ''
|
||||
export EXAMPLES_DIR=${../src/test/examples}
|
||||
yarn --offline run build
|
||||
rm node_modules/client/client
|
||||
find deps/client/build -type f -exec sed -r "s,/nix/store/[a-z0-9]{32}-[^/]*,$out,g" -i '{}' \;
|
||||
'';
|
||||
distPhase = "true";
|
||||
installPhase = "mkdir $out; cp -Lr deps/client/build $out";
|
||||
inherit yarnLock;
|
||||
# Downloads node-sass from the official github repo
|
||||
# Uncomment the commented lines if you wish to build it from source
|
||||
yarnPreBuild = "export SASS_BINARY_PATH=${sources.node-sass-bin}";
|
||||
/* ''
|
||||
mkdir -p "$HOME/.node-gyp/${nodejs.version}"
|
||||
echo 9 > "$HOME/.node-gyp/${nodejs.version}/installVersion"
|
||||
ln -sfv "${nodejs}/include" "$HOME/.node-gyp/${nodejs.version}"
|
||||
'';
|
||||
*/
|
||||
};
|
||||
|
||||
# Perform the e2e tests; output is empty on purpose
|
||||
e2e = mkYarnPackage rec {
|
||||
name = "webide-e2e";
|
||||
src = ../tools/webide/packages/e2e;
|
||||
# Provide puppeteer with chromium, since it can't download it inside the nix sandbox.
|
||||
# Also, since we override nodejs in our overlays, import chromium from pure nixpkgs to avoid a rebuild
|
||||
buildPhase = ''
|
||||
export HOME="$(pwd)"
|
||||
export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
|
||||
export PUPPETEER_EXECUTABLE_PATH=${(import (import ./sources.nix).nixpkgs {}).chromium.outPath}/bin/chromium
|
||||
${ligo-editor}/bin/ligo-editor &
|
||||
export API_HOST=http://localhost:8080
|
||||
export FONTCONFIG_FILE=${makeFontsConf { fontDirectories = [ ]; }}
|
||||
yarn --offline jest
|
||||
'';
|
||||
distPhase = "true";
|
||||
installPhase = "touch $out";
|
||||
inherit yarnLock;
|
||||
};
|
||||
|
||||
# Run the WebIDE server with all the needed env variables
|
||||
ligo-editor = writeShellScriptBin "ligo-editor" ''
|
||||
set -e
|
||||
LIGO_CMD=${ligo-bin}/bin/ligo \
|
||||
STATIC_ASSETS=${client} \
|
||||
DATA_DIR=/tmp \
|
||||
${nodejs}/bin/node ${server}/node_modules/server/dist/src/index.js
|
||||
'';
|
||||
in ligo-editor // { inherit e2e; }
|
18
nix/ligo-website.nix
Normal file
@ -0,0 +1,18 @@
|
||||
{ buildNpmPackage, writeShellScriptBin, yarn, linkFarm, nodejs-slim, python2
|
||||
, ligo-doc, ligo-deb, ligo-static }:
|
||||
buildNpmPackage {
|
||||
src = ../gitlab-pages/website;
|
||||
npmBuild = "npm run build";
|
||||
preBuild = ''
|
||||
cp -r ${../gitlab-pages/docs} $NIX_BUILD_TOP/docs
|
||||
chmod 700 -R $NIX_BUILD_TOP/docs
|
||||
'';
|
||||
installPhase = ''
|
||||
cp -Lr build $out
|
||||
cp -r ${ligo-deb}/*.deb $out/deb/ligo.deb
|
||||
mkdir -p $out/bin/linux
|
||||
cp -r ${ligo-static}/bin/ligo $out/bin/linux/ligo
|
||||
cp -r ${ligo-doc}/share/doc $out/odoc
|
||||
'';
|
||||
extraEnvVars.nativeBuildInputs = [ python2 ];
|
||||
}
|
9
nix/mac-overlay.nix
Normal file
@ -0,0 +1,9 @@
|
||||
oself: osuper:
|
||||
let
|
||||
fixHardeningWarning = pkg: pkg.overrideAttrs (_: {
|
||||
hardeningDisable = [ "strictoverflow" ];
|
||||
});
|
||||
in
|
||||
{
|
||||
hacl = fixHardeningWarning osuper.hacl;
|
||||
}
|
6
nix/nodejs-overlay.nix
Normal file
@ -0,0 +1,6 @@
|
||||
self: super: {
|
||||
# Note: this overlay doesn't apply to nix-npm-buildpackage
|
||||
nodejs = super.nodejs-12_x;
|
||||
nodePackages = super.nodePackages_12_x;
|
||||
nodejs-slim = super.nodejs-slim-12_x;
|
||||
}
|
@ -1,94 +1,152 @@
|
||||
{ sources ? import ./sources.nix, version ? "git" }:
|
||||
# An overlay that adds ligo to ocamlPackages
|
||||
|
||||
{ sources ? import ./sources.nix
|
||||
, CI_COMMIT_SHA ? builtins.getEnv "CI_COMMIT_SHA"
|
||||
, COMMIT_DATE ? builtins.getEnv "COMMIT_DATE" }:
|
||||
self: super:
|
||||
let lib = import ./lib.nix self;
|
||||
let
|
||||
opam-nix = import sources.opam-nix (import sources.nixpkgs { });
|
||||
inherit (import sources."gitignore.nix" { inherit (self) lib; })
|
||||
gitignoreSource;
|
||||
# Remove list of directories or files from source (to stop unneeded rebuilds)
|
||||
# Also, apply the gitignore here.
|
||||
filterOut = xs:
|
||||
gitignoreSource (self.lib.cleanSourceWith {
|
||||
filter = p: type: !(builtins.elem (builtins.baseNameOf p) xs);
|
||||
src = gitignoreSource ../.;
|
||||
});
|
||||
in {
|
||||
ocamlPackages = super.ocaml-ng.ocamlPackages_4_07.overrideScope'
|
||||
ocamlPackages = self.ocaml-ng.ocamlPackages_4_07.overrideScope'
|
||||
(builtins.foldl' self.lib.composeExtensions (_: _: { }) [
|
||||
(lib.traverseOPAMRepo' sources.opam-repository)
|
||||
(lib.traverseOPAMRepo sources.tezos-opam-repository)
|
||||
(lib.callOPAMPackage)
|
||||
(oself: osuper:
|
||||
with oself; {
|
||||
ocamlfind = findlib;
|
||||
lwt = lwt4;
|
||||
bigstring = osuper.bigstring.overrideAttrs (_: { doCheck = false; });
|
||||
xmldiff =
|
||||
osuper.xmldiff.overrideAttrs (_: { src = sources.xmldiff; });
|
||||
ipaddr = osuper.ipaddr.versions."4.0.0";
|
||||
conduit = osuper.conduit.versions."2.1.0";
|
||||
conduit-lwt-unix = osuper.conduit-lwt-unix.versions."2.0.2";
|
||||
cohttp-lwt-unix = osuper.cohttp-lwt-unix.versions."2.4.0";
|
||||
cohttp-lwt = osuper.cohttp-lwt.versions."2.4.0";
|
||||
macaddr = osuper.macaddr.versions."4.0.0";
|
||||
ocaml-migrate-parsetree =
|
||||
osuper.ocaml-migrate-parsetree.versions."1.4.0";
|
||||
ppx_tools_versioned = osuper.ppx_tools_versioned.versions."5.2.3";
|
||||
tezos-protocol-compiler = osuper.tezos-protocol-compiler.overrideAttrs
|
||||
(oa: {
|
||||
buildInputs = oa.buildInputs ++ [ oself.pprint ];
|
||||
postInstall =
|
||||
"ln -s $out/lib/ocaml/*/site-lib/tezos-protocol-compiler/* $out";
|
||||
});
|
||||
conf-gmp = self.gmp;
|
||||
conf-libev = self.libev;
|
||||
conf-hidapi = self.hidapi;
|
||||
conf-pkg-config = self.pkg-config;
|
||||
# Both opam-repository and tezos-opam-repository are updated manually with `niv update`
|
||||
(opam-nix.traverseOPAMRepo' sources.opam-repository)
|
||||
(opam-nix.traverseOPAMRepo sources.tezos-opam-repository)
|
||||
(opam-nix.callOPAMPackage (filterOut [
|
||||
".git"
|
||||
".gitlab-ci.yml"
|
||||
".gitignore"
|
||||
"nix"
|
||||
"docker"
|
||||
"tools"
|
||||
"gitlab-pages"
|
||||
]))
|
||||
(oself: osuper: {
|
||||
# Strange naming in nixpkgs
|
||||
ocamlfind = oself.findlib;
|
||||
lablgtk = null;
|
||||
lwt = oself.lwt4;
|
||||
|
||||
tezos-protocol-006-PsCARTHA =
|
||||
oself.callOPAMPackage ../vendors/ligo-utils/tezos-protocol-alpha {
|
||||
pname = "tezos-protocol-006-PsCARTHA";
|
||||
version = "0.0.0";
|
||||
opamFile = "tezos-protocol-006-PsCARTHA.opam";
|
||||
} { };
|
||||
# Native dependencies
|
||||
conf-gmp = self.gmp;
|
||||
conf-libev = self.libev;
|
||||
conf-hidapi = self.hidapi;
|
||||
conf-pkg-config = self.pkg-config;
|
||||
|
||||
tezos-protocol-006-PsCARTHA-parameters = oself.callOPAMPackage
|
||||
../vendors/ligo-utils/tezos-protocol-alpha-parameters {
|
||||
pname = "tezos-protocol-006-PsCARTHA-parameters";
|
||||
version = "0.0.0";
|
||||
} { };
|
||||
# Strange problems
|
||||
bigstring = osuper.bigstring.overrideAttrs (_: { doCheck = false; });
|
||||
xmldiff = osuper.xmldiff.overrideAttrs (_: { src = sources.xmldiff; });
|
||||
getopt = osuper.getopt.overrideAttrs (_: { configurePhase = "true"; });
|
||||
|
||||
tezos-utils =
|
||||
oself.callOPAMPackage ../vendors/ligo-utils/tezos-utils {
|
||||
pname = "tezos-utils";
|
||||
version = "0.1";
|
||||
} { };
|
||||
# Force certain versions
|
||||
ipaddr = osuper.ipaddr.versions."4.0.0";
|
||||
conduit = osuper.conduit.versions."2.1.0";
|
||||
conduit-lwt-unix = osuper.conduit-lwt-unix.versions."2.0.2";
|
||||
cohttp-lwt-unix = osuper.cohttp-lwt-unix.versions."2.4.0";
|
||||
cohttp-lwt = osuper.cohttp-lwt.versions."2.4.0";
|
||||
macaddr = osuper.macaddr.versions."4.0.0";
|
||||
ocaml-migrate-parsetree =
|
||||
osuper.ocaml-migrate-parsetree.versions."1.4.0";
|
||||
ppx_tools_versioned = osuper.ppx_tools_versioned.versions."5.2.3";
|
||||
bisect_ppx = osuper.bisect_ppx.versions."2.0.0".overrideAttrs (_: {
|
||||
src = builtins.fetchTarball
|
||||
"https://github.com/aantron/bisect_ppx/archive/02dfb10188033a26d07d23480c2bc44a3a670357.tar.gz";
|
||||
});
|
||||
|
||||
proto-alpha-utils =
|
||||
oself.callOPAMPackage ../vendors/ligo-utils/proto-alpha-utils {
|
||||
pname = "proto-alpha-utils";
|
||||
version = "0.1";
|
||||
extraBuildInputs =
|
||||
[ oself.tezos-protocol-006-PsCARTHA-parameters ];
|
||||
} { };
|
||||
proto-alpha-utils = osuper.proto-alpha-utils.overrideAttrs (oa: rec {
|
||||
buildInputs = oa.buildInputs
|
||||
++ [ oself.tezos-protocol-006-PsCARTHA-parameters ];
|
||||
propagatedBuildInputs = buildInputs;
|
||||
});
|
||||
tezos-protocol-compiler = osuper.tezos-protocol-compiler.overrideAttrs
|
||||
(oa: rec {
|
||||
buildInputs = oa.buildInputs ++ [ oself.pprint ];
|
||||
propagatedBuildInputs = buildInputs;
|
||||
});
|
||||
|
||||
simple-utils =
|
||||
oself.callOPAMPackage ../vendors/ligo-utils/simple-utils {
|
||||
pname = "simple-utils";
|
||||
version = "0.1";
|
||||
} { };
|
||||
# A combination of executables, libraries, documentation and test coverage
|
||||
ligo = self.buildEnv {
|
||||
name = "ligo";
|
||||
paths = with oself; [
|
||||
ligo-out.out
|
||||
ligo-tests
|
||||
ligo-doc
|
||||
ligo-coverage
|
||||
];
|
||||
};
|
||||
|
||||
tezos-memory-proto-alpha =
|
||||
oself.callOPAMPackage ../vendors/ligo-utils/memory-proto-alpha {
|
||||
pname = "tezos-memory-proto-alpha";
|
||||
version = "0.0.0";
|
||||
} { };
|
||||
# LIGO executable and public libraries
|
||||
ligo-out = osuper.ligo.overrideAttrs (oa: {
|
||||
name = "ligo-out";
|
||||
inherit CI_COMMIT_SHA COMMIT_DATE;
|
||||
buildInputs = oa.buildInputs
|
||||
++ [ oself.UnionFind oself.Preprocessor ];
|
||||
nativeBuildInputs = oa.nativeBuildInputs
|
||||
++ [ self.buildPackages.rakudo ];
|
||||
});
|
||||
|
||||
michelson-parser = oself.callOPAMPackage
|
||||
../vendors/ligo-utils/tezos-utils/michelson-parser {
|
||||
pname = "michelson-parser";
|
||||
version = "0.0.0";
|
||||
} { ocamlfind = oself.findlib; };
|
||||
|
||||
UnionFind = oself.callOPAMPackage ../vendors/UnionFind rec {
|
||||
pname = "UnionFind";
|
||||
version = "master";
|
||||
buildPhase = "echo ${version} > Version.ml; dune build -p ${pname}";
|
||||
} { };
|
||||
|
||||
ligo = oself.callOPAMPackage ../. {
|
||||
version = "0.1";
|
||||
extraBuildInputs = with oself; [ ppx_tools_versioned getopt self.getopt UnionFind ];
|
||||
} { };
|
||||
})
|
||||
# LIGO test suite; output empty on purpose
|
||||
ligo-tests = osuper.ligo.overrideAttrs (oa: {
|
||||
name = "ligo-tests";
|
||||
src = filterOut [
|
||||
".git"
|
||||
".gitlab-ci.yml"
|
||||
".gitignore"
|
||||
"nix"
|
||||
"docker"
|
||||
"tools"
|
||||
];
|
||||
outputs = [ "out" ];
|
||||
buildPhase = "dune runtest";
|
||||
nativeBuildInputs = oa.nativeBuildInputs
|
||||
++ [ self.buildPackages.rakudo ];
|
||||
installPhase = "mkdir $out";
|
||||
});
|
||||
# LIGO odoc documentation
|
||||
ligo-doc = osuper.ligo.overrideAttrs (oa: {
|
||||
name = "ligo-doc";
|
||||
buildInputs = oa.buildInputs
|
||||
++ [ oself.odoc oself.tezos-protocol-updater ];
|
||||
outputs = [ "out" ];
|
||||
buildPhase = "dune build @doc";
|
||||
nativeBuildInputs = oa.nativeBuildInputs
|
||||
++ [ self.buildPackages.rakudo ];
|
||||
installPhase =
|
||||
"mkdir $out; cp -r _build/default/_doc/_html/ $out/doc";
|
||||
});
|
||||
# LIGO test coverage reports
|
||||
ligo-coverage = oself.ligo-tests.overrideAttrs (oa: {
|
||||
name = "ligo-coverage";
|
||||
nativeBuildInputs = oa.nativeBuildInputs
|
||||
++ [ self.buildPackages.rakudo ];
|
||||
buildPhase = ''
|
||||
# Needed for coverage and nothing else
|
||||
mkdir -p $out/share/coverage
|
||||
echo "Coverage:"
|
||||
BISECT_ENABLE=yes dune runtest --force
|
||||
bisect-ppx-report html -o $out/share/coverage/all --title="LIGO overall test coverage"
|
||||
bisect-ppx-report summary --per-file > $out/share/coverage-all
|
||||
echo "Test coverage:"
|
||||
BISECT_ENABLE=yes dune runtest src/test --force
|
||||
bisect-ppx-report html -o $out/share/coverage/ligo --title="LIGO test coverage"
|
||||
echo "Doc coverage:"
|
||||
BISECT_ENABLE=yes dune build @doc-test --force
|
||||
bisect-ppx-report html -o $out/share/coverage/docs --title="LIGO doc coverage"
|
||||
echo "CLI test coverage:"
|
||||
BISECT_ENABLE=yes dune runtest src/bin/expect_tests
|
||||
bisect-ppx-report html -o $out/share/coverage/cli --title="CLI test coverage"
|
||||
'';
|
||||
installPhase = "true";
|
||||
});
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
@ -1,201 +0,0 @@
|
||||
{-# LANGUAGE FlexibleContexts, LambdaCase, RecordWildCards #-}
|
||||
|
||||
import Text.Parsec
|
||||
import Data.Functor.Identity (Identity ())
|
||||
import System.Environment (getEnv)
|
||||
import Data.Maybe (fromJust, isNothing, maybeToList)
|
||||
import Control.Monad (void)
|
||||
import Data.List (intersperse, nub, isPrefixOf)
|
||||
import qualified Control.Applicative as A (optional)
|
||||
|
||||
data OPAM
|
||||
= OPAM
|
||||
{ name :: Maybe String
|
||||
, version :: Maybe String
|
||||
, nativeBuildInputs :: Maybe [String]
|
||||
, buildInputs :: Maybe [String]
|
||||
, buildPhase :: Maybe [[String]]
|
||||
, checkInputs :: Maybe [String]
|
||||
, checkPhase :: Maybe [[String]]
|
||||
, source :: Maybe String
|
||||
} deriving Show
|
||||
|
||||
-- Turn a description into a nix file
|
||||
opam2nix :: OPAM -> String
|
||||
opam2nix OPAM {..} =
|
||||
let
|
||||
normalize = nub . map (\case 'b':'a':'s':'e':'-':_ -> "base"; s -> s)
|
||||
buildInputs' = [ "findlib" ] ++ mconcat (maybeToList buildInputs);
|
||||
checkInputs' = mconcat $ maybeToList checkInputs
|
||||
nativeBuildInputs' = [ "dune", "opaline", "ocaml", "findlib" ]
|
||||
++ (if any (isPrefixOf "conf-")
|
||||
(buildInputs' ++ checkInputs' ++ mconcat (maybeToList nativeBuildInputs))
|
||||
then ["conf-pkg-config"]
|
||||
else [])
|
||||
++ mconcat (maybeToList nativeBuildInputs)
|
||||
inputs = buildInputs' ++ checkInputs' ++ nativeBuildInputs'
|
||||
deps = mconcat $ intersperse ", " $ normalize $ inputs
|
||||
sepspace = mconcat . intersperse " " . normalize
|
||||
preparephase = mconcat . intersperse " " . mconcat . intersperse ["\n"]
|
||||
in
|
||||
"{ stdenv, fetchzip, " <>deps<> ", extraArgs ? { } }:\n"
|
||||
<>"\n" -- Awful hack to allow this to evaluate even if some of the variables are undefined
|
||||
<>"stdenv.mkDerivation (let self = with self; with extraArgs; {\n"
|
||||
<>foldMap (\name' -> " pname = \""<>name'<>"\";\n") name
|
||||
<>foldMap (\version' -> " version = \""<>version'<>"\";\n") version
|
||||
<>foldMap (\url -> " src = builtins.fetchTarball { url = \""<>url<>"\"; };\n") source
|
||||
<>" buildInputs = [ "<>sepspace buildInputs'<>" ];\n"
|
||||
<>" checkInputs = [ "<>sepspace checkInputs'<>" ];\n"
|
||||
<>" nativeBuildInputs = [ "<>sepspace nativeBuildInputs'<>" ];\n"
|
||||
<>" propagatedBuildInputs = buildInputs;\n"
|
||||
<>" propagatedNativeBuildInputs = nativeBuildInputs;\n"
|
||||
<>foldMap (\buildPhase' ->
|
||||
" buildPhase = ''runHook preBuild\n"
|
||||
<> preparephase buildPhase'
|
||||
<>"\nrunHook postBuild\n'';\n") buildPhase
|
||||
<>foldMap (\checkPhase' ->
|
||||
" checkPhase = ''runHook preCheck\n"
|
||||
<>preparephase checkPhase'
|
||||
<>"\nrunHook postCheck\n'';\n") checkPhase
|
||||
<>" installPhase = ''\nrunHook preInstall\nopaline -prefix $out -libdir $OCAMLFIND_DESTDIR\nrunHook postInstall\n'';\n"
|
||||
<>"}; in self // extraArgs)\n"
|
||||
|
||||
update :: Maybe a -> a -> Maybe a
|
||||
update old new = if isNothing old then Just new else old
|
||||
|
||||
-- Evaluate a Field and update OPAM description accordingly
|
||||
evaluateField :: OPAM -> Field -> OPAM
|
||||
evaluateField o@OPAM {..} = \case
|
||||
Name s -> o { name = update name s }
|
||||
Version s -> o { version = update version s }
|
||||
Depends s -> o {
|
||||
buildInputs = update buildInputs $
|
||||
fmap identifier $ filter (\(Package _ info) -> not $ ("with-test" `elem` info || "build" `elem` info)) s,
|
||||
nativeBuildInputs = update nativeBuildInputs $
|
||||
fmap identifier $ filter (\(Package _ info) -> "build" `elem` info) s,
|
||||
checkInputs = update checkInputs $
|
||||
fmap identifier $ filter (\(Package _ info) -> "with-test" `elem` info) s
|
||||
}
|
||||
Build e -> o {
|
||||
buildPhase = update buildPhase
|
||||
$ fmap ((fmap evaluateExp) . command) $ filter (\(Command _ info) -> not $ "with-test" `elem` info) e,
|
||||
checkPhase = update checkPhase
|
||||
$ fmap ((fmap evaluateExp) . command) $ filter (\(Command _ info) -> "with-test" `elem` info) e
|
||||
}
|
||||
URL url -> o { source = update source url}
|
||||
Other _ -> o
|
||||
|
||||
evaluateFields :: OPAM -> [Field] -> OPAM
|
||||
evaluateFields = foldl evaluateField
|
||||
|
||||
|
||||
-- Descriptions for various Fields of an opam file
|
||||
|
||||
data Package
|
||||
= Package
|
||||
{ identifier :: String
|
||||
, additionalPackageInfo :: [String]
|
||||
} deriving Show
|
||||
|
||||
-- An expression as found in a Command
|
||||
data Exp = Str String | Var String deriving Show
|
||||
|
||||
evaluateExp :: Exp -> String
|
||||
evaluateExp =
|
||||
let
|
||||
repl ('%':'{':xs) = '$':'{':repl xs
|
||||
repl ('}':'%':xs) = '}':repl xs
|
||||
repl (':':_:_:_:'}':'%':xs) = '}':repl xs
|
||||
repl (x:xs) = x:repl xs
|
||||
repl "" = ""
|
||||
in
|
||||
\case
|
||||
Str s -> repl s
|
||||
Var "name" -> "${pname}"
|
||||
Var "make" -> "make"
|
||||
Var "prefix" -> "$out"
|
||||
Var "jobs" -> "1"
|
||||
Var s -> "${"<>s<>"}"
|
||||
|
||||
data Command
|
||||
= Command
|
||||
{ command :: [Exp]
|
||||
, additionalCommandInfo :: [String]
|
||||
} deriving Show
|
||||
|
||||
data Field
|
||||
= Name String
|
||||
| Version String
|
||||
| Depends [Package]
|
||||
| Build [Command]
|
||||
| URL String
|
||||
| Other String
|
||||
deriving Show
|
||||
|
||||
|
||||
-- An opam file is a collection of fields,
|
||||
opamFile :: ParsecT String u Identity [Field]
|
||||
opamFile = many field <* eof
|
||||
|
||||
-- Each has a name and a type;
|
||||
field :: ParsecT String u Identity Field
|
||||
field = Name <$> fieldParser "name" stringParser
|
||||
<|> Version <$> fieldParser "version" stringParser
|
||||
<|> Depends <$> fieldParser "depends" (listParser packageParser)
|
||||
<|> Build <$> fieldParser "build" (pure <$> try commandParser <|> listParser commandParser)
|
||||
<|> sectionParser "url" (URL <$> (fieldParser "src" stringParser <* many (noneOf "}")))
|
||||
<|> Other <$> (many (noneOf "\n") <* char '\n')
|
||||
|
||||
-- Field's structure is "name: value"
|
||||
fieldParser :: String -> ParsecT String u Identity t -> ParsecT String u Identity t
|
||||
fieldParser name valueParser = try $ between (string (name<>":") >> many (oneOf " \n")) (many $ oneOf " \n") valueParser <* commentParser
|
||||
|
||||
-- Sections's structure is "name { fields }"
|
||||
sectionParser :: String -> ParsecT String u Identity t -> ParsecT String u Identity t
|
||||
sectionParser name valueParser = try $ between (string name >> many (oneOf " ") >> string "{" >> many (oneOf " \n")) (many (oneOf " \n") >> char '}' >> char '\n') valueParser
|
||||
|
||||
-- String is enclosed in quotes
|
||||
stringParser :: ParsecT String u Identity String
|
||||
stringParser = between (char '"') (char '"') (many $ noneOf "\"")
|
||||
|
||||
-- Expression is either a string or a variable
|
||||
expParser :: ParsecT String u Identity Exp
|
||||
expParser = try (Str <$> stringParser)
|
||||
<|> Var <$> many1 (noneOf " \n\"{}[]")
|
||||
|
||||
-- "Additional Info" is additional information about a package or command, "{like-this}"
|
||||
additionalInfoParser :: ParsecT String u Identity [String]
|
||||
additionalInfoParser = option [] $ try
|
||||
$ between (many (char ' ') >> char '{') (char '}')
|
||||
((many $ noneOf " &}") `sepBy` (oneOf " &"))
|
||||
|
||||
-- Command is a [expressions] with additionional information
|
||||
commandParser :: ParsecT String u Identity Command
|
||||
commandParser = Command <$> (listParser $ try expParser) <*> additionalInfoParser
|
||||
|
||||
-- Comment starts with # and goes to the end of line
|
||||
commentParser :: ParsecT String u Identity ()
|
||||
commentParser = optional $ do
|
||||
void $ string "#"
|
||||
many $ noneOf "\n"
|
||||
|
||||
-- Package is a "string" with additional information
|
||||
packageParser :: ParsecT String u Identity Package
|
||||
packageParser = Package <$> stringParser <*> additionalInfoParser
|
||||
|
||||
|
||||
listParser :: ParsecT String u Identity t -> ParsecT String u Identity [t]
|
||||
listParser valueParser =
|
||||
between (char '[') (char ']') $ between startPadding endPadding
|
||||
valueParser `sepBy` sep
|
||||
where
|
||||
startPadding = sep
|
||||
endPadding = whiteSpace
|
||||
sep = (whiteSpace >> commentParser) <|> whiteSpace
|
||||
whiteSpace = optional $ many $ oneOf " \n"
|
||||
|
||||
main :: IO ()
|
||||
main = getContents >>= \s -> case parse opamFile "(unknown)" s of
|
||||
Left e -> print e
|
||||
Right fs -> putStrLn $ opam2nix $ evaluateFields (OPAM Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing) fs
|
||||
-- Right fs -> mapM_ print fs
|
47
nix/packageDeb.nix
Normal file
@ -0,0 +1,47 @@
|
||||
# Create a debian package from static executable
|
||||
{ stdenv, lib, writeTextFile, ligo-static, dpkg }:
|
||||
let
|
||||
project = "ligo";
|
||||
version = "0.0.0";
|
||||
revision = lib.commitIdFromGitRepo ../.git;
|
||||
pkgArch = "amd64";
|
||||
bin = "${ligo-static}/bin/ligo";
|
||||
pkgName = "${project}_0ubuntu${version}-${revision}_${pkgArch}";
|
||||
depends = "";
|
||||
maintainer = "ligolang ligolang.org";
|
||||
description = "A friendly Smart Contract Language for Tezos";
|
||||
|
||||
writeControlFile = writeTextFile {
|
||||
name = "control";
|
||||
text = ''
|
||||
Package: ${project}
|
||||
Version: ${version}-${revision}
|
||||
Priority: optional
|
||||
Architecture: ${pkgArch}
|
||||
Depends: ${depends}
|
||||
Maintainer: ${maintainer}
|
||||
Description: ${project}
|
||||
${description}
|
||||
'';
|
||||
};
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
name = "${pkgName}.deb";
|
||||
|
||||
nativeBuildInputs = [ dpkg ];
|
||||
|
||||
phases = "packagePhase";
|
||||
|
||||
packagePhase = ''
|
||||
mkdir ${pkgName}
|
||||
mkdir -p ${pkgName}/usr/local/bin
|
||||
cp ${bin} ${pkgName}/usr/local/bin/${project}
|
||||
|
||||
mkdir ${pkgName}/DEBIAN
|
||||
cp ${writeControlFile} ${pkgName}/DEBIAN/control
|
||||
|
||||
dpkg-deb --build ${pkgName}
|
||||
mkdir -p $out
|
||||
cp ${name} $out/
|
||||
'';
|
||||
}
|
42
nix/pkgs.nix
Normal file
@ -0,0 +1,42 @@
|
||||
# nixpkgs extended with all the overlays for LIGO
|
||||
{ sources ? import ./sources.nix }:
|
||||
let
|
||||
ocaml-overlay = import ./ocaml-overlay.nix { inherit sources; };
|
||||
static-overlay = import ./static-overlay.nix pkgs;
|
||||
mac-overlay = import ./mac-overlay.nix;
|
||||
nodejs-overlay = import ./nodejs-overlay.nix;
|
||||
nix-npm-buildpackage = pkgs.callPackage sources.nix-npm-buildpackage { };
|
||||
|
||||
pkgs = import sources.nixpkgs {
|
||||
overlays = [ ocaml-overlay nodejs-overlay ]
|
||||
# This is done here to prevent the need for bootstrap nixpkgs
|
||||
++ (if builtins.currentSystem == "x86_64-darwin"
|
||||
then [ mac-overlay ]
|
||||
else [ ]);
|
||||
};
|
||||
|
||||
# Takes $pkg/ligo and creates a new package with $pkg/bin/ligo
|
||||
separateBinary = pkg:
|
||||
pkgs.runCommandNoCC "${pkg.name}-bin" { }
|
||||
"mkdir -p $out/bin; cp -Lr ${pkg}/ligo $out/bin";
|
||||
|
||||
|
||||
tmp = pkgs.runCommandNoCC "tmpdir" { } "mkdir -p $out/tmp";
|
||||
|
||||
in pkgs.extend (self: super: {
|
||||
inherit (self.ocamlPackages) ligo ligo-out ligo-tests ligo-doc ligo-coverage;
|
||||
ligo-bin = separateBinary self.ligo-out.bin;
|
||||
ligo-docker = self.callPackage ./docker.nix { ligo = self.ligo-bin; };
|
||||
ligo-deb = self.callPackage ./packageDeb.nix { };
|
||||
ligo-editor = self.callPackage ./ligo-editor.nix { inherit sources; };
|
||||
ligo-editor-docker = self.callPackage ./docker.nix {
|
||||
ligo = self.ligo-editor;
|
||||
name = "ligo-editor";
|
||||
extraContents = [ tmp ];
|
||||
};
|
||||
ligo-website = self.callPackage ./ligo-website.nix {
|
||||
inherit (nix-npm-buildpackage) buildNpmPackage;
|
||||
};
|
||||
ligo-static = self.pkgsMusl.ligo-bin;
|
||||
pkgsMusl = super.pkgsMusl.extend static-overlay;
|
||||
})
|
@ -1,14 +1,57 @@
|
||||
{
|
||||
"nixpkgs": {
|
||||
"branch": "ocaml-cross-fixes",
|
||||
"description": "Pinned Nixpkgs tree (master follows nixos-unstable-small, only tags have stable history)",
|
||||
"gitignore.nix": {
|
||||
"branch": "master",
|
||||
"description": "Nix function for filtering local git sources",
|
||||
"homepage": "",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "2ced4519f865341adcb143c5d668f955a2cb997f",
|
||||
"sha256": "0fc5bgv9syfcblp23y05kkfnpgh3gssz6vn24frs8dzw39algk2z",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/hercules-ci/gitignore.nix/archive/2ced4519f865341adcb143c5d668f955a2cb997f.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nix-npm-buildpackage": {
|
||||
"branch": "balsoft/local-deps",
|
||||
"description": "Build nix packages that use npm/yarn",
|
||||
"homepage": "",
|
||||
"owner": "serokell",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "80a7615300badde924f2ca30caa988484c6c11cc",
|
||||
"sha256": "09i6f2qpsbgr2m8b5a1ac13fvhvg25560xvscl83bj9bb28sc3xc",
|
||||
"repo": "nix-npm-buildpackage",
|
||||
"rev": "f2107f638f7df7450a5b7b77b96aaf9752b838d9",
|
||||
"sha256": "02w8jxmmhxsq7fgzml75b8w8i9mdqxnaajia99jajg6rdiam8zfp",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/serokell/nixpkgs/archive/80a7615300badde924f2ca30caa988484c6c11cc.tar.gz",
|
||||
"url": "https://github.com/serokell/nix-npm-buildpackage/archive/f2107f638f7df7450a5b7b77b96aaf9752b838d9.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nixpkgs": {
|
||||
"branch": "nixos-unstable",
|
||||
"description": "Pinned Nixpkgs tree (master follows nixos-unstable-small, only tags have stable history)",
|
||||
"homepage": "",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs-channels",
|
||||
"rev": "3320a06049fc259e87a2bd98f4cd42f15f746b96",
|
||||
"sha256": "1g5l186d5xh187vdcpfsz1ff8s749949c1pclvzfkylpar09ldkl",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/nixos/nixpkgs-channels/archive/3320a06049fc259e87a2bd98f4cd42f15f746b96.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"node-sass-bin": {
|
||||
"sha256": "0dl91l414na44h090cgghd06q0j2whlj9h98im2qb9823glq7xff",
|
||||
"type": "file",
|
||||
"url": "https://github.com/sass/node-sass/releases/download/v4.12.0/linux-x64-64_binding.node",
|
||||
"url_template": "https://github.com/sass/node-sass/releases/download/v<version>/linux-x64-64_binding.node",
|
||||
"version": "4.12.0"
|
||||
},
|
||||
"opam-nix": {
|
||||
"branch": "master",
|
||||
"description": "A handy nix library to package OCaml software from OPAM repositories",
|
||||
"homepage": null,
|
||||
"owner": "balsoft",
|
||||
"repo": "opam-nix",
|
||||
"rev": "75ad75c18b8d80d82c13dc30c3b8d70960b1b441",
|
||||
"sha256": "0mcr32f5i71diysvpblbvgdnx2pdymwjb9nxz5gbcsib3vdg2p83",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/balsoft/opam-nix/archive/75ad75c18b8d80d82c13dc30c3b8d70960b1b441.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"opam-repository": {
|
||||
|
27
nix/static-overlay.nix
Normal file
@ -0,0 +1,27 @@
|
||||
# An overlay that adds flags needed to build LIGO statically;
|
||||
# Supposed to be applied to pkgsMusl
|
||||
# Takes `native` as a package set that doesn't cause mass rebuilds (so that we don't have to build perl with musl)
|
||||
native: self: super:
|
||||
let dds = x: x.overrideAttrs (o: { dontDisableStatic = true; });
|
||||
in {
|
||||
buildPackages = super.buildPackages // { inherit (native) rakudo; };
|
||||
ocaml = self.ocaml-ng.ocamlPackages_4_07.ocaml;
|
||||
libev = dds super.libev;
|
||||
libusb = self.libusb1;
|
||||
systemd = self.eudev;
|
||||
libusb1 = dds (super.libusb1.override {
|
||||
enableSystemd = true;
|
||||
});
|
||||
gdb = null;
|
||||
hidapi = dds (super.hidapi.override { systemd = self.eudev; });
|
||||
glib = (super.glib.override { libselinux = null; }).overrideAttrs
|
||||
(o: { mesonFlags = o.mesonFlags ++ [ "-Dselinux=disabled" ]; });
|
||||
eudev = dds (super.eudev.overrideAttrs
|
||||
(o: { nativeBuildInputs = o.nativeBuildInputs ++ [ super.gperf ]; }));
|
||||
gmp = dds (super.gmp);
|
||||
ocamlPackages = super.ocamlPackages.overrideScope' (self: super: {
|
||||
ligo-out = super.ligo-out.overrideAttrs (_: {
|
||||
patches = [ ./static.patch ];
|
||||
});
|
||||
});
|
||||
}
|
13
nix/static.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/src/bin/dune b/src/bin/dune
|
||||
index 162963b4b..29dfa5191 100644
|
||||
With this patch, a static executable is produced
|
||||
--- a/src/bin/dune
|
||||
+++ b/src/bin/dune
|
||||
@@ -34,5 +34,6 @@
|
||||
(preprocess
|
||||
(pps ppx_let ppx_blob bisect_ppx --conditional)
|
||||
)
|
||||
- (flags (:standard -open Simple_utils))
|
||||
+ (flags (:standard -open Simple_utils)
|
||||
+ -ccopt -static -cclib "-lgmp")
|
||||
)
|
@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
if test $# -ne 1 || test "x$1" = "-h" -o "x$1" = "x--help"; then
|
||||
echo "Usage: build_docker_image.sh TAG_NAME"
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
eval $(opam config env)
|
||||
dune build -p ligo
|
||||
|
@ -1,4 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
dockerfile_name="build"
|
||||
# Generic dockerfile
|
||||
@ -8,4 +10,9 @@ dockerfile="./docker/distribution/generic/build.Dockerfile"
|
||||
echo "Building LIGO for $target"
|
||||
echo "Using Dockerfile: $dockerfile"
|
||||
echo "Tagging as: $tag_build\n"
|
||||
docker build --build-arg ci_job_id="${CI_JOB_ID}" --build-arg target="$target" -t "$tag_build" -f "$dockerfile" .
|
||||
docker build \
|
||||
--build-arg ci_job_id="${CI_JOB_ID}" \
|
||||
--build-arg ci_commit_sha="${CI_COMMIT_SHA}" \
|
||||
--build-arg commit_date="${COMMIT_DATE}" \
|
||||
--build-arg target="$target" \
|
||||
-t "$tag_build" -f "$dockerfile" .
|
||||
|
@ -9,4 +9,6 @@ export LIGO_REGISTRY_IMAGE_BASE_NAME="ligolang/ligo"
|
||||
# ligo_incrementing-id_commit-hash
|
||||
export CI_JOB_ID="0"
|
||||
export CI_COMMIT_SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
export CI_COMMIT_SHA="$(git rev-parse HEAD)"
|
||||
export COMMIT_DATE="$(git show --no-patch --format=%ci)"
|
||||
export LIGO_DIST_DIR="./dist"
|
||||
|
@ -1,4 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
dockerfile_name="package"
|
||||
dockerfile=""
|
||||
|
@ -1,16 +1,22 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# This script accepts three arguments, os family, os and its version,
|
||||
# which are subsequently used to fetch the respective docker
|
||||
# image from the ocaml/infrastructure project.
|
||||
#
|
||||
# https://github.com/ocaml/infrastructure/wiki/Containers#selecting-linux-distributions
|
||||
target_os_family=$1
|
||||
target_os=$2
|
||||
target_os_version=$3
|
||||
target_os_family="$1"
|
||||
target_os="$2"
|
||||
target_os_version="$3"
|
||||
|
||||
# Variables configured at the CI level
|
||||
dist="$LIGO_DIST_DIR"
|
||||
version="$(echo $CI_JOB_ID)-$(echo $CI_COMMIT_SHORT_SHA)"
|
||||
ci_job_id="$CI_JOB_ID"
|
||||
ci_commit_sha="$CI_COMMIT_SHA"
|
||||
commit_date="$COMMIT_DATE"
|
||||
|
||||
# Image names for building & packaging
|
||||
target="$target_os-$target_os_version"
|
||||
@ -29,4 +35,4 @@ fi
|
||||
target_os_specific_dockerfile="./docker/distribution/$target_os_family/$target_os/$dockerfile_name.Dockerfile"
|
||||
if test -f "$target_os_specific_dockerfile"; then
|
||||
dockerfile="$target_os_specific_dockerfile"
|
||||
fi
|
||||
fi
|
||||
|
@ -5,16 +5,16 @@ set -e
|
||||
|
||||
if [ -n "`which opam`" ]
|
||||
then
|
||||
if [ -n "`opam --version | grep -P "2\..\.."`" ]
|
||||
if [ -n "`opam --version | grep -P "2\..\.."`" ]
|
||||
then
|
||||
echo "Opam 2.x seems to already exist, exiting..."
|
||||
exit 1
|
||||
echo "Opam 2.x seems to already exist, exiting..."
|
||||
exit 1
|
||||
else
|
||||
read -p "This script will upgrade opam to the 2.x series, are you okay with that? (y/n)" choice1
|
||||
case "$choice1" in
|
||||
y|Y ) : ;;
|
||||
n|N ) exit ;;
|
||||
esac
|
||||
read -p "This script will upgrade opam to the 2.x series, are you okay with that? (y/n)" choice1
|
||||
case "$choice1" in
|
||||
y|Y ) : ;;
|
||||
n|N ) exit ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -22,26 +22,27 @@ echo "Installing dependencies.."
|
||||
if [ -n "`uname -a | grep -i arch`" ]
|
||||
then
|
||||
sudo pacman -Sy --noconfirm \
|
||||
rakudo \
|
||||
make \
|
||||
m4 \
|
||||
gcc \
|
||||
patch \
|
||||
bubblewrap \
|
||||
rsync \
|
||||
curl
|
||||
curl
|
||||
fi
|
||||
|
||||
if [ -n "`uname -a | grep -i ubuntu`" ]
|
||||
then
|
||||
sudo apt-get install -y make \
|
||||
perl6 \
|
||||
make \
|
||||
m4 \
|
||||
gcc \
|
||||
patch \
|
||||
bubblewrap \
|
||||
rsync \
|
||||
curl
|
||||
curl
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "`uname -a | grep -i ubuntu`" ]
|
||||
then
|
||||
echo "ubuntu"
|
||||
@ -84,10 +85,8 @@ else
|
||||
echo "(If you actually get this message, you should probably file an issue)"
|
||||
echo "https://gitlab.com/ligolang/ligo/issues"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
opam init -a --bare
|
||||
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
. /etc/os-release
|
||||
|
||||
if [ $ID = arch ]
|
||||
then
|
||||
pacman -Sy
|
||||
sudo pacman -S --noconfirm \
|
||||
rakudo \
|
||||
libevdev \
|
||||
perl \
|
||||
pkg-config \
|
||||
@ -20,6 +22,7 @@ then
|
||||
else
|
||||
apt-get update -qq
|
||||
apt-get -y -qq install \
|
||||
perl6 \
|
||||
libev-dev \
|
||||
perl \
|
||||
pkg-config \
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Install local dependencies
|
||||
opam install -y --deps-only --with-test ./ligo.opam $(find vendors -name \*.opam)
|
||||
|
@ -7,7 +7,7 @@ dry_run_output=$(./scripts/ligo_ci.sh dry-run src/test/contracts/website2.ligo m
|
||||
|
||||
expected_compiled_parameter="(Right 1)";
|
||||
expected_compiled_storage=1;
|
||||
expected_dry_run_output="( list[] , 2 )";
|
||||
expected_dry_run_output="( LIST_EMPTY() , 2 )";
|
||||
|
||||
if [ "$compiled_storage" != "$expected_compiled_storage" ]; then
|
||||
echo "Expected $expected_compiled_storage as compile-storage output, got $compiled_storage instead";
|
||||
|
45
scripts/versioning.sh
Executable file
@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
|
||||
apt-get update -qq
|
||||
apt-get -y -qq install jq
|
||||
|
||||
fetch_version () {
|
||||
local LAST_VERSION=`curl --silent "https://gitlab.com/api/v4/projects/12294987/repository/tags?search=^V&order_by=name" | jq "map(.name)[0]"`
|
||||
MAJOR=`echo $LAST_VERSION | sed -E "s/\.|\"|\V/\n/g" | grep -e . | sed -n 1p`
|
||||
MINOR=`echo $LAST_VERSION | sed -E "s/\.|\"|\V/\n/g" | grep -e . | sed -n 2p`
|
||||
PATCH=`echo $LAST_VERSION | sed -E "s/\.|\"|\V/\n/g" | grep -e . | sed -n 3p`
|
||||
}
|
||||
increment_patch () {
|
||||
fetch_version
|
||||
local NEW_PATCH=$((PATCH+1))
|
||||
NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}"
|
||||
}
|
||||
increment_minor () {
|
||||
fetch_version
|
||||
local NEW_MINOR=$((MINOR+1))
|
||||
NEW_VERSION="${MAJOR}.${NEW_MINOR}.0"
|
||||
}
|
||||
increment_major () {
|
||||
fetch_version
|
||||
local NEW_MAJOR=$((MAJOR+1))
|
||||
NEW_VERSION="${NEW_MAJOR}.0.0"
|
||||
}
|
||||
|
||||
tag_dev () {
|
||||
curl --request POST --header "PRIVATE-TOKEN: ${AUTH}" https://gitlab.com/api/v4/projects/12294987/repository/tags -d "tag_name=V.${1}&ref=dev"
|
||||
}
|
||||
|
||||
|
||||
increment_minor
|
||||
echo $NEW_VERSION
|
||||
# increment_major
|
||||
# echo $NEW_VERSION
|
||||
# increment_patch
|
||||
# echo $NEW_VERSION
|
||||
|
||||
tag_dev $NEW_VERSION
|
||||
|
||||
|
||||
# curl --header "PRIVATE-TOKEN: W-7UVDzeofRmejE17_Gn" https://gitlab.com/api/v4/version
|
||||
# curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/repository/branches?branch=newbranch&ref=master
|
||||
|
427
src/bin/cli.ml
@ -2,12 +2,7 @@ open Cmdliner
|
||||
open Trace
|
||||
open Cli_helpers
|
||||
|
||||
let version =
|
||||
Format.asprintf
|
||||
"Rolling release\nHash: %s\nDate: %s\nCI job id: %s"
|
||||
Version.hash
|
||||
Version.commit_date
|
||||
Version.job_id
|
||||
let version = Version.version
|
||||
|
||||
let main =
|
||||
let man =
|
||||
@ -101,6 +96,13 @@ let disable_michelson_typechecking =
|
||||
info ~doc ["disable-michelson-typechecking"] in
|
||||
value @@ flag info
|
||||
|
||||
let with_types =
|
||||
let open Arg in
|
||||
let info =
|
||||
let doc = "tries to infer types for all named expressions" in
|
||||
info ~doc ["with-types"] in
|
||||
value @@ flag info
|
||||
|
||||
let predecessor_timestamp =
|
||||
let open Arg in
|
||||
let info =
|
||||
@ -111,16 +113,25 @@ let predecessor_timestamp =
|
||||
|
||||
let display_format =
|
||||
let open Arg in
|
||||
let open Display in
|
||||
let info =
|
||||
let docv = "DISPLAY_FORMAT" in
|
||||
let doc = "$(docv) is the format that will be used by the CLI. Available formats are 'dev', 'json', and 'human-readable' (default). When human-readable lacks details (we are still tweaking it), please contact us and use another format in the meanwhile." in
|
||||
info ~docv ~doc ["format" ; "display-format"] in
|
||||
value @@
|
||||
opt
|
||||
(enum [("human-readable", `Human_readable); ("dev", `Dev); ("json", `Json)])
|
||||
`Human_readable
|
||||
(enum [("human-readable", human_readable); ("dev", dev); ("json", json)])
|
||||
human_readable
|
||||
info
|
||||
|
||||
let output_file =
|
||||
let open Arg in
|
||||
let info =
|
||||
let docv = "OUTPUT_FILE" in
|
||||
let doc = "$(docv) if used, prints the output into the specified file instead of stdout" in
|
||||
info ~docv ~doc ["output" ; "output-file"] in
|
||||
value @@ opt (some string) None info
|
||||
|
||||
let michelson_code_format =
|
||||
let open Arg in
|
||||
let info =
|
||||
@ -132,32 +143,58 @@ let michelson_code_format =
|
||||
(enum [("text", `Text); ("json", `Json); ("hex", `Hex)])
|
||||
`Text info
|
||||
|
||||
module Helpers = Ligo.Compile.Helpers
|
||||
module Compile = Ligo.Compile
|
||||
module Uncompile = Ligo.Uncompile
|
||||
let optimize =
|
||||
let open Arg in
|
||||
let docv = "ENTRY_POINT" in
|
||||
let doc = "Apply Mini-C optimizations as if compiling $(docv)" in
|
||||
let info =
|
||||
info ~docv ~doc ["optimize"] in
|
||||
value @@ opt (some string) None info
|
||||
|
||||
|
||||
module Helpers = Ligo.Compile.Helpers
|
||||
module Compile = Ligo.Compile
|
||||
module Decompile = Ligo.Decompile
|
||||
module Run = Ligo.Run.Of_michelson
|
||||
|
||||
let compile_file =
|
||||
let f source_file entry_point syntax display_format disable_typecheck michelson_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind typed,_ = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||
let%bind mini_c = Compile.Of_typed.compile typed in
|
||||
let%bind michelson = Compile.Of_mini_c.aggregate_and_compile_contract mini_c entry_point in
|
||||
let%bind contract = Compile.Of_michelson.build_contract ~disable_typecheck michelson in
|
||||
ok @@ Format.asprintf "%a\n" (Main.Display.michelson_pp michelson_format) contract
|
||||
let f source_file entry_point syntax display_format disable_typecheck michelson_format output_file =
|
||||
return_result ~output_file ~display_format (Tezos_utils.Michelson.michelson_format michelson_format) @@
|
||||
let%bind typed,_ = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||
let%bind mini_c = Compile.Of_typed.compile typed in
|
||||
let%bind michelson = Compile.Of_mini_c.aggregate_and_compile_contract mini_c entry_point in
|
||||
Compile.Of_michelson.build_contract ~disable_typecheck michelson
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ entry_point 1 $ syntax $ display_format $ disable_michelson_typechecking $ michelson_code_format) in
|
||||
Term.(const f $ source_file 0 $ entry_point 1 $ syntax $ display_format $ disable_michelson_typechecking $ michelson_code_format $ output_file) in
|
||||
let cmdname = "compile-contract" in
|
||||
let doc = "Subcommand: Compile a contract." in
|
||||
(Term.ret term , Term.info ~doc cmdname)
|
||||
|
||||
let preprocess =
|
||||
let f source_file syntax display_format =
|
||||
return_result ~display_format (Parser.Formatter.ppx_format) @@
|
||||
Compile.Of_source.preprocess source_file (Syntax_name syntax)
|
||||
in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
|
||||
let cmdname = "preprocess" in
|
||||
let doc = "Subcommand: Preprocess the source file.\nWarning: Intended for development of LIGO and can break at any time." in
|
||||
(Term.ret term, Term.info ~doc cmdname)
|
||||
|
||||
let pretty_print =
|
||||
let f source_file syntax display_format =
|
||||
return_result ~display_format (Parser.Formatter.ppx_format) @@
|
||||
Compile.Of_source.pretty_print source_file (Syntax_name syntax)
|
||||
in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
|
||||
let cmdname = "pretty-print" in
|
||||
let doc = "Subcommand: Pretty-print the source file."
|
||||
in (Term.ret term, Term.info ~doc cmdname)
|
||||
|
||||
let print_cst =
|
||||
let f source_file syntax display_format = (
|
||||
toplevel ~display_format @@
|
||||
let%bind pp = Compile.Of_source.pretty_print source_file (Syntax_name syntax) in
|
||||
ok @@ Format.asprintf "%s \n" (Buffer.contents pp)
|
||||
)
|
||||
let f source_file syntax display_format =
|
||||
return_result ~display_format (Parser.Formatter.ppx_format) @@
|
||||
Compile.Of_source.pretty_print_cst source_file (Syntax_name syntax)
|
||||
in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
|
||||
let cmdname = "print-cst" in
|
||||
@ -165,23 +202,20 @@ let print_cst =
|
||||
(Term.ret term, Term.info ~doc cmdname)
|
||||
|
||||
let print_ast =
|
||||
let f source_file syntax display_format = (
|
||||
toplevel ~display_format @@
|
||||
let%bind imperative = Compile.Utils.to_imperatve source_file syntax in
|
||||
ok @@ Format.asprintf "%a\n" Compile.Of_imperative.pretty_print imperative
|
||||
)
|
||||
let f source_file syntax display_format =
|
||||
return_result ~display_format (Ast_imperative.Formatter.program_format) @@
|
||||
Compile.Utils.to_imperatve source_file syntax
|
||||
in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
|
||||
let cmdname = "print-ast" in
|
||||
let doc = "Subcommand: Print the AST.\n Warning: Intended for development of LIGO and can break at any time." in
|
||||
(Term.ret term, Term.info ~doc cmdname)
|
||||
|
||||
|
||||
let print_ast_sugar =
|
||||
let f source_file syntax display_format = (
|
||||
toplevel ~display_format @@
|
||||
let%bind sugar = Compile.Utils.to_sugar source_file syntax in
|
||||
ok @@ Format.asprintf "%a\n" Compile.Of_sugar.pretty_print sugar
|
||||
)
|
||||
let f source_file syntax display_format =
|
||||
return_result ~display_format (Ast_sugar.Formatter.program_format) @@
|
||||
Compile.Utils.to_sugar source_file syntax
|
||||
in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
|
||||
let cmdname = "print-ast-sugar" in
|
||||
@ -189,23 +223,20 @@ let print_ast_sugar =
|
||||
(Term.ret term, Term.info ~doc cmdname)
|
||||
|
||||
let print_ast_core =
|
||||
let f source_file syntax display_format = (
|
||||
toplevel ~display_format @@
|
||||
let%bind core = Compile.Utils.to_core source_file syntax in
|
||||
ok @@ Format.asprintf "%a\n" Compile.Of_core.pretty_print core
|
||||
)
|
||||
let f source_file syntax display_format =
|
||||
return_result ~display_format (Ast_core.Formatter.program_format) @@
|
||||
Compile.Utils.to_core source_file syntax
|
||||
in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
|
||||
let cmdname = "print-ast-core" in
|
||||
let doc = "Subcommand: Print the AST.\n Warning: Intended for development of LIGO and can break at any time." in
|
||||
(Term.ret term, Term.info ~doc cmdname)
|
||||
(Term.ret term, Term.info ~doc cmdname)
|
||||
|
||||
let print_ast_typed =
|
||||
let f source_file syntax display_format = (
|
||||
toplevel ~display_format @@
|
||||
let%bind typed,_ = Compile.Utils.type_file source_file syntax Env in
|
||||
ok @@ Format.asprintf "%a\n" Compile.Of_typed.pretty_print typed
|
||||
)
|
||||
let f source_file syntax display_format =
|
||||
return_result ~display_format (Ast_typed.Formatter.program_format) @@
|
||||
let%bind typed,_ = Compile.Utils.type_file source_file syntax Env in
|
||||
ok typed
|
||||
in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
|
||||
let cmdname = "print-ast-typed" in
|
||||
@ -213,24 +244,28 @@ let print_ast_typed =
|
||||
(Term.ret term, Term.info ~doc cmdname)
|
||||
|
||||
let print_mini_c =
|
||||
let f source_file syntax display_format = (
|
||||
toplevel ~display_format @@
|
||||
let%bind typed,_ = Compile.Utils.type_file source_file syntax Env in
|
||||
let%bind mini_c = Compile.Of_typed.compile typed in
|
||||
ok @@ Format.asprintf "%a\n" Compile.Of_mini_c.pretty_print mini_c
|
||||
)
|
||||
let f source_file syntax display_format optimize =
|
||||
return_result ~display_format (Mini_c.Formatter.program_format) @@
|
||||
let%bind typed,_ = Compile.Utils.type_file source_file syntax Env in
|
||||
let%bind mini_c = Compile.Of_typed.compile typed in
|
||||
match optimize with
|
||||
| None -> ok @@ Mini_c.Formatter.Raw mini_c
|
||||
| Some entry_point ->
|
||||
let%bind o = Compile.Of_mini_c.aggregate_contract mini_c entry_point in
|
||||
ok @@ Mini_c.Formatter.Optimized o
|
||||
in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
|
||||
let term = Term.(const f $ source_file 0 $ syntax $ display_format $ optimize) in
|
||||
let cmdname = "print-mini-c" in
|
||||
let doc = "Subcommand: Print Mini-C. Warning: Intended for development of LIGO and can break at any time." in
|
||||
(Term.ret term, Term.info ~doc cmdname)
|
||||
|
||||
let measure_contract =
|
||||
let f source_file entry_point syntax display_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind contract = Compile.Utils.compile_file source_file syntax entry_point in
|
||||
let open Tezos_utils in
|
||||
ok @@ Format.asprintf "%d bytes\n" (Michelson.measure contract)
|
||||
let f source_file entry_point syntax display_format =
|
||||
let value =
|
||||
let%bind contract = Compile.Utils.compile_file source_file syntax entry_point in
|
||||
ok @@ Tezos_utils.Michelson.measure contract in
|
||||
let format = Display.bind_format Formatter.contract_size_format Main.Formatter.error_format in
|
||||
toplevel ~display_format (Display.Displayable { value ; format }) value
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ entry_point 1 $ syntax $ display_format) in
|
||||
@ -240,24 +275,23 @@ let measure_contract =
|
||||
|
||||
let compile_parameter =
|
||||
let f source_file entry_point expression syntax amount balance sender source predecessor_timestamp display_format michelson_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||
let env = Ast_typed.program_environment typed_prg in
|
||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||
(* fails if the given entry point is not a valid contract *)
|
||||
Compile.Of_michelson.build_contract michelson_prg in
|
||||
return_result ~display_format (Tezos_utils.Michelson.michelson_format michelson_format) @@
|
||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||
(* fails if the given entry point is not a valid contract *)
|
||||
Compile.Of_michelson.build_contract michelson_prg in
|
||||
|
||||
let%bind (typed_param,_) = Compile.Utils.type_expression (Some source_file) syntax expression env state in
|
||||
let%bind mini_c_param = Compile.Of_typed.compile_expression typed_param in
|
||||
let%bind compiled_param = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg mini_c_param in
|
||||
let%bind () = Compile.Of_typed.assert_equal_contract_type Check_parameter entry_point typed_prg typed_param in
|
||||
let%bind () = Compile.Of_michelson.assert_equal_contract_type Check_parameter michelson_prg compiled_param in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind value = Run.evaluate_expression ~options compiled_param.expr compiled_param.expr_ty in
|
||||
ok @@ Format.asprintf "%a\n" (Main.Display.michelson_pp michelson_format) value
|
||||
in
|
||||
let%bind (typed_param,_) = Compile.Utils.type_expression (Some source_file) syntax expression env state in
|
||||
let%bind mini_c_param = Compile.Of_typed.compile_expression typed_param in
|
||||
let%bind compiled_param = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg mini_c_param in
|
||||
let%bind () = Compile.Of_typed.assert_equal_contract_type Check_parameter entry_point typed_prg typed_param in
|
||||
let%bind () = Compile.Of_michelson.assert_equal_contract_type Check_parameter michelson_prg compiled_param in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
Run.evaluate_expression ~options compiled_param.expr compiled_param.expr_ty
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ syntax $ amount $ balance $ sender $ source $ predecessor_timestamp $ display_format $ michelson_code_format) in
|
||||
let cmdname = "compile-parameter" in
|
||||
@ -266,27 +300,21 @@ let compile_parameter =
|
||||
|
||||
let interpret =
|
||||
let f expression init_file syntax amount balance sender source predecessor_timestamp display_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind (decl_list,state,env) = match init_file with
|
||||
| Some init_file ->
|
||||
let%bind typed_prg,state = Compile.Utils.type_file init_file syntax Env in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
let env = Ast_typed.program_environment typed_prg in
|
||||
ok (mini_c_prg,state,env)
|
||||
| None -> ok ([],Typer.Solver.initial_state,Ast_typed.Environment.full_empty) in
|
||||
return_result ~display_format (Decompile.Formatter.expression_format) @@
|
||||
let%bind (decl_list,state,env) = match init_file with
|
||||
| Some init_file ->
|
||||
let%bind typed_prg,state = Compile.Utils.type_file init_file syntax Env in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||
ok (mini_c_prg,state,env)
|
||||
| None -> ok ([],Typer.Solver.initial_state,Environment.default) in
|
||||
|
||||
let%bind (typed_exp,_) = Compile.Utils.type_expression init_file syntax expression env state in
|
||||
let%bind mini_c_exp = Compile.Of_typed.compile_expression typed_exp in
|
||||
let%bind compiled_exp = Compile.Of_mini_c.aggregate_and_compile_expression decl_list mini_c_exp in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind runres = Run.run_expression ~options compiled_exp.expr compiled_exp.expr_ty in
|
||||
match runres with
|
||||
| Fail fail_res ->
|
||||
let%bind failstring = Run.failwith_to_string fail_res in
|
||||
ok @@ Format.asprintf "%s" failstring
|
||||
| Success value' ->
|
||||
let%bind core_output = Uncompile.uncompile_expression typed_exp.type_expression value' in
|
||||
ok @@ Format.asprintf "%a\n" Ast_core.PP.expression core_output
|
||||
let%bind (typed_exp,_) = Compile.Utils.type_expression init_file syntax expression env state in
|
||||
let%bind mini_c_exp = Compile.Of_typed.compile_expression typed_exp in
|
||||
let%bind compiled_exp = Compile.Of_mini_c.aggregate_and_compile_expression decl_list mini_c_exp in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind runres = Run.run_expression ~options compiled_exp.expr compiled_exp.expr_ty in
|
||||
Decompile.Of_michelson.decompile_expression typed_exp.type_expression runres
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ expression "EXPRESSION" 0 $ init_file $ syntax $ amount $ balance $ sender $ source $ predecessor_timestamp $ display_format ) in
|
||||
@ -296,10 +324,9 @@ let interpret =
|
||||
|
||||
let temp_ligo_interpreter =
|
||||
let f source_file syntax display_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind typed,_ = Compile.Utils.type_file source_file syntax Env in
|
||||
let%bind res = Compile.Of_typed.some_interpret typed in
|
||||
ok @@ Format.asprintf "%s\n" res
|
||||
return_result ~display_format (Ligo_interpreter.Formatter.program_format) @@
|
||||
let%bind typed,_ = Compile.Utils.type_file source_file syntax Env in
|
||||
Compile.Of_typed.some_interpret typed
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ syntax $ display_format ) in
|
||||
@ -309,24 +336,22 @@ let temp_ligo_interpreter =
|
||||
|
||||
let compile_storage =
|
||||
let f source_file entry_point expression syntax amount balance sender source predecessor_timestamp display_format michelson_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||
let env = Ast_typed.program_environment typed_prg in
|
||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||
(* fails if the given entry point is not a valid contract *)
|
||||
Compile.Of_michelson.build_contract michelson_prg in
|
||||
return_result ~display_format (Tezos_utils.Michelson.michelson_format michelson_format) @@
|
||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||
(* fails if the given entry point is not a valid contract *)
|
||||
Compile.Of_michelson.build_contract michelson_prg in
|
||||
|
||||
let%bind (typed_param,_) = Compile.Utils.type_expression (Some source_file) syntax expression env state in
|
||||
let%bind mini_c_param = Compile.Of_typed.compile_expression typed_param in
|
||||
let%bind compiled_param = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg mini_c_param in
|
||||
let%bind () = Compile.Of_typed.assert_equal_contract_type Check_storage entry_point typed_prg typed_param in
|
||||
let%bind () = Compile.Of_michelson.assert_equal_contract_type Check_storage michelson_prg compiled_param in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind value = Run.evaluate_expression ~options compiled_param.expr compiled_param.expr_ty in
|
||||
ok @@ Format.asprintf "%a\n" (Main.Display.michelson_pp michelson_format) value
|
||||
in
|
||||
let%bind (typed_param,_) = Compile.Utils.type_expression (Some source_file) syntax expression env state in
|
||||
let%bind mini_c_param = Compile.Of_typed.compile_expression typed_param in
|
||||
let%bind compiled_param = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg mini_c_param in
|
||||
let%bind () = Compile.Of_typed.assert_equal_contract_type Check_storage entry_point typed_prg typed_param in
|
||||
let%bind () = Compile.Of_michelson.assert_equal_contract_type Check_storage michelson_prg compiled_param in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
Run.evaluate_expression ~options compiled_param.expr compiled_param.expr_ty in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ entry_point 1 $ expression "STORAGE" 2 $ syntax $ amount $ balance $ sender $ source $ predecessor_timestamp $ display_format $ michelson_code_format) in
|
||||
let cmdname = "compile-storage" in
|
||||
@ -335,28 +360,22 @@ let compile_storage =
|
||||
|
||||
let dry_run =
|
||||
let f source_file entry_point storage input amount balance sender source predecessor_timestamp syntax display_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||
let env = Ast_typed.program_environment typed_prg in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||
(* fails if the given entry point is not a valid contract *)
|
||||
Compile.Of_michelson.build_contract michelson_prg in
|
||||
return_result ~display_format (Decompile.Formatter.expression_format) @@
|
||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||
(* fails if the given entry point is not a valid contract *)
|
||||
Compile.Of_michelson.build_contract michelson_prg in
|
||||
|
||||
let%bind compiled_params = Compile.Utils.compile_storage storage input source_file syntax env state mini_c_prg in
|
||||
let%bind args_michelson = Run.evaluate_expression compiled_params.expr compiled_params.expr_ty in
|
||||
let%bind compiled_params = Compile.Utils.compile_storage storage input source_file syntax env state mini_c_prg in
|
||||
let%bind args_michelson = Run.evaluate_expression compiled_params.expr compiled_params.expr_ty in
|
||||
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind runres = Run.run_contract ~options michelson_prg.expr michelson_prg.expr_ty args_michelson in
|
||||
match runres with
|
||||
| Fail fail_res ->
|
||||
let%bind failstring = Run.failwith_to_string fail_res in
|
||||
ok @@ Format.asprintf "%s" failstring
|
||||
| Success michelson_output ->
|
||||
let%bind core_output = Uncompile.uncompile_typed_program_entry_function_result typed_prg entry_point michelson_output in
|
||||
ok @@ Format.asprintf "%a\n" Ast_core.PP.expression core_output
|
||||
in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind runres = Run.run_contract ~options michelson_prg.expr michelson_prg.expr_ty args_michelson in
|
||||
Decompile.Of_michelson.decompile_typed_program_entry_function_result typed_prg entry_point runres
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ expression "STORAGE" 3 $ amount $ balance $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in
|
||||
let cmdname = "dry-run" in
|
||||
@ -365,31 +384,25 @@ let dry_run =
|
||||
|
||||
let run_function =
|
||||
let f source_file entry_point parameter amount balance sender source predecessor_timestamp syntax display_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax Env in
|
||||
let env = Ast_typed.program_environment typed_prg in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
return_result ~display_format (Decompile.Formatter.expression_format) @@
|
||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax Env in
|
||||
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||
|
||||
|
||||
let%bind v_syntax = Helpers.syntax_to_variant (Syntax_name syntax) (Some source_file) in
|
||||
let%bind imperative_param = Compile.Of_source.compile_expression v_syntax parameter in
|
||||
let%bind sugar_param = Compile.Of_imperative.compile_expression imperative_param in
|
||||
let%bind core_param = Compile.Of_sugar.compile_expression sugar_param in
|
||||
let%bind app = Compile.Of_core.apply entry_point core_param in
|
||||
let%bind (typed_app,_) = Compile.Of_core.compile_expression ~env ~state app in
|
||||
let%bind compiled_applied = Compile.Of_typed.compile_expression typed_app in
|
||||
let%bind v_syntax = Helpers.syntax_to_variant (Syntax_name syntax) (Some source_file) in
|
||||
let%bind imperative_param = Compile.Of_source.compile_expression v_syntax parameter in
|
||||
let%bind sugar_param = Compile.Of_imperative.compile_expression imperative_param in
|
||||
let%bind core_param = Compile.Of_sugar.compile_expression sugar_param in
|
||||
let%bind app = Compile.Of_core.apply entry_point core_param in
|
||||
let%bind (typed_app,_) = Compile.Of_core.compile_expression ~env ~state app in
|
||||
let%bind compiled_applied = Compile.Of_typed.compile_expression typed_app in
|
||||
|
||||
let%bind michelson = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg compiled_applied in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind runres = Run.run_expression ~options michelson.expr michelson.expr_ty in
|
||||
match runres with
|
||||
| Fail fail_res ->
|
||||
let%bind failstring = Run.failwith_to_string fail_res in
|
||||
ok @@ Format.asprintf "%s" failstring
|
||||
| Success michelson_output ->
|
||||
let%bind core_output = Uncompile.uncompile_typed_program_entry_function_result typed_prg entry_point michelson_output in
|
||||
ok @@ Format.asprintf "%a\n" Ast_core.PP.expression core_output
|
||||
in
|
||||
let%bind michelson = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg compiled_applied in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind runres = Run.run_expression ~options michelson.expr michelson.expr_ty in
|
||||
Decompile.Of_michelson.decompile_typed_program_entry_function_result typed_prg entry_point runres
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ amount $ balance $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in
|
||||
let cmdname = "run-function" in
|
||||
@ -398,16 +411,15 @@ let run_function =
|
||||
|
||||
let evaluate_value =
|
||||
let f source_file entry_point amount balance sender source predecessor_timestamp syntax display_format =
|
||||
toplevel ~display_format @@
|
||||
let%bind typed_prg,_ = Compile.Utils.type_file source_file syntax Env in
|
||||
let%bind mini_c = Compile.Of_typed.compile typed_prg in
|
||||
let%bind (exp,_) = Mini_c.get_entry mini_c entry_point in
|
||||
let%bind compiled = Compile.Of_mini_c.aggregate_and_compile_expression mini_c exp in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind michelson_output = Run.run_no_failwith ~options compiled.expr compiled.expr_ty in
|
||||
let%bind core_output = Uncompile.uncompile_typed_program_entry_expression_result typed_prg entry_point michelson_output in
|
||||
ok @@ Format.asprintf "%a\n" Ast_core.PP.expression core_output
|
||||
in
|
||||
return_result ~display_format Decompile.Formatter.expression_format @@
|
||||
let%bind typed_prg,_ = Compile.Utils.type_file source_file syntax Env in
|
||||
let%bind mini_c = Compile.Of_typed.compile typed_prg in
|
||||
let%bind (exp,_) = trace_option Main_errors.entrypoint_not_found @@ Mini_c.get_entry mini_c entry_point in
|
||||
let%bind compiled = Compile.Of_mini_c.aggregate_and_compile_expression mini_c exp in
|
||||
let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in
|
||||
let%bind runres = Run.run_expression ~options compiled.expr compiled.expr_ty in
|
||||
Decompile.Of_michelson.decompile_typed_program_entry_expression_result typed_prg entry_point runres
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ entry_point 1 $ amount $ balance $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in
|
||||
let cmdname = "evaluate-value" in
|
||||
@ -416,13 +428,12 @@ let evaluate_value =
|
||||
|
||||
let compile_expression =
|
||||
let f expression syntax display_format michelson_format =
|
||||
toplevel ~display_format @@
|
||||
let env = Ast_typed.Environment.full_empty in
|
||||
let state = Typer.Solver.initial_state in
|
||||
let%bind compiled_exp = Compile.Utils.compile_expression None syntax expression env state in
|
||||
let%bind value = Run.evaluate_expression compiled_exp.expr compiled_exp.expr_ty in
|
||||
ok @@ Format.asprintf "%a\n" (Main.Display.michelson_pp michelson_format) value
|
||||
in
|
||||
return_result ~display_format (Tezos_utils.Michelson.michelson_format michelson_format) @@
|
||||
let env = Environment.default in
|
||||
let state = Typer.Solver.initial_state in
|
||||
let%bind compiled_exp = Compile.Utils.compile_expression None syntax expression env state in
|
||||
Run.evaluate_expression compiled_exp.expr compiled_exp.expr_ty
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ expression "" 1 $ req_syntax 0 $ display_format $ michelson_code_format) in
|
||||
let cmdname = "compile-expression" in
|
||||
@ -430,7 +441,10 @@ let compile_expression =
|
||||
(Term.ret term , Term.info ~doc cmdname)
|
||||
|
||||
let dump_changelog =
|
||||
let f display_format = toplevel ~display_format @@ (ok @@ [%blob "../../CHANGELOG.md"]) in
|
||||
let f display_format =
|
||||
let value = [%blob "../../CHANGELOG.md"] in
|
||||
let format = Formatter.changelog_format in
|
||||
toplevel ~display_format (Display.Displayable {value ; format}) (ok value) in
|
||||
let term =
|
||||
Term.(const f $ display_format) in
|
||||
let cmdname = "changelog" in
|
||||
@ -438,18 +452,64 @@ let dump_changelog =
|
||||
(Term.ret term , Term.info ~doc cmdname)
|
||||
|
||||
let list_declarations =
|
||||
let f source_file syntax =
|
||||
toplevel ~display_format:(`Human_readable) @@
|
||||
let%bind core_prg = Compile.Utils.to_core source_file syntax in
|
||||
let json_decl = List.map (fun decl -> `String decl) @@ Compile.Of_core.list_declarations core_prg in
|
||||
ok @@ J.to_string @@ `Assoc [ ("source_file", `String source_file) ; ("declarations", `List json_decl) ]
|
||||
let f source_file syntax display_format =
|
||||
return_result ~display_format Formatter.declarations_format @@
|
||||
let%bind core_prg = Compile.Utils.to_core source_file syntax in
|
||||
let declarations = Compile.Of_core.list_declarations core_prg in
|
||||
ok (source_file, declarations)
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ syntax ) in
|
||||
Term.(const f $ source_file 0 $ syntax $ display_format ) in
|
||||
let cmdname = "list-declarations" in
|
||||
let doc = "Subcommand: List all the top-level declarations." in
|
||||
(Term.ret term , Term.info ~doc cmdname)
|
||||
|
||||
let transpile_contract =
|
||||
let f source_file new_syntax syntax display_format =
|
||||
return_result ~display_format (Parser.Formatter.ppx_format) @@
|
||||
let%bind core = Compile.Utils.to_core source_file syntax in
|
||||
let%bind sugar = Decompile.Of_core.decompile core in
|
||||
let%bind imperative = Decompile.Of_sugar.decompile sugar in
|
||||
let%bind buffer = Decompile.Of_imperative.decompile imperative (Syntax_name new_syntax) in
|
||||
ok @@ buffer
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ req_syntax 1 $ syntax $ display_format) in
|
||||
let cmdname = "transpile-contract" in
|
||||
let doc = "Subcommand: Transpile a contract to another syntax." in
|
||||
(Term.ret term , Term.info ~doc cmdname)
|
||||
|
||||
let transpile_expression =
|
||||
let f expression new_syntax syntax display_format =
|
||||
return_result ~display_format (Parser.Formatter.ppx_format) @@
|
||||
let%bind v_syntax = Helpers.syntax_to_variant (Syntax_name syntax) None in
|
||||
let%bind n_syntax = Decompile.Helpers.syntax_to_variant (Syntax_name new_syntax) None in
|
||||
let%bind imperative = Compile.Of_source.compile_expression v_syntax expression in
|
||||
let%bind sugar = Compile.Of_imperative.compile_expression imperative in
|
||||
let%bind core = Compile.Of_sugar.compile_expression sugar in
|
||||
let%bind sugar = Decompile.Of_core.decompile_expression core in
|
||||
let%bind imperative = Decompile.Of_sugar.decompile_expression sugar in
|
||||
let%bind buffer = Decompile.Of_imperative.decompile_expression imperative n_syntax in
|
||||
ok @@ buffer
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ expression "" 1 $ req_syntax 2 $ req_syntax 0 $ display_format) in
|
||||
let cmdname = "transpile-expression" in
|
||||
let doc = "Subcommand: Transpile an expression to another syntax." in
|
||||
(Term.ret term , Term.info ~doc cmdname)
|
||||
|
||||
|
||||
let get_scope =
|
||||
let f source_file syntax display_format with_types =
|
||||
return_result ~display_format Ligo.Scopes.Formatter.scope_format @@
|
||||
Ligo.Scopes.scopes ~with_types source_file syntax
|
||||
in
|
||||
let term =
|
||||
Term.(const f $ source_file 0 $ syntax $ display_format $ with_types) in
|
||||
let cmdname = "get-scope" in
|
||||
let doc = "Subcommand: Return the JSON encoded environment for a given file." in
|
||||
(Term.ret term , Term.info ~doc cmdname)
|
||||
|
||||
let run ?argv () =
|
||||
Term.eval_choice ?argv main [
|
||||
temp_ligo_interpreter ;
|
||||
@ -458,6 +518,8 @@ let run ?argv () =
|
||||
compile_parameter ;
|
||||
compile_storage ;
|
||||
compile_expression ;
|
||||
transpile_contract ;
|
||||
transpile_expression ;
|
||||
interpret ;
|
||||
dry_run ;
|
||||
run_function ;
|
||||
@ -470,4 +532,7 @@ let run ?argv () =
|
||||
print_ast_typed ;
|
||||
print_mini_c ;
|
||||
list_declarations ;
|
||||
preprocess;
|
||||
pretty_print;
|
||||
get_scope;
|
||||
]
|
||||
|