From 520261fbfdc1ba3257ff9e8b92d3a5a40fb07338 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Thu, 29 Aug 2024 15:46:42 +0200 Subject: [PATCH] Update Playground for Aiken v1.1.0 --- .github/workflows/continuous-deployment.yml | 8 + Cargo.lock | 278 +++-- Cargo.toml | 14 +- build.sh | 20 +- output.css | 1174 ++++++++++++++++++- src/compiler_error.rs | 8 +- src/components/code_editor.rs | 44 +- src/components/header.rs | 4 +- src/components/navigation.rs | 8 +- src/components/output.rs | 86 +- src/components/share.rs | 6 +- src/macros.rs | 7 + src/main.rs | 3 +- src/playground.rs | 6 +- src/project.rs | 406 ++++--- src/stdlib.rs | 76 -- src/vendor/fuzz.rs | 10 + src/vendor/mod.rs | 2 + src/vendor/stdlib.rs | 53 + styles.css | 10 + 20 files changed, 1822 insertions(+), 401 deletions(-) create mode 100644 src/macros.rs delete mode 100644 src/stdlib.rs create mode 100644 src/vendor/fuzz.rs create mode 100644 src/vendor/mod.rs create mode 100644 src/vendor/stdlib.rs diff --git a/.github/workflows/continuous-deployment.yml b/.github/workflows/continuous-deployment.yml index 92fe7eb..d44f2de 100644 --- a/.github/workflows/continuous-deployment.yml +++ b/.github/workflows/continuous-deployment.yml @@ -14,3 +14,11 @@ jobs: - uses: actions/checkout@v4 - shell: bash run: ./build.sh + - name: Publish + uses: cloudflare/pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: play + directory: dist + gitHubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index 244c701..a2173f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,20 +51,23 @@ dependencies = [ [[package]] name = "aiken-lang" -version = "1.0.31-alpha" -source = "git+https://github.com/aiken-lang/aiken.git?branch=main#4645257e62bad0fb660974e1559898cc468d6e7a" +version = "1.1.0" +source = "git+https://github.com/aiken-lang/aiken#79cf0b8d973cf1afcde886bdda296daeecef6e7c" dependencies = [ "blst", + "built", "chumsky", + "cryptoxide", "hex", "indexmap 1.9.3", "indoc", - "itertools", - "miette", + "itertools 0.10.5", + "miette 7.2.0", "num-bigint", "ordinal", "owo-colors", "pallas-primitives", + "patricia_tree", "petgraph", "serde", "strum", @@ -114,7 +117,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -125,7 +128,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -278,6 +281,15 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "built" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" +dependencies = [ + "git2", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -292,15 +304,19 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" [[package]] name = "cc" version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +dependencies = [ + "jobserver", + "libc", +] [[package]] name = "cfg-if" @@ -513,7 +529,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -610,7 +626,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -619,6 +635,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + [[package]] name = "ff" version = "0.13.0" @@ -706,7 +728,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -769,6 +791,19 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "glob" version = "0.3.1" @@ -982,16 +1017,36 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b2f1d4ae384d1b89b0381ca12f14031157dc4fb02c055e9fc9d852a7b97002c" dependencies = [ + "icondata_bi", "icondata_core", + "icondata_lu", "icondata_ri", ] +[[package]] +name = "icondata_bi" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d69be6d42d99e3b93e5bf553f0546746bea8cfbe9ccf85c40c7d174db18ea0" +dependencies = [ + "icondata_core", +] + [[package]] name = "icondata_core" version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1640a4c1d5ddd08ab1d9854ffa7a2fa3dc52339492676b6d3031e77ca579f434" +[[package]] +name = "icondata_lu" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad486d1988db53ddf6b502eabf3a5f25d58cdf05f0e797b2154d264eb1d960cb" +dependencies = [ + "icondata_core", +] + [[package]] name = "icondata_ri" version = "0.0.6" @@ -1064,17 +1119,35 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -1104,15 +1177,6 @@ dependencies = [ "signature", ] -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - [[package]] name = "lazy_static" version = "1.5.0" @@ -1162,7 +1226,7 @@ dependencies = [ "futures", "html-escape", "indexmap 1.9.3", - "itertools", + "itertools 0.10.5", "js-sys", "leptos_reactive", "once_cell", @@ -1216,7 +1280,7 @@ dependencies = [ "cfg-if", "convert_case", "html-escape", - "itertools", + "itertools 0.10.5", "leptos_hot_reload", "prettyplease", "proc-macro-error", @@ -1298,6 +1362,30 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linear-map" version = "1.2.0" @@ -1342,12 +1430,24 @@ version = "5.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" dependencies = [ - "miette-derive", + "miette-derive 5.10.0", "once_cell", "thiserror", "unicode-width", ] +[[package]] +name = "miette" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +dependencies = [ + "cfg-if", + "miette-derive 7.2.0", + "thiserror", + "unicode-width", +] + [[package]] name = "miette-derive" version = "5.10.0" @@ -1356,7 +1456,18 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", +] + +[[package]] +name = "miette-derive" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.76", ] [[package]] @@ -1523,25 +1634,25 @@ checksum = "56d80efc4b6721e8be2a10a5df21a30fa0b470f1539e53d8b4e6e75faf938b63" [[package]] name = "pallas-addresses" -version = "0.22.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a186bac65200a9b720326082b2bd64fe2f0f9284e8709c70fa16d9f9aeed89e6" +checksum = "c38fac39e0da3b0fc4c859635c72e97584f01f3a0f4f1508b0851c02d6d52f15" dependencies = [ "base58", "bech32", "crc", + "cryptoxide", "hex", "pallas-codec", "pallas-crypto", - "sha3", "thiserror", ] [[package]] name = "pallas-codec" -version = "0.22.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4530d1a558070d6b46bfd68cfd77f3a7b2cff3b4426b32ad9f02ff270387b248" +checksum = "ea8a4b87dbc8bcb8aeb865f7cca5e1eb29744330e23b307169fc30537648b264" dependencies = [ "hex", "minicbor", @@ -1552,9 +1663,9 @@ dependencies = [ [[package]] name = "pallas-crypto" -version = "0.22.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dd0ccf9909e47c1273000eb11945b3d909356c0f0fd2a380f49ced849d2c77" +checksum = "7b98c3f204299d47d9b581ab425043789caff1f491c078ee3d3f109d6556f725" dependencies = [ "cryptoxide", "hex", @@ -1566,9 +1677,9 @@ dependencies = [ [[package]] name = "pallas-primitives" -version = "0.22.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb19819e37c14cafa0a5bba51cd2966b07b72399a8096910f48e34d49c05adf1" +checksum = "9f64835dd9cbdd75a38961a190b983f02746c872340daf1a921eada8c525a4b6" dependencies = [ "base58", "bech32", @@ -1582,11 +1693,12 @@ dependencies = [ [[package]] name = "pallas-traverse" -version = "0.22.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebf62cdadb4d9d15b390fd540fc639fcbeaf3875a6bee490c104d305426cb262" +checksum = "ad516b05ba7d838ee84f9998d7b2b4ff7acc178cb052bcfd5fea9edc2ef6023f" dependencies = [ "hex", + "itertools 0.13.0", "pallas-addresses", "pallas-codec", "pallas-crypto", @@ -1631,6 +1743,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +[[package]] +name = "patricia_tree" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f2f4539bffe53fc4b4da301df49d114b845b077bd5727b7fe2bd9d8df2ae68" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "peg" version = "0.8.4" @@ -1695,7 +1816,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -1736,7 +1857,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -1761,22 +1882,30 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "play" -version = "1.0.29-alpha" +version = "1.1.0" dependencies = [ "aiken-lang", "base64 0.21.7", "brotli", "console_error_panic_hook", + "fastrand", "getrandom", "indexmap 1.9.3", "js-sys", "leptos", "leptos_icons", "leptos_router", - "miette", + "miette 7.2.0", "monaco", + "supports-color", "uplc", "wasm-bindgen", "web-sys", @@ -2097,7 +2226,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -2203,16 +2332,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest", - "keccak", -] - [[package]] name = "signature" version = "2.2.0" @@ -2329,9 +2448,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" dependencies = [ "proc-macro2", "quote", @@ -2394,7 +2513,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -2483,7 +2602,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -2571,16 +2690,16 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uplc" -version = "1.0.31-alpha" -source = "git+https://github.com/aiken-lang/aiken.git?branch=main#4645257e62bad0fb660974e1559898cc468d6e7a" +version = "1.1.0" +source = "git+https://github.com/aiken-lang/aiken#79cf0b8d973cf1afcde886bdda296daeecef6e7c" dependencies = [ "blst", "cryptoxide", "hex", "indexmap 1.9.3", - "itertools", + "itertools 0.10.5", "k256", - "miette", + "miette 5.10.0", "num-bigint", "num-integer", "num-traits", @@ -2626,6 +2745,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec1" version = "1.12.1" @@ -2665,26 +2790,27 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", "wasm-bindgen-shared", ] @@ -2702,9 +2828,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2712,28 +2838,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -2960,7 +3086,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] [[package]] @@ -2980,5 +3106,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.76", ] diff --git a/Cargo.toml b/Cargo.toml index 9271f4e..9987e3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,23 +1,25 @@ [package] name = "play" -version = "1.0.29-alpha" +version = "1.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -aiken-lang = { git = "https://github.com/aiken-lang/aiken.git", branch = "main" } -uplc = { git = "https://github.com/aiken-lang/aiken.git", branch = "main" } +aiken-lang = { git = "https://github.com/aiken-lang/aiken" } +uplc = { git = "https://github.com/aiken-lang/aiken" } getrandom = { version = "0.2.9", features = ["js"] } indexmap = "1.9.2" leptos = { version = "0.3.0", features = ["stable"] } leptos_icons = { version = "0.0.11", default-features = false, features = [ "csr", + "BiLinkExternalRegular", + "LuDices", "RiAlertSystemLine", "RiBook2DocumentFill", - "RiCpuDeviceLine", "RiClipboardDocumentLine", "RiCloseSystemLine", + "RiCpuDeviceLine", "RiDatabase2DeviceLine", "RiDiscordLogosFill", "RiErrorWarningSystemLine", @@ -29,10 +31,12 @@ leptos_icons = { version = "0.0.11", default-features = false, features = [ "RiShareForwardSystemFill", ] } leptos_router = { version = "0.3.0", features = ["stable", "csr"] } +supports-color = "1.3.1" +fastrand = "2.1.1" monaco = { git = "https://github.com/siku2/rust-monaco.git" } wasm-bindgen = { version = "0.2.84" } web-sys = { version = "0.3.61", features = ["Navigator", "Clipboard"] } -miette = "5.8.0" +miette = "7.2.0" js-sys = "0.3.61" base64 = "0.21.0" brotli = "3.3.4" diff --git a/build.sh b/build.sh index 242e774..1c002b7 100755 --- a/build.sh +++ b/build.sh @@ -1,11 +1,7 @@ brew install llvm zlib bzip2 -echo $(which clang) - export PATH=/opt/homebrew/opt/llvm/bin:$PATH -echo $(which clang) - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y source $HOME/.cargo/env @@ -30,13 +26,13 @@ tar -xvf stdlib.tar --strip-components 1 -C stdlib rm stdlib.tar # Unpack fuzz -# rm -rf fuzz && mkdir -p fuzz -# curl -L \ -# -H "Accept: application/vnd.github+json" \ -# -H "X-GitHub-Api-Version: 2022-11-28" \ -# https://api.github.com/repos/aiken-lang/fuzz/tarball/main \ -# -o fuzz.tar -# tar -xvf fuzz.tar --strip-components 1 -C fuzz -# rm fuzz.tar +rm -rf fuzz && mkdir -p fuzz +curl -L \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/aiken-lang/fuzz/tarball/main \ + -o fuzz.tar +tar -xvf fuzz.tar --strip-components 1 -C fuzz +rm fuzz.tar trunk build --release diff --git a/output.css b/output.css index db828d6..f4459c4 100644 --- a/output.css +++ b/output.css @@ -1 +1,1173 @@ -/*! tailwindcss v3.4.7 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Source Sans Pro;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.inset-0{inset:0}.inset-x-1\/4{left:25%;right:25%}.top-1\/4{top:25%}.z-10{z-index:10}.my-3{margin-top:.75rem;margin-bottom:.75rem}.mb-5{margin-bottom:1.25rem}.mr-9{margin-right:2.25rem}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-full{height:100%}.h-screen{height:100vh}.w-1\/2{width:50%}.w-2{width:.5rem}.w-24{width:6rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.grow{flex-grow:1}.list-disc{list-style-type:disc}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-x-1{-moz-column-gap:.25rem;column-gap:.25rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-3\.5{-moz-column-gap:.875rem;column-gap:.875rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-x-9{-moz-column-gap:2.25rem;column-gap:2.25rem}.gap-y-11{row-gap:2.75rem}.gap-y-2{row-gap:.5rem}.gap-y-4{row-gap:1rem}.gap-y-7{row-gap:1.75rem}.justify-self-end{justify-self:end}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-scroll{overflow-y:scroll}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-solid{border-style:solid}.border-gray-500{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-neutral-600{--tw-bg-opacity:1;background-color:rgb(82 82 82/var(--tw-bg-opacity))}.bg-neutral-800{--tw-bg-opacity:1;background-color:rgb(38 38 38/var(--tw-bg-opacity))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pl-1{padding-left:.25rem}.pl-3{padding-left:.75rem}.pr-2{padding-right:.5rem}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-normal{font-weight:400}.font-semibold{font-weight:600}.leading-5{line-height:1.25rem}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-purple-200{--tw-text-opacity:1;color:rgb(233 213 255/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.drop-shadow-md{--tw-drop-shadow:drop-shadow(0 4px 3px #00000012) drop-shadow(0 2px 2px #0000000f)}.drop-shadow-md,.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.bg-gray-40{background-color:#4d4d4d}.bg-gray-80{background-color:#2e2e2e}.bg-gray-90{background-color:#141414}.bg-blue-0{background-color:#4199eb}.bg-pink{background-color:#f73090}.border-gray-40{border-color:#4d4d4d}.text-gray-0{color:grey}.text-blue-40{color:#83bef6}.text-gray-40{color:#b3b3b3}.text-gray-70{color:#d9d9d9}.text-orange-0{color:#f8ae61}.text-pink{color:#f73090}.bg-share-button{background:linear-gradient(131.15deg,#f7ccfe -8.51%,#660ff7 82.79%);box-shadow:0 0 4px #660ff7}.output-item{box-shadow:2px 2px 4px #00000040}.bg-warning-gradient{background:linear-gradient(180deg,#f8ae61,#f8ae6100)}.bg-error-gradient{background:linear-gradient(180deg,#f73090,#f7309000)}@media (min-width:768px){.md\:flex{display:flex}.md\:hidden{display:none}} \ No newline at end of file +/* +! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS +*/ + +html, +:host { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: Source Sans Pro; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + -webkit-tap-highlight-color: transparent; + /* 7 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-feature-settings: normal; + /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + letter-spacing: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +input:where([type='button']), +input:where([type='reset']), +input:where([type='submit']) { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} + +.container { + width: 100%; +} + +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} + +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} + +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} + +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} + +.visible { + visibility: visible; +} + +.static { + position: static; +} + +.fixed { + position: fixed; +} + +.absolute { + position: absolute; +} + +.relative { + position: relative; +} + +.inset-0 { + inset: 0px; +} + +.inset-x-1\/4 { + left: 25%; + right: 25%; +} + +.left-\[42px\] { + left: 42px; +} + +.top-1\/4 { + top: 25%; +} + +.top-2 { + top: 0.5rem; +} + +.top-\[2em\] { + top: 2em; +} + +.z-10 { + z-index: 10; +} + +.my-3 { + margin-top: 0.75rem; + margin-bottom: 0.75rem; +} + +.mb-5 { + margin-bottom: 1.25rem; +} + +.mr-9 { + margin-right: 2.25rem; +} + +.mt-auto { + margin-top: auto; +} + +.ml-2 { + margin-left: 0.5rem; +} + +.ml-1 { + margin-left: 0.25rem; +} + +.flex { + display: flex; +} + +.grid { + display: grid; +} + +.hidden { + display: none; +} + +.h-3\.5 { + height: 0.875rem; +} + +.h-4 { + height: 1rem; +} + +.h-6 { + height: 1.5rem; +} + +.h-8 { + height: 2rem; +} + +.h-full { + height: 100%; +} + +.h-screen { + height: 100vh; +} + +.h-5 { + height: 1.25rem; +} + +.h-3 { + height: 0.75rem; +} + +.w-1\/2 { + width: 50%; +} + +.w-2 { + width: 0.5rem; +} + +.w-24 { + width: 6rem; +} + +.w-3\.5 { + width: 0.875rem; +} + +.w-4 { + width: 1rem; +} + +.w-6 { + width: 1.5rem; +} + +.w-8 { + width: 2rem; +} + +.w-full { + width: 100%; +} + +.w-5 { + width: 1.25rem; +} + +.w-3 { + width: 0.75rem; +} + +.grow { + flex-grow: 1; +} + +.list-disc { + list-style-type: disc; +} + +.grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.flex-row { + flex-direction: row; +} + +.flex-col { + flex-direction: column; +} + +.items-start { + align-items: flex-start; +} + +.items-center { + align-items: center; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.gap-x-1 { + -moz-column-gap: 0.25rem; + column-gap: 0.25rem; +} + +.gap-x-2 { + -moz-column-gap: 0.5rem; + column-gap: 0.5rem; +} + +.gap-x-3 { + -moz-column-gap: 0.75rem; + column-gap: 0.75rem; +} + +.gap-x-3\.5 { + -moz-column-gap: 0.875rem; + column-gap: 0.875rem; +} + +.gap-x-4 { + -moz-column-gap: 1rem; + column-gap: 1rem; +} + +.gap-x-9 { + -moz-column-gap: 2.25rem; + column-gap: 2.25rem; +} + +.gap-y-11 { + row-gap: 2.75rem; +} + +.gap-y-2 { + row-gap: 0.5rem; +} + +.gap-y-4 { + row-gap: 1rem; +} + +.gap-y-7 { + row-gap: 1.75rem; +} + +.space-y-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.justify-self-end { + justify-self: end; +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.overflow-y-scroll { + overflow-y: scroll; +} + +.rounded { + border-radius: 0.25rem; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.rounded-l-md { + border-top-left-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; +} + +.rounded-r-md { + border-top-right-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-r { + border-right-width: 1px; +} + +.border-solid { + border-style: solid; +} + +.border-gray-500 { + --tw-border-opacity: 1; + border-color: rgb(107 114 128 / var(--tw-border-opacity)); +} + +.bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); +} + +.bg-neutral-600 { + --tw-bg-opacity: 1; + background-color: rgb(82 82 82 / var(--tw-bg-opacity)); +} + +.bg-neutral-800 { + --tw-bg-opacity: 1; + background-color: rgb(38 38 38 / var(--tw-bg-opacity)); +} + +.p-2 { + padding: 0.5rem; +} + +.p-3 { + padding: 0.75rem; +} + +.p-4 { + padding: 1rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-1\.5 { + padding-top: 0.375rem; + padding-bottom: 0.375rem; +} + +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.pb-2 { + padding-bottom: 0.5rem; +} + +.pb-4 { + padding-bottom: 1rem; +} + +.pl-1 { + padding-left: 0.25rem; +} + +.pl-3 { + padding-left: 0.75rem; +} + +.pr-2 { + padding-right: 0.5rem; +} + +.pt-2 { + padding-top: 0.5rem; +} + +.pt-4 { + padding-top: 1rem; +} + +.text-left { + text-align: left; +} + +.font-mono { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + +.font-normal { + font-weight: 400; +} + +.font-semibold { + font-weight: 600; +} + +.leading-5 { + line-height: 1.25rem; +} + +.text-gray-300 { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.text-purple-200 { + --tw-text-opacity: 1; + color: rgb(233 213 255 / var(--tw-text-opacity)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.text-violet-600 { + --tw-text-opacity: 1; + color: rgb(124 58 237 / var(--tw-text-opacity)); +} + +.text-violet-400 { + --tw-text-opacity: 1; + color: rgb(167 139 250 / var(--tw-text-opacity)); +} + +.text-violet-300 { + --tw-text-opacity: 1; + color: rgb(196 181 253 / var(--tw-text-opacity)); +} + +.text-violet-200 { + --tw-text-opacity: 1; + color: rgb(221 214 254 / var(--tw-text-opacity)); +} + +.underline { + text-decoration-line: underline; +} + +.opacity-30 { + opacity: 0.3; +} + +.drop-shadow-md { + --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.bg-gray-40 { + background-color: rgb(77, 77, 77); +} + +.bg-gray-80 { + background-color: rgb(46, 46, 46); +} + +.bg-gray-90 { + background-color: rgb(20, 20, 20); +} + +.bg-blue-0 { + background-color: rgb(65, 153, 235); +} + +.bg-pink { + background-color: rgb(247, 48, 144); +} + +.border-gray-40 { + border-color: rgb(77, 77, 77); +} + +.text-gray-0 { + color: rgb(128, 128, 128); +} + +.text-blue-40 { + color: rgb(131, 190, 246); +} + +.text-gray-40 { + color: rgb(179, 179, 179); +} + +.text-gray-70 { + color: rgb(217, 217, 217); +} + +.text-orange-0 { + color: rgb(248, 174, 97); +} + +.text-pink { + color: rgb(247, 48, 144); +} + +.bg-share-button { + background: linear-gradient(131.15deg, #F7CCFE -8.51%, #660FF7 82.79%); + box-shadow: 0px 0px 4px #660FF7; +} + +.output-item { + box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25); +} + +.bg-warning-gradient { + background: linear-gradient(180deg, rgba(248, 174, 97, 1) 0%, rgba(248, 174, 97, 0) 100%); +} + +.bg-error-gradient { + background: linear-gradient(180deg, rgba(247, 48, 144, 1) 0%, rgba(247, 48, 144, 0) 100%); +} + +pre.test-trace { + --color-trace: rgb(247, 48, 144); +} + +pre.test-trace.success { + --color-trace: rgb(131, 190, 246); +} + +pre.test-trace::before { + content: 'Trace'; + font-variant: small-caps; + color: var(--color-trace); + font-size: 0.9em; + padding-right: 0.65rem; + font-weight: bold; +} + +.hover\:text-violet-400:hover { + --tw-text-opacity: 1; + color: rgb(167 139 250 / var(--tw-text-opacity)); +} + +.hover\:text-violet-300:hover { + --tw-text-opacity: 1; + color: rgb(196 181 253 / var(--tw-text-opacity)); +} + +.hover\:underline:hover { + text-decoration-line: underline; +} + +@media (min-width: 768px) { + .md\:flex { + display: flex; + } + + .md\:hidden { + display: none; + } +} diff --git a/src/compiler_error.rs b/src/compiler_error.rs index cda80c3..c6b06f8 100644 --- a/src/compiler_error.rs +++ b/src/compiler_error.rs @@ -1,7 +1,9 @@ -use std::error::Error; - -use aiken_lang::{parser::error::ParseError, tipo}; +use aiken_lang::{ + parser::error::ParseError, + tipo::{self}, +}; use miette::Diagnostic; +use std::error::Error; #[derive(Clone)] pub enum CompilerError { diff --git a/src/components/code_editor.rs b/src/components/code_editor.rs index 38ed220..1c8df24 100644 --- a/src/components/code_editor.rs +++ b/src/components/code_editor.rs @@ -17,15 +17,38 @@ use monaco::{ }; use wasm_bindgen::JsValue; -const INITIAL_CONTENT: &str = r#"use aiken/list +const INITIAL_CONTENT: &str = r#"use aiken/collection/list +use aiken/fuzz +use cardano/assets +use cardano/transaction.{Transaction} + +validator main() { + mint(redeemer: List, policy_id: ByteArray, self: Transaction) { + trace @"minting": policy_id, @"with", redeemer + + let quantities = self.mint + |> assets.flatten + |> list.map(fn(t) { t.3rd }) + + quicksort(redeemer) == quantities + } + + else(_) { + fail + } +} fn quicksort(xs: List) -> List { when xs is { [] -> [] [p, ..tail] -> { - let before = tail |> list.filter(fn(x) { x < p }) |> quicksort - let after = tail |> list.filter(fn(x) { x >= p }) |> quicksort + let before = tail + |> list.filter(fn(x) { x < p }) + |> quicksort + let after = tail + |> list.filter(fn(x) { x >= p }) + |> quicksort list.concat(before, [p, ..after]) } } @@ -42,19 +65,22 @@ test quicksort_1() { test quicksort_2() { quicksort([1, 2, 3, 4]) == [1, 2, 3, 4] } -"#; + +test quicksort_prop(xs via fuzz.list(fuzz.int())) { + quicksort(xs) == quicksort(quicksort(xs)) +}"#; const HIGHLIGHTING: &str = r#" { "keywords": [ "if", "else", "when", "is", "fn", "use", "let", "pub", "type", "opaque", "const", - "todo", "expect", "check", "test", "trace", - "fail", "validator", "and", "or", "via" + "todo", "expect", "test", "trace", "fail", + "once", "validator", "and", "or", "via" ], "operators": [ "->", "|>", "..", "<=", ">=", "==", "!=", "<", ">", "&&", "||", - "|", "+", "-", "/", "*", "%", "=", "<-" + "|", "+", "-", "/", "*", "%", "=", "<-", "?" ], "digits": "\\d+(_+\\d+)*", "octaldigits": "[0-7]+(_+[0-7]+)*", @@ -74,7 +100,9 @@ const HIGHLIGHTING: &str = r#" ["0[xX](@hexdigits)", "number.hex"], ["0[oO]?(@octaldigits)", "number.octal"], ["0[bB](@binarydigits)", "number.binary"], - ["(@digits)", "number"] + ["(@digits)", "number"], + ["\"([^\"\\\\]|\\\\.)*$", "string.invalid"], + ["\"([^\"\\\\]|\\\\.)*\"", "string"] ] } } diff --git a/src/components/header.rs b/src/components/header.rs index fab4b5a..e048f23 100644 --- a/src/components/header.rs +++ b/src/components/header.rs @@ -1,3 +1,4 @@ +use aiken_lang::version::compiler_version; use leptos::*; use leptos_icons::*; @@ -18,13 +19,14 @@ where { view! { cx,
- + { move || { + if !test_result.logs.is_empty() { + view! { cx, +
+ {test_result.logs.iter().map(|log| { + view! { cx,
{log}
+ } + }).collect_view(cx)} +
+ } + } else { + view! { cx,
} + } + }} } } @@ -185,6 +216,31 @@ pub fn Output( /> +
} } diff --git a/src/components/share.rs b/src/components/share.rs index 9acc632..fa04712 100644 --- a/src/components/share.rs +++ b/src/components/share.rs @@ -21,11 +21,7 @@ where let share_url = move || get_share_url(editor); let on_copy = move |_| { - let _ = window() - .navigator() - .clipboard() - .unwrap() - .write_text(&share_url()); + let _ = window().navigator().clipboard().write_text(&share_url()); set_copy.set(true); }; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..31b85d6 --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,7 @@ +#[macro_export] +macro_rules! hashmap { + // map-like + ($($k:expr => $v:expr),* $(,)?) => {{ + core::convert::From::from([$(($k, $v),)*]) + }}; +} diff --git a/src/main.rs b/src/main.rs index 95502d6..0ac56dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,10 @@ use leptos::*; mod compiler_error; mod components; +mod macros; mod playground; mod project; -mod stdlib; +pub(crate) mod vendor; use playground::Playground; diff --git a/src/playground.rs b/src/playground.rs index 4d0eccb..c1f0fbd 100644 --- a/src/playground.rs +++ b/src/playground.rs @@ -89,11 +89,11 @@ pub fn Playground(cx: Scope) -> impl IntoView { />
- "The playground is not optimized for small screens. You're probably using a mobile device, please come back on desktop to try out the playground." + "The playground is not operational for small screens and devices. You're probably using a mobile device, please come back on desktop to try out the playground."
  • - - "Install" + + "Get started"
  • diff --git a/src/project.rs b/src/project.rs index a7f4f0f..0ae2bea 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,32 +1,55 @@ -use std::{cell::RefCell, collections::HashMap, rc::Rc}; - +use crate::{ + compiler_error::CompilerError, + vendor::{fuzz, stdlib}, +}; use aiken_lang::{ ast::{ - BinOp, Definition, ModuleKind, Tracing, TypedDataType, TypedDefinition, TypedFunction, - TypedValidator, + DataTypeKey, Definition, FunctionAccessKey, ModuleKind, OnTestFailure, TraceLevel, Tracing, + TypedDataType, TypedFunction, TypedModule, TypedTest, TypedValidator, UntypedModule, }, builtins, - gen_uplc::{ - builder::{DataTypeKey, FunctionAccessKey}, - CodeGenerator, - }, + gen_uplc::CodeGenerator, + line_numbers::LineNumbers, parser, - tipo::{error::Warning, TypeInfo}, - IdGenerator, + parser::{error::ParseError, extra::ModuleExtra}, + plutus_version::PlutusVersion, + test_framework::{self, Test}, + tipo::{error::Warning, Type, TypeInfo}, + utils, IdGenerator, }; use indexmap::IndexMap; use leptos::{log, SignalSet, SignalUpdate, WriteSignal}; +use std::{ + cell::RefCell, + collections::{BTreeSet, HashMap}, + path::PathBuf, + rc::Rc, +}; +use supports_color::Stream::Stderr; use uplc::{ - ast::{DeBruijn, NamedDeBruijn, Program}, + ast::{DeBruijn, Program}, machine::cost_model::ExBudget, + PlutusData, }; -use crate::{compiler_error::CompilerError, stdlib}; +const KIND: ModuleKind = ModuleKind::Validator; +const NAME: &str = "play"; +const PLUTUS_VERSION: PlutusVersion = PlutusVersion::V3; +const PROPERTY_MAX_SUCCESS: usize = 30; +const TRACING: Tracing = Tracing::All(TraceLevel::Verbose); + +#[derive(Clone)] +pub struct TestResult { + pub name: String, + pub success: bool, + pub logs: Vec, + pub meta: TestResultMeta, +} -pub struct EvalHint { - pub bin_op: BinOp, - pub left: Program, - pub right: Program, +#[derive(Clone)] +pub enum TestResultMeta { + ExBudget(ExBudget), + Iterations(usize), } #[derive(Clone)] @@ -35,15 +58,8 @@ pub struct Project { module_types: HashMap, functions: IndexMap, data_types: IndexMap, - is_stdlib_setup: bool, -} - -#[derive(Clone)] -pub struct TestResult { - pub success: bool, - pub spent_budget: ExBudget, - pub logs: Vec, - pub name: String, + module_sources: HashMap, + dependencies: BTreeSet, } impl Project { @@ -54,7 +70,7 @@ impl Project { module_types.insert("aiken".to_string(), builtins::prelude(&id_gen)); module_types.insert("aiken/builtin".to_string(), builtins::plutus(&id_gen)); - let functions = builtins::prelude_functions(&id_gen); + let functions = builtins::prelude_functions(&id_gen, &module_types); let data_types = builtins::prelude_data_types(&id_gen); RefCell::new(Project { @@ -62,11 +78,25 @@ impl Project { module_types, functions, data_types, - is_stdlib_setup: false, + module_sources: HashMap::new(), + dependencies: BTreeSet::new(), }) .into() } + pub fn package_name(&self) -> String { + format!("aiken-lang/{}", NAME) + } + + pub fn parse( + &self, + source_code: &str, + ) -> Result<(UntypedModule, ModuleExtra), Vec> { + let (mut ast, extra) = parser::module(source_code, KIND)?; + ast.name = NAME.to_string(); + Ok((ast, extra)) + } + pub fn build( &mut self, source_code: &str, @@ -75,61 +105,63 @@ impl Project { set_errors: WriteSignal>, set_test_results: WriteSignal>, ) { - if !self.is_stdlib_setup { - self.setup_stdlib(); + if !self.dependencies.contains("stdlib") { + self.setup_dependency("stdlib", stdlib::modules(), &stdlib::MODULES_SEQUENCE[..]); + self.dependencies.insert("stdlib".to_string()); } - let kind = ModuleKind::Validator; - - match parser::module(source_code, kind) { - Ok((mut ast, _extra)) => { - let name = "play".to_string(); - ast.name = name.clone(); + if !self.dependencies.contains("fuzz") { + self.setup_dependency("fuzz", fuzz::modules(), &fuzz::MODULES_SEQUENCE[..]); + self.dependencies.insert("fuzz".to_string()); + } + match self.parse(source_code) { + Ok((ast, _extra)) => { let mut warnings = vec![]; - match ast.infer( &self.id_gen, - kind, - &name, + KIND, + &self.package_name(), &self.module_types, - Tracing::NoTraces, + TRACING, &mut warnings, + None, ) { - Ok(typed_ast) => { - let mut module_types: IndexMap<&String, &TypeInfo> = - self.module_types.iter().collect(); - - module_types.insert(&name, &typed_ast.type_info); - - let (tests, validators, functions, data_types) = - self.collect_definitions(name.clone(), typed_ast.definitions()); + Ok(ast) => { + // Register module sources for an easier access later. + self.module_sources.insert( + NAME.to_string(), + (source_code.to_string(), LineNumbers::new(source_code)), + ); - let mut generator = - CodeGenerator::new(functions, data_types, module_types, false); + // Register the types from this module so they can be + // imported into other modules. + self.module_types + .insert(NAME.to_string(), ast.type_info.clone()); - run_tests(tests, &mut generator, set_test_results); + // Register function definitions & data-types for easier access later. + ast.register_definitions(&mut self.functions, &mut self.data_types); - for (index, validator) in validators.into_iter().enumerate() { - let name = format!( - "{}{}", - validator.fun.name, - validator - .other_fun - .clone() - .map(|o| format!(".{}", o.name)) - .unwrap_or_else(|| "".to_string()) - ); + // Run all tests + self.run_tests(&ast, set_test_results); - let program = generator.generate(validator); + let mut generator = self.new_generator(); + for (index, validator) in + self.collect_validators(&ast).into_iter().enumerate() + { + let program = generator.generate(validator, NAME); let program: Program = program.try_into().unwrap(); - let program = program.to_hex().unwrap(); - set_validators.update(|v| v.push((index, name, program))) + for handler in validator.handlers.iter() { + let name = + TypedValidator::handler_name(&validator.name, &handler.name); + set_validators.update(|v| v.push((index, name, program.clone()))) + } } } + Err(err) => set_errors.set(vec![(0, CompilerError::Type(err))]), } @@ -146,162 +178,160 @@ impl Project { } } - #[allow(clippy::type_complexity)] - fn collect_definitions<'a>( - &'a self, - name: String, - definitions: impl Iterator, - ) -> ( - Vec<&'a TypedFunction>, - Vec<&'a TypedValidator>, - IndexMap, - IndexMap, + pub fn collect_validators<'a>(&'_ self, ast: &'a TypedModule) -> Vec<&'a TypedValidator> { + ast.definitions() + .filter_map(|def| match def { + Definition::Validator(validator) => Some(validator), + Definition::Test { .. } + | Definition::ModuleConstant { .. } + | Definition::Fn { .. } + | Definition::TypeAlias { .. } + | Definition::DataType { .. } + | Definition::Use { .. } => None, + }) + .collect::>() + } + + pub fn collect_tests<'a>(&'_ self, ast: &'a TypedModule) -> Vec<&'a TypedTest> { + ast.definitions() + .filter_map(|def| match def { + Definition::Test(test) => Some(test), + Definition::ModuleConstant { .. } + | Definition::Validator { .. } + | Definition::Fn { .. } + | Definition::TypeAlias { .. } + | Definition::DataType { .. } + | Definition::Use { .. } => None, + }) + .collect::>() + } + + pub fn new_generator(&'_ self) -> CodeGenerator<'_> { + CodeGenerator::new( + PLUTUS_VERSION, + utils::indexmap::as_ref_values(&self.functions), + utils::indexmap::as_ref_values(&self.data_types), + utils::indexmap::as_str_ref_values(&self.module_types), + utils::indexmap::as_str_ref_values(&self.module_sources), + TRACING, + ) + } + + fn run_tests( + &self, + ast: &TypedModule, + set_test_results: WriteSignal>, ) { - let mut functions = IndexMap::new(); - for (k, v) in &self.functions { - functions.insert(k.clone(), v); - } + let mut generator = self.new_generator(); + let mut rng = fastrand::Rng::new(); + for (index, test) in self.collect_tests(ast).into_iter().enumerate() { + let test = Test::from_function_definition( + &mut generator, + test.to_owned(), + NAME.to_string(), + PathBuf::new(), + ); - let mut data_types = IndexMap::new(); - for (k, v) in &self.data_types { - data_types.insert(k.clone(), v); + set_test_results.update(|t| { + t.push(( + index, + self.test_result(match test { + Test::UnitTest(unit_test) => unit_test.run(&PLUTUS_VERSION), + Test::PropertyTest(property_test) => { + property_test.run(rng.u32(..), PROPERTY_MAX_SUCCESS, &PLUTUS_VERSION) + } + }), + )) + }); } + } + + fn test_result( + &self, + result: test_framework::TestResult<(uplc::ast::Constant, Rc), PlutusData>, + ) -> TestResult { + let data_types = utils::indexmap::as_ref_values(&self.data_types); - let mut tests = vec![]; - let mut validators = vec![]; - - for def in definitions { - match def { - Definition::Fn(func) => { - functions.insert( - FunctionAccessKey { - module_name: name.clone(), - function_name: func.name.clone(), - }, - func, - ); + let success = result.is_success(); + + match result { + test_framework::TestResult::UnitTestResult(unit_test) => { + let unit_test = unit_test.reify(&data_types); + + let mut logs = Vec::new(); + if !unit_test.success { + let expect_failure = match unit_test.test.on_test_failure { + OnTestFailure::FailImmediately => false, + OnTestFailure::SucceedEventually | OnTestFailure::SucceedImmediately => { + true + } + }; + + if let Some(assertion) = unit_test.assertion { + logs.push(format!( + "assertion failure\n{}", + assertion.to_string(Stderr, expect_failure) + )); + } } - Definition::DataType(dt) => { - data_types.insert( - DataTypeKey { - module_name: name.clone(), - defined_type: dt.name.clone(), - }, - dt, - ); + logs.extend(unit_test.traces); + + TestResult { + name: unit_test.test.name, + success, + logs, + meta: TestResultMeta::ExBudget(unit_test.spent_budget), } - Definition::Test(t) => tests.push(t), - Definition::Validator(v) => validators.push(v), + } + test_framework::TestResult::PropertyTestResult(prop_test) => { + let logs = Vec::new(); - Definition::TypeAlias(_) | Definition::ModuleConstant(_) | Definition::Use(_) => {} + TestResult { + name: prop_test.test.name, + success, + meta: TestResultMeta::Iterations(prop_test.iterations), + logs, + } } } - - (tests, validators, functions, data_types) } - pub fn setup_stdlib(&mut self) { - for (module_name, module_src) in stdlib::MODULES { - log!("{}", module_name); + fn setup_dependency(&mut self, context: &str, modules: HashMap<&str, &str>, sequence: &[&str]) { + for module_name in sequence { + let module_src = modules + .get(module_name) + .expect("couldn't find sources for '{module_name}' when compiling {context}"); let (mut ast, _extra) = parser::module(module_src, ModuleKind::Lib).unwrap(); ast.name = module_name.to_string(); let mut warnings = vec![]; - let typed_ast = ast + let ast = ast .infer( &self.id_gen, ModuleKind::Lib, module_name, &self.module_types, - Tracing::NoTraces, + Tracing::silent(), &mut warnings, + None, ) .map_err(|e| { - log!("{}", e); + log!("failed to type-checked {context}: {e}"); }) .unwrap(); - for def in typed_ast.definitions.into_iter() { - match def { - Definition::Fn(func) => { - self.functions.insert( - FunctionAccessKey { - module_name: module_name.to_string(), - function_name: func.name.clone(), - }, - func, - ); - } - Definition::DataType(data) => { - self.data_types.insert( - DataTypeKey { - module_name: module_name.to_string(), - defined_type: data.name.clone(), - }, - data, - ); - } - Definition::TypeAlias(_) - | Definition::Use(_) - | Definition::ModuleConstant(_) - | Definition::Test(_) - | Definition::Validator(_) => (), - } - } + ast.register_definitions(&mut self.functions, &mut self.data_types); + + self.module_sources.insert( + module_name.to_string(), + (module_src.to_string(), LineNumbers::new(module_src)), + ); self.module_types - .insert(module_name.to_string(), typed_ast.type_info); + .insert(module_name.to_string(), ast.type_info); } - - self.is_stdlib_setup = true - } -} - -fn run_tests( - tests: Vec<&TypedFunction>, - generator: &mut CodeGenerator, - set_test_results: WriteSignal>, -) { - for (index, test) in tests.into_iter().enumerate() { - let _evaluation_hint = test.test_hint().map(|(bin_op, left_src, right_src)| { - let left = generator - .clone() - .generate_test(&left_src) - .try_into() - .unwrap(); - - let right = generator - .clone() - .generate_test(&right_src) - .try_into() - .unwrap(); - - EvalHint { - bin_op, - left, - right, - } - }); - - let program = generator.generate_test(&test.body); - - let program: Program = program.try_into().unwrap(); - - let mut eval_result = program.eval(ExBudget::default()); - - set_test_results.update(|t| { - t.push(( - index, - TestResult { - success: !eval_result.failed(test.can_error), - spent_budget: eval_result.cost(), - logs: eval_result.logs(), - name: test.name.clone(), - }, - )) - }); } } diff --git a/src/stdlib.rs b/src/stdlib.rs deleted file mode 100644 index 60a96c9..0000000 --- a/src/stdlib.rs +++ /dev/null @@ -1,76 +0,0 @@ -pub const MODULES: [(&str, &str); 20] = [ - ("aiken/cbor", include_str!("../stdlib/lib/aiken/cbor.ak")), - ( - "aiken/collection", - include_str!("../stdlib/lib/aiken/collection.ak"), - ), - ( - "aiken/collection/dict", - include_str!("../stdlib/lib/aiken/collection/dict.ak"), - ), - ( - "aiken/collection/list", - include_str!("../stdlib/lib/aiken/collection/list.ak"), - ), - ( - "aiken/collection/pairs", - include_str!("../stdlib/lib/aiken/collection/pairs.ak"), - ), - ( - "aiken/crypto", - include_str!("../stdlib/lib/aiken/crypto.ak"), - ), - ( - "aiken/interval", - include_str!("../stdlib/lib/aiken/interval.ak"), - ), - ("aiken/math", include_str!("../stdlib/lib/aiken/math.ak")), - ( - "aiken/math/rational", - include_str!("../stdlib/lib/aiken/math/rational.ak"), - ), - ( - "aiken/option", - include_str!("../stdlib/lib/aiken/option.ak"), - ), - ( - "aiken/primitive/bytearray", - include_str!("../stdlib/lib/aiken/primitive/bytearray.ak"), - ), - ( - "aiken/primitive/int", - include_str!("../stdlib/lib/aiken/primitive/int.ak"), - ), - ( - "aiken/primitive/string", - include_str!("../stdlib/lib/aiken/primitive/string.ak"), - ), - ( - "cardano/address", - include_str!("../stdlib/lib/cardano/address.ak"), - ), - ( - "cardano/assets", - include_str!("../stdlib/lib/cardano/assets.ak"), - ), - ( - "cardano/certificate", - include_str!("../stdlib/lib/cardano/certificate.ak"), - ), - ( - "cardano/governance", - include_str!("../stdlib/lib/cardano/governance.ak"), - ), - ( - "cardano/governance/protocol_parameters", - include_str!("../stdlib/lib/cardano/governance/protocol_parameters.ak"), - ), - ( - "cardano/script_context", - include_str!("../stdlib/lib/cardano/script_context.ak"), - ), - ( - "cardano/transaction", - include_str!("../stdlib/lib/cardano/transaction.ak"), - ), -]; diff --git a/src/vendor/fuzz.rs b/src/vendor/fuzz.rs new file mode 100644 index 0000000..634f88b --- /dev/null +++ b/src/vendor/fuzz.rs @@ -0,0 +1,10 @@ +use crate::hashmap; +use std::collections::HashMap; + +pub const MODULES_SEQUENCE: [&str; 1] = ["aiken/fuzz"]; + +pub fn modules() -> HashMap<&'static str, &'static str> { + hashmap! { + "aiken/fuzz" => include_str!("../../fuzz/lib/aiken/fuzz.ak"), + } +} diff --git a/src/vendor/mod.rs b/src/vendor/mod.rs new file mode 100644 index 0000000..7c62853 --- /dev/null +++ b/src/vendor/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod fuzz; +pub(crate) mod stdlib; diff --git a/src/vendor/stdlib.rs b/src/vendor/stdlib.rs new file mode 100644 index 0000000..0b9c7ee --- /dev/null +++ b/src/vendor/stdlib.rs @@ -0,0 +1,53 @@ +use crate::hashmap; +use std::collections::HashMap; + +/// The type-checking sequence in which we must compile the modules. +/// In a 'real' project, this is done using a dependency graph which +/// code lies under aiken-project -- not importable here. +pub const MODULES_SEQUENCE: [&str; 20] = [ + "aiken/crypto", + "cardano/address", + "aiken/math", + "aiken/option", + "aiken/primitive/bytearray", + "aiken/primitive/int", + "aiken/collection", + "aiken/collection/dict", + "aiken/collection/list", + "aiken/math/rational", + "cardano/assets", + "cardano/governance/protocol_parameters", + "aiken/cbor", + "cardano/certificate", + "aiken/primitive/string", + "cardano/governance", + "aiken/collection/pairs", + "aiken/interval", + "cardano/transaction", + "cardano/script_context", +]; + +pub fn modules() -> HashMap<&'static str, &'static str> { + hashmap! { + "aiken/cbor" => include_str!("../../stdlib/lib/aiken/cbor.ak"), + "aiken/collection" => include_str!("../../stdlib/lib/aiken/collection.ak"), + "aiken/collection/dict" => include_str!("../../stdlib/lib/aiken/collection/dict.ak"), + "aiken/collection/list" => include_str!("../../stdlib/lib/aiken/collection/list.ak"), + "aiken/collection/pairs" => include_str!("../../stdlib/lib/aiken/collection/pairs.ak"), + "aiken/crypto" => include_str!("../../stdlib/lib/aiken/crypto.ak"), + "aiken/interval" => include_str!("../../stdlib/lib/aiken/interval.ak"), + "aiken/math" => include_str!("../../stdlib/lib/aiken/math.ak"), + "aiken/math/rational" => include_str!("../../stdlib/lib/aiken/math/rational.ak"), + "aiken/option" => include_str!("../../stdlib/lib/aiken/option.ak"), + "aiken/primitive/bytearray" => include_str!("../../stdlib/lib/aiken/primitive/bytearray.ak"), + "aiken/primitive/int" => include_str!("../../stdlib/lib/aiken/primitive/int.ak"), + "aiken/primitive/string" => include_str!("../../stdlib/lib/aiken/primitive/string.ak"), + "cardano/address" => include_str!("../../stdlib/lib/cardano/address.ak"), + "cardano/assets" => include_str!("../../stdlib/lib/cardano/assets.ak"), + "cardano/certificate" => include_str!("../../stdlib/lib/cardano/certificate.ak"), + "cardano/governance" => include_str!("../../stdlib/lib/cardano/governance.ak"), + "cardano/governance/protocol_parameters" => include_str!("../../stdlib/lib/cardano/governance/protocol_parameters.ak"), + "cardano/script_context" => include_str!("../../stdlib/lib/cardano/script_context.ak"), + "cardano/transaction" => include_str!("../../stdlib/lib/cardano/transaction.ak"), + } +} diff --git a/styles.css b/styles.css index 29e934b..dfe7e27 100644 --- a/styles.css +++ b/styles.css @@ -67,3 +67,13 @@ background: linear-gradient(180deg, rgba(247, 48, 144, 1) 0%, rgba(247, 48, 144, 0) 100%); } +pre.test-trace { --color-trace: rgb(247, 48, 144); } +pre.test-trace.success { --color-trace: rgb(131, 190, 246); } +pre.test-trace::before { + content: 'Trace'; + font-variant: small-caps; + color: var(--color-trace); + font-size: 0.9em; + padding-right: 0.65rem; + font-weight: bold; +}