Merge branch 'develop' of github.com:Zokrates/ZoKrates into add-magic-square
This commit is contained in:
commit
4cef8756fd
39 changed files with 970 additions and 523 deletions
178
Cargo.lock
generated
178
Cargo.lock
generated
|
@ -323,7 +323,7 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8dd4e5f0bf8285d5ed538d27fab7411f3e297908fd93c62195de8bee3f199e82"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -402,7 +402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33"
|
||||
dependencies = [
|
||||
"proc-macro-error 1.0.4",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -415,9 +415,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.66"
|
||||
version = "0.3.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
|
||||
checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
|
@ -470,9 +470,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||
checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
|
@ -614,9 +614,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.2.0"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e"
|
||||
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
|
@ -708,7 +708,7 @@ checksum = "c6dd675567eb3e35787bd2583d129e85fabc7503b0a093d08c51198a307e2091"
|
|||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error 0.4.12",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -838,9 +838,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
|||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
checksum = "5999502d32b9c48d492abe66392408144895020ec4709e549e840799f3bb74c0"
|
||||
dependencies = [
|
||||
"generic-array 0.14.5",
|
||||
"typenum",
|
||||
|
@ -904,7 +904,7 @@ version = "2.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -1084,7 +1084,7 @@ version = "0.1.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
"synstructure",
|
||||
|
@ -1098,9 +1098,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
|||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.8.0"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
|
||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
@ -1126,7 +1126,7 @@ dependencies = [
|
|||
"num-bigint 0.2.6",
|
||||
"num-integer",
|
||||
"num-traits 0.2.15",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -1283,9 +1283,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.26.2"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
|
||||
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
|
@ -1322,9 +1322,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
@ -1417,7 +1417,7 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -1473,9 +1473,9 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
|||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.59"
|
||||
version = "0.3.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
|
||||
checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
@ -1692,16 +1692,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.29.0"
|
||||
version = "0.28.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
|
||||
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -1765,7 +1765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -1816,7 +1816,7 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
|
|||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -1920,7 +1920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr 0.4.12",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
"version_check",
|
||||
|
@ -1933,7 +1933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr 1.0.4",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
"version_check",
|
||||
|
@ -1945,7 +1945,7 @@ version = "0.4.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
"syn-mid",
|
||||
|
@ -1958,7 +1958,7 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"version_check",
|
||||
]
|
||||
|
@ -1980,9 +1980,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.42"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b"
|
||||
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -2013,7 +2013,7 @@ version = "1.0.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2091,9 +2091,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.15"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534cfe58d6a18cc17120fbf4635d53d14691c1fe4d951064df9bd326178d7d5a"
|
||||
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
@ -2171,14 +2171,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "revm"
|
||||
version = "1.7.0"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "455988f0a9920c91f192268ee31d79fcb980006058514d1e6b543af3d71670f3"
|
||||
checksum = "b60030444003ac25474f5281e7e91f15e8475c173b729aac1c10aced56b3adac"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"auto_impl",
|
||||
"bytes",
|
||||
"hashbrown 0.12.3",
|
||||
"hashbrown 0.12.1",
|
||||
"num_enum",
|
||||
"primitive-types",
|
||||
"revm_precompiles",
|
||||
|
@ -2188,9 +2188,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "revm_precompiles"
|
||||
version = "1.1.0"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af88e7e9feb30cc4ed64645f09b966e84a1f6be56551ce5f1691105def45705d"
|
||||
checksum = "cd6aae8f44783ef6ff39fc22c9c999dfa0e17b79d663b752730c02a025935185"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"num 0.4.0",
|
||||
|
@ -2288,18 +2288,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||
|
||||
[[package]]
|
||||
name = "secp256k1"
|
||||
version = "0.23.4"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ece73253dd9e1fb540ff324eae554113a31c25fb598d22fd13b088a6a03f90d"
|
||||
checksum = "26947345339603ae8395f68e2f3d85a6b0a8ddfe6315818e80b8504415099db0"
|
||||
dependencies = [
|
||||
"secp256k1-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "secp256k1-sys"
|
||||
version = "0.6.0"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7058dc8eaf3f2810d7828680320acda0b25a288f6d288e19278e249bbf74226b"
|
||||
checksum = "152e20a0fd0519390fc43ab404663af8a0b794273d2a91d60ad4a39f13ffe110"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
@ -2333,9 +2333,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.140"
|
||||
version = "1.0.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
|
||||
checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
@ -2352,11 +2352,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.140"
|
||||
version = "1.0.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"
|
||||
checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -2432,9 +2432,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "single"
|
||||
version = "1.0.1"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9db45bb685b486eec37e0271dcc0dac76eae5e893125f8a4f0511d0a1d29543b"
|
||||
checksum = "bd5add732a1ab689845591a1b50339cf5310b563e08dc5813c65991f30369ea2"
|
||||
dependencies = [
|
||||
"failure",
|
||||
]
|
||||
|
@ -2456,12 +2456,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.7"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
|
||||
|
||||
[[package]]
|
||||
name = "solc"
|
||||
|
@ -2538,7 +2535,7 @@ version = "1.0.98"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -2549,7 +2546,7 @@ version = "0.5.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baa8e7560a164edb1621a55d18a0c59abf49d360f47aa7b821061dd7eea7fac9"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -2560,7 +2557,7 @@ version = "0.12.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
"unicode-xid 0.2.3",
|
||||
|
@ -2629,7 +2626,7 @@ version = "1.0.31"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -2679,7 +2676,7 @@ version = "0.1.22"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
]
|
||||
|
@ -2737,9 +2734,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.2"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
|
||||
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
|
@ -2808,9 +2805,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.82"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
|
||||
checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"serde",
|
||||
|
@ -2820,14 +2817,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.82"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
|
||||
checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
"wasm-bindgen-shared",
|
||||
|
@ -2835,9 +2832,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.32"
|
||||
version = "0.4.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad"
|
||||
checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
|
@ -2847,9 +2844,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.82"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
|
||||
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
|
||||
dependencies = [
|
||||
"quote 1.0.20",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
@ -2857,11 +2854,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.82"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
|
||||
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
"wasm-bindgen-backend",
|
||||
|
@ -2870,15 +2867,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.82"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
|
||||
checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.3.32"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "513df541345bb9fcc07417775f3d51bbb677daf307d8035c0afafd87dc2e6599"
|
||||
checksum = "68b30cf2cba841a812f035c40c50f53eb9c56181192a9dd2c71b65e6a87a05ba"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
|
@ -2890,19 +2887,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.3.32"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6150d36a03e90a3cf6c12650be10626a9902d70c5270fd47d7a47e5389a10d56"
|
||||
checksum = "88ad594bf33e73cafcac2ae9062fc119d4f75f9c77e25022f91c9a64bd5b6463"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.59"
|
||||
version = "0.3.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1"
|
||||
checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
@ -2950,9 +2947,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.5.7"
|
||||
version = "1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
|
||||
checksum = "20b578acffd8516a6c3f2a1bdefc1ec37e547bb4e0fb8b6b01a4cafc886b4442"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
@ -2963,7 +2960,7 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.42",
|
||||
"proc-macro2 1.0.40",
|
||||
"quote 1.0.20",
|
||||
"syn 1.0.98",
|
||||
"synstructure",
|
||||
|
@ -3090,6 +3087,7 @@ dependencies = [
|
|||
"hex 0.3.2",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"pretty_assertions 1.2.1",
|
||||
"primitive-types",
|
||||
"rand 0.4.6",
|
||||
"rand 0.8.5",
|
||||
|
|
|
@ -51,5 +51,5 @@ We enforce strict formatting of `.{js,json,ts}` files in CI. This check is not i
|
|||
|
||||
```
|
||||
npm i -g prettier
|
||||
prettier --write ./**/*.{js,ts,json}
|
||||
prettier --write "./**/*.{js,ts,json}"
|
||||
```
|
||||
|
|
1
changelogs/unreleased/1206-schaeff
Normal file
1
changelogs/unreleased/1206-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Introduce dead code elimination
|
1
changelogs/unreleased/1222-dark64
Normal file
1
changelogs/unreleased/1222-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Make return statement optional if no returns are expected
|
|
@ -16,13 +16,11 @@ pub enum RuntimeError {
|
|||
BranchIsolation,
|
||||
ConstantLtBitness,
|
||||
ConstantLtSum,
|
||||
LtBitness,
|
||||
LtSum,
|
||||
LtFinalBitness,
|
||||
LtFinalSum,
|
||||
LtSymetric,
|
||||
Or,
|
||||
Xor,
|
||||
IncompleteDynamicRange,
|
||||
Inverse,
|
||||
Euclidean,
|
||||
ShaXor,
|
||||
|
@ -37,6 +35,10 @@ impl From<crate::zir::RuntimeError> for RuntimeError {
|
|||
match error {
|
||||
crate::zir::RuntimeError::SourceAssertion(s) => RuntimeError::SourceAssertion(s),
|
||||
crate::zir::RuntimeError::SelectRangeCheck => RuntimeError::SelectRangeCheck,
|
||||
crate::zir::RuntimeError::DivisionByZero => RuntimeError::Inverse,
|
||||
crate::zir::RuntimeError::IncompleteDynamicRange => {
|
||||
RuntimeError::IncompleteDynamicRange
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +49,11 @@ impl RuntimeError {
|
|||
|
||||
!matches!(
|
||||
self,
|
||||
SourceAssertion(_) | Inverse | LtSum | SelectRangeCheck | ArgumentBitness
|
||||
SourceAssertion(_)
|
||||
| Inverse
|
||||
| SelectRangeCheck
|
||||
| ArgumentBitness
|
||||
| IncompleteDynamicRange
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -70,13 +76,13 @@ impl fmt::Display for RuntimeError {
|
|||
BranchIsolation => "Branch isolation failed",
|
||||
ConstantLtBitness => "Bitness check failed in constant Lt check",
|
||||
ConstantLtSum => "Sum check failed in constant Lt check",
|
||||
LtBitness => "Bitness check failed in Lt check",
|
||||
LtSum => "Sum check failed in Lt check",
|
||||
LtFinalBitness => "Bitness check failed in final Lt check",
|
||||
LtFinalSum => "Sum check failed in final Lt check",
|
||||
LtSymetric => "Symetrical check failed in Lt check",
|
||||
Or => "Or check failed",
|
||||
Xor => "Xor check failed",
|
||||
IncompleteDynamicRange => {
|
||||
"Failed to compare field elements because dynamic comparison is incomplete"
|
||||
}
|
||||
Inverse => "Division by zero",
|
||||
Euclidean => "Euclidean check failed",
|
||||
ShaXor => "Internal Sha check failed",
|
||||
|
|
|
@ -188,15 +188,6 @@ impl<T: Field> fmt::Display for Prog<T> {
|
|||
for s in &self.statements {
|
||||
writeln!(f, "\t{}", s)?;
|
||||
}
|
||||
writeln!(
|
||||
f,
|
||||
"\treturn {}",
|
||||
(0..self.return_count)
|
||||
.map(Variable::public)
|
||||
.map(|e| format!("{}", e))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)?;
|
||||
|
||||
writeln!(f, "\treturn {}", returns)?;
|
||||
writeln!(f, "}}")
|
||||
|
|
|
@ -264,6 +264,10 @@ pub trait Folder<'ast, T: Field>: Sized {
|
|||
fold_statement(self, s)
|
||||
}
|
||||
|
||||
fn fold_definition_rhs(&mut self, rhs: DefinitionRhs<'ast, T>) -> DefinitionRhs<'ast, T> {
|
||||
fold_definition_rhs(self, rhs)
|
||||
}
|
||||
|
||||
fn fold_embed_call(&mut self, e: EmbedCall<'ast, T>) -> EmbedCall<'ast, T> {
|
||||
fold_embed_call(self, e)
|
||||
}
|
||||
|
@ -491,6 +495,16 @@ pub fn fold_constant_symbol_declaration<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fold_definition_rhs<'ast, T: Field, F: Folder<'ast, T>>(
|
||||
f: &mut F,
|
||||
rhs: DefinitionRhs<'ast, T>,
|
||||
) -> DefinitionRhs<'ast, T> {
|
||||
match rhs {
|
||||
DefinitionRhs::EmbedCall(c) => DefinitionRhs::EmbedCall(f.fold_embed_call(c)),
|
||||
DefinitionRhs::Expression(e) => DefinitionRhs::Expression(f.fold_expression(e)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>(
|
||||
f: &mut F,
|
||||
s: TypedStatement<'ast, T>,
|
||||
|
@ -498,7 +512,7 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
let res = match s {
|
||||
TypedStatement::Return(e) => TypedStatement::Return(f.fold_expression(e)),
|
||||
TypedStatement::Definition(a, e) => {
|
||||
TypedStatement::Definition(f.fold_assignee(a), f.fold_expression(e))
|
||||
TypedStatement::Definition(f.fold_assignee(a), f.fold_definition_rhs(e))
|
||||
}
|
||||
TypedStatement::Assertion(e, error) => {
|
||||
TypedStatement::Assertion(f.fold_boolean_expression(e), error)
|
||||
|
@ -515,12 +529,6 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
TypedStatement::Log(s, e) => {
|
||||
TypedStatement::Log(s, e.into_iter().map(|e| f.fold_expression(e)).collect())
|
||||
}
|
||||
TypedStatement::EmbedCallDefinition(assignee, embed_call) => {
|
||||
TypedStatement::EmbedCallDefinition(
|
||||
f.fold_assignee(assignee),
|
||||
f.fold_embed_call(embed_call),
|
||||
)
|
||||
}
|
||||
s => s,
|
||||
};
|
||||
vec![res]
|
||||
|
|
|
@ -588,6 +588,7 @@ impl fmt::Display for AssertionMetadata {
|
|||
pub enum RuntimeError {
|
||||
SourceAssertion(AssertionMetadata),
|
||||
SelectRangeCheck,
|
||||
DivisionByZero,
|
||||
}
|
||||
|
||||
impl fmt::Display for RuntimeError {
|
||||
|
@ -595,6 +596,7 @@ impl fmt::Display for RuntimeError {
|
|||
match self {
|
||||
RuntimeError::SourceAssertion(metadata) => write!(f, "{}", metadata),
|
||||
RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"),
|
||||
RuntimeError::DivisionByZero => write!(f, "Division by zero"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -646,12 +648,39 @@ impl<'ast, T: fmt::Display> fmt::Display for EmbedCall<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)]
|
||||
pub enum DefinitionRhs<'ast, T> {
|
||||
Expression(TypedExpression<'ast, T>),
|
||||
EmbedCall(EmbedCall<'ast, T>),
|
||||
}
|
||||
|
||||
impl<'ast, T> From<TypedExpression<'ast, T>> for DefinitionRhs<'ast, T> {
|
||||
fn from(e: TypedExpression<'ast, T>) -> Self {
|
||||
Self::Expression(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> From<EmbedCall<'ast, T>> for DefinitionRhs<'ast, T> {
|
||||
fn from(c: EmbedCall<'ast, T>) -> Self {
|
||||
Self::EmbedCall(c)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Display> fmt::Display for DefinitionRhs<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
DefinitionRhs::EmbedCall(c) => write!(f, "{}", c),
|
||||
DefinitionRhs::Expression(e) => write!(f, "{}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A statement in a `TypedFunction`
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)]
|
||||
pub enum TypedStatement<'ast, T> {
|
||||
Return(TypedExpression<'ast, T>),
|
||||
Definition(TypedAssignee<'ast, T>, TypedExpression<'ast, T>),
|
||||
Definition(TypedAssignee<'ast, T>, DefinitionRhs<'ast, T>),
|
||||
Assertion(BooleanExpression<'ast, T>, RuntimeError),
|
||||
For(
|
||||
Variable<'ast, T>,
|
||||
|
@ -660,7 +689,6 @@ pub enum TypedStatement<'ast, T> {
|
|||
Vec<TypedStatement<'ast, T>>,
|
||||
),
|
||||
Log(FormatString, Vec<TypedExpression<'ast, T>>),
|
||||
EmbedCallDefinition(TypedAssignee<'ast, T>, EmbedCall<'ast, T>),
|
||||
// Aux
|
||||
PushCallLog(
|
||||
DeclarationFunctionKey<'ast, T>,
|
||||
|
@ -669,6 +697,16 @@ pub enum TypedStatement<'ast, T> {
|
|||
PopCallLog,
|
||||
}
|
||||
|
||||
impl<'ast, T> TypedStatement<'ast, T> {
|
||||
pub fn definition(a: TypedAssignee<'ast, T>, e: TypedExpression<'ast, T>) -> Self {
|
||||
Self::Definition(a, e.into())
|
||||
}
|
||||
|
||||
pub fn embed_call_definition(a: TypedAssignee<'ast, T>, c: EmbedCall<'ast, T>) -> Self {
|
||||
Self::Definition(a, c.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Display> TypedStatement<'ast, T> {
|
||||
fn fmt_indented(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
|
||||
match self {
|
||||
|
@ -710,9 +748,6 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedStatement<'ast, T> {
|
|||
}
|
||||
write!(f, "\t}}")
|
||||
}
|
||||
TypedStatement::EmbedCallDefinition(ref lhs, ref rhs) => {
|
||||
write!(f, "{} = {};", lhs, rhs)
|
||||
}
|
||||
TypedStatement::Log(ref l, ref expressions) => write!(
|
||||
f,
|
||||
"log({}, {})",
|
||||
|
@ -752,6 +787,12 @@ pub enum TypedExpression<'ast, T> {
|
|||
Int(IntExpression<'ast, T>),
|
||||
}
|
||||
|
||||
impl<'ast, T> TypedExpression<'ast, T> {
|
||||
pub fn empty_tuple() -> TypedExpression<'ast, T> {
|
||||
TypedExpression::Tuple(TupleExpressionInner::Value(vec![]).annotate(TupleType::new(vec![])))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> From<BooleanExpression<'ast, T>> for TypedExpression<'ast, T> {
|
||||
fn from(e: BooleanExpression<'ast, T>) -> TypedExpression<T> {
|
||||
TypedExpression::Boolean(e)
|
||||
|
@ -909,7 +950,7 @@ impl<E> EqExpression<E> {
|
|||
|
||||
impl<E: fmt::Display> fmt::Display for EqExpression<E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} == {}", self.left, self.right)
|
||||
write!(f, "({} == {})", self.left, self.right)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1659,22 +1700,22 @@ impl<'ast, T: fmt::Display> fmt::Display for BooleanExpression<'ast, T> {
|
|||
match *self {
|
||||
BooleanExpression::Block(ref block) => write!(f, "{}", block,),
|
||||
BooleanExpression::Identifier(ref var) => write!(f, "{}", var),
|
||||
BooleanExpression::FieldLt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs),
|
||||
BooleanExpression::FieldLe(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs),
|
||||
BooleanExpression::FieldGe(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs),
|
||||
BooleanExpression::FieldGt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs),
|
||||
BooleanExpression::UintLt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs),
|
||||
BooleanExpression::UintLe(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs),
|
||||
BooleanExpression::UintGe(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs),
|
||||
BooleanExpression::UintGt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs),
|
||||
BooleanExpression::FieldLt(ref lhs, ref rhs) => write!(f, "({} < {})", lhs, rhs),
|
||||
BooleanExpression::FieldLe(ref lhs, ref rhs) => write!(f, "({} <= {})", lhs, rhs),
|
||||
BooleanExpression::FieldGe(ref lhs, ref rhs) => write!(f, "({} >= {})", lhs, rhs),
|
||||
BooleanExpression::FieldGt(ref lhs, ref rhs) => write!(f, "({} > {})", lhs, rhs),
|
||||
BooleanExpression::UintLt(ref lhs, ref rhs) => write!(f, "({} < {})", lhs, rhs),
|
||||
BooleanExpression::UintLe(ref lhs, ref rhs) => write!(f, "({} <= {})", lhs, rhs),
|
||||
BooleanExpression::UintGe(ref lhs, ref rhs) => write!(f, "({} >= {})", lhs, rhs),
|
||||
BooleanExpression::UintGt(ref lhs, ref rhs) => write!(f, "({} > {})", lhs, rhs),
|
||||
BooleanExpression::FieldEq(ref e) => write!(f, "{}", e),
|
||||
BooleanExpression::BoolEq(ref e) => write!(f, "{}", e),
|
||||
BooleanExpression::ArrayEq(ref e) => write!(f, "{}", e),
|
||||
BooleanExpression::StructEq(ref e) => write!(f, "{}", e),
|
||||
BooleanExpression::TupleEq(ref e) => write!(f, "{}", e),
|
||||
BooleanExpression::UintEq(ref e) => write!(f, "{}", e),
|
||||
BooleanExpression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs),
|
||||
BooleanExpression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs),
|
||||
BooleanExpression::Or(ref lhs, ref rhs) => write!(f, "({} || {})", lhs, rhs),
|
||||
BooleanExpression::And(ref lhs, ref rhs) => write!(f, "({} && {})", lhs, rhs),
|
||||
BooleanExpression::Not(ref exp) => write!(f, "!{}", exp),
|
||||
BooleanExpression::Value(b) => write!(f, "{}", b),
|
||||
BooleanExpression::FunctionCall(ref function_call) => write!(f, "{}", function_call),
|
||||
|
|
|
@ -385,6 +385,13 @@ pub trait ResultFolder<'ast, T: Field>: Sized {
|
|||
fold_statement(self, s)
|
||||
}
|
||||
|
||||
fn fold_definition_rhs(
|
||||
&mut self,
|
||||
rhs: DefinitionRhs<'ast, T>,
|
||||
) -> Result<DefinitionRhs<'ast, T>, Self::Error> {
|
||||
fold_definition_rhs(self, rhs)
|
||||
}
|
||||
|
||||
fn fold_embed_call(
|
||||
&mut self,
|
||||
e: EmbedCall<'ast, T>,
|
||||
|
@ -508,7 +515,7 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
let res = match s {
|
||||
TypedStatement::Return(e) => TypedStatement::Return(f.fold_expression(e)?),
|
||||
TypedStatement::Definition(a, e) => {
|
||||
TypedStatement::Definition(f.fold_assignee(a)?, f.fold_expression(e)?)
|
||||
TypedStatement::Definition(f.fold_assignee(a)?, f.fold_definition_rhs(e)?)
|
||||
}
|
||||
TypedStatement::Assertion(e, error) => {
|
||||
TypedStatement::Assertion(f.fold_boolean_expression(e)?, error)
|
||||
|
@ -531,17 +538,21 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
.map(|e| f.fold_expression(e))
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
),
|
||||
TypedStatement::EmbedCallDefinition(assignee, embed_call) => {
|
||||
TypedStatement::EmbedCallDefinition(
|
||||
f.fold_assignee(assignee)?,
|
||||
f.fold_embed_call(embed_call)?,
|
||||
)
|
||||
}
|
||||
s => s,
|
||||
};
|
||||
Ok(vec![res])
|
||||
}
|
||||
|
||||
pub fn fold_definition_rhs<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
||||
f: &mut F,
|
||||
rhs: DefinitionRhs<'ast, T>,
|
||||
) -> Result<DefinitionRhs<'ast, T>, F::Error> {
|
||||
Ok(match rhs {
|
||||
DefinitionRhs::EmbedCall(c) => DefinitionRhs::EmbedCall(f.fold_embed_call(c)?),
|
||||
DefinitionRhs::Expression(e) => DefinitionRhs::Expression(f.fold_expression(e)?),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fold_embed_call<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
||||
f: &mut F,
|
||||
e: EmbedCall<'ast, T>,
|
||||
|
|
|
@ -895,6 +895,10 @@ impl<S> GType<S> {
|
|||
pub fn uint<W: Into<UBitwidth>>(b: W) -> Self {
|
||||
GType::Uint(b.into())
|
||||
}
|
||||
|
||||
pub fn is_empty_tuple(&self) -> bool {
|
||||
matches!(self, GType::Tuple(ty) if ty.elements.is_empty())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Display + PartialEq + fmt::Debug> Type<'ast, T> {
|
||||
|
|
|
@ -92,6 +92,8 @@ pub type ZirAssignee<'ast> = Variable<'ast>;
|
|||
pub enum RuntimeError {
|
||||
SourceAssertion(String),
|
||||
SelectRangeCheck,
|
||||
DivisionByZero,
|
||||
IncompleteDynamicRange,
|
||||
}
|
||||
|
||||
impl fmt::Display for RuntimeError {
|
||||
|
@ -99,6 +101,8 @@ impl fmt::Display for RuntimeError {
|
|||
match self {
|
||||
RuntimeError::SourceAssertion(message) => write!(f, "{}", message),
|
||||
RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"),
|
||||
RuntimeError::DivisionByZero => write!(f, "Division by zero"),
|
||||
RuntimeError::IncompleteDynamicRange => write!(f, "Dynamic comparison is incomplete"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -716,7 +720,6 @@ impl<'ast, T> Conditional<'ast, T> for UExpression<'ast, T> {
|
|||
.annotate(bitwidth)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Select<'ast, T>: Sized {
|
||||
fn select(array: Vec<Self>, index: UExpression<'ast, T>) -> Self;
|
||||
}
|
||||
|
@ -745,7 +748,6 @@ impl<'ast, T> Select<'ast, T> for UExpression<'ast, T> {
|
|||
UExpressionInner::Select(SelectExpression::new(array, index)).annotate(bitwidth)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoType {
|
||||
fn into_type(self) -> Type;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
## Functions
|
||||
|
||||
Functions are declared using the `def` keyword. A function's signature has to be explicitly provided.
|
||||
Its arguments are type annotated, just like variables, and, if the function returns a value,
|
||||
the return type must be specified after an arrow `->`.
|
||||
|
||||
A function has to be declared at the top level before it is called.
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/function_declaration.zok}}
|
||||
```
|
||||
|
||||
A function's signature has to be explicitly provided.
|
||||
|
||||
A function can be generic over any number of values of type `u32`.
|
||||
|
||||
```zokrates
|
||||
|
@ -18,4 +20,10 @@ The generic parameters can be provided explicitly, especially when they cannot b
|
|||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/explicit_generic_parameters.zok}}
|
||||
```
|
||||
|
||||
If the return type of a function is the empty tuple `()`, the return type as well as the return statement can be omitted.
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/no_return.zok}}
|
||||
```
|
|
@ -50,6 +50,7 @@ zokrates_solidity_test = { version = "0.1", path = "../zokrates_solidity_test",
|
|||
ethabi = "17.0.0"
|
||||
primitive-types = { version = "0.11", features = ["rlp"] }
|
||||
fs_extra = "1.1.0"
|
||||
pretty_assertions = "1.2.1"
|
||||
|
||||
[build-dependencies]
|
||||
fs_extra = "1.1.0"
|
||||
|
|
1
zokrates_cli/examples/book/no_return.zok
Normal file
1
zokrates_cli/examples/book/no_return.zok
Normal file
|
@ -0,0 +1 @@
|
|||
def main() {}
|
|
@ -1,5 +1 @@
|
|||
def foo() {}
|
||||
|
||||
def main() {
|
||||
return;
|
||||
}
|
||||
def main() -> field {}
|
|
@ -4,9 +4,10 @@ from "field" import FIELD_SIZE_IN_BITS;
|
|||
// It should not work for the maxvalue = 2^(pbits - 2) - 1 augmented by one
|
||||
// /!\ should be called with a = 0
|
||||
|
||||
def main(field a) -> bool {
|
||||
def main(field a) {
|
||||
u32 pbits = FIELD_SIZE_IN_BITS;
|
||||
// we added a = 0 to prevent the condition to be evaluated at compile time
|
||||
field maxvalue = a + (2**(pbits - 2) - 1);
|
||||
return a < maxvalue + 1;
|
||||
bool c = a < maxvalue + 1;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,10 @@ from "field" import FIELD_SIZE_IN_BITS;
|
|||
// It should not work for the maxvalue = 2^(pbits - 2) - 1 augmented by one
|
||||
// /!\ should be called with a = 0
|
||||
|
||||
def main(field a) -> bool {
|
||||
def main(field a) {
|
||||
u32 pbits = FIELD_SIZE_IN_BITS;
|
||||
// we added a = 0 to prevent the condition to be evaluated at compile time
|
||||
field maxvalue = a + (2**(pbits - 2) - 1);
|
||||
return maxvalue + 1 < a;
|
||||
bool c = maxvalue + 1 < a;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -523,7 +523,7 @@
|
|||
|
||||
(= (mod (* (+ (* |~one| 14651237294507013008273219182214280847718990358813499091232105186081237893121) (* |_0| 1) (* |_1| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (* |_258| 1)) |~prime|) (mod (* |_257| 1) |~prime|))
|
||||
(= (mod (* (+ (* |~one| 1) (* |_257| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (+ (* |~one| 14651237294507013008273219182214280847718990358813499091232105186081237893121) (* |_0| 1) (* |_1| 21888242871839275222246405745257275088548364400416034343698204186575808495616))) |~prime|) (mod 0 |~prime|))
|
||||
(= (mod (* (* |~one| 1) 0) |~prime|) (mod (+ (* |~one| 1) (* |_257| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) |~prime|))
|
||||
(= (mod (* (* |~one| 1) (* |~one| 1)) |~prime|) (mod (* |_257| 1) |~prime|))
|
||||
(= (mod (* (* |_2| 1) (+ (* |_0| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_1| 1))) |~prime|) (mod (* |_264| 1) |~prime|))
|
||||
(= (mod (* (* |~one| 1) (* |_264| 1)) |~prime|) (mod (* |~out_0| 1) |~prime|))
|
||||
))
|
|
@ -10,6 +10,7 @@ extern crate zokrates_solidity_test;
|
|||
mod integration {
|
||||
use fs_extra::copy_items;
|
||||
use fs_extra::dir::CopyOptions;
|
||||
use pretty_assertions::assert_eq;
|
||||
use primitive_types::U256;
|
||||
use serde_json::from_reader;
|
||||
use std::fs;
|
||||
|
@ -452,6 +453,8 @@ mod integration {
|
|||
program_path: &Path,
|
||||
expected_smtlib2_path: &Path,
|
||||
) {
|
||||
println!("test smtlib2 for {}", program_path.display());
|
||||
|
||||
let tmp_dir = TempDir::new(program_name).unwrap();
|
||||
let tmp_base = tmp_dir.path();
|
||||
let test_case_path = tmp_base.join(program_name);
|
||||
|
|
|
@ -280,9 +280,29 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
a: &[FlatExpression<T>],
|
||||
b: &[bool],
|
||||
) -> Vec<FlatExpression<T>> {
|
||||
let len = b.len();
|
||||
assert_eq!(a.len(), b.len());
|
||||
|
||||
let is_power_of_two_minus_one = b.iter().all(|b| *b);
|
||||
|
||||
// if `b` is all ones, then the check is always verified because that's the maximum possible value
|
||||
if is_power_of_two_minus_one {
|
||||
let statements: Vec<_> = a
|
||||
.iter()
|
||||
.map(|e| {
|
||||
let e_id = self.define(e.clone(), statements_flattened);
|
||||
FlatStatement::Condition(
|
||||
e_id.into(),
|
||||
FlatExpression::Mult(box e_id.into(), box e_id.into()),
|
||||
RuntimeError::Bitness,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
statements_flattened.extend(statements);
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let len = b.len();
|
||||
|
||||
let mut is_not_smaller_run = vec![];
|
||||
let mut size_unknown = vec![];
|
||||
|
||||
|
@ -778,66 +798,17 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
|
||||
let sub_width = bit_width + 1;
|
||||
|
||||
// define variables for the bits
|
||||
let shifted_sub_bits_be: Vec<Variable> =
|
||||
(0..sub_width).map(|_| self.use_sym()).collect();
|
||||
|
||||
// add a directive to get the bits
|
||||
statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new(
|
||||
shifted_sub_bits_be.clone(),
|
||||
Solver::bits(sub_width),
|
||||
vec![shifted_sub.clone()],
|
||||
)));
|
||||
|
||||
// bitness checks
|
||||
for bit in shifted_sub_bits_be.iter() {
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(*bit),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Identifier(*bit),
|
||||
),
|
||||
RuntimeError::LtFinalBitness,
|
||||
));
|
||||
}
|
||||
|
||||
// sum(sym_b{i} * 2**i)
|
||||
let mut expr = FlatExpression::Number(T::from(0));
|
||||
|
||||
for (i, bit) in shifted_sub_bits_be.iter().take(sub_width).enumerate() {
|
||||
expr = FlatExpression::Add(
|
||||
box expr,
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Number(T::from(2).pow(sub_width - i - 1)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
shifted_sub,
|
||||
expr,
|
||||
RuntimeError::LtFinalSum,
|
||||
));
|
||||
|
||||
// to make this check symetric, we ban the value `a - b == -2**N`, as the value `a - b == 2**N` is already banned
|
||||
let fail = self.eq_check(
|
||||
let shifted_sub_bits_be = self.get_bits_unchecked(
|
||||
&FlatUExpression::with_field(shifted_sub),
|
||||
sub_width,
|
||||
sub_width,
|
||||
statements_flattened,
|
||||
FlatExpression::Sub(
|
||||
box FlatExpression::Identifier(rhs_id),
|
||||
box FlatExpression::Identifier(lhs_id),
|
||||
),
|
||||
FlatExpression::Number(T::from(2).pow(bit_width)),
|
||||
RuntimeError::IncompleteDynamicRange,
|
||||
);
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
fail,
|
||||
FlatExpression::Number(T::from(0)),
|
||||
RuntimeError::LtSymetric,
|
||||
));
|
||||
|
||||
FlatExpression::Sub(
|
||||
box FlatExpression::Number(T::one()),
|
||||
box FlatExpression::Identifier(shifted_sub_bits_be[0]),
|
||||
box shifted_sub_bits_be[0].clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1351,24 +1322,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
FlatExpression::Identifier(id)
|
||||
};
|
||||
|
||||
// first check that the d is not 0 by giving its inverse
|
||||
let invd = self.use_sym();
|
||||
|
||||
// # invd = 1/d
|
||||
statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new(
|
||||
vec![invd],
|
||||
Solver::Div,
|
||||
vec![FlatExpression::Number(T::one()), d.clone()],
|
||||
)));
|
||||
|
||||
// assert(invd * d == 1)
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
FlatExpression::Number(T::one()),
|
||||
FlatExpression::Mult(box invd.into(), box d.clone()),
|
||||
RuntimeError::Inverse,
|
||||
));
|
||||
|
||||
// now introduce the quotient and remainder
|
||||
// introduce the quotient and remainder
|
||||
let q = self.use_sym();
|
||||
let r = self.use_sym();
|
||||
|
||||
|
@ -2163,23 +2117,11 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
id.into()
|
||||
};
|
||||
|
||||
let invb = self.use_sym();
|
||||
// `right` is assumed to already be non-zero so this is an unchecked division
|
||||
// TODO: we could save one constraint here by reusing the inverse of `right` computed earlier
|
||||
|
||||
let inverse = self.use_sym();
|
||||
|
||||
// # invb = 1/b
|
||||
statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new(
|
||||
vec![invb],
|
||||
Solver::Div,
|
||||
vec![FlatExpression::Number(T::one()), new_right.clone()],
|
||||
)));
|
||||
|
||||
// assert(invb * b == 1)
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
FlatExpression::Number(T::one()),
|
||||
FlatExpression::Mult(box invb.into(), box new_right.clone()),
|
||||
RuntimeError::Inverse,
|
||||
));
|
||||
|
||||
// # c = a/b
|
||||
statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new(
|
||||
vec![inverse],
|
||||
|
@ -2458,6 +2400,40 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
BooleanExpression::UintLe(box lhs, box rhs) => {
|
||||
let lhs = self
|
||||
.flatten_uint_expression(statements_flattened, lhs)
|
||||
.get_field_unchecked();
|
||||
let rhs = self
|
||||
.flatten_uint_expression(statements_flattened, rhs)
|
||||
.get_field_unchecked();
|
||||
|
||||
match (lhs, rhs) {
|
||||
(e, FlatExpression::Number(c)) => self.enforce_constant_le_check(
|
||||
statements_flattened,
|
||||
e,
|
||||
c,
|
||||
error.into(),
|
||||
),
|
||||
// c <= e <=> p - 1 - e <= p - 1 - c
|
||||
(FlatExpression::Number(c), e) => self.enforce_constant_le_check(
|
||||
statements_flattened,
|
||||
FlatExpression::Sub(box T::max_value().into(), box e),
|
||||
T::max_value() - c,
|
||||
error.into(),
|
||||
),
|
||||
(lhs, rhs) => {
|
||||
let bit_width = T::get_required_bits();
|
||||
let safe_width = bit_width - 2; // dynamic comparison is not complete
|
||||
let e = self.le_check(statements_flattened, lhs, rhs, safe_width);
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
e,
|
||||
FlatExpression::Number(T::one()),
|
||||
error.into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
BooleanExpression::UintEq(box lhs, box rhs) => {
|
||||
let lhs = self
|
||||
.flatten_uint_expression(statements_flattened, lhs)
|
||||
|
@ -2484,6 +2460,80 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
error.into(),
|
||||
)
|
||||
}
|
||||
// `!(x == 0)` can be asserted by giving the inverse of `x`
|
||||
BooleanExpression::Not(box BooleanExpression::UintEq(
|
||||
box UExpression {
|
||||
inner: UExpressionInner::Value(0),
|
||||
..
|
||||
},
|
||||
box x,
|
||||
))
|
||||
| BooleanExpression::Not(box BooleanExpression::UintEq(
|
||||
box x,
|
||||
box UExpression {
|
||||
inner: UExpressionInner::Value(0),
|
||||
..
|
||||
},
|
||||
)) => {
|
||||
let x = self
|
||||
.flatten_uint_expression(statements_flattened, x)
|
||||
.get_field_unchecked();
|
||||
|
||||
// introduce intermediate variable
|
||||
let x_id = self.define(x, statements_flattened);
|
||||
|
||||
// check that `x` is not 0 by giving its inverse
|
||||
let invx = self.use_sym();
|
||||
|
||||
// # invx = 1/x
|
||||
statements_flattened.push_back(FlatStatement::Directive(
|
||||
FlatDirective::new(
|
||||
vec![invx],
|
||||
Solver::Div,
|
||||
vec![FlatExpression::Number(T::one()), x_id.into()],
|
||||
),
|
||||
));
|
||||
|
||||
// assert(invx * x == 1)
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
FlatExpression::Number(T::one()),
|
||||
FlatExpression::Mult(box invx.into(), box x_id.into()),
|
||||
RuntimeError::Inverse,
|
||||
));
|
||||
}
|
||||
// `!(x == 0)` can be asserted by giving the inverse of `x`
|
||||
BooleanExpression::Not(box BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Number(zero),
|
||||
box x,
|
||||
))
|
||||
| BooleanExpression::Not(box BooleanExpression::FieldEq(
|
||||
box x,
|
||||
box FieldElementExpression::Number(zero),
|
||||
)) if zero == T::from(0) => {
|
||||
let x = self.flatten_field_expression(statements_flattened, x);
|
||||
|
||||
// introduce intermediate variable
|
||||
let x_id = self.define(x, statements_flattened);
|
||||
|
||||
// check that `x` is not 0 by giving its inverse
|
||||
let invx = self.use_sym();
|
||||
|
||||
// # invx = 1/x
|
||||
statements_flattened.push_back(FlatStatement::Directive(
|
||||
FlatDirective::new(
|
||||
vec![invx],
|
||||
Solver::Div,
|
||||
vec![FlatExpression::Number(T::one()), x_id.into()],
|
||||
),
|
||||
));
|
||||
|
||||
// assert(invx * x == 1)
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
FlatExpression::Number(T::one()),
|
||||
FlatExpression::Mult(box invx.into(), box x_id.into()),
|
||||
RuntimeError::Inverse,
|
||||
));
|
||||
}
|
||||
e => {
|
||||
// naive approach: flatten the boolean to a single field element and constrain it to 1
|
||||
let e = self.flatten_boolean_expression(statements_flattened, e);
|
||||
|
@ -3580,18 +3630,14 @@ mod tests {
|
|||
// define new wires for members of Div
|
||||
let five = Variable::new(1);
|
||||
let b0 = Variable::new(2);
|
||||
// Define inverse of denominator to prevent div by 0
|
||||
let invb0 = Variable::new(3);
|
||||
// Define inverse
|
||||
let sym_0 = Variable::new(4);
|
||||
let sym_0 = Variable::new(3);
|
||||
// Define result, which is first member to next Div
|
||||
let sym_1 = Variable::new(5);
|
||||
let sym_1 = Variable::new(4);
|
||||
// Define second member
|
||||
let b1 = Variable::new(6);
|
||||
// Define inverse of denominator to prevent div by 0
|
||||
let invb1 = Variable::new(7);
|
||||
let b1 = Variable::new(5);
|
||||
// Define inverse
|
||||
let sym_2 = Variable::new(8);
|
||||
let sym_2 = Variable::new(6);
|
||||
|
||||
assert_eq!(
|
||||
statements_flattened,
|
||||
|
@ -3600,17 +3646,6 @@ mod tests {
|
|||
// inputs to first div (5/b)
|
||||
FlatStatement::Definition(five, FlatExpression::Number(Bn128Field::from(5))),
|
||||
FlatStatement::Definition(b0, b.into()),
|
||||
// check div by 0
|
||||
FlatStatement::Directive(FlatDirective::new(
|
||||
vec![invb0],
|
||||
Solver::Div,
|
||||
vec![FlatExpression::Number(Bn128Field::from(1)), b0.into()]
|
||||
)),
|
||||
FlatStatement::Condition(
|
||||
FlatExpression::Number(Bn128Field::from(1)),
|
||||
FlatExpression::Mult(box invb0.into(), box b0.into()),
|
||||
RuntimeError::Inverse,
|
||||
),
|
||||
// execute div
|
||||
FlatStatement::Directive(FlatDirective::new(
|
||||
vec![sym_0],
|
||||
|
@ -3625,17 +3660,6 @@ mod tests {
|
|||
// inputs to second div (res/b)
|
||||
FlatStatement::Definition(sym_1, sym_0.into()),
|
||||
FlatStatement::Definition(b1, b.into()),
|
||||
// check div by 0
|
||||
FlatStatement::Directive(FlatDirective::new(
|
||||
vec![invb1],
|
||||
Solver::Div,
|
||||
vec![FlatExpression::Number(Bn128Field::from(1)), b1.into()]
|
||||
)),
|
||||
FlatStatement::Condition(
|
||||
FlatExpression::Number(Bn128Field::from(1)),
|
||||
FlatExpression::Mult(box invb1.into(), box b1.into()),
|
||||
RuntimeError::Inverse
|
||||
),
|
||||
// execute div
|
||||
FlatStatement::Directive(FlatDirective::new(
|
||||
vec![sym_2],
|
||||
|
|
|
@ -1204,10 +1204,16 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
}
|
||||
|
||||
if !found_return {
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: "Expected a return statement".to_string(),
|
||||
});
|
||||
match (&*s.output).is_empty_tuple() {
|
||||
true => statements_checked
|
||||
.push(TypedStatement::Return(TypedExpression::empty_tuple())),
|
||||
false => {
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: "Expected a return statement".to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signature = Some(s);
|
||||
|
@ -1843,11 +1849,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
}
|
||||
.map_err(|e| vec![e])
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
Ok(TupleExpressionInner::Value(vec![])
|
||||
.annotate(TupleType::new(vec![]))
|
||||
.into())
|
||||
})?;
|
||||
.unwrap_or_else(|| Ok(TypedExpression::empty_tuple()))?;
|
||||
|
||||
let res = match TypedExpression::align_to_type(e_checked.clone(), &return_type)
|
||||
.map_err(|e| {
|
||||
|
@ -1939,7 +1941,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
var_ty
|
||||
),
|
||||
})
|
||||
.map(|e| TypedStatement::Definition(var.into(), e))
|
||||
.map(|e| TypedStatement::Definition(var.into(), e.into()))
|
||||
.map_err(|e| vec![e])
|
||||
}
|
||||
Statement::Assignment(assignee, expr) => {
|
||||
|
@ -1986,7 +1988,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
assignee_ty
|
||||
),
|
||||
})
|
||||
.map(|e| TypedStatement::Definition(assignee, e))
|
||||
.map(|e| TypedStatement::Definition(assignee, e.into()))
|
||||
.map_err(|e| vec![e])
|
||||
}
|
||||
Statement::Assertion(e, message) => {
|
||||
|
@ -4483,7 +4485,7 @@ mod tests {
|
|||
checker.enter_scope();
|
||||
assert_eq!(
|
||||
checker.check_statement(statement, &*MODULE_ID, &TypeMap::new()),
|
||||
Ok(TypedStatement::Definition(
|
||||
Ok(TypedStatement::definition(
|
||||
typed::Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("b".into()).into()
|
||||
))
|
||||
|
@ -4712,7 +4714,7 @@ mod tests {
|
|||
Statement::Return(None).mock(),
|
||||
];
|
||||
|
||||
let for_statements_checked = vec![TypedStatement::Definition(
|
||||
let for_statements_checked = vec![TypedStatement::definition(
|
||||
typed::Variable::uint(
|
||||
CoreIdentifier::Source(ShadowedIdentifier::shadow("a", 1)),
|
||||
UBitwidth::B32,
|
||||
|
@ -4735,11 +4737,7 @@ mod tests {
|
|||
10u32.into(),
|
||||
for_statements_checked,
|
||||
),
|
||||
TypedStatement::Return(
|
||||
TupleExpressionInner::Value(vec![])
|
||||
.annotate(TupleType::new(vec![]))
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Return(TypedExpression::empty_tuple()),
|
||||
];
|
||||
|
||||
let foo = Function {
|
||||
|
@ -5334,7 +5332,7 @@ mod tests {
|
|||
];
|
||||
|
||||
let expected = vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
typed::Variable::new(
|
||||
CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)),
|
||||
Type::FieldElement,
|
||||
|
@ -5352,7 +5350,7 @@ mod tests {
|
|||
0u32.into(),
|
||||
0u32.into(),
|
||||
vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
typed::Variable::new(
|
||||
CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)),
|
||||
Type::FieldElement,
|
||||
|
@ -5361,7 +5359,7 @@ mod tests {
|
|||
.into(),
|
||||
FieldElementExpression::Number(3.into()).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
typed::Variable::new(
|
||||
CoreIdentifier::from(ShadowedIdentifier::shadow("a", 1)),
|
||||
Type::FieldElement,
|
||||
|
@ -5372,7 +5370,7 @@ mod tests {
|
|||
),
|
||||
],
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
typed::Variable::new(
|
||||
CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)),
|
||||
Type::FieldElement,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use zokrates_ast::typed::{
|
||||
folder::*, BlockExpression, BooleanExpression, Conditional, ConditionalExpression,
|
||||
ConditionalOrExpression, CoreIdentifier, Expr, Identifier, Type, TypedProgram, TypedStatement,
|
||||
Variable,
|
||||
ConditionalOrExpression, CoreIdentifier, Expr, Identifier, Type, TypedExpression, TypedProgram,
|
||||
TypedStatement, Variable,
|
||||
};
|
||||
use zokrates_field::Field;
|
||||
|
||||
|
@ -65,9 +65,9 @@ impl<'ast, T: Field> Folder<'ast, T> for ConditionRedefiner<'ast, T> {
|
|||
| condition @ BooleanExpression::Identifier(_) => condition,
|
||||
condition => {
|
||||
let condition_id = Identifier::from(CoreIdentifier::Condition(self.index));
|
||||
self.buffer.push(TypedStatement::Definition(
|
||||
self.buffer.push(TypedStatement::definition(
|
||||
Variable::immutable(condition_id.clone(), Type::Boolean).into(),
|
||||
condition.into(),
|
||||
TypedExpression::from(condition),
|
||||
));
|
||||
self.index += 1;
|
||||
BooleanExpression::Identifier(condition_id)
|
||||
|
@ -99,7 +99,7 @@ mod tests {
|
|||
// field foo = if true { 1 } else { 2 };
|
||||
// should be left unchanged
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
Variable::field_element("foo").into(),
|
||||
FieldElementExpression::conditional(
|
||||
BooleanExpression::Value(true),
|
||||
|
@ -120,7 +120,7 @@ mod tests {
|
|||
// field foo = if c { 1 } else { 2 };
|
||||
// should be left unchanged
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
Variable::field_element("foo").into(),
|
||||
FieldElementExpression::conditional(
|
||||
BooleanExpression::Identifier("c".into()),
|
||||
|
@ -148,7 +148,7 @@ mod tests {
|
|||
box BooleanExpression::Identifier("d".into()),
|
||||
);
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
Variable::field_element("foo").into(),
|
||||
FieldElementExpression::conditional(
|
||||
condition.clone(),
|
||||
|
@ -163,12 +163,12 @@ mod tests {
|
|||
|
||||
let expected = vec![
|
||||
// define condition
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(),
|
||||
condition.into(),
|
||||
),
|
||||
// rewrite statement
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("foo").into(),
|
||||
FieldElementExpression::conditional(
|
||||
BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()),
|
||||
|
@ -212,7 +212,7 @@ mod tests {
|
|||
box BooleanExpression::Identifier("f".into()),
|
||||
);
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
Variable::field_element("foo").into(),
|
||||
FieldElementExpression::conditional(
|
||||
condition_0.clone(),
|
||||
|
@ -232,16 +232,16 @@ mod tests {
|
|||
|
||||
let expected = vec![
|
||||
// define conditions
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(),
|
||||
condition_0.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::immutable(CoreIdentifier::Condition(1), Type::Boolean).into(),
|
||||
condition_1.into(),
|
||||
),
|
||||
// rewrite statement
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("foo").into(),
|
||||
FieldElementExpression::conditional(
|
||||
BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()),
|
||||
|
@ -303,12 +303,12 @@ mod tests {
|
|||
let condition_id_1 = BooleanExpression::Identifier(CoreIdentifier::Condition(1).into());
|
||||
let condition_id_2 = BooleanExpression::Identifier(CoreIdentifier::Condition(2).into());
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
Variable::field_element("foo").into(),
|
||||
FieldElementExpression::conditional(
|
||||
condition_0.clone(),
|
||||
FieldElementExpression::block(
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Number(Bn128Field::from(1)).into(),
|
||||
)],
|
||||
|
@ -320,7 +320,7 @@ mod tests {
|
|||
),
|
||||
),
|
||||
FieldElementExpression::block(
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
Variable::field_element("b").into(),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
)],
|
||||
|
@ -340,22 +340,22 @@ mod tests {
|
|||
|
||||
let expected = vec![
|
||||
// define conditions
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(),
|
||||
condition_0.into(),
|
||||
),
|
||||
// rewrite statement
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("foo").into(),
|
||||
FieldElementExpression::conditional(
|
||||
condition_id_0.clone(),
|
||||
FieldElementExpression::block(
|
||||
vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Number(Bn128Field::from(1)).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::immutable(CoreIdentifier::Condition(1), Type::Boolean)
|
||||
.into(),
|
||||
condition_1.into(),
|
||||
|
@ -370,11 +370,11 @@ mod tests {
|
|||
),
|
||||
FieldElementExpression::block(
|
||||
vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("b").into(),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::immutable(CoreIdentifier::Condition(2), Type::Boolean)
|
||||
.into(),
|
||||
condition_2.into(),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use std::fmt;
|
||||
use zokrates_ast::common::FlatEmbed;
|
||||
use zokrates_ast::typed::TypedProgram;
|
||||
use zokrates_ast::typed::{
|
||||
result_folder::ResultFolder,
|
||||
result_folder::{fold_statement, fold_uint_expression_inner},
|
||||
Constant, EmbedCall, TypedStatement, UBitwidth, UExpressionInner,
|
||||
};
|
||||
use zokrates_ast::typed::{DefinitionRhs, TypedProgram};
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub struct ConstantArgumentChecker;
|
||||
|
@ -33,37 +33,41 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantArgumentChecker {
|
|||
s: TypedStatement<'ast, T>,
|
||||
) -> Result<Vec<TypedStatement<'ast, T>>, Self::Error> {
|
||||
match s {
|
||||
TypedStatement::EmbedCallDefinition(assignee, embed_call) => match embed_call {
|
||||
EmbedCall {
|
||||
embed: FlatEmbed::BitArrayLe,
|
||||
..
|
||||
} => {
|
||||
let arguments = embed_call
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|a| self.fold_expression(a))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
TypedStatement::Definition(assignee, DefinitionRhs::EmbedCall(embed_call)) => {
|
||||
match embed_call {
|
||||
EmbedCall {
|
||||
embed: FlatEmbed::BitArrayLe,
|
||||
..
|
||||
} => {
|
||||
let arguments = embed_call
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|a| self.fold_expression(a))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
if arguments[1].is_constant() {
|
||||
Ok(vec![TypedStatement::EmbedCallDefinition(
|
||||
assignee,
|
||||
EmbedCall {
|
||||
embed: FlatEmbed::BitArrayLe,
|
||||
generics: embed_call.generics,
|
||||
arguments,
|
||||
},
|
||||
)])
|
||||
} else {
|
||||
Err(Error(format!(
|
||||
"Cannot compare to a variable value, found `{}`",
|
||||
arguments[1]
|
||||
)))
|
||||
if arguments[1].is_constant() {
|
||||
Ok(vec![TypedStatement::Definition(
|
||||
assignee,
|
||||
EmbedCall {
|
||||
embed: FlatEmbed::BitArrayLe,
|
||||
generics: embed_call.generics,
|
||||
arguments,
|
||||
}
|
||||
.into(),
|
||||
)])
|
||||
} else {
|
||||
Err(Error(format!(
|
||||
"Cannot compare to a variable value, found `{}`",
|
||||
arguments[1]
|
||||
)))
|
||||
}
|
||||
}
|
||||
embed_call => Ok(vec![TypedStatement::Definition(
|
||||
assignee,
|
||||
embed_call.into(),
|
||||
)]),
|
||||
}
|
||||
embed_call => Ok(vec![TypedStatement::EmbedCallDefinition(
|
||||
assignee, embed_call,
|
||||
)]),
|
||||
},
|
||||
}
|
||||
s => fold_statement(self, s),
|
||||
}
|
||||
}
|
||||
|
|
68
zokrates_core/src/static_analysis/dead_code.rs
Normal file
68
zokrates_core/src/static_analysis/dead_code.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use std::collections::HashSet;
|
||||
use zokrates_ast::zir::{folder::*, Identifier, ZirFunction, ZirProgram, ZirStatement};
|
||||
use zokrates_field::Field;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DeadCodeEliminator<'ast> {
|
||||
used: HashSet<Identifier<'ast>>,
|
||||
}
|
||||
|
||||
impl<'ast> DeadCodeEliminator<'ast> {
|
||||
pub fn eliminate<T: Field>(p: ZirProgram<'ast, T>) -> ZirProgram<'ast, T> {
|
||||
Self::default().fold_program(p)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Folder<'ast, T> for DeadCodeEliminator<'ast> {
|
||||
fn fold_function(&mut self, f: ZirFunction<'ast, T>) -> ZirFunction<'ast, T> {
|
||||
// iterate on the statements starting from the end, as we want to see usage before definition
|
||||
let mut statements: Vec<_> = f
|
||||
.statements
|
||||
.into_iter()
|
||||
.rev()
|
||||
.flat_map(|s| self.fold_statement(s))
|
||||
.collect();
|
||||
statements.reverse();
|
||||
ZirFunction { statements, ..f }
|
||||
}
|
||||
|
||||
fn fold_statement(&mut self, s: ZirStatement<'ast, T>) -> Vec<ZirStatement<'ast, T>> {
|
||||
match s {
|
||||
ZirStatement::Definition(v, e) => {
|
||||
// if the lhs is used later in the program
|
||||
if self.used.remove(&v.id) {
|
||||
// include this statement
|
||||
fold_statement(self, ZirStatement::Definition(v, e))
|
||||
} else {
|
||||
// otherwise remove it
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
ZirStatement::IfElse(condition, consequence, alternative) => {
|
||||
let condition = self.fold_boolean_expression(condition);
|
||||
|
||||
let mut consequence: Vec<_> = consequence
|
||||
.into_iter()
|
||||
.rev()
|
||||
.flat_map(|e| self.fold_statement(e))
|
||||
.collect();
|
||||
consequence.reverse();
|
||||
|
||||
let mut alternative: Vec<_> = alternative
|
||||
.into_iter()
|
||||
.rev()
|
||||
.flat_map(|e| self.fold_statement(e))
|
||||
.collect();
|
||||
alternative.reverse();
|
||||
|
||||
vec![ZirStatement::IfElse(condition, consequence, alternative)]
|
||||
}
|
||||
s => fold_statement(self, s),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_name(&mut self, n: Identifier<'ast>) -> Identifier<'ast> {
|
||||
self.used.insert(n.clone());
|
||||
n
|
||||
}
|
||||
}
|
|
@ -402,7 +402,7 @@ fn fold_statement<'ast, T: Field>(
|
|||
typed::TypedStatement::Return(expression) => vec![zir::ZirStatement::Return(
|
||||
f.fold_expression(statements_buffer, expression),
|
||||
)],
|
||||
typed::TypedStatement::Definition(a, e) => {
|
||||
typed::TypedStatement::Definition(a, typed::DefinitionRhs::Expression(e)) => {
|
||||
let a = f.fold_assignee(a);
|
||||
let e = f.fold_expression(statements_buffer, e);
|
||||
assert_eq!(a.len(), e.len());
|
||||
|
@ -418,10 +418,14 @@ fn fold_statement<'ast, T: Field>(
|
|||
zir::RuntimeError::SourceAssertion(metadata.to_string())
|
||||
}
|
||||
typed::RuntimeError::SelectRangeCheck => zir::RuntimeError::SelectRangeCheck,
|
||||
typed::RuntimeError::DivisionByZero => zir::RuntimeError::DivisionByZero,
|
||||
};
|
||||
vec![zir::ZirStatement::Assertion(e, error)]
|
||||
}
|
||||
typed::TypedStatement::EmbedCallDefinition(assignee, embed_call) => {
|
||||
typed::TypedStatement::Definition(
|
||||
assignee,
|
||||
typed::DefinitionRhs::EmbedCall(embed_call),
|
||||
) => {
|
||||
vec![zir::ZirStatement::MultipleDefinition(
|
||||
f.fold_assignee(assignee),
|
||||
zir::ZirExpressionList::EmbedCall(
|
||||
|
|
|
@ -8,10 +8,12 @@ mod branch_isolator;
|
|||
mod condition_redefiner;
|
||||
mod constant_argument_checker;
|
||||
mod constant_resolver;
|
||||
mod dead_code;
|
||||
mod flat_propagation;
|
||||
mod flatten_complex_types;
|
||||
mod log_ignorer;
|
||||
mod out_of_bounds;
|
||||
mod panic_extractor;
|
||||
mod propagation;
|
||||
mod reducer;
|
||||
mod struct_concretizer;
|
||||
|
@ -32,6 +34,8 @@ use self::uint_optimizer::UintOptimizer;
|
|||
use self::variable_write_remover::VariableWriteRemover;
|
||||
use crate::compile::CompileConfig;
|
||||
use crate::static_analysis::constant_resolver::ConstantResolver;
|
||||
use crate::static_analysis::dead_code::DeadCodeEliminator;
|
||||
use crate::static_analysis::panic_extractor::PanicExtractor;
|
||||
use crate::static_analysis::zir_propagation::ZirPropagator;
|
||||
use std::fmt;
|
||||
use zokrates_ast::typed::{abi::Abi, TypedProgram};
|
||||
|
@ -172,6 +176,14 @@ pub fn analyse<'ast, T: Field>(
|
|||
let zir = ZirPropagator::propagate(zir).map_err(Error::from)?;
|
||||
log::trace!("\n{}", zir);
|
||||
|
||||
log::debug!("Static analyser: Extract panics");
|
||||
let zir = PanicExtractor::extract(zir);
|
||||
log::trace!("\n{}", zir);
|
||||
|
||||
log::debug!("Static analyser: Remove dead code");
|
||||
let zir = DeadCodeEliminator::eliminate(zir);
|
||||
log::trace!("\n{}", zir);
|
||||
|
||||
// optimize uint expressions
|
||||
log::debug!("Static analyser: Optimize uints");
|
||||
let zir = UintOptimizer::optimize(zir);
|
||||
|
|
190
zokrates_core/src/static_analysis/panic_extractor.rs
Normal file
190
zokrates_core/src/static_analysis/panic_extractor.rs
Normal file
|
@ -0,0 +1,190 @@
|
|||
use zokrates_ast::zir::{
|
||||
folder::*, BooleanExpression, Conditional, ConditionalExpression, ConditionalOrExpression,
|
||||
FieldElementExpression, RuntimeError, UBitwidth, UExpressionInner, ZirProgram, ZirStatement,
|
||||
};
|
||||
use zokrates_field::Field;
|
||||
|
||||
// a static analyser pass to extract the failure modes into separate assert statements, so that a statement can panic iff it's an assertion
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PanicExtractor<'ast, T> {
|
||||
panic_buffer: Vec<ZirStatement<'ast, T>>,
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> PanicExtractor<'ast, T> {
|
||||
pub fn extract(p: ZirProgram<'ast, T>) -> ZirProgram<'ast, T> {
|
||||
Self::default().fold_program(p)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Folder<'ast, T> for PanicExtractor<'ast, T> {
|
||||
fn fold_statement(&mut self, s: ZirStatement<'ast, T>) -> Vec<ZirStatement<'ast, T>> {
|
||||
match s {
|
||||
ZirStatement::IfElse(condition, consequence, alternative) => {
|
||||
let condition = self.fold_boolean_expression(condition);
|
||||
let mut consequence_extractor = Self::default();
|
||||
let consequence = consequence
|
||||
.into_iter()
|
||||
.flat_map(|s| consequence_extractor.fold_statement(s))
|
||||
.collect();
|
||||
assert!(consequence_extractor.panic_buffer.is_empty());
|
||||
let mut alternative_extractor = Self::default();
|
||||
let alternative = alternative
|
||||
.into_iter()
|
||||
.flat_map(|s| alternative_extractor.fold_statement(s))
|
||||
.collect();
|
||||
assert!(alternative_extractor.panic_buffer.is_empty());
|
||||
|
||||
self.panic_buffer
|
||||
.drain(..)
|
||||
.chain(std::iter::once(ZirStatement::IfElse(
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
)))
|
||||
.collect()
|
||||
}
|
||||
s => {
|
||||
let s = fold_statement(self, s);
|
||||
self.panic_buffer.drain(..).chain(s).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_field_expression(
|
||||
&mut self,
|
||||
e: FieldElementExpression<'ast, T>,
|
||||
) -> FieldElementExpression<'ast, T> {
|
||||
match e {
|
||||
FieldElementExpression::Div(box n, box d) => {
|
||||
let n = self.fold_field_expression(n);
|
||||
let d = self.fold_field_expression(d);
|
||||
self.panic_buffer.push(ZirStatement::Assertion(
|
||||
BooleanExpression::Not(box BooleanExpression::FieldEq(
|
||||
box d.clone(),
|
||||
box FieldElementExpression::Number(T::zero()),
|
||||
)),
|
||||
RuntimeError::DivisionByZero,
|
||||
));
|
||||
FieldElementExpression::Div(box n, box d)
|
||||
}
|
||||
e => fold_field_expression(self, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_conditional_expression<
|
||||
E: zokrates_ast::zir::Expr<'ast, T> + Fold<'ast, T> + Conditional<'ast, T>,
|
||||
>(
|
||||
&mut self,
|
||||
_: &E::Ty,
|
||||
e: ConditionalExpression<'ast, T, E>,
|
||||
) -> ConditionalOrExpression<'ast, T, E> {
|
||||
let condition = self.fold_boolean_expression(*e.condition);
|
||||
let mut consequence_extractor = Self::default();
|
||||
let consequence = e.consequence.fold(&mut consequence_extractor);
|
||||
let mut alternative_extractor = Self::default();
|
||||
let alternative = e.alternative.fold(&mut alternative_extractor);
|
||||
|
||||
let consequence_panics: Vec<_> = consequence_extractor.panic_buffer.drain(..).collect();
|
||||
let alternative_panics: Vec<_> = alternative_extractor.panic_buffer.drain(..).collect();
|
||||
|
||||
if !(consequence_panics.is_empty() && alternative_panics.is_empty()) {
|
||||
self.panic_buffer.push(ZirStatement::IfElse(
|
||||
condition.clone(),
|
||||
consequence_panics,
|
||||
alternative_panics,
|
||||
));
|
||||
}
|
||||
|
||||
ConditionalOrExpression::Conditional(ConditionalExpression::new(
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
))
|
||||
}
|
||||
|
||||
fn fold_uint_expression_inner(
|
||||
&mut self,
|
||||
b: UBitwidth,
|
||||
e: UExpressionInner<'ast, T>,
|
||||
) -> UExpressionInner<'ast, T> {
|
||||
match e {
|
||||
UExpressionInner::Div(box n, box d) => {
|
||||
let n = self.fold_uint_expression(n);
|
||||
let d = self.fold_uint_expression(d);
|
||||
self.panic_buffer.push(ZirStatement::Assertion(
|
||||
BooleanExpression::Not(box BooleanExpression::UintEq(
|
||||
box d.clone(),
|
||||
box UExpressionInner::Value(0).annotate(b),
|
||||
)),
|
||||
RuntimeError::DivisionByZero,
|
||||
));
|
||||
UExpressionInner::Div(box n, box d)
|
||||
}
|
||||
e => fold_uint_expression_inner(self, b, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_boolean_expression(
|
||||
&mut self,
|
||||
e: BooleanExpression<'ast, T>,
|
||||
) -> BooleanExpression<'ast, T> {
|
||||
match e {
|
||||
// constant range checks are complete, so no panic needs to be extracted
|
||||
e @ BooleanExpression::FieldLt(box FieldElementExpression::Number(_), _)
|
||||
| e @ BooleanExpression::FieldLt(_, box FieldElementExpression::Number(_)) => {
|
||||
fold_boolean_expression(self, e)
|
||||
}
|
||||
BooleanExpression::FieldLt(box left, box right) => {
|
||||
let left = self.fold_field_expression(left);
|
||||
let right = self.fold_field_expression(right);
|
||||
|
||||
let bit_width = T::get_required_bits();
|
||||
|
||||
let safe_width = bit_width - 2; // dynamic comparison is not complete, it only applies to field elements whose difference is strictly smaller than 2**(bitwidth - 2)
|
||||
|
||||
let offset = FieldElementExpression::Number(T::from(2).pow(safe_width));
|
||||
let max = FieldElementExpression::Number(T::from(2).pow(safe_width + 1));
|
||||
|
||||
// `|left - right|` must be of bitwidth at most `safe_bitwidth`
|
||||
// this means we need to guarantee the following: `-2**(safe_width) < left - right < 2**(safe_width)`
|
||||
// adding an offset of `2**(safe_width)` we turn this into:
|
||||
// require `0 < 2**(safe_width) + left - right < 2**(safe_width + 1)`
|
||||
|
||||
// we split this check in two:
|
||||
// `2**(safe_width) + left - right < 2**(safe_width + 1)`
|
||||
self.panic_buffer.push(ZirStatement::Assertion(
|
||||
BooleanExpression::FieldLt(
|
||||
box FieldElementExpression::Add(
|
||||
box offset.clone(),
|
||||
box FieldElementExpression::Sub(box left.clone(), box right.clone()),
|
||||
),
|
||||
box max,
|
||||
),
|
||||
RuntimeError::IncompleteDynamicRange,
|
||||
));
|
||||
|
||||
// and
|
||||
// `2**(safe_width) + left - right != 0`
|
||||
self.panic_buffer.push(ZirStatement::Assertion(
|
||||
BooleanExpression::Not(box BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Sub(box right.clone(), box left.clone()),
|
||||
box offset,
|
||||
)),
|
||||
RuntimeError::IncompleteDynamicRange,
|
||||
));
|
||||
|
||||
// NOTE:
|
||||
// instead of splitting the check in two, we could have used a single `Lt` here, by simply subtracting 1 from all sides:
|
||||
// `let x = 2**(safe_width) + left - right`
|
||||
// `0 <= x - 1 < 2**(safe_width + 1) - 1` which is a single constant `Lt`
|
||||
// however, the *result* of `left < right` requires knowing the bits of `x`
|
||||
// if we use `x - 1` here, we end up having to calculate the bits of both `x` and `x - 1`, which is expensive
|
||||
// by splitting, we can reuse the bits of `x` needed for this completeness check when computing the result
|
||||
|
||||
BooleanExpression::FieldLt(box left, box right)
|
||||
}
|
||||
e => fold_boolean_expression(self, e),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -221,9 +221,9 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
) -> Result<Vec<TypedStatement<'ast, T>>, Error> {
|
||||
match s {
|
||||
// propagation to the defined variable if rhs is a constant
|
||||
TypedStatement::Definition(assignee, expr) => {
|
||||
let expr = self.fold_expression(expr)?;
|
||||
TypedStatement::Definition(assignee, DefinitionRhs::Expression(expr)) => {
|
||||
let assignee = self.fold_assignee(assignee)?;
|
||||
let expr = self.fold_expression(expr)?;
|
||||
|
||||
if let (Ok(a), Ok(e)) = (
|
||||
ConcreteType::try_from(assignee.get_type()),
|
||||
|
@ -255,10 +255,10 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
// invalidate the cache for this identifier, and define the latest
|
||||
// version of the constant in the program, if any
|
||||
Some(c) => Ok(vec![
|
||||
TypedStatement::Definition(v.clone().into(), c),
|
||||
TypedStatement::Definition(assignee, expr),
|
||||
TypedStatement::Definition(v.clone().into(), c.into()),
|
||||
TypedStatement::Definition(assignee, expr.into()),
|
||||
]),
|
||||
None => Ok(vec![TypedStatement::Definition(assignee, expr)]),
|
||||
None => Ok(vec![TypedStatement::Definition(assignee, expr.into())]),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -271,10 +271,10 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
match self.constants.remove(&v.id) {
|
||||
Some(c) => Ok(vec![
|
||||
TypedStatement::Definition(v.clone().into(), c),
|
||||
TypedStatement::Definition(assignee, expr),
|
||||
TypedStatement::Definition(v.clone().into(), c.into()),
|
||||
TypedStatement::Definition(assignee, expr.into()),
|
||||
]),
|
||||
None => Ok(vec![TypedStatement::Definition(assignee, expr)]),
|
||||
None => Ok(vec![TypedStatement::Definition(assignee, expr.into())]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
Ok(vec![TypedStatement::For(v, from, to, statements)])
|
||||
}
|
||||
TypedStatement::EmbedCallDefinition(assignee, embed_call) => {
|
||||
TypedStatement::Definition(assignee, DefinitionRhs::EmbedCall(embed_call)) => {
|
||||
let assignee = self.fold_assignee(assignee)?;
|
||||
let embed_call = self.fold_embed_call(embed_call)?;
|
||||
|
||||
|
@ -299,37 +299,37 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
let argument = argument.into_canonical_constant();
|
||||
|
||||
match ArrayExpression::try_from(argument)
|
||||
.unwrap()
|
||||
.into_inner()
|
||||
{
|
||||
ArrayExpressionInner::Value(v) =>
|
||||
UExpressionInner::Value(
|
||||
v.into_iter()
|
||||
.map(|v| match v {
|
||||
TypedExpressionOrSpread::Expression(
|
||||
TypedExpression::Boolean(
|
||||
BooleanExpression::Value(v),
|
||||
),
|
||||
) => v,
|
||||
_ => unreachable!("Should be a constant boolean expression. Spreads are not expected here, as in their presence the argument isn't constant"),
|
||||
})
|
||||
.enumerate()
|
||||
.fold(0, |acc, (i, v)| {
|
||||
if v {
|
||||
acc + 2u128.pow(
|
||||
(bitwidth.to_usize() - i - 1)
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
acc
|
||||
}
|
||||
}),
|
||||
)
|
||||
.annotate(bitwidth)
|
||||
.into(),
|
||||
_ => unreachable!("should be an array value"),
|
||||
}
|
||||
.unwrap()
|
||||
.into_inner()
|
||||
{
|
||||
ArrayExpressionInner::Value(v) =>
|
||||
UExpressionInner::Value(
|
||||
v.into_iter()
|
||||
.map(|v| match v {
|
||||
TypedExpressionOrSpread::Expression(
|
||||
TypedExpression::Boolean(
|
||||
BooleanExpression::Value(v),
|
||||
),
|
||||
) => v,
|
||||
_ => unreachable!("Should be a constant boolean expression. Spreads are not expected here, as in their presence the argument isn't constant"),
|
||||
})
|
||||
.enumerate()
|
||||
.fold(0, |acc, (i, v)| {
|
||||
if v {
|
||||
acc + 2u128.pow(
|
||||
(bitwidth.to_usize() - i - 1)
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
acc
|
||||
}
|
||||
}),
|
||||
)
|
||||
.annotate(bitwidth)
|
||||
.into(),
|
||||
_ => unreachable!("should be an array value"),
|
||||
}
|
||||
}
|
||||
|
||||
fn process_u_to_bits<'ast, T: Field>(
|
||||
|
@ -471,11 +471,11 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
}
|
||||
Err(v) => match self.constants.remove(&v.id) {
|
||||
Some(c) => vec![
|
||||
TypedStatement::Definition(v.clone().into(), c),
|
||||
TypedStatement::Definition(assignee, expr),
|
||||
TypedStatement::Definition(v.clone().into(), c.into()),
|
||||
TypedStatement::Definition(assignee, expr.into()),
|
||||
],
|
||||
None => {
|
||||
vec![TypedStatement::Definition(assignee, expr)]
|
||||
vec![TypedStatement::Definition(assignee, expr.into())]
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -491,11 +491,12 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
match self.constants.remove(&v.id) {
|
||||
Some(c) => vec![
|
||||
TypedStatement::Definition(v.clone().into(), c),
|
||||
TypedStatement::EmbedCallDefinition(assignee, embed_call),
|
||||
TypedStatement::Definition(v.clone().into(), c.into()),
|
||||
TypedStatement::Definition(assignee, embed_call.into()),
|
||||
],
|
||||
None => vec![TypedStatement::EmbedCallDefinition(
|
||||
assignee, embed_call,
|
||||
None => vec![TypedStatement::Definition(
|
||||
assignee,
|
||||
embed_call.into(),
|
||||
)],
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +505,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
false => {
|
||||
// if the function arguments are not constant, invalidate the cache
|
||||
// for the return assignees
|
||||
let def = TypedStatement::EmbedCallDefinition(assignee.clone(), embed_call);
|
||||
let def = TypedStatement::Definition(assignee.clone(), embed_call.into());
|
||||
|
||||
let v = self
|
||||
.try_get_constant_mut(&assignee)
|
||||
|
@ -513,7 +514,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
Ok(match self.constants.remove(&v.id) {
|
||||
Some(c) => {
|
||||
vec![TypedStatement::Definition(v.clone().into(), c), def]
|
||||
vec![TypedStatement::Definition(v.clone().into(), c.into()), def]
|
||||
}
|
||||
None => vec![def],
|
||||
})
|
||||
|
@ -524,9 +525,10 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
let e_str = e.to_string();
|
||||
let expr = self.fold_boolean_expression(e)?;
|
||||
match expr {
|
||||
BooleanExpression::Value(v) if !v => {
|
||||
BooleanExpression::Value(false) => {
|
||||
Err(Error::AssertionFailed(format!("{}: ({})", ty, e_str)))
|
||||
}
|
||||
BooleanExpression::Value(true) => Ok(vec![]),
|
||||
_ => Ok(vec![TypedStatement::Assertion(expr, ty)]),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ pub fn inline_call<'a, 'ast, T: Field, E: Expr<'ast, T>>(
|
|||
.zip(inferred_signature.inputs.clone())
|
||||
.map(|(p, t)| ConcreteVariable::new(p.id.id, t, false))
|
||||
.zip(arguments.clone())
|
||||
.map(|(v, a)| TypedStatement::Definition(Variable::from(v).into(), a))
|
||||
.map(|(v, a)| TypedStatement::definition(Variable::from(v).into(), a))
|
||||
.collect();
|
||||
|
||||
let (statements, mut returns): (Vec<_>, Vec<_>) = ssa_f
|
||||
|
@ -205,7 +205,7 @@ pub fn inline_call<'a, 'ast, T: Field, E: Expr<'ast, T>>(
|
|||
|
||||
let expression = TypedExpression::from(Variable::from(v.clone()));
|
||||
|
||||
let output_binding = TypedStatement::Definition(Variable::from(v).into(), return_expression);
|
||||
let output_binding = TypedStatement::definition(Variable::from(v).into(), return_expression);
|
||||
|
||||
let pop_log = TypedStatement::PopCallLog;
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
let v = var.clone().into();
|
||||
|
||||
self.statement_buffer
|
||||
.push(TypedStatement::EmbedCallDefinition(
|
||||
.push(TypedStatement::embed_call_definition(
|
||||
v,
|
||||
EmbedCall::new(embed, generics, arguments),
|
||||
));
|
||||
|
@ -352,7 +352,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
|
||||
for index in *from..*to {
|
||||
let statements: Vec<TypedStatement<_>> =
|
||||
std::iter::once(TypedStatement::Definition(
|
||||
std::iter::once(TypedStatement::definition(
|
||||
v.clone().into(),
|
||||
UExpression::from(index as u32).into(),
|
||||
))
|
||||
|
@ -611,21 +611,21 @@ mod tests {
|
|||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(42u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo").signature(
|
||||
|
@ -638,7 +638,7 @@ mod tests {
|
|||
)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
|
@ -687,7 +687,7 @@ mod tests {
|
|||
let expected_main = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(1)).into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
|
@ -699,17 +699,17 @@ mod tests {
|
|||
),
|
||||
GGenericsAssignment::default(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(3)).into(),
|
||||
FieldElementExpression::Identifier(Identifier::from("a").version(1)).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from(CoreIdentifier::Call(0)).version(0))
|
||||
.into(),
|
||||
FieldElementExpression::Identifier(Identifier::from("a").version(3)).into(),
|
||||
),
|
||||
TypedStatement::PopCallLog,
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(2)).into(),
|
||||
FieldElementExpression::Identifier(
|
||||
Identifier::from(CoreIdentifier::Call(0)).version(0),
|
||||
|
@ -804,17 +804,17 @@ mod tests {
|
|||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(42u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array("b", Type::FieldElement, 1u32).into(),
|
||||
ArrayExpressionInner::Value(
|
||||
vec![FieldElementExpression::Identifier("a".into()).into()].into(),
|
||||
|
@ -822,7 +822,7 @@ mod tests {
|
|||
.annotate(Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array("b", Type::FieldElement, 1u32).into(),
|
||||
ArrayExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo")
|
||||
|
@ -835,7 +835,7 @@ mod tests {
|
|||
.annotate(Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
|
@ -889,7 +889,7 @@ mod tests {
|
|||
let expected_main = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array("b", Type::FieldElement, 1u32).into(),
|
||||
ArrayExpressionInner::Value(
|
||||
vec![FieldElementExpression::Identifier("a".into()).into()].into(),
|
||||
|
@ -906,14 +906,14 @@ mod tests {
|
|||
.collect(),
|
||||
),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array(Identifier::from("a").version(1), Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
ArrayExpressionInner::Identifier("b".into())
|
||||
.annotate(Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array(
|
||||
Identifier::from(CoreIdentifier::Call(0)).version(0),
|
||||
Type::FieldElement,
|
||||
|
@ -925,7 +925,7 @@ mod tests {
|
|||
.into(),
|
||||
),
|
||||
TypedStatement::PopCallLog,
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array(Identifier::from("b").version(1), Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
ArrayExpressionInner::Identifier(
|
||||
|
@ -1028,17 +1028,17 @@ mod tests {
|
|||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(2u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array(
|
||||
"b",
|
||||
Type::FieldElement,
|
||||
|
@ -1055,7 +1055,7 @@ mod tests {
|
|||
.annotate(Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array("b", Type::FieldElement, 1u32).into(),
|
||||
ArrayExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo")
|
||||
|
@ -1068,7 +1068,7 @@ mod tests {
|
|||
.annotate(Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
|
@ -1122,7 +1122,7 @@ mod tests {
|
|||
let expected_main = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array("b", Type::FieldElement, 1u32).into(),
|
||||
ArrayExpressionInner::Value(
|
||||
vec![FieldElementExpression::Identifier("a".into()).into()].into(),
|
||||
|
@ -1139,14 +1139,14 @@ mod tests {
|
|||
.collect(),
|
||||
),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array(Identifier::from("a").version(1), Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
ArrayExpressionInner::Identifier("b".into())
|
||||
.annotate(Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array(
|
||||
Identifier::from(CoreIdentifier::Call(0)).version(0),
|
||||
Type::FieldElement,
|
||||
|
@ -1158,7 +1158,7 @@ mod tests {
|
|||
.into(),
|
||||
),
|
||||
TypedStatement::PopCallLog,
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array(Identifier::from("b").version(1), Type::FieldElement, 1u32)
|
||||
.into(),
|
||||
ArrayExpressionInner::Identifier(
|
||||
|
@ -1254,7 +1254,7 @@ mod tests {
|
|||
)
|
||||
.into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array(
|
||||
"ret",
|
||||
Type::FieldElement,
|
||||
|
@ -1333,7 +1333,7 @@ mod tests {
|
|||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array("b", Type::FieldElement, 1u32).into(),
|
||||
ArrayExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo")
|
||||
|
@ -1485,7 +1485,7 @@ mod tests {
|
|||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::array("b", Type::FieldElement, 1u32).into(),
|
||||
ArrayExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo")
|
||||
|
|
|
@ -106,7 +106,7 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> {
|
|||
.clone()
|
||||
.into_iter()
|
||||
.map(|(g, v)| {
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::new(CoreIdentifier::from(g), Type::Uint(UBitwidth::B32), false)
|
||||
.into(),
|
||||
UExpression::from(v as u32).into(),
|
||||
|
@ -126,7 +126,7 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> {
|
|||
impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> {
|
||||
fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec<TypedStatement<'ast, T>> {
|
||||
match s {
|
||||
TypedStatement::Definition(a, e) => {
|
||||
TypedStatement::Definition(a, DefinitionRhs::Expression(e)) => {
|
||||
let e = self.fold_expression(e);
|
||||
|
||||
let a = match a {
|
||||
|
@ -137,9 +137,9 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> {
|
|||
a => fold_assignee(self, a),
|
||||
};
|
||||
|
||||
vec![TypedStatement::Definition(a, e)]
|
||||
vec![TypedStatement::definition(a, e)]
|
||||
}
|
||||
TypedStatement::EmbedCallDefinition(assignee, embed_call) => {
|
||||
TypedStatement::Definition(assignee, DefinitionRhs::EmbedCall(embed_call)) => {
|
||||
let assignee = match assignee {
|
||||
TypedAssignee::Identifier(v) => {
|
||||
let v = self.issue_next_ssa_variable(v);
|
||||
|
@ -148,7 +148,7 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> {
|
|||
a => fold_assignee(self, a),
|
||||
};
|
||||
let embed_call = self.fold_embed_call(embed_call);
|
||||
vec![TypedStatement::EmbedCallDefinition(assignee, embed_call)]
|
||||
vec![TypedStatement::embed_call_definition(assignee, embed_call)]
|
||||
}
|
||||
TypedStatement::For(v, from, to, stats) => {
|
||||
let from = self.fold_uint_expression(from);
|
||||
|
@ -236,13 +236,13 @@ mod tests {
|
|||
|
||||
let mut u = ShallowTransformer::with_versions(&mut versions);
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element("a")),
|
||||
FieldElementExpression::Number(Bn128Field::from(5)).into(),
|
||||
);
|
||||
assert_eq!(
|
||||
u.fold_statement(s),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element(
|
||||
Identifier::from("a").version(0)
|
||||
)),
|
||||
|
@ -250,13 +250,13 @@ mod tests {
|
|||
)]
|
||||
);
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element("a")),
|
||||
FieldElementExpression::Number(Bn128Field::from(6)).into(),
|
||||
);
|
||||
assert_eq!(
|
||||
u.fold_statement(s),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element(
|
||||
Identifier::from("a").version(1)
|
||||
)),
|
||||
|
@ -286,13 +286,13 @@ mod tests {
|
|||
|
||||
let mut u = ShallowTransformer::with_versions(&mut versions);
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element("a")),
|
||||
FieldElementExpression::Number(Bn128Field::from(5)).into(),
|
||||
);
|
||||
assert_eq!(
|
||||
u.fold_statement(s),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element(
|
||||
Identifier::from("a").version(0)
|
||||
)),
|
||||
|
@ -300,7 +300,7 @@ mod tests {
|
|||
)]
|
||||
);
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element("a")),
|
||||
FieldElementExpression::Add(
|
||||
box FieldElementExpression::Identifier("a".into()),
|
||||
|
@ -310,7 +310,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
u.fold_statement(s),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element(
|
||||
Identifier::from("a").version(1)
|
||||
)),
|
||||
|
@ -337,13 +337,13 @@ mod tests {
|
|||
|
||||
let mut u = ShallowTransformer::with_versions(&mut versions);
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element("a")),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
);
|
||||
assert_eq!(
|
||||
u.fold_statement(s),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::field_element(
|
||||
Identifier::from("a").version(0)
|
||||
)),
|
||||
|
@ -351,7 +351,7 @@ mod tests {
|
|||
)]
|
||||
);
|
||||
|
||||
let s: TypedStatement<Bn128Field> = TypedStatement::Definition(
|
||||
let s: TypedStatement<Bn128Field> = TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo").signature(
|
||||
|
@ -366,7 +366,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
u.fold_statement(s),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(1)).into(),
|
||||
FieldElementExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo").signature(
|
||||
|
@ -398,7 +398,7 @@ mod tests {
|
|||
|
||||
let mut u = ShallowTransformer::with_versions(&mut versions);
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::array("a", Type::FieldElement, 2u32)),
|
||||
ArrayExpressionInner::Value(
|
||||
vec![
|
||||
|
@ -413,7 +413,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
u.fold_statement(s),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::array(
|
||||
Identifier::from("a").version(0),
|
||||
Type::FieldElement,
|
||||
|
@ -431,7 +431,7 @@ mod tests {
|
|||
)]
|
||||
);
|
||||
|
||||
let s: TypedStatement<Bn128Field> = TypedStatement::Definition(
|
||||
let s: TypedStatement<Bn128Field> = TypedStatement::definition(
|
||||
TypedAssignee::Select(
|
||||
box TypedAssignee::Identifier(Variable::array("a", Type::FieldElement, 2u32)),
|
||||
box UExpression::from(1u32),
|
||||
|
@ -457,7 +457,7 @@ mod tests {
|
|||
|
||||
let array_of_array_ty = Type::array((Type::array((Type::FieldElement, 2u32)), 2u32));
|
||||
|
||||
let s = TypedStatement::Definition(
|
||||
let s = TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::new("a", array_of_array_ty.clone(), true)),
|
||||
ArrayExpressionInner::Value(
|
||||
vec![
|
||||
|
@ -488,7 +488,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
u.fold_statement(s),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
TypedAssignee::Identifier(Variable::new(
|
||||
Identifier::from("a").version(0),
|
||||
array_of_array_ty.clone(),
|
||||
|
@ -522,7 +522,7 @@ mod tests {
|
|||
)]
|
||||
);
|
||||
|
||||
let s: TypedStatement<Bn128Field> = TypedStatement::Definition(
|
||||
let s: TypedStatement<Bn128Field> = TypedStatement::definition(
|
||||
TypedAssignee::Select(
|
||||
box TypedAssignee::Identifier(Variable::new(
|
||||
"a",
|
||||
|
@ -588,17 +588,17 @@ mod tests {
|
|||
let f: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(42u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
|
@ -607,12 +607,12 @@ mod tests {
|
|||
UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32)
|
||||
* UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
)],
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
|
@ -621,12 +621,12 @@ mod tests {
|
|||
UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32)
|
||||
* UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
)],
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
|
@ -655,21 +655,21 @@ mod tests {
|
|||
let expected = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("K", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(1u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(42u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint(Identifier::from("n").version(1), UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(1)).into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
|
@ -681,12 +681,12 @@ mod tests {
|
|||
.annotate(UBitwidth::B32)
|
||||
* UExpressionInner::Identifier(Identifier::from("n").version(1))
|
||||
.annotate(UBitwidth::B32),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
)],
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(3)).into(),
|
||||
FieldElementExpression::Identifier(Identifier::from("a").version(2)).into(),
|
||||
),
|
||||
|
@ -698,12 +698,12 @@ mod tests {
|
|||
.annotate(UBitwidth::B32)
|
||||
* UExpressionInner::Identifier(Identifier::from("n").version(2))
|
||||
.annotate(UBitwidth::B32),
|
||||
vec![TypedStatement::Definition(
|
||||
vec![TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
)],
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(5)).into(),
|
||||
FieldElementExpression::Identifier(Identifier::from("a").version(4)).into(),
|
||||
),
|
||||
|
@ -766,11 +766,11 @@ mod tests {
|
|||
let f: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
TypedExpression::Uint(42u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::boolean("a").into(),
|
||||
BooleanExpression::Value(true).into(),
|
||||
),
|
||||
|
@ -788,11 +788,11 @@ mod tests {
|
|||
let expected: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(1)).into(),
|
||||
TypedExpression::Uint(42u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::boolean(Identifier::from("a").version(2)).into(),
|
||||
BooleanExpression::Value(true).into(),
|
||||
),
|
||||
|
@ -844,11 +844,11 @@ mod tests {
|
|||
0u32.into(),
|
||||
1u32.into(),
|
||||
vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a")).into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a")).into(),
|
||||
FieldElementExpression::Number(42usize.into()).into(),
|
||||
),
|
||||
|
@ -877,11 +877,11 @@ mod tests {
|
|||
0u32.into(),
|
||||
1u32.into(),
|
||||
vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a")).into(),
|
||||
FieldElementExpression::Identifier(Identifier::from("a")).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a")).into(),
|
||||
FieldElementExpression::Number(42usize.into()).into(),
|
||||
),
|
||||
|
@ -945,21 +945,21 @@ mod tests {
|
|||
let f: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(42u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
FieldElementExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo"),
|
||||
|
@ -970,13 +970,13 @@ mod tests {
|
|||
)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element("a").into(),
|
||||
(FieldElementExpression::Identifier("a".into())
|
||||
* FieldElementExpression::function_call(
|
||||
|
@ -1014,25 +1014,25 @@ mod tests {
|
|||
let expected = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::field_element("a").into()],
|
||||
statements: vec![
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("K", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(1u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint("n", UBitwidth::B32).into(),
|
||||
TypedExpression::Uint(42u32.into()),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint(Identifier::from("n").version(1), UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier("n".into())
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(1)).into(),
|
||||
FieldElementExpression::Identifier("a".into()).into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(2)).into(),
|
||||
FieldElementExpression::function_call(
|
||||
DeclarationFunctionKey::with_location("main", "foo"),
|
||||
|
@ -1047,13 +1047,13 @@ mod tests {
|
|||
)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::uint(Identifier::from("n").version(2), UBitwidth::B32).into(),
|
||||
UExpressionInner::Identifier(Identifier::from("n").version(1))
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
),
|
||||
TypedStatement::Definition(
|
||||
TypedStatement::definition(
|
||||
Variable::field_element(Identifier::from("a").version(3)).into(),
|
||||
(FieldElementExpression::Identifier(Identifier::from("a").version(2))
|
||||
* FieldElementExpression::function_call(
|
||||
|
|
|
@ -457,11 +457,11 @@ fn is_constant<T>(assignee: &TypedAssignee<T>) -> bool {
|
|||
impl<'ast, T: Field> Folder<'ast, T> for VariableWriteRemover {
|
||||
fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec<TypedStatement<'ast, T>> {
|
||||
match s {
|
||||
TypedStatement::Definition(assignee, expr) => {
|
||||
TypedStatement::Definition(assignee, DefinitionRhs::Expression(expr)) => {
|
||||
let expr = self.fold_expression(expr);
|
||||
|
||||
if is_constant(&assignee) {
|
||||
vec![TypedStatement::Definition(assignee, expr)]
|
||||
vec![TypedStatement::definition(assignee, expr)]
|
||||
} else {
|
||||
// Note: here we redefine the whole object, ideally we would only redefine some of it
|
||||
// Example: `a[0][i] = 42` we redefine `a` but we could redefine just `a[0]`
|
||||
|
@ -511,7 +511,7 @@ impl<'ast, T: Field> Folder<'ast, T> for VariableWriteRemover {
|
|||
|
||||
range_checks
|
||||
.into_iter()
|
||||
.chain(std::iter::once(TypedStatement::Definition(
|
||||
.chain(std::iter::once(TypedStatement::definition(
|
||||
TypedAssignee::Identifier(variable),
|
||||
e,
|
||||
)))
|
||||
|
|
|
@ -1,18 +1,10 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use zokrates_ast::zir::result_folder::fold_boolean_expression;
|
||||
use zokrates_ast::zir::result_folder::fold_field_expression;
|
||||
use zokrates_ast::zir::result_folder::fold_statement;
|
||||
use zokrates_ast::zir::result_folder::fold_uint_expression_inner;
|
||||
use zokrates_ast::zir::result_folder::ResultFold;
|
||||
use zokrates_ast::zir::result_folder::ResultFolder;
|
||||
use zokrates_ast::zir::types::UBitwidth;
|
||||
use zokrates_ast::zir::Conditional;
|
||||
use zokrates_ast::zir::ConditionalExpression;
|
||||
use zokrates_ast::zir::ConditionalOrExpression;
|
||||
use zokrates_ast::zir::Expr;
|
||||
use zokrates_ast::zir::SelectExpression;
|
||||
use zokrates_ast::zir::SelectOrExpression;
|
||||
use zokrates_ast::zir::{
|
||||
result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr,
|
||||
SelectExpression, SelectOrExpression,
|
||||
};
|
||||
use zokrates_ast::zir::{
|
||||
BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression,
|
||||
UExpressionInner, ZirExpression, ZirProgram, ZirStatement,
|
||||
|
@ -667,6 +659,7 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod field {
|
||||
use zokrates_ast::zir::Conditional;
|
||||
use zokrates_ast::zir::Select;
|
||||
|
||||
use super::*;
|
||||
|
@ -868,6 +861,7 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod bool {
|
||||
use zokrates_ast::zir::Conditional;
|
||||
use zokrates_ast::zir::Select;
|
||||
|
||||
use super::*;
|
||||
|
@ -1174,6 +1168,8 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod uint {
|
||||
use zokrates_ast::zir::Conditional;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
|
65
zokrates_core_test/tests/tests/div.json
Normal file
65
zokrates_core_test/tests/tests/div.json
Normal file
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/div.zok",
|
||||
"max_constraint_count": 3,
|
||||
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["0", "0"]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "4",
|
||||
"right": "2",
|
||||
"error": "Inverse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["1", "0"]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "4",
|
||||
"right": "2",
|
||||
"error": "Inverse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["0", "1"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["2", "2"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["4", "2"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
3
zokrates_core_test/tests/tests/div.zok
Normal file
3
zokrates_core_test/tests/tests/div.zok
Normal file
|
@ -0,0 +1,3 @@
|
|||
def main(field x, field y) -> field {
|
||||
return x / y;
|
||||
}
|
4
zokrates_core_test/tests/tests/no_return.json
Normal file
4
zokrates_core_test/tests/tests/no_return.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/no_return.zok",
|
||||
"tests": []
|
||||
}
|
9
zokrates_core_test/tests/tests/no_return.zok
Normal file
9
zokrates_core_test/tests/tests/no_return.zok
Normal file
|
@ -0,0 +1,9 @@
|
|||
def foo() {
|
||||
return;
|
||||
}
|
||||
|
||||
def bar() {
|
||||
return foo();
|
||||
}
|
||||
|
||||
def main() {}
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/shadowing.zok",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": []
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": ["2", "84"]
|
||||
}
|
||||
}
|
||||
"entry_point": "./tests/tests/shadowing.zok",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": []
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": ["2", "84"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -76,10 +76,7 @@ impl Evm {
|
|||
|
||||
pub fn create_account(&mut self, address: &Address, balance: impl Into<U256>) {
|
||||
let acc = AccountInfo::from_balance(balance.into());
|
||||
self.vm
|
||||
.db()
|
||||
.unwrap()
|
||||
.insert_account_info(*address.as_ref(), acc);
|
||||
self.vm.db().unwrap().insert_cache(*address.as_ref(), acc);
|
||||
}
|
||||
|
||||
pub fn set_account_balance(
|
||||
|
@ -89,10 +86,7 @@ impl Evm {
|
|||
) -> Result<(), Error> {
|
||||
let mut acc = self.vm.db().unwrap().basic(*address.as_ref());
|
||||
acc.balance = balance.into();
|
||||
self.vm
|
||||
.db()
|
||||
.unwrap()
|
||||
.insert_account_info(*address.as_ref(), acc);
|
||||
self.vm.db().unwrap().insert_cache(*address.as_ref(), acc);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue