diff --git a/Cargo.lock b/Cargo.lock index 3e7412a..f24a738 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -141,9 +141,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "arbitrary" @@ -174,9 +174,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backoff" @@ -191,9 +191,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -216,6 +216,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "base64ct" version = "1.6.0" @@ -274,9 +280,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -312,15 +318,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.3" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" [[package]] name = "byteorder" @@ -330,9 +336,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cached" @@ -349,9 +355,9 @@ dependencies = [ [[package]] name = "candid" -version = "0.10.5" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088c2e3d22a0fb1ada78b968946b0f7b96027ac8669973fe7c0815a98e8d13ef" +checksum = "818394610ed32d9e4c81025f97c8580698b69542527efde18514cf9ad1f8f5f0" dependencies = [ "anyhow", "binread", @@ -379,7 +385,7 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -412,9 +418,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" [[package]] name = "cfg-if" @@ -430,9 +436,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "clap" -version = "4.5.2" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -452,14 +458,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -470,9 +476,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "clipboard-win" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f9a0700e0127ba15d1d52dd742097f821cd9c65939303a44d970465040a297" +checksum = "d517d4b86184dbb111d3556a10f1c8a04da7428d2987bf1081602bf11c3aa9ee" dependencies = [ "error-code", ] @@ -663,9 +669,9 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -891,9 +897,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -944,9 +950,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "fd-lock" @@ -1048,7 +1054,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -1093,9 +1099,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", @@ -1152,8 +1158,8 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", - "indexmap 2.2.5", + "http 0.2.12", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1202,9 +1208,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -1250,6 +1256,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -1257,10 +1274,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", "pin-project-lite", ] +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + [[package]] name = "httparse" version = "1.8.0" @@ -1284,8 +1311,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -1304,7 +1331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", + "http 0.2.12", "hyper", "rustls", "tokio", @@ -1313,9 +1340,9 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.33.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32c4711ca94eee9b7966116698b69ca99e7e24cba68c1f3dd86f2ed70218a7e" +checksum = "555eda283b8ba1a996d44d80b6c9a6d38a6cbb81797a7b7bbee134fdde64ce48" dependencies = [ "backoff", "cached", @@ -1323,8 +1350,8 @@ dependencies = [ "ed25519-consensus", "futures-util", "hex", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "ic-certification", "ic-transport-types", "ic-verify-bls-signature", @@ -1336,7 +1363,7 @@ dependencies = [ "rand", "rangemap", "reqwest", - "ring 0.16.20", + "ring", "rustls-webpki", "sec1", "serde", @@ -1353,9 +1380,9 @@ dependencies = [ [[package]] name = "ic-certification" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480b6a64a6602ed8c4eac150ef72f2206dc2910069d0cf524b5c6f90d8bc03fc" +checksum = "20052ce9255fbe2de7041a4f6996fddd095ba1f31ae83b6c0ccdee5be6e7bbcf" dependencies = [ "hex", "serde", @@ -1365,9 +1392,9 @@ dependencies = [ [[package]] name = "ic-identity-hsm" -version = "0.33.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d363914507e81896a6edd1768aa2524bd923b94ed4c27a9793a90b0880f741" +checksum = "33256dea2080fc7d36b749abe469437170b05f9172838152d8d16448ced780d4" dependencies = [ "hex", "ic-agent", @@ -1379,10 +1406,10 @@ dependencies = [ [[package]] name = "ic-repl" -version = "0.7.0" +version = "0.7.1" dependencies = [ "anyhow", - "base64", + "base64 0.21.7", "candid", "candid_parser", "clap", @@ -1400,12 +1427,12 @@ dependencies = [ "lalrpop-util", "libflate", "logos", - "pem 3.0.3", + "pem 3.0.4", "pretty 0.12.3", "pretty_assertions", "qrcode", "rand", - "ring 0.16.20", + "ring", "rpassword", "rustyline", "rustyline-derive", @@ -1419,9 +1446,9 @@ dependencies = [ [[package]] name = "ic-transport-types" -version = "0.33.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d595b9f72e5952bcb22e5cda37ae1c8d6579a24aaa224b63b8d245f386bdcbb2" +checksum = "7c06d3c1292368c813f8104d9d8294bda5577ea6fe4501a65997d0b7f155f15f" dependencies = [ "candid", "hex", @@ -1448,11 +1475,12 @@ dependencies = [ [[package]] name = "ic-wasm" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2aa0d7deeb38f18fcec6e4c25c5004422e2e9f8c3fbad15bb795ebac37aca6" +checksum = "a1f3f1ec63f08807d176691225de0b993e832b1fff71c631ed897df5888c7be4" dependencies = [ "candid", + "libflate", "rustc-demangle", "thiserror", "walrus", @@ -1513,9 +1541,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -1531,7 +1559,7 @@ dependencies = [ "crossbeam-channel", "crossbeam-utils", "dashmap", - "indexmap 2.2.5", + "indexmap 2.2.6", "is-terminal", "itoa", "log", @@ -1597,9 +1625,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" @@ -1638,7 +1666,7 @@ dependencies = [ "petgraph", "pico-args", "regex", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", "string_cache", "term", "tiny-keccak", @@ -1709,13 +1737,12 @@ dependencies = [ [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "libc", - "redox_syscall", ] [[package]] @@ -1760,7 +1787,7 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax 0.6.29", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -1774,9 +1801,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -1813,9 +1840,9 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nibble_vec" @@ -1832,7 +1859,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "cfg-if", "cfg_aliases", "libc", @@ -1998,17 +2025,17 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" dependencies = [ - "base64", + "base64 0.21.7", "serde", ] [[package]] name = "pem" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64", + "base64 0.22.0", "serde", ] @@ -2029,9 +2056,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" dependencies = [ "memchr", "thiserror", @@ -2062,9 +2089,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" dependencies = [ "pest", "pest_generator", @@ -2072,22 +2099,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] name = "pest_meta" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" dependencies = [ "once_cell", "pest", @@ -2101,7 +2128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.2.5", + "indexmap 2.2.6", ] [[package]] @@ -2121,9 +2148,9 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2226,9 +2253,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -2262,9 +2289,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2326,9 +2353,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -2337,14 +2364,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -2355,7 +2382,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -2366,24 +2393,24 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" -version = "0.11.25" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "hyper", "hyper-rustls", "ipnet", @@ -2432,21 +2459,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.8" @@ -2457,8 +2469,8 @@ dependencies = [ "cfg-if", "getrandom", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.52.0", ] @@ -2497,11 +2509,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -2515,7 +2527,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.17.8", + "ring", "rustls-webpki", "sct", ] @@ -2526,7 +2538,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64", + "base64 0.21.7", ] [[package]] @@ -2535,15 +2547,15 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "rustyline" @@ -2551,7 +2563,7 @@ version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "cfg-if", "clipboard-win", "fd-lock", @@ -2575,7 +2587,7 @@ checksum = "e5af959c8bf6af1aff6d2b463a57f71aae53d1332da58419e30ad8dc7011d951" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2605,8 +2617,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -2659,7 +2671,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2677,9 +2689,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -2688,13 +2700,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2802,9 +2814,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -2816,12 +2828,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -2878,9 +2884,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" @@ -2907,9 +2913,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -2924,20 +2930,20 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "system-configuration" -version = "0.6.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 2.4.2", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ "core-foundation-sys", "libc", @@ -2977,29 +2983,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -3018,9 +3024,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -3052,9 +3058,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -3077,7 +3083,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -3192,12 +3198,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -3301,7 +3301,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -3335,7 +3335,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3586,7 +3586,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 00563f6..549d168 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ic-repl" -version = "0.7.0" +version = "0.7.1" authors = ["DFINITY Team"] edition = "2021" default-run = "ic-repl" @@ -24,9 +24,9 @@ codespan-reporting = "0.11" pretty = "0.12" pem = "3.0" shellexpand = "3.1" -ic-agent = "0.33" -ic-identity-hsm = "0.33" -ic-transport-types = "0.33" +ic-agent = "0.34" +ic-identity-hsm = "0.34" +ic-transport-types = "0.34" ic-wasm = { version = "0.7", default-features = false } inferno = { version = "0.11", default-features = false, features = ["multithreaded", "nameattr"] } tokio = { version = "1.35", features = ["full"] } @@ -35,7 +35,7 @@ rand = "0.8" logos = "0.13" lalrpop-util = "0.20" clap = { version = "4.4", features = ["derive"] } -ring = "0.16" +ring = "0.17" rpassword = "7.2" serde = "1.0" serde_json = "1.0" diff --git a/README.md b/README.md index 389a245..879023c 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,17 @@ ic-repl [--replica [local|ic|url] | --offline [--format [json|ascii|png]]] --con ``` := - | import = (as )? // bind canister URI to , with optional did file - | export // export current environment variables - | load // load and run a script file - | config // set config for random value generator in dhall format - | let = // bind to a variable - | // show the value of - | assert // assertion + | import = (as )? // bind canister URI to , with optional did file + | export // export current environment variables + | load // load and run a script file + | config // set config for random value generator in dhall format + | let = // bind to a variable + | // show the value of + | assert // assertion | identity ( | record { slot_index = ; key_id = })? // switch to identity , with optional pem file or HSM config - | function ( ,* ) { ;* } // define a function + | function ( ,* ) { ;* } // define a function + | if { ;* } else { ;* } // conditional branch + | while { ;* } // while loop := | // any candid value | * // variable with optional transformers @@ -31,7 +33,7 @@ ic-repl [--replica [local|ic|url] | --offline [--format [json|ascii|png]]] --con := | ? // select opt value | . // select field name from record or variant value - | [ ] // select index from vec, record, or variant value + | [ ] // select index from vec, text, record, or variant value | . ( ,* ) // transform (map, filter, fold) a collection value := | == // structural equality @@ -42,7 +44,6 @@ ic-repl [--replica [local|ic|url] | --offline [--format [json|ascii|png]]] --con ## Functions Similar to most shell languages, functions in ic-repl is dynamically scoped and untyped. -You cannot define recursive functions, as there is no control flow in the language. We also provide some built-in functions: * `account(principal)`: convert principal to account id. @@ -54,7 +55,12 @@ We also provide some built-in functions: * `wasm_profiling(path)/wasm_profiling(path, record { trace_only_funcs = ; start_page = ; page_limit = })`: load Wasm module, instrument the code and store as a blob value. Calling profiled canister binds the cost to variable `__cost_{id}` or `__cost__`. The second argument is optional, and all fields in the record are also optional. If provided, `trace_only_funcs` will only count and trace the provided set of functions; `start_page` writes the logs to a preallocated pages in stable memory; `page_limit` specifies the number of the preallocated pages, default to 4096 if omitted. See [ic-wasm's doc](https://github.com/dfinity/ic-wasm#working-with-upgrades-and-stable-memory) for more details. * `flamegraph(canister_id, title, filename)`: generate flamegraph for the last update call to canister_id, with title and write to `{filename}.svg`. The cost of the update call is returned. * `concat(e1, e2)`: concatenate two vec/record/text together. -* `add/sub/mul/div(e1, e2)`: addition/subtraction/multiplication/division of two integer/float numbers. If one of the arguments is float32/float64, the result is float64; otherwise, the result is integer. You can use type annotation to get the integer part of the float number. For example `div((mul(div(1, 3.0), 1000) : nat), 100.0)` returns `3.33`. +* `add/sub/mul/div(e1, e2)`: addition/subtraction/multiplication/division of two integers/floats. If one of the arguments is float32/float64, the result is float64; otherwise, the result is integer. You can use type annotation to get the integer part of the float number. For example `div((mul(div(1, 3.0), 1000) : nat), 100.0)` returns `3.33`. +* `lt/lte/gt/gte(e1, e2)`: check if integer/float `e1` is less than/less than or equal to/greater than/greater than or equal to `e2`. +* `eq/neq(e1, e2)`: check if `e1` and `e2` are equal or not. `e1` and `e2` must have the same type. +* `and/or(e1, e2)/not(e)`: logical and/or/not. +* `exist(e)`: check if `e` can be evaluated without errors. This is useful to check the existence of data, e.g., `exist(res[10])`. +* `ite(cond, e1, e2)`: expression version of conditional branch. For example, `ite(exist(res.ok), "success", "error")`. The following functions are only available in non-offline mode: * `read_state([effective_id,] prefix, id, paths, ...)`: fetch the state tree path of `//`. Some useful examples, @@ -62,11 +68,10 @@ The following functions are only available in non-offline mode: + canister controllers: `read_state("canister", principal "canister_id", "controllers")` + list all subnet ids: `read_state("subnet")` + subnet metrics: `read_state("subnet", principal "subnet_id", "metrics")` - + list subnet nodes: `read_state(principal "effective_canister_id", "subnet", principal "subnet_id", "node")` - + node public key: `read_state(principal "effective_canister_id", "subnet", principal "subnet_id", "node", principal "node_id", "public_key")` + + list subnet nodes: `read_state("subnet", principal "subnet_id", "node")` + + node public key: `read_state("subnet", principal "subnet_id", "node", principal "node_id", "public_key")` * `send(blob)`: send signed JSON messages generated from offline mode. The function can take a single message or an array of messages. Most likely use is `send(file("messages.json"))`. The return result is the return results of all calls. Alternatively, you can use `ic-repl -s messages.json -r ic`. - ## Object methods For `vec`, `record` or `text` value, we provide some built-in methods for value transformation: @@ -209,6 +214,33 @@ flamegraph(cid, "hashmap.put(50)", "put.svg"); output(file, stringify("[", __cost_put, "](put.svg)|\n")); ``` +### recursion.sh +``` +function fib(n) { + let _ = ite(lt(n, 2), 1, add(fib(sub(n, 1)), fib(sub(n, 2)))) +}; +function fib2(n) { + let a = 1; + let b = 1; + while gt(n, 0) { + let b = add(a, b); + let a = sub(b, a); + let n = sub(n, 1); + }; + let _ = a; +}; +function fib3(n) { + if lt(n, 2) { + let _ = 1; + } else { + let _ = add(fib3(sub(n, 1)), fib3(sub(n, 2))); + } +}; +assert fib(10) == 89; +assert fib2(10) == 89; +assert fib3(10) == 89; +``` + ## Relative paths Several commands and functions are taking arguments from the file system. We have different definitions for diff --git a/examples/func.sh b/examples/func.sh index aeecbbc..76b316d 100644 --- a/examples/func.sh +++ b/examples/func.sh @@ -2,7 +2,8 @@ function f(x) { let _ = x.id; }; function f2(x) { let _ = record { abc = x.id; } }; -function f3(x) { let _ = x.y }; +function f3(x) { let _ = exist(x.y) }; +function f3_2(x) { let _ = x.y }; function f4(acc, x) { let _ = add(acc, x) }; let x = vec{record {id=1;x=opt 2};record {id=2;y=opt 5}}; assert x.map(f) == vec {1;2}; @@ -12,14 +13,16 @@ assert x.filter(f3).map(f) == vec {2}; assert x.map(f).fold(0, f4) == 3; let y = vec { variant { y = 1 }; variant { x = "error" }; variant { y = 2 } }; -assert y.filter(f3).map(f3) == vec {1;2}; +assert y.filter(f3).map(f3_2) == vec {1;2}; +assert y[sub(y.size(), 1)].y == 2; let z = record { opt 1;2;opt 3;opt 4 }; function f5(x) { let _ = record { x[0]; x[1]? } }; -function f6(x) { let _ = x[1]? }; +function f6(x) { let _ = exist(x[1]?) }; function f7(acc, x) { let _ = concat(acc, vec{x[1]}) }; assert z.filter(f6).map(f5) == record { 1; 2 = 3; 4 }; assert z.filter(f6).map(f5).fold(vec{}, f7) == vec {1;3;4}; +assert z[sub(z.size(), 1)]? == 4; let s = "abcdef"; function f8(x) { let _ = stringify(" ", x) }; @@ -27,14 +30,68 @@ function f9(acc, x) { let _ = add(acc, 1) }; assert s.map(f8) == " a b c d e f"; assert s.map(f8).fold(0, f9) == 12; assert s.map(f8).size() == (12 : nat); +assert s[sub(s.size(), 1)] == "f"; assert div(1, 2) == 0; assert div(1, 2.0) == 0.5; assert div((mul(div(((1:nat8):float32), (3:float64)), 1000) : nat), 100.0) == 3.33; +assert eq("text", "text") == true; +assert not(eq("text", "text")) == false; +assert eq(div(1,2), sub(2,2)) == true; +assert gt(div(1, 2.0), 1) == false; +assert eq(div(1, 2.0), 0.5) == true; +assert and(lte(div(1, 2), 0), gte(div(1, 2), 0)) == true; +assert or(lt(div(1, 2), 0), gt(div(1, 2), 0)) == false; assert (service "aaaaa-aa" : principal) == principal "aaaaa-aa"; +assert eq((service "aaaaa-aa" : principal), principal "aaaaa-aa") == true; assert (func "aaaaa-aa".test : service {}) == service "aaaaa-aa"; assert (principal "aaaaa-aa" : service {}) == service "aaaaa-aa"; assert ("this is a text" : blob) == blob "this is a text"; assert (blob "this is a blob" : text) == "this is a blob"; + +function fac(n) { + if eq(n, 0) { + let _ = 1; + } else { + let _ = mul(n, fac(sub(n, 1))); + } +}; +function fac2(n) { + let res = 1; + while gt(n, 0) { + let res = mul(res, n); + let n = sub(n, 1); + }; + let _ = res; +}; +function fac3(n) { + let _ = ite(eq(n, 0), 1, mul(n, fac3(sub(n, 1)))) +}; +function fib(n) { + let _ = ite(lt(n, 2), 1, add(fib(sub(n, 1)), fib(sub(n, 2)))) +}; +function fib2(n) { + let a = 1; + let b = 1; + while gt(n, 0) { + let b = add(a, b); + let a = sub(b, a); + let n = sub(n, 1); + }; + let _ = a; +}; +function fib3(n) { + if lt(n, 2) { + let _ = 1; + } else { + let _ = add(fib3(sub(n, 1)), fib3(sub(n, 2))); + } +}; +assert fac(5) == 120; +assert fac2(5) == 120; +assert fac3(5) == 120; +assert fib(10) == 89; +assert fib2(10) == 89; +assert fib3(10) == 89; diff --git a/src/command.rs b/src/command.rs index 37a53e3..0345627 100644 --- a/src/command.rs +++ b/src/command.rs @@ -28,6 +28,15 @@ pub enum Command { args: Vec, body: Vec, }, + While { + cond: Exp, + body: Vec, + }, + If { + cond: Exp, + then: Vec, + else_: Vec, + }, } #[derive(Debug, Clone)] pub enum IdentityConfig { @@ -174,6 +183,31 @@ impl Command { } helper.base_path = old_base; } + Command::If { cond, then, else_ } => { + let IDLValue::Bool(cond) = cond.eval(helper)? else { + return Err(anyhow!("if condition is not a boolean expression")); + }; + if cond { + for cmd in then.into_iter() { + cmd.run(helper)?; + } + } else { + for cmd in else_.into_iter() { + cmd.run(helper)?; + } + } + } + Command::While { cond, body } => loop { + let IDLValue::Bool(cond) = cond.clone().eval(helper)? else { + return Err(anyhow!("while condition is not a boolean expression")); + }; + if !cond { + break; + } + for cmd in body.iter() { + cmd.clone().run(helper)?; + } + }, } Ok(()) } diff --git a/src/exp.rs b/src/exp.rs index d34a903..0db83e7 100644 --- a/src/exp.rs +++ b/src/exp.rs @@ -93,6 +93,36 @@ impl Exp { Exp::Apply(func, exps) => { use crate::account_identifier::*; + // functions that cannot evaluate arguments first + match func.as_str() { + "ite" => { + if exps.len() != 3 { + return Err(anyhow!( + "ite expects a bool, true branch and false branch" + )); + } + return Ok(match exps[0].clone().eval(helper)? { + IDLValue::Bool(true) => exps[1].clone().eval(helper)?, + IDLValue::Bool(false) => exps[2].clone().eval(helper)?, + _ => { + return Err(anyhow!( + "ite expects the first argument to be a boolean expression" + )); + } + }); + } + "exist" => { + if exps.len() != 1 { + return Err(anyhow!("exist expects an expression")); + } + return Ok(match exps[0].clone().eval(helper) { + Ok(_) => IDLValue::Bool(true), + Err(_) => IDLValue::Bool(false), + }); + } + _ => (), + } + let mut args = Vec::new(); for e in exps.into_iter() { args.push(e.eval(helper)?); @@ -318,7 +348,39 @@ impl Exp { } _ => return Err(anyhow!("concat expects two vec, record or text")), }, - "add" | "sub" | "mul" | "div" => match args.as_slice() { + "eq" | "neq" => match args.as_slice() { + [v1, v2] => { + if v1.value_ty() != v2.value_ty() { + return Err(anyhow!( + "{} expects two values of the same type", + func + )); + } + IDLValue::Bool(match func.as_str() { + "eq" => v1 == v2, + "neq" => v1 != v2, + _ => unreachable!(), + }) + } + _ => return Err(anyhow!("{func} expects two values")), + }, + "and" | "or" => match args.as_slice() { + [IDLValue::Bool(v1), IDLValue::Bool(v2)] => { + IDLValue::Bool(match func.as_str() { + "and" => *v1 && *v2, + "or" => *v1 || *v2, + _ => unreachable!(), + }) + } + _ => return Err(anyhow!("{func} expects bool values")), + }, + "not" => match args.as_slice() { + [IDLValue::Bool(v)] => IDLValue::Bool(!v), + _ => return Err(anyhow!("not expects a bool value")), + }, + "lt" | "lte" | "gt" | "gte" | "add" | "sub" | "mul" | "div" => match args + .as_slice() + { [IDLValue::Float32(_) | IDLValue::Float64(_), _] | [_, IDLValue::Float32(_) | IDLValue::Float64(_)] => { let IDLValue::Float64(v1) = @@ -331,13 +393,17 @@ impl Exp { else { panic!() }; - IDLValue::Float64(match func.as_str() { - "add" => v1 + v2, - "sub" => v1 - v2, - "mul" => v1 * v2, - "div" => v1 / v2, + match func.as_str() { + "add" => IDLValue::Float64(v1 + v2), + "sub" => IDLValue::Float64(v1 - v2), + "mul" => IDLValue::Float64(v1 * v2), + "div" => IDLValue::Float64(v1 / v2), + "lt" => IDLValue::Bool(v1 < v2), + "lte" => IDLValue::Bool(v1 <= v2), + "gt" => IDLValue::Bool(v1 > v2), + "gte" => IDLValue::Bool(v1 >= v2), _ => unreachable!(), - }) + } } [v1, v2] => { let IDLValue::Int(v1) = cast_type(v1.clone(), &TypeInner::Int.into())? @@ -348,18 +414,19 @@ impl Exp { else { panic!() }; - IDLValue::Number( - match func.as_str() { - "add" => v1 + v2, - "sub" => v1 - v2, - "mul" => v1 * v2, - "div" => v1 / v2, - _ => unreachable!(), - } - .to_string(), - ) + match func.as_str() { + "add" => IDLValue::Number((v1 + v2).to_string()), + "sub" => IDLValue::Number((v1 - v2).to_string()), + "mul" => IDLValue::Number((v1 * v2).to_string()), + "div" => IDLValue::Number((v1 / v2).to_string()), + "lt" => IDLValue::Bool(v1 < v2), + "lte" => IDLValue::Bool(v1 <= v2), + "gt" => IDLValue::Bool(v1 > v2), + "gte" => IDLValue::Bool(v1 >= v2), + _ => unreachable!(), + } } - _ => return Err(anyhow!("add expects two numbers")), + _ => return Err(anyhow!("{func} expects two numbers")), }, func => match helper.func_env.0.get(func) { None => return Err(anyhow!("Unknown function {}", func)), diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 2c095a8..052423c 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -44,6 +44,9 @@ extern { "fail" => Token::Fail, "identity" => Token::Identity, "function" => Token::Function, + "while" => Token::While, + "if" => Token::If, + "else" => Token::Else, "sign" => Token::Sign(), "=" => Token::Equals, "==" => Token::TestEqual, @@ -91,6 +94,8 @@ pub Command: Command = { }) }, "function" "(" > ")" "{" > "}" => Command::Func {name,args,body}, + "while" "{" > "}" => Command::While {cond, body}, + "if" "{" > "}" "else" "{" > "}" => Command::If{cond, then, else_}, } pub Exp: Exp = { @@ -107,10 +112,7 @@ Variable: Exp = )*> => Exp::Path(v, path); Selector: Selector = { "?" => Selector::Option, "." => Selector::Field(<>), - "[" > "]" =>? { - let idx = <>.0.parse::().map_err(|_| error2("index out of u64 range", <>.1))?; - Ok(Selector::Index(idx)) - }, + "[" "]" => Selector::Index(<>), "." > "(" > ")" =>? { match (method.0.as_str(), args.as_slice()) { ("map", [Exp::Path(func, _x)]) if _x.is_empty() => Ok(Selector::Map(func.to_string())), diff --git a/src/selector.rs b/src/selector.rs index 19fe366..b3642ea 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -1,5 +1,6 @@ use super::exp::Exp; use super::helper::MyHelper; +use super::utils::as_u32; use anyhow::{anyhow, Result}; use candid::{ types::value::{IDLField, IDLValue, VariantValue}, @@ -9,7 +10,7 @@ use candid::{ #[derive(Debug, Clone)] pub enum Selector { - Index(u64), + Index(Exp), Field(String), Option, Map(String), @@ -18,12 +19,15 @@ pub enum Selector { Size, // Size is not required, but it is faster than using fold } impl Selector { - fn to_label(&self) -> Label { - match self { - Selector::Index(idx) => Label::Id(*idx as u32), + fn to_label(&self, helper: &MyHelper) -> Result