Merge branch 'develop' of https://github.com/Zokrates/ZoKrates into bool_eq
This commit is contained in:
commit
1d118b9298
66 changed files with 5937 additions and 2230 deletions
|
@ -42,9 +42,9 @@ jobs:
|
|||
- restore_cache:
|
||||
keys:
|
||||
- v4-cargo-cache-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||
- run:
|
||||
name: Check format
|
||||
command: rustup component add rustfmt-preview; cargo fmt --all -- --check
|
||||
# - run:
|
||||
# name: Check format
|
||||
# command: rustup component add rustfmt; cargo fmt --all -- --check
|
||||
- run:
|
||||
name: Install libsnark prerequisites
|
||||
command: ./scripts/install_libsnark_prerequisites.sh
|
||||
|
|
324
Cargo.lock
generated
324
Cargo.lock
generated
|
@ -2,7 +2,7 @@
|
|||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -51,7 +51,7 @@ dependencies = [
|
|||
"difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -71,11 +71,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.37"
|
||||
version = "0.3.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -104,7 +104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -120,7 +120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -130,7 +130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -170,7 +170,7 @@ dependencies = [
|
|||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -194,7 +194,7 @@ version = "0.4.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -214,9 +214,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -230,7 +230,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -250,7 +250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -262,7 +262,7 @@ name = "cloudabi"
|
|||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -306,8 +306,8 @@ dependencies = [
|
|||
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -332,7 +332,7 @@ name = "crc32fast"
|
|||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -340,7 +340,7 @@ name = "crossbeam"
|
|||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -371,7 +371,7 @@ version = "0.7.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -391,7 +391,7 @@ name = "crossbeam-utils"
|
|||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -409,7 +409,7 @@ dependencies = [
|
|||
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -422,13 +422,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "curl-sys"
|
||||
version = "0.4.21"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -467,15 +467,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.2"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.19"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -488,7 +488,7 @@ name = "error-chain"
|
|||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -496,7 +496,7 @@ name = "error-chain"
|
|||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -505,7 +505,7 @@ name = "failure"
|
|||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -551,12 +551,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.11"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz_oxide 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -601,7 +602,7 @@ name = "fuchsia-zircon"
|
|||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -650,7 +651,7 @@ name = "getrandom"
|
|||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -660,12 +661,12 @@ name = "git2"
|
|||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -729,7 +730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.12.34"
|
||||
version = "0.12.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -749,9 +750,9 @@ dependencies = [
|
|||
"tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -763,7 +764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -807,7 +808,7 @@ name = "itertools"
|
|||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -850,23 +851,23 @@ version = "0.7.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"curl-sys 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"curl-sys 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libssh2-sys 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.11"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -884,11 +885,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.1.5"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -896,7 +896,7 @@ name = "log"
|
|||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -946,10 +946,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -992,7 +992,7 @@ dependencies = [
|
|||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1003,10 +1003,10 @@ dependencies = [
|
|||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1017,7 +1017,7 @@ name = "net2"
|
|||
version = "0.2.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -1054,7 +1054,7 @@ dependencies = [
|
|||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1107,15 +1107,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.24"
|
||||
version = "0.10.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1125,7 +1125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.49"
|
||||
version = "0.9.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1135,14 +1135,6 @@ dependencies = [
|
|||
"vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pairing_ce"
|
||||
version = "0.18.0"
|
||||
|
@ -1171,20 +1163,23 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.7.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.4.0"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1236,7 +1231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"pest 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pest_meta 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -1271,7 +1266,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.3"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1294,7 +1289,7 @@ name = "pulldown-cmark"
|
|||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1310,7 +1305,7 @@ name = "quote"
|
|||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1366,7 +1361,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.0"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1551,31 +1546,31 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.9.20"
|
||||
version = "0.9.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1646,25 +1641,20 @@ dependencies = [
|
|||
"digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.0.0"
|
||||
|
@ -1695,7 +1685,7 @@ version = "0.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1705,10 +1695,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.100"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1716,27 +1706,27 @@ name = "serde_bytes"
|
|||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.100"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.40"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1746,7 +1736,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -1779,7 +1769,7 @@ dependencies = [
|
|||
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -1794,11 +1784,6 @@ name = "smallvec"
|
|||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "string"
|
||||
version = "0.2.1"
|
||||
|
@ -1837,7 +1822,7 @@ name = "syn"
|
|||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -1867,9 +1852,9 @@ name = "tempfile"
|
|||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1921,9 +1906,9 @@ dependencies = [
|
|||
"tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -1933,7 +1918,7 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -1967,7 +1952,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-reactor"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1976,7 +1961,7 @@ dependencies = [
|
|||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2002,21 +1987,21 @@ dependencies = [
|
|||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-threadpool"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -2042,12 +2027,12 @@ name = "try_from"
|
|||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "1.5.0"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -2265,6 +2250,17 @@ dependencies = [
|
|||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zokrates_abi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_core 0.3.14",
|
||||
"zokrates_field 0.3.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zokrates_cli"
|
||||
version = "0.4.11"
|
||||
|
@ -2275,8 +2271,9 @@ dependencies = [
|
|||
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_abi 0.1.0",
|
||||
"zokrates_core 0.3.14",
|
||||
"zokrates_field 0.3.3",
|
||||
"zokrates_fs_resolver 0.4.1",
|
||||
|
@ -2306,11 +2303,11 @@ dependencies = [
|
|||
"reduce 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"typed-arena 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"typed-arena 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_embed 0.1.0",
|
||||
"zokrates_field 0.3.3",
|
||||
|
@ -2345,9 +2342,9 @@ dependencies = [
|
|||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pairing_ce 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2362,7 +2359,7 @@ name = "zokrates_github_resolver"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mockito 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -2402,16 +2399,16 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_core 0.3.14",
|
||||
"zokrates_field 0.3.3",
|
||||
"zokrates_fs_resolver 0.4.1",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
|
||||
"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
|
||||
"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
|
||||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
|
@ -2420,13 +2417,13 @@ dependencies = [
|
|||
"checksum assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72342c21057a3cb5f7c2d849bf7999a83795434dd36d74fa8c24680581bd1930"
|
||||
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
|
||||
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
|
||||
"checksum backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2"
|
||||
"checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5"
|
||||
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
|
||||
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||
"checksum bellman_ce 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "938ec0feff00f9dfda0e7cbfe8db8b717966a84f6a12e63ed0943c4a90d6a5de"
|
||||
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
|
||||
"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
|
||||
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
|
||||
"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2"
|
||||
"checksum blake2-rfc_bellman_edition 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdc60350286c7c3db13b98e91dbe5c8b6830a6821bc20af5b0c310ce94d74915"
|
||||
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09"
|
||||
|
@ -2438,7 +2435,7 @@ dependencies = [
|
|||
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
|
||||
"checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe"
|
||||
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
|
||||
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
|
||||
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
|
@ -2459,14 +2456,14 @@ dependencies = [
|
|||
"checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
|
||||
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
|
||||
"checksum curl-sys 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)" = "520594da9914c1dc77ce3be450fc1c74fde67c82966d80f8e93c6d460eb0e9ae"
|
||||
"checksum curl-sys 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9a9a4e417722876332136a00cacf92c2ceb331fab4b52b6a1ad16c6cd79255"
|
||||
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
|
||||
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||
"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
|
||||
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
|
||||
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
|
||||
"checksum encoding_rs 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)" = "79906e1ad1f7f8bc48864fcc6ffd58336fb5992e627bf61928099cb25fdf4314"
|
||||
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
"checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9"
|
||||
"checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee"
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
|
||||
|
@ -2475,7 +2472,7 @@ dependencies = [
|
|||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
"checksum ff_ce 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "18af1ea1b80a4b474fae13af4c58cf0a5a2bc33832d5fa70f68a4b286178fdb5"
|
||||
"checksum ff_derive_ce 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d245b4e76c5b36bb7721ea15b7fbc61bebf0c5d2890eaf49fe1e2a3eed36db9"
|
||||
"checksum flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "2adaffba6388640136149e18ed080b77a78611c1e1d6de75aedcdf78df5d4682"
|
||||
"checksum flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ad3c5233c9a940c8719031b423d7e6c16af66e031cb0420b0896f5245bf181d3"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
@ -2498,7 +2495,7 @@ dependencies = [
|
|||
"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4"
|
||||
"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
|
||||
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
|
||||
"checksum hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)" = "898a87371a3999b2f731b9af636cd76aa20de10e69c2daf3e71388326b619fe0"
|
||||
"checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6"
|
||||
"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f"
|
||||
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
|
||||
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
|
||||
|
@ -2511,9 +2508,9 @@ dependencies = [
|
|||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||
"checksum libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "48441cb35dc255da8ae72825689a95368bf510659ae1ad55dc4aa88cb1789bf1"
|
||||
"checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d"
|
||||
"checksum libssh2-sys 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8914d10b159fc288f2b6f253c94bd0c15a777fd5a297691141d89674b87e66fd"
|
||||
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
||||
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
||||
"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc"
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
@ -2522,7 +2519,7 @@ dependencies = [
|
|||
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
|
||||
"checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf"
|
||||
"checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599"
|
||||
"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10"
|
||||
"checksum miniz_oxide 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "304f66c19be2afa56530fa7c39796192eef38618da8d19df725ad7c6d6b2aaae"
|
||||
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
|
||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||
"checksum mockito 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d303c060b18db22e0a9ac12133c32f927c3f980b6f70004bc0cb2f8accc94704"
|
||||
|
@ -2538,15 +2535,14 @@ dependencies = [
|
|||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
||||
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
|
||||
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
"checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15"
|
||||
"checksum openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449"
|
||||
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
"checksum openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)" = "f4fad9e54bd23bd4cbbe48fdc08a1b8091707ac869ef8508edea2fec77dcc884"
|
||||
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
|
||||
"checksum openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)" = "2c42dcccb832556b5926bc9ae61e8775f2a61e725ab07ab3d1e7fcf8ae62c3b6"
|
||||
"checksum pairing_ce 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f075a9c570e2026111cb6dddf6a320e5163c42aa32500b315ec34acbcf7c9b36"
|
||||
"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc"
|
||||
"checksum parity-wasm 0.35.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3e1e076c4e01399b6cd0793a8df42f90bba3ae424671ef421d1608a943155d93"
|
||||
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
|
||||
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
|
||||
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
|
||||
"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
|
||||
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
"checksum pest 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e4fb201c5c22a55d8b24fef95f78be52738e5e1361129be1b5e862ecdb6894a"
|
||||
|
@ -2557,7 +2553,7 @@ dependencies = [
|
|||
"checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea"
|
||||
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
|
||||
"checksum proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0"
|
||||
"checksum publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9bf259a81de2b2eb9850ec990ec78e6a25319715584fd7652b9b26f96fcb1510"
|
||||
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
|
||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
|
@ -2566,7 +2562,7 @@ dependencies = [
|
|||
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
|
||||
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
|
||||
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
|
||||
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
|
@ -2588,7 +2584,7 @@ dependencies = [
|
|||
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
|
||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||
"checksum reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6d896143a583047512e59ac54a215cb203c29cc941917343edea3be8df9c78"
|
||||
"checksum reqwest 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)" = "02b7e953e14c6f3102b7e8d1f1ee3abf5ecee80b427f5565c9389835cecae95c"
|
||||
"checksum rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2089e4031214d129e201f8c3c8c2fe97cd7322478a0d1cdf78e7029b0042efdb"
|
||||
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||
|
@ -2598,24 +2594,22 @@ dependencies = [
|
|||
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
|
||||
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
|
||||
"checksum sapling-crypto_ce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d385cebab4241e694ca5979b0cbf9b353ba12fe6a17d66643a958b397362d56d"
|
||||
"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021"
|
||||
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||
"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2"
|
||||
"checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "f4473e8506b213730ff2061073b48fa51dcc66349219e2e7c5608f0296a1d95a"
|
||||
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
|
||||
"checksum serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "defbb8a83d7f34cc8380751eeb892b825944222888aff18996ea7901f24aec88"
|
||||
"checksum serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "11e410fde43e157d789fc290d26bc940778ad0fdd47836426fbac36573710dbb"
|
||||
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
|
||||
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
|
||||
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
|
||||
"checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a"
|
||||
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
|
||||
"checksum single 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5add732a1ab689845591a1b50339cf5310b563e08dc5813c65991f30369ea2"
|
||||
"checksum skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fb8ed853fdc19ce09752d63f3a2e5b5158aeb261520cd75eb618bd60305165"
|
||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
|
||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||
"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
|
||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
|
||||
|
@ -2633,14 +2627,14 @@ dependencies = [
|
|||
"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
|
||||
"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac"
|
||||
"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
|
||||
"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce"
|
||||
"checksum tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c56391be9805bc80163151c0b9e5164ee64f4b0200962c346fea12773158f22d"
|
||||
"checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7"
|
||||
"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
|
||||
"checksum tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "90ca01319dea1e376a001e8dc192d42ebde6dd532532a5bad988ac37db365b19"
|
||||
"checksum tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd2c6a3885302581f4401c82af70d792bb9df1700e7437b0aeb4ada94d5388c"
|
||||
"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e"
|
||||
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
||||
"checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b"
|
||||
"checksum typed-arena 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f70f5c346cc11bc044ae427ab2feae213350dca9e2d637047797d5ff316a646"
|
||||
"checksum typed-arena 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c0704a799d314795d3d847d519b284bae681ef9b1f3da99f7ebc7b47ba2e607"
|
||||
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
||||
"checksum ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
|
||||
"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874"
|
||||
|
|
|
@ -7,6 +7,7 @@ members = [
|
|||
"zokrates_github_resolver",
|
||||
"zokrates_stdlib",
|
||||
"zokrates_embed",
|
||||
"zokrates_abi",
|
||||
"zokrates_test",
|
||||
"zokrates_core_test",
|
||||
]
|
12
zokrates_abi/Cargo.toml
Normal file
12
zokrates_abi/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "zokrates_abi"
|
||||
version = "0.1.0"
|
||||
authors = ["Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
zokrates_field = { version = "0.3", path = "../zokrates_field" }
|
||||
zokrates_core = { version = "0.3", path = "../zokrates_core" }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
491
zokrates_abi/src/lib.rs
Normal file
491
zokrates_abi/src/lib.rs
Normal file
|
@ -0,0 +1,491 @@
|
|||
#![feature(box_patterns, box_syntax)]
|
||||
|
||||
pub enum Inputs<T> {
|
||||
Raw(Vec<T>),
|
||||
Abi(CheckedValues<T>),
|
||||
}
|
||||
|
||||
impl<T: From<usize>> Encode<T> for Inputs<T> {
|
||||
fn encode(self) -> Vec<T> {
|
||||
match self {
|
||||
Inputs::Raw(v) => v,
|
||||
Inputs::Abi(v) => v.encode(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use zokrates_core::typed_absy::Type;
|
||||
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
type Map<K, V> = BTreeMap<K, V>;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
Json(String),
|
||||
Conversion(String),
|
||||
Type(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Error::Json(e) => write!(f, "Invalid JSON: {}", e),
|
||||
Error::Conversion(e) => write!(f, "Invalid ZoKrates values: {}", e),
|
||||
Error::Type(e) => write!(f, "Type error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum Value<T> {
|
||||
Field(T),
|
||||
Boolean(bool),
|
||||
Array(Vec<Value<T>>),
|
||||
Struct(Map<String, Value<T>>),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum CheckedValue<T> {
|
||||
Field(T),
|
||||
Boolean(bool),
|
||||
Array(Vec<CheckedValue<T>>),
|
||||
Struct(Vec<(String, CheckedValue<T>)>),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct CheckedValues<T>(Vec<CheckedValue<T>>);
|
||||
|
||||
impl<T: Field> fmt::Display for Value<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Value::Field(v) => write!(f, "{}", v),
|
||||
Value::Boolean(v) => write!(f, "{}", v),
|
||||
Value::Array(v) => write!(
|
||||
f,
|
||||
"[{}]",
|
||||
v.iter()
|
||||
.map(|v| format!("{}", v))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Value::Struct(v) => write!(
|
||||
f,
|
||||
"{{{}}}",
|
||||
v.iter()
|
||||
.map(|(k, v)| format!("{}: {}", k, v))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> Value<T> {
|
||||
fn check(self, ty: Type) -> Result<CheckedValue<T>, String> {
|
||||
match (self, ty) {
|
||||
(Value::Field(f), Type::FieldElement) => Ok(CheckedValue::Field(f)),
|
||||
(Value::Boolean(b), Type::Boolean) => Ok(CheckedValue::Boolean(b)),
|
||||
(Value::Array(a), Type::Array(box inner_ty, size)) => {
|
||||
if a.len() != size {
|
||||
Err(format!(
|
||||
"Expected array of size {}, found array of size {}",
|
||||
size,
|
||||
a.len()
|
||||
))
|
||||
} else {
|
||||
let a = a
|
||||
.into_iter()
|
||||
.map(|val| val.check(inner_ty.clone()))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(CheckedValue::Array(a))
|
||||
}
|
||||
}
|
||||
(Value::Struct(mut s), Type::Struct(members)) => {
|
||||
if s.len() != members.len() {
|
||||
Err(format!(
|
||||
"Expected {} member(s), found {}",
|
||||
members.len(),
|
||||
s.len()
|
||||
))
|
||||
} else {
|
||||
let s = members
|
||||
.into_iter()
|
||||
.map(|(id, ty)| {
|
||||
s.remove(&id)
|
||||
.ok_or_else(|| format!("Member with id `{}` not found", id))
|
||||
.map(|v| v.check(ty).map(|v| (id, v)))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.collect::<Result<_, _>>()?;
|
||||
Ok(CheckedValue::Struct(s))
|
||||
}
|
||||
}
|
||||
(v, t) => Err(format!("Value `{}` doesn't match expected type `{}`", v, t)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Encode<T> {
|
||||
fn encode(self) -> Vec<T>;
|
||||
}
|
||||
|
||||
pub trait Decode<T> {
|
||||
type Expected;
|
||||
|
||||
fn decode(raw: Vec<T>, expected: Self::Expected) -> Self;
|
||||
}
|
||||
|
||||
impl<T: From<usize>> Encode<T> for CheckedValue<T> {
|
||||
fn encode(self) -> Vec<T> {
|
||||
match self {
|
||||
CheckedValue::Field(t) => vec![t],
|
||||
CheckedValue::Boolean(b) => vec![if b { 1.into() } else { 0.into() }],
|
||||
CheckedValue::Array(a) => a.into_iter().flat_map(|v| v.encode()).collect(),
|
||||
CheckedValue::Struct(s) => s.into_iter().flat_map(|(_, v)| v.encode()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + From<usize> + PartialEq> Decode<T> for CheckedValues<T> {
|
||||
type Expected = Vec<Type>;
|
||||
|
||||
fn decode(raw: Vec<T>, expected: Self::Expected) -> Self {
|
||||
CheckedValues(
|
||||
expected
|
||||
.into_iter()
|
||||
.scan(0, |state, e| {
|
||||
let new_state = *state + e.get_primitive_count();
|
||||
let res = CheckedValue::decode(raw[*state..new_state].to_vec(), e);
|
||||
*state = new_state;
|
||||
Some(res)
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: From<usize> + PartialEq + Clone> Decode<T> for CheckedValue<T> {
|
||||
type Expected = Type;
|
||||
|
||||
fn decode(raw: Vec<T>, expected: Self::Expected) -> Self {
|
||||
let mut raw = raw;
|
||||
|
||||
match expected {
|
||||
Type::FieldElement => CheckedValue::Field(raw.pop().unwrap()),
|
||||
Type::Boolean => {
|
||||
let v = raw.pop().unwrap();
|
||||
CheckedValue::Boolean(if v == 0.into() {
|
||||
false
|
||||
} else if v == 1.into() {
|
||||
true
|
||||
} else {
|
||||
unreachable!()
|
||||
})
|
||||
}
|
||||
Type::Array(box inner_ty, _) => CheckedValue::Array(
|
||||
raw.chunks(inner_ty.get_primitive_count())
|
||||
.map(|c| CheckedValue::decode(c.to_vec(), inner_ty.clone()))
|
||||
.collect(),
|
||||
),
|
||||
Type::Struct(members) => CheckedValue::Struct(
|
||||
members
|
||||
.into_iter()
|
||||
.scan(0, |state, (id, ty)| {
|
||||
let new_state = *state + ty.get_primitive_count();
|
||||
let res = CheckedValue::decode(raw[*state..new_state].to_vec(), ty);
|
||||
*state = new_state;
|
||||
Some((id, res))
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: From<usize>> Encode<T> for CheckedValues<T> {
|
||||
fn encode(self) -> Vec<T> {
|
||||
self.0.into_iter().flat_map(|v| v.encode()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct Values<T>(Vec<Value<T>>);
|
||||
|
||||
impl<T: Field> TryFrom<serde_json::Value> for Values<T> {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(v: serde_json::Value) -> Result<Values<T>, Self::Error> {
|
||||
match v {
|
||||
serde_json::Value::Array(a) => a
|
||||
.into_iter()
|
||||
.map(|v| Value::try_from(v))
|
||||
.collect::<Result<_, _>>()
|
||||
.map(|v| Values(v)),
|
||||
v => Err(format!("Expected an array of values, found `{}`", v)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> TryFrom<serde_json::Value> for Value<T> {
|
||||
type Error = String;
|
||||
fn try_from(v: serde_json::Value) -> Result<Value<T>, Self::Error> {
|
||||
match v {
|
||||
serde_json::Value::String(s) => T::try_from_dec_str(&s)
|
||||
.map(|v| Value::Field(v))
|
||||
.map_err(|_| format!("Could not parse `{}` as field element", s)),
|
||||
serde_json::Value::Bool(b) => Ok(Value::Boolean(b)),
|
||||
serde_json::Value::Number(n) => Err(format!(
|
||||
"Value `{}` isn't allowed, did you mean `\"{}\"`?",
|
||||
n, n
|
||||
)),
|
||||
serde_json::Value::Array(a) => a
|
||||
.into_iter()
|
||||
.map(|v| Value::try_from(v))
|
||||
.collect::<Result<_, _>>()
|
||||
.map(|v| Value::Array(v)),
|
||||
serde_json::Value::Object(o) => o
|
||||
.into_iter()
|
||||
.map(|(k, v)| Value::try_from(v).map(|v| (k, v)))
|
||||
.collect::<Result<Map<_, _>, _>>()
|
||||
.map(|v| Value::Struct(v)),
|
||||
v => Err(format!("Value `{}` isn't allowed", v)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> Into<serde_json::Value> for CheckedValue<T> {
|
||||
fn into(self) -> serde_json::Value {
|
||||
match self {
|
||||
CheckedValue::Field(f) => serde_json::Value::String(f.to_dec_string()),
|
||||
CheckedValue::Boolean(b) => serde_json::Value::Bool(b),
|
||||
CheckedValue::Array(a) => {
|
||||
serde_json::Value::Array(a.into_iter().map(|e| e.into()).collect())
|
||||
}
|
||||
CheckedValue::Struct(s) => {
|
||||
serde_json::Value::Object(s.into_iter().map(|(k, v)| (k, v.into())).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> Into<serde_json::Value> for CheckedValues<T> {
|
||||
fn into(self) -> serde_json::Value {
|
||||
serde_json::Value::Array(self.0.into_iter().map(|e| e.into()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse<T: Field>(s: &str) -> Result<Values<T>, Error> {
|
||||
let json_values: serde_json::Value =
|
||||
serde_json::from_str(s).map_err(|e| Error::Json(e.to_string()))?;
|
||||
Values::try_from(json_values).map_err(|e| Error::Conversion(e))
|
||||
}
|
||||
|
||||
pub fn parse_strict<T: Field>(s: &str, types: Vec<Type>) -> Result<CheckedValues<T>, Error> {
|
||||
let parsed = parse(s)?;
|
||||
if parsed.0.len() != types.len() {
|
||||
return Err(Error::Type(format!(
|
||||
"Expected {} inputs, found {}",
|
||||
types.len(),
|
||||
parsed.0.len()
|
||||
)));
|
||||
}
|
||||
let checked = parsed
|
||||
.0
|
||||
.into_iter()
|
||||
.zip(types.into_iter())
|
||||
.map(|(v, ty)| v.check(ty))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|e| Error::Type(e))?;
|
||||
Ok(CheckedValues(checked))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
fn numbers() {
|
||||
let s = "[1, 2]";
|
||||
assert_eq!(
|
||||
parse::<FieldPrime>(s).unwrap_err(),
|
||||
Error::Conversion(String::from(
|
||||
"Value `1` isn't allowed, did you mean `\"1\"`?"
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fields() {
|
||||
let s = r#"["1", "2"]"#;
|
||||
assert_eq!(
|
||||
parse::<FieldPrime>(s).unwrap(),
|
||||
Values(vec![Value::Field(1.into()), Value::Field(2.into())])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bools() {
|
||||
let s = "[true, false]";
|
||||
assert_eq!(
|
||||
parse::<FieldPrime>(s).unwrap(),
|
||||
Values(vec![Value::Boolean(true), Value::Boolean(false)])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array() {
|
||||
let s = "[[true, false]]";
|
||||
assert_eq!(
|
||||
parse::<FieldPrime>(s).unwrap(),
|
||||
Values(vec![Value::Array(vec![
|
||||
Value::Boolean(true),
|
||||
Value::Boolean(false)
|
||||
])])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struc() {
|
||||
let s = r#"[{"a": "42"}]"#;
|
||||
assert_eq!(
|
||||
parse::<FieldPrime>(s).unwrap(),
|
||||
Values(vec![Value::Struct(
|
||||
vec![("a".to_string(), Value::Field(42.into()))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
)])
|
||||
);
|
||||
}
|
||||
|
||||
mod strict {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn fields() {
|
||||
let s = r#"["1", "2"]"#;
|
||||
assert_eq!(
|
||||
parse_strict::<FieldPrime>(s, vec![Type::FieldElement, Type::FieldElement])
|
||||
.unwrap(),
|
||||
CheckedValues(vec![
|
||||
CheckedValue::Field(1.into()),
|
||||
CheckedValue::Field(2.into())
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bools() {
|
||||
let s = "[true, false]";
|
||||
assert_eq!(
|
||||
parse_strict::<FieldPrime>(s, vec![Type::Boolean, Type::Boolean]).unwrap(),
|
||||
CheckedValues(vec![
|
||||
CheckedValue::Boolean(true),
|
||||
CheckedValue::Boolean(false)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array() {
|
||||
let s = "[[true, false]]";
|
||||
assert_eq!(
|
||||
parse_strict::<FieldPrime>(s, vec![Type::array(Type::Boolean, 2)]).unwrap(),
|
||||
CheckedValues(vec![CheckedValue::Array(vec![
|
||||
CheckedValue::Boolean(true),
|
||||
CheckedValue::Boolean(false)
|
||||
])])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struc() {
|
||||
let s = r#"[{"a": "42"}]"#;
|
||||
assert_eq!(
|
||||
parse_strict::<FieldPrime>(
|
||||
s,
|
||||
vec![Type::Struct(vec![("a".into(), Type::FieldElement)])]
|
||||
)
|
||||
.unwrap(),
|
||||
CheckedValues(vec![CheckedValue::Struct(
|
||||
vec![("a".to_string(), CheckedValue::Field(42.into()))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
)])
|
||||
);
|
||||
|
||||
let s = r#"[{"b": "42"}]"#;
|
||||
assert_eq!(
|
||||
parse_strict::<FieldPrime>(
|
||||
s,
|
||||
vec![Type::Struct(vec![("a".into(), Type::FieldElement)])]
|
||||
)
|
||||
.unwrap_err(),
|
||||
Error::Type("Member with id `a` not found".into())
|
||||
);
|
||||
|
||||
let s = r#"[{}]"#;
|
||||
assert_eq!(
|
||||
parse_strict::<FieldPrime>(
|
||||
s,
|
||||
vec![Type::Struct(vec![("a".into(), Type::FieldElement)])]
|
||||
)
|
||||
.unwrap_err(),
|
||||
Error::Type("Expected 1 member(s), found 0".into())
|
||||
);
|
||||
|
||||
let s = r#"[{"a": false}]"#;
|
||||
assert_eq!(
|
||||
parse_strict::<FieldPrime>(
|
||||
s,
|
||||
vec![Type::Struct(vec![("a".into(), Type::FieldElement)])]
|
||||
)
|
||||
.unwrap_err(),
|
||||
Error::Type("Value `false` doesn't match expected type `field`".into())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mod encode {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn fields() {
|
||||
let v = CheckedValues(vec![CheckedValue::Field(1), CheckedValue::Field(2)]);
|
||||
assert_eq!(v.encode(), vec![1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bools() {
|
||||
let v: CheckedValues<usize> = CheckedValues(vec![
|
||||
CheckedValue::Boolean(true),
|
||||
CheckedValue::Boolean(false),
|
||||
]);
|
||||
assert_eq!(v.encode(), vec![1, 0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array() {
|
||||
let v: CheckedValues<usize> = CheckedValues(vec![CheckedValue::Array(vec![
|
||||
CheckedValue::Boolean(true),
|
||||
CheckedValue::Boolean(false),
|
||||
])]);
|
||||
assert_eq!(v.encode(), vec![1, 0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struc() {
|
||||
let v: CheckedValues<usize> = CheckedValues(vec![CheckedValue::Struct(
|
||||
vec![("a".to_string(), CheckedValue::Field(42))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
)]);
|
||||
assert_eq!(v.encode(), vec![42]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +1,66 @@
|
|||
## Imports
|
||||
|
||||
You can separate your code into multiple ZoKrates files using `import` statements, ignoring the `.zok` extension of the imported file:
|
||||
You can separate your code into multiple ZoKrates files using `import` statements to import symbols, ignoring the `.zok` extension of the imported file.
|
||||
|
||||
### Import syntax
|
||||
|
||||
#### Symbol selection
|
||||
|
||||
The preferred way to import a symbol is by module and name:
|
||||
```zokrates
|
||||
from "./path/to/my/module" import MySymbol
|
||||
|
||||
// `MySymbol` is now in scope.
|
||||
```
|
||||
|
||||
#### Aliasing
|
||||
|
||||
The `as` keyword enables renaming symbols:
|
||||
|
||||
```zokrates
|
||||
from "./path/to/my/module" import MySymbol as MyAlias
|
||||
|
||||
// `MySymbol` is now in scope under the alias MyAlias.
|
||||
```
|
||||
#### Legacy
|
||||
|
||||
The legacy way to import a symbol is by only specifying a module:
|
||||
```
|
||||
import "./path/to/my/module"
|
||||
```
|
||||
In this case, the name of the symbol is assumed to be `main` and the alias is assumed to be the module's filename so that the above is equivalent to
|
||||
```zokrates
|
||||
from "./path/to/my/module" import main as module
|
||||
|
||||
// `main` is now in scope under the alias `module`.
|
||||
```
|
||||
|
||||
Note that this legacy method is likely to be become deprecated, so it is recommended to use the preferred way instead.
|
||||
### Symbols
|
||||
|
||||
Two type of symbols can be imported
|
||||
|
||||
#### Functions
|
||||
Functions are imported by name. If many functions have the same name but different signatures, all of them get imported, and which one to use in a particular call is infered.
|
||||
|
||||
#### User-defined types
|
||||
User-defined types declared with the `struct` keyword are imported by name.
|
||||
|
||||
### Relative Imports
|
||||
|
||||
You can import a resource in the same folder directly, like this:
|
||||
```zokrates
|
||||
import "./mycode"
|
||||
from "./mycode" import foo
|
||||
```
|
||||
|
||||
There also is a handy syntax to import from the parent directory:
|
||||
```zokrates
|
||||
import "../mycode"
|
||||
from "../mycode" import foo
|
||||
```
|
||||
|
||||
Also imports further up the file-system are supported:
|
||||
```zokrates
|
||||
import "../../../mycode"
|
||||
```
|
||||
|
||||
You can also choose to rename the imported resource, like so:
|
||||
```zokrates
|
||||
import "./mycode" as abc
|
||||
from "../../../mycode" import foo
|
||||
```
|
||||
|
||||
### Absolute Imports
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
## Types
|
||||
# Types
|
||||
|
||||
ZoKrates currently exposes two primitive types and a complex array type:
|
||||
ZoKrates currently exposes two primitive types and two complex types:
|
||||
|
||||
### Primitive Types
|
||||
## Primitive Types
|
||||
|
||||
#### `field`
|
||||
### `field`
|
||||
|
||||
This is the most basic type in ZoKrates, and it represents a positive integer in `[0, p - 1]` where `p` is a (large) prime number.
|
||||
|
||||
|
@ -16,7 +16,7 @@ While `field` values mostly behave like unsigned integers, one should keep in mi
|
|||
{{#include ../../../zokrates_cli/examples/book/field_overflow.zok}}
|
||||
```
|
||||
|
||||
#### `bool`
|
||||
### `bool`
|
||||
|
||||
ZoKrates has limited support for booleans, to the extent that they can only be used as the condition in `if ... else ... endif` expressions.
|
||||
|
||||
|
@ -24,9 +24,11 @@ You can use them for equality checks, inequality checks and inequality checks be
|
|||
|
||||
Note that while equality checks are cheap, inequality checks should be use wisely as they are orders of magnitude more expensive.
|
||||
|
||||
### Complex Types
|
||||
## Complex Types
|
||||
|
||||
#### Arrays
|
||||
ZoKrates provides two complex types, Arrays and Structs.
|
||||
|
||||
### Arrays
|
||||
|
||||
ZoKrates supports static arrays, i.e., their length needs to be known at compile time.
|
||||
Arrays can contain elements of any type and have arbitrary dimensions.
|
||||
|
@ -37,10 +39,10 @@ The following examples code shows examples of how to use arrays:
|
|||
{{#include ../../../zokrates_cli/examples/book/array.zok}}
|
||||
```
|
||||
|
||||
##### Declaration and Initialization
|
||||
#### Declaration and Initialization
|
||||
An array is defined by appending `[]` to a type literal representing the type of the array's elements.
|
||||
|
||||
Initialization always needs to happen in the same statement than declaration, unless the array is declared within a function's signature.
|
||||
Initialization always needs to happen in the same statement as declaration, unless the array is declared within a function's signature.
|
||||
|
||||
For initialization, a list of comma-separated values is provided within brackets `[]`.
|
||||
|
||||
|
@ -54,7 +56,7 @@ The following code provides examples for declaration and initialization:
|
|||
bool[13] b = [false; 13] // initialize a bool array with value false
|
||||
```
|
||||
|
||||
##### Multidimensional Arrays
|
||||
#### Multidimensional Arrays
|
||||
|
||||
As an array can contain any type of elements, it can contain arrays again.
|
||||
There is a special syntax to declare such multi-dimensional arrays, i.e., arrays of arrays.
|
||||
|
@ -67,21 +69,59 @@ Consider the following example:
|
|||
{{#include ../../../zokrates_cli/examples/book/multidim_array.zok}}
|
||||
```
|
||||
|
||||
##### Spreads and Slices
|
||||
#### Spreads and Slices
|
||||
ZoKrates provides some syntactic sugar to retrieve subsets of arrays.
|
||||
|
||||
###### Spreads
|
||||
The spread operator `...` applied to an copies the elements of an existing array.
|
||||
##### Spreads
|
||||
The spread operator `...` applied to an array copies the elements of the existing array.
|
||||
This can be used to conveniently compose new arrays, as shown in the following example:
|
||||
```
|
||||
field[3] = [1, 2, 3]
|
||||
field[4] c = [...a, 4] // initialize an array copying values from `a`, followed by 4
|
||||
```
|
||||
|
||||
###### Slices
|
||||
##### Slices
|
||||
An array can also be assigned to by creating a copy of a subset of an existing array.
|
||||
This operation is called slicing, and the following example shows how to slice in ZoKrates:
|
||||
```
|
||||
field[3] a = [1, 2, 3]
|
||||
field[2] b = a[1..3] // initialize an array copying a slice from `a`
|
||||
```
|
||||
|
||||
### Structs
|
||||
A struct is a composite datatype representing a named collection of variables.
|
||||
The contained variables can be of any type.
|
||||
|
||||
The following code shows an example of how to use structs.
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/structs.code}}
|
||||
```
|
||||
|
||||
#### Definition
|
||||
Before a struct data type can be used, it needs to be defined.
|
||||
A struct definition starts with the `struct` keyword followed by a name. Afterwards, a new-line separated list of variables is declared in curly braces `{}`. For example:
|
||||
|
||||
```zokrates
|
||||
struct Point {
|
||||
field x
|
||||
field y
|
||||
}
|
||||
```
|
||||
|
||||
#### Declaration and Initialization
|
||||
|
||||
Initialization of a variable of a struct type always needs to happen in the same statement as declaration, unless the struct-typed variable is declared within a function's signature.
|
||||
|
||||
The following example shows declaration and initialization of a variable of the `Point` struct type:
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/struct_init.code}}
|
||||
```
|
||||
|
||||
#### Assignment
|
||||
The variables within a struct instance, the so called members, can be accessed through the `.` operator as shown in the following extended example:
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/struct_assign.code}}
|
||||
```
|
||||
|
|
670
zokrates_cli/Cargo.lock
generated
670
zokrates_cli/Cargo.lock
generated
|
@ -1,670 +0,0 @@
|
|||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assert_cli"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"skeptic 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace-sys"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "difference"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "environment"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "error-chain"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reduce"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "skeptic"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cargo_metadata 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempdir"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-util"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "zokrates"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reduce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zokrates-cli"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates 0.1.0",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0ba20154ea1f47ce2793322f049c5646cc6d0fa9759d5f333f286e507bf8080"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72342c21057a3cb5f7c2d849bf7999a83795434dd36d74fa8c24680581bd1930"
|
||||
"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
|
||||
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
|
||||
"checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e"
|
||||
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
|
||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
|
||||
"checksum bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "882585cd7ec84e902472df34a5e01891202db3bf62614e1f0afe459c1afcf744"
|
||||
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
|
||||
"checksum cargo_metadata 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "682476b87b3e22cd3820d86b26cd8603cd84ab76dce7547b2631858347aa8967"
|
||||
"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d"
|
||||
"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e"
|
||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||
"checksum cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "95470235c31c726d72bf2e1f421adc1e65b9d561bf5529612cbe1a72da1467b3"
|
||||
"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
|
||||
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
|
||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||
"checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee"
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
|
||||
"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417"
|
||||
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
||||
"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
|
||||
"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
|
||||
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
||||
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
|
||||
"checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1"
|
||||
"checksum num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656"
|
||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||
"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124"
|
||||
"checksum num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e"
|
||||
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
|
||||
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
|
||||
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
||||
"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum reduce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f77b717415291f4d7929a111402316b272c566ae9d4b75a61507dba88ecbd89"
|
||||
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
|
||||
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
|
||||
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
|
||||
"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
|
||||
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)" = "429fcc4efa8a11341b5422c2ace724daba276c1748467e869478f53c0ba4562e"
|
||||
"checksum serde_derive 1.0.68 (registry+https://github.com/rust-lang/crates.io-index)" = "6a25ad0bf818ed2d180c89addbe29198d1de6c89ed08a48aa6a4d3d16a63cbfe"
|
||||
"checksum serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "84b8035cabe9b35878adec8ac5fe03d5f6bc97ff6edd7ccb96b44c1276ba390e"
|
||||
"checksum skeptic 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4474d6da9593171bcb086890fc344a3a12783cb24e5b141f8a5d0e43561f4b6"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c67da57e61ebc7b7b6fff56bb34440ca3a83db037320b0507af4c10368deda7d"
|
||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
|
||||
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
|
||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
|
||||
"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -16,6 +16,7 @@ clap = "2.26.2"
|
|||
bincode = "0.8.0"
|
||||
regex = "0.2"
|
||||
zokrates_field = { version = "0.3", path = "../zokrates_field" }
|
||||
zokrates_abi = { version = "0.1", path = "../zokrates_abi" }
|
||||
zokrates_core = { version = "0.3", path = "../zokrates_core" }
|
||||
zokrates_fs_resolver = { version = "0.4", path = "../zokrates_fs_resolver"}
|
||||
zokrates_github_resolver = { version = "0.1", path = "../zokrates_github_resolver", optional = true}
|
||||
|
|
10
zokrates_cli/examples/book/struct_assign.code
Normal file
10
zokrates_cli/examples/book/struct_assign.code
Normal file
|
@ -0,0 +1,10 @@
|
|||
struct Point {
|
||||
field x
|
||||
field y
|
||||
}
|
||||
|
||||
def main(field a) -> (Point):
|
||||
Point p = Point {x: 1, y: 0}
|
||||
p.x = a
|
||||
p.y = p.x
|
||||
return p
|
8
zokrates_cli/examples/book/struct_init.code
Normal file
8
zokrates_cli/examples/book/struct_init.code
Normal file
|
@ -0,0 +1,8 @@
|
|||
struct Point {
|
||||
field x
|
||||
field y
|
||||
}
|
||||
|
||||
def main() -> (Point):
|
||||
Point p = Point {x: 1, y: 0}
|
||||
return p
|
14
zokrates_cli/examples/book/structs.code
Normal file
14
zokrates_cli/examples/book/structs.code
Normal file
|
@ -0,0 +1,14 @@
|
|||
struct Bar {
|
||||
field[2] c
|
||||
bool d
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
Bar a
|
||||
bool b
|
||||
}
|
||||
|
||||
def main() -> (Foo):
|
||||
Foo[2] f = [Foo { a: Bar { c: [0, 0], d: false }, b: true}, Foo { a: Bar {c: [0, 0], d: false}, b: true}]
|
||||
f[0].a.c = [42, 43]
|
||||
return f[0]
|
16
zokrates_cli/examples/structs/add.code
Normal file
16
zokrates_cli/examples/structs/add.code
Normal file
|
@ -0,0 +1,16 @@
|
|||
struct Point {
|
||||
field x
|
||||
field y
|
||||
}
|
||||
|
||||
def main(Point p, Point q) -> (Point):
|
||||
|
||||
field a = 42
|
||||
field d = 21
|
||||
|
||||
field dpxpyqxqy = d * p.x * p.y * q.x * q.y
|
||||
|
||||
return Point {
|
||||
x: (p.x * q.y + q.x * p.y) / (1 + dpxpyqxqy),
|
||||
y: (q.x * q.y - a * p.x * p.y) / (1 - dpxpyqxqy)
|
||||
}
|
29
zokrates_cli/examples/structs/set_member.code
Normal file
29
zokrates_cli/examples/structs/set_member.code
Normal file
|
@ -0,0 +1,29 @@
|
|||
struct Bar {
|
||||
field[2] c
|
||||
bool d
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
Bar a
|
||||
bool b
|
||||
}
|
||||
|
||||
def main() -> (Foo):
|
||||
Foo[2] f = [
|
||||
Foo {
|
||||
a: Bar {
|
||||
c: [0, 0],
|
||||
d: false
|
||||
},
|
||||
b: true
|
||||
},
|
||||
Foo {
|
||||
a: Bar {
|
||||
c: [0, 0],
|
||||
d: false
|
||||
},
|
||||
b: true
|
||||
}
|
||||
]
|
||||
f[0].a.c = [42, 43]
|
||||
return f[0]
|
|
@ -12,6 +12,7 @@ use std::io::{stdin, BufReader, BufWriter, Read, Write};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::string::String;
|
||||
use std::{env, io};
|
||||
use zokrates_abi::Encode;
|
||||
use zokrates_core::compile::compile;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::proof_system::*;
|
||||
|
@ -176,10 +177,19 @@ fn cli() -> Result<(), String> {
|
|||
).arg(Arg::with_name("arguments")
|
||||
.short("a")
|
||||
.long("arguments")
|
||||
.help("Arguments for the program's main method as a space separated list")
|
||||
.help("Arguments for the program's main function")
|
||||
.takes_value(true)
|
||||
.multiple(true) // allows multiple values
|
||||
.required(false)
|
||||
).arg(Arg::with_name("abi")
|
||||
.long("abi")
|
||||
.help("Use the ABI")
|
||||
.required(false)
|
||||
).arg(Arg::with_name("stdin")
|
||||
.long("stdin")
|
||||
.help("Read arguments from stdin")
|
||||
.conflicts_with("arguments")
|
||||
.required(false)
|
||||
).arg(Arg::with_name("light")
|
||||
.long("light")
|
||||
.help("Skip logs and human readable output")
|
||||
|
@ -329,60 +339,89 @@ fn cli() -> Result<(), String> {
|
|||
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
let program_ast: ir::Prog<FieldPrime> =
|
||||
let ir_prog: ir::Prog<FieldPrime> =
|
||||
deserialize_from(&mut reader, Infinite).map_err(|why| why.to_string())?;
|
||||
|
||||
// print deserialized flattened program
|
||||
if !sub_matches.is_present("light") {
|
||||
println!("{}", program_ast);
|
||||
println!("{}", ir_prog);
|
||||
}
|
||||
|
||||
let expected_cli_args_count =
|
||||
program_ast.public_arguments_count() + program_ast.private_arguments_count();
|
||||
let signature = ir_prog.signature.clone();
|
||||
|
||||
let is_stdin = sub_matches.is_present("stdin");
|
||||
let is_abi = sub_matches.is_present("abi");
|
||||
|
||||
if !is_stdin && is_abi {
|
||||
return Err(
|
||||
"ABI input as inline argument is not supported. Please use `--stdin`.".into(),
|
||||
);
|
||||
}
|
||||
|
||||
use zokrates_abi::Inputs;
|
||||
|
||||
// get arguments
|
||||
let arguments: Vec<_> = match sub_matches.values_of("arguments") {
|
||||
let arguments = match is_stdin {
|
||||
// take inline arguments
|
||||
Some(p) => p
|
||||
.map(|x| FieldPrime::try_from_dec_str(x).map_err(|_| x.to_string()))
|
||||
.collect(),
|
||||
false => {
|
||||
let arguments = sub_matches.values_of("arguments");
|
||||
arguments
|
||||
.map(|a| {
|
||||
a.map(|x| FieldPrime::try_from_dec_str(x).map_err(|_| x.to_string()))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
})
|
||||
.unwrap_or(Ok(vec![]))
|
||||
.map(|v| Inputs::Raw(v))
|
||||
}
|
||||
// take stdin arguments
|
||||
None => {
|
||||
if expected_cli_args_count > 0 {
|
||||
let mut stdin = stdin();
|
||||
let mut input = String::new();
|
||||
match stdin.read_to_string(&mut input) {
|
||||
true => {
|
||||
let mut stdin = stdin();
|
||||
let mut input = String::new();
|
||||
|
||||
match is_abi {
|
||||
true => match stdin.read_to_string(&mut input) {
|
||||
Ok(_) => {
|
||||
input.retain(|x| x != '\n');
|
||||
input
|
||||
.split(" ")
|
||||
.map(|x| {
|
||||
FieldPrime::try_from_dec_str(x).map_err(|_| x.to_string())
|
||||
})
|
||||
.collect()
|
||||
use zokrates_abi::parse_strict;
|
||||
|
||||
parse_strict(&input, signature.inputs)
|
||||
.map(|parsed| Inputs::Abi(parsed))
|
||||
.map_err(|why| why.to_string())
|
||||
}
|
||||
Err(_) => Err(String::from("???")),
|
||||
}
|
||||
} else {
|
||||
Ok(vec![])
|
||||
},
|
||||
false => match ir_prog.arguments_count() {
|
||||
0 => Ok(Inputs::Raw(vec![])),
|
||||
_ => match stdin.read_to_string(&mut input) {
|
||||
Ok(_) => {
|
||||
input.retain(|x| x != '\n');
|
||||
input
|
||||
.split(" ")
|
||||
.map(|x| {
|
||||
FieldPrime::try_from_dec_str(x)
|
||||
.map_err(|_| x.to_string())
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map(|v| Inputs::Raw(v))
|
||||
}
|
||||
Err(_) => Err(String::from("???")),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
.map_err(|e| format!("Could not parse argument: {}", e))?;
|
||||
|
||||
if arguments.len() != expected_cli_args_count {
|
||||
Err(format!(
|
||||
"Wrong number of arguments. Given: {}, Required: {}.",
|
||||
arguments.len(),
|
||||
expected_cli_args_count
|
||||
))?
|
||||
}
|
||||
|
||||
let witness = program_ast
|
||||
.execute(&arguments)
|
||||
let witness = ir_prog
|
||||
.execute(&arguments.encode())
|
||||
.map_err(|e| format!("Execution failed: {}", e))?;
|
||||
|
||||
println!("\nWitness: \n\n{}", witness.format_outputs());
|
||||
use zokrates_abi::Decode;
|
||||
|
||||
let results_json_value: serde_json::Value =
|
||||
zokrates_abi::CheckedValues::decode(witness.return_values(), signature.outputs)
|
||||
.into();
|
||||
|
||||
println!("\nWitness: \n\n{}", results_json_value.to_string());
|
||||
|
||||
// write witness to file
|
||||
let output_path = Path::new(sub_matches.value_of("output").unwrap());
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[
|
||||
1,
|
||||
2
|
||||
"1",
|
||||
"2"
|
||||
]
|
|
@ -1 +1,3 @@
|
|||
[0]
|
||||
[
|
||||
"0"
|
||||
]
|
|
@ -1 +1,3 @@
|
|||
[1]
|
||||
[
|
||||
"1"
|
||||
]
|
|
@ -1,6 +1,12 @@
|
|||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
[
|
||||
[
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
[
|
||||
"0",
|
||||
"0"
|
||||
]
|
||||
]
|
||||
]
|
|
@ -1 +1,4 @@
|
|||
[5, 1]
|
||||
[
|
||||
"5",
|
||||
"1"
|
||||
]
|
|
@ -1,4 +1,4 @@
|
|||
[
|
||||
1,
|
||||
1
|
||||
"1",
|
||||
"1"
|
||||
]
|
|
@ -1 +1,14 @@
|
|||
[1, 1, 1, 2, 3, 3, 3, 3]
|
||||
[
|
||||
[
|
||||
"1",
|
||||
"1",
|
||||
"1"
|
||||
],
|
||||
"2",
|
||||
[
|
||||
"3",
|
||||
"3",
|
||||
"3",
|
||||
"3"
|
||||
]
|
||||
]
|
|
@ -1 +1,260 @@
|
|||
[0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1]
|
||||
[
|
||||
[
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1"
|
||||
]
|
||||
]
|
|
@ -1 +1,4 @@
|
|||
[1, 2]
|
||||
[
|
||||
"1",
|
||||
"2"
|
||||
]
|
|
@ -1 +1,5 @@
|
|||
[2, 3, 4]
|
||||
[
|
||||
"2",
|
||||
"3",
|
||||
"4"
|
||||
]
|
|
@ -1 +1,4 @@
|
|||
[15, 12]
|
||||
[
|
||||
"15",
|
||||
"12"
|
||||
]
|
|
@ -4,14 +4,16 @@ extern crate serde_json;
|
|||
#[cfg(test)]
|
||||
mod integration {
|
||||
use assert_cli;
|
||||
use serde_json;
|
||||
use serde_json::Value;
|
||||
use bincode::{deserialize_from, Infinite};
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::panic;
|
||||
use std::path::Path;
|
||||
use tempdir::TempDir;
|
||||
use zokrates_abi::{parse_strict, Encode};
|
||||
use zokrates_core::ir;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
|
@ -29,8 +31,13 @@ mod integration {
|
|||
Path::new(Path::new(path.file_stem().unwrap()).file_stem().unwrap());
|
||||
let prog = dir.join(program_name).with_extension("zok");
|
||||
let witness = dir.join(program_name).with_extension("expected.witness");
|
||||
let args = dir.join(program_name).with_extension("arguments.json");
|
||||
test_compile_and_witness(program_name.to_str().unwrap(), &prog, &args, &witness);
|
||||
let json_input = dir.join(program_name).with_extension("arguments.json");
|
||||
test_compile_and_witness(
|
||||
program_name.to_str().unwrap(),
|
||||
&prog,
|
||||
&json_input,
|
||||
&witness,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +54,7 @@ mod integration {
|
|||
fn test_compile_and_witness(
|
||||
program_name: &str,
|
||||
program_path: &Path,
|
||||
arguments_path: &Path,
|
||||
inputs_path: &Path,
|
||||
expected_witness_path: &Path,
|
||||
) {
|
||||
let tmp_dir = TempDir::new(".tmp").unwrap();
|
||||
|
@ -88,24 +95,51 @@ mod integration {
|
|||
assert_cli::Assert::command(&compile).succeeds().unwrap();
|
||||
|
||||
// COMPUTE_WITNESS
|
||||
let arguments: Value =
|
||||
serde_json::from_reader(File::open(arguments_path).unwrap()).unwrap();
|
||||
|
||||
let arguments_str_list: Vec<String> = arguments
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|i| match *i {
|
||||
Value::Number(ref n) => n.to_string(),
|
||||
_ => panic!(format!(
|
||||
"Cannot read arguments. Check {}",
|
||||
arguments_path.to_str().unwrap()
|
||||
)),
|
||||
})
|
||||
// derive program signature from IR program representation
|
||||
let file = File::open(&flattened_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", flattened_path.display(), why))
|
||||
.unwrap();
|
||||
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
let ir_prog: ir::Prog<FieldPrime> = deserialize_from(&mut reader, Infinite)
|
||||
.map_err(|why| why.to_string())
|
||||
.unwrap();
|
||||
|
||||
let signature = ir_prog.signature.clone();
|
||||
|
||||
// run witness-computation for ABI-encoded inputs through stdin
|
||||
let json_input_str = fs::read_to_string(inputs_path).unwrap();
|
||||
|
||||
let compute = vec![
|
||||
"../target/release/zokrates",
|
||||
"compute-witness",
|
||||
"-i",
|
||||
flattened_path.to_str().unwrap(),
|
||||
"-o",
|
||||
witness_path.to_str().unwrap(),
|
||||
"--stdin",
|
||||
"--abi",
|
||||
];
|
||||
|
||||
assert_cli::Assert::command(&compute)
|
||||
.stdin(&json_input_str)
|
||||
.succeeds()
|
||||
.unwrap();
|
||||
|
||||
// run witness-computation for raw-encoded inputs (converted) with `-a <arguments>`
|
||||
let inputs_abi: zokrates_abi::Inputs<zokrates_field::field::FieldPrime> =
|
||||
parse_strict(&json_input_str, signature.inputs)
|
||||
.map(|parsed| zokrates_abi::Inputs::Abi(parsed))
|
||||
.map_err(|why| why.to_string())
|
||||
.unwrap();
|
||||
let inputs_raw: Vec<_> = inputs_abi
|
||||
.encode()
|
||||
.into_iter()
|
||||
.map(|v| v.to_string())
|
||||
.collect();
|
||||
|
||||
// WITH `-a <arguments>`
|
||||
|
||||
let mut compute_inline = vec![
|
||||
"../target/release/zokrates",
|
||||
"compute-witness",
|
||||
|
@ -116,7 +150,7 @@ mod integration {
|
|||
"-a",
|
||||
];
|
||||
|
||||
for arg in arguments_str_list.iter() {
|
||||
for arg in &inputs_raw {
|
||||
compute_inline.push(arg);
|
||||
}
|
||||
|
||||
|
@ -124,22 +158,6 @@ mod integration {
|
|||
.succeeds()
|
||||
.unwrap();
|
||||
|
||||
// WITH stdin ARGUMENTS
|
||||
|
||||
let compute = vec![
|
||||
"../target/release/zokrates",
|
||||
"compute-witness",
|
||||
"-i",
|
||||
flattened_path.to_str().unwrap(),
|
||||
"-o",
|
||||
witness_path.to_str().unwrap(),
|
||||
];
|
||||
|
||||
assert_cli::Assert::command(&compute)
|
||||
.stdin(&arguments_str_list.join(" "))
|
||||
.succeeds()
|
||||
.unwrap();
|
||||
|
||||
// load the expected witness
|
||||
let mut expected_witness_file = File::open(&expected_witness_path).unwrap();
|
||||
let mut expected_witness = String::new();
|
||||
|
|
|
@ -1,48 +1,96 @@
|
|||
use absy;
|
||||
use imports;
|
||||
use types::Type;
|
||||
use zokrates_field::field::Field;
|
||||
use zokrates_pest_ast as pest;
|
||||
|
||||
impl<'ast, T: Field> From<pest::File<'ast>> for absy::Module<'ast, T> {
|
||||
fn from(prog: pest::File<'ast>) -> absy::Module<T> {
|
||||
absy::Module {
|
||||
functions: prog
|
||||
.functions
|
||||
absy::Module::with_symbols(
|
||||
prog.structs
|
||||
.into_iter()
|
||||
.map(|f| absy::FunctionDeclarationNode::from(f))
|
||||
.collect(),
|
||||
imports: prog
|
||||
.imports
|
||||
.into_iter()
|
||||
.map(|i| absy::ImportNode::from(i))
|
||||
.collect(),
|
||||
}
|
||||
.map(|t| absy::SymbolDeclarationNode::from(t))
|
||||
.chain(
|
||||
prog.functions
|
||||
.into_iter()
|
||||
.map(|f| absy::SymbolDeclarationNode::from(f)),
|
||||
),
|
||||
)
|
||||
.imports(prog.imports.into_iter().map(|i| absy::ImportNode::from(i)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<pest::ImportDirective<'ast>> for absy::ImportNode<'ast> {
|
||||
fn from(import: pest::ImportDirective<'ast>) -> absy::ImportNode {
|
||||
use absy::NodeValue;
|
||||
imports::Import::new(import.source.span.as_str())
|
||||
|
||||
match import {
|
||||
pest::ImportDirective::Main(import) => {
|
||||
imports::Import::new(None, import.source.span.as_str())
|
||||
.alias(import.alias.map(|a| a.span.as_str()))
|
||||
.span(import.span)
|
||||
}
|
||||
pest::ImportDirective::From(import) => imports::Import::new(
|
||||
Some(import.symbol.span.as_str()),
|
||||
import.source.span.as_str(),
|
||||
)
|
||||
.alias(import.alias.map(|a| a.span.as_str()))
|
||||
.span(import.span)
|
||||
.span(import.span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionDeclarationNode<'ast, T> {
|
||||
fn from(function: pest::Function<'ast>) -> absy::FunctionDeclarationNode<T> {
|
||||
impl<'ast, T: Field> From<pest::StructDefinition<'ast>> for absy::SymbolDeclarationNode<'ast, T> {
|
||||
fn from(definition: pest::StructDefinition<'ast>) -> absy::SymbolDeclarationNode<'ast, T> {
|
||||
use absy::NodeValue;
|
||||
|
||||
let span = definition.span;
|
||||
|
||||
let id = definition.id.span.as_str();
|
||||
|
||||
let ty = absy::StructType {
|
||||
fields: definition
|
||||
.fields
|
||||
.into_iter()
|
||||
.map(|f| absy::StructFieldNode::from(f))
|
||||
.collect(),
|
||||
}
|
||||
.span(span.clone());
|
||||
|
||||
absy::SymbolDeclaration {
|
||||
id,
|
||||
symbol: absy::Symbol::HereType(ty),
|
||||
}
|
||||
.span(span)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<pest::StructField<'ast>> for absy::StructFieldNode<'ast> {
|
||||
fn from(field: pest::StructField<'ast>) -> absy::StructFieldNode {
|
||||
use absy::NodeValue;
|
||||
|
||||
let span = field.span;
|
||||
|
||||
let id = field.id.span.as_str();
|
||||
|
||||
let ty = absy::UnresolvedTypeNode::from(field.ty);
|
||||
|
||||
absy::StructField { id, ty }.span(span)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> From<pest::Function<'ast>> for absy::SymbolDeclarationNode<'ast, T> {
|
||||
fn from(function: pest::Function<'ast>) -> absy::SymbolDeclarationNode<T> {
|
||||
use absy::NodeValue;
|
||||
|
||||
let span = function.span;
|
||||
|
||||
let signature = absy::Signature::new()
|
||||
let signature = absy::UnresolvedSignature::new()
|
||||
.inputs(
|
||||
function
|
||||
.parameters
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|p| absy::ParameterNode::from(p).value.id.value.get_type())
|
||||
.map(|p| absy::UnresolvedTypeNode::from(p.ty))
|
||||
.collect(),
|
||||
)
|
||||
.outputs(
|
||||
|
@ -50,7 +98,7 @@ impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionDeclarationNod
|
|||
.returns
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|r| Type::from(r))
|
||||
.map(|r| absy::UnresolvedTypeNode::from(r))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
|
@ -71,9 +119,9 @@ impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionDeclarationNod
|
|||
}
|
||||
.span(span.clone());
|
||||
|
||||
absy::FunctionDeclaration {
|
||||
absy::SymbolDeclaration {
|
||||
id,
|
||||
symbol: absy::FunctionSymbol::Here(function),
|
||||
symbol: absy::Symbol::HereFunction(function),
|
||||
}
|
||||
.span(span)
|
||||
}
|
||||
|
@ -91,8 +139,11 @@ impl<'ast> From<pest::Parameter<'ast>> for absy::ParameterNode<'ast> {
|
|||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
let variable =
|
||||
absy::Variable::new(param.id.span.as_str(), Type::from(param.ty)).span(param.id.span);
|
||||
let variable = absy::Variable::new(
|
||||
param.id.span.as_str(),
|
||||
absy::UnresolvedTypeNode::from(param.ty),
|
||||
)
|
||||
.span(param.id.span);
|
||||
|
||||
absy::Parameter::new(variable, private).span(param.span)
|
||||
}
|
||||
|
@ -123,7 +174,11 @@ fn statements_from_multi_assignment<'ast, T: Field>(
|
|||
.filter(|i| i.ty.is_some())
|
||||
.map(|i| {
|
||||
absy::Statement::Declaration(
|
||||
absy::Variable::new(i.id.span.as_str(), Type::from(i.ty.unwrap())).span(i.id.span),
|
||||
absy::Variable::new(
|
||||
i.id.span.as_str(),
|
||||
absy::UnresolvedTypeNode::from(i.ty.unwrap()),
|
||||
)
|
||||
.span(i.id.span),
|
||||
)
|
||||
.span(i.span)
|
||||
});
|
||||
|
@ -158,8 +213,11 @@ fn statements_from_definition<'ast, T: Field>(
|
|||
|
||||
vec![
|
||||
absy::Statement::Declaration(
|
||||
absy::Variable::new(definition.id.span.as_str(), Type::from(definition.ty))
|
||||
.span(definition.id.span.clone()),
|
||||
absy::Variable::new(
|
||||
definition.id.span.as_str(),
|
||||
absy::UnresolvedTypeNode::from(definition.ty),
|
||||
)
|
||||
.span(definition.id.span.clone()),
|
||||
)
|
||||
.span(definition.span.clone()),
|
||||
absy::Statement::Definition(
|
||||
|
@ -218,7 +276,7 @@ impl<'ast, T: Field> From<pest::IterationStatement<'ast>> for absy::StatementNod
|
|||
let from = absy::ExpressionNode::from(statement.from);
|
||||
let to = absy::ExpressionNode::from(statement.to);
|
||||
let index = statement.index.span.as_str();
|
||||
let ty = Type::from(statement.ty);
|
||||
let ty = absy::UnresolvedTypeNode::from(statement.ty);
|
||||
let statements: Vec<absy::StatementNode<T>> = statement
|
||||
.statements
|
||||
.into_iter()
|
||||
|
@ -262,6 +320,7 @@ impl<'ast, T: Field> From<pest::Expression<'ast>> for absy::ExpressionNode<'ast,
|
|||
pest::Expression::Identifier(e) => absy::ExpressionNode::from(e),
|
||||
pest::Expression::Postfix(e) => absy::ExpressionNode::from(e),
|
||||
pest::Expression::InlineArray(e) => absy::ExpressionNode::from(e),
|
||||
pest::Expression::InlineStruct(e) => absy::ExpressionNode::from(e),
|
||||
pest::Expression::ArrayInitializer(e) => absy::ExpressionNode::from(e),
|
||||
pest::Expression::Unary(e) => absy::ExpressionNode::from(e),
|
||||
}
|
||||
|
@ -414,6 +473,25 @@ impl<'ast, T: Field> From<pest::InlineArrayExpression<'ast>> for absy::Expressio
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> From<pest::InlineStructExpression<'ast>> for absy::ExpressionNode<'ast, T> {
|
||||
fn from(s: pest::InlineStructExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
|
||||
use absy::NodeValue;
|
||||
absy::Expression::InlineStruct(
|
||||
s.ty.span.as_str().to_string(),
|
||||
s.members
|
||||
.into_iter()
|
||||
.map(|member| {
|
||||
(
|
||||
member.id.span.as_str(),
|
||||
absy::ExpressionNode::from(member.expression),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.span(s.span)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> From<pest::ArrayInitializerExpression<'ast>>
|
||||
for absy::ExpressionNode<'ast, T>
|
||||
{
|
||||
|
@ -471,6 +549,9 @@ impl<'ast, T: Field> From<pest::PostfixExpression<'ast>> for absy::ExpressionNod
|
|||
absy::Expression::Select(box acc, box absy::RangeOrExpression::from(a.expression))
|
||||
.span(a.span)
|
||||
}
|
||||
pest::Access::Member(m) => {
|
||||
absy::Expression::Member(box acc, box m.id.span.as_str()).span(m.span)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -511,29 +592,44 @@ impl<'ast, T: Field> From<pest::Assignee<'ast>> for absy::AssigneeNode<'ast, T>
|
|||
let a = absy::AssigneeNode::from(assignee.id);
|
||||
let span = assignee.span;
|
||||
|
||||
assignee
|
||||
.indices
|
||||
.into_iter()
|
||||
.map(|i| absy::RangeOrExpression::from(i))
|
||||
.fold(a, |acc, s| {
|
||||
absy::Assignee::Select(box acc, box s).span(span.clone())
|
||||
})
|
||||
assignee.accesses.into_iter().fold(a, |acc, s| {
|
||||
match s {
|
||||
pest::AssigneeAccess::Select(s) => {
|
||||
absy::Assignee::Select(box acc, box absy::RangeOrExpression::from(s.expression))
|
||||
}
|
||||
pest::AssigneeAccess::Member(m) => {
|
||||
absy::Assignee::Member(box acc, box m.id.span.as_str())
|
||||
}
|
||||
}
|
||||
.span(span.clone())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<pest::Type<'ast>> for Type {
|
||||
fn from(t: pest::Type<'ast>) -> Type {
|
||||
impl<'ast> From<pest::Type<'ast>> for absy::UnresolvedTypeNode {
|
||||
fn from(t: pest::Type<'ast>) -> absy::UnresolvedTypeNode {
|
||||
use absy::NodeValue;
|
||||
|
||||
match t {
|
||||
pest::Type::Basic(t) => match t {
|
||||
pest::BasicType::Field(_) => Type::FieldElement,
|
||||
pest::BasicType::Boolean(_) => Type::Boolean,
|
||||
pest::BasicType::Field(t) => absy::UnresolvedType::FieldElement.span(t.span),
|
||||
pest::BasicType::Boolean(t) => absy::UnresolvedType::Boolean.span(t.span),
|
||||
},
|
||||
pest::Type::Array(t) => {
|
||||
let inner_type = match t.ty {
|
||||
pest::BasicType::Field(_) => Type::FieldElement,
|
||||
pest::BasicType::Boolean(_) => Type::Boolean,
|
||||
pest::BasicOrStructType::Basic(t) => match t {
|
||||
pest::BasicType::Field(t) => {
|
||||
absy::UnresolvedType::FieldElement.span(t.span)
|
||||
}
|
||||
pest::BasicType::Boolean(t) => absy::UnresolvedType::Boolean.span(t.span),
|
||||
},
|
||||
pest::BasicOrStructType::Struct(t) => {
|
||||
absy::UnresolvedType::User(t.span.as_str().to_string()).span(t.span)
|
||||
}
|
||||
};
|
||||
|
||||
let span = t.span;
|
||||
|
||||
t.dimensions
|
||||
.into_iter()
|
||||
.map(|s| match s {
|
||||
|
@ -553,10 +649,14 @@ impl<'ast> From<pest::Type<'ast>> for Type {
|
|||
})
|
||||
.rev()
|
||||
.fold(None, |acc, s| match acc {
|
||||
None => Some(Type::array(inner_type.clone(), s)),
|
||||
Some(acc) => Some(Type::array(acc, s)),
|
||||
None => Some(absy::UnresolvedType::array(inner_type.clone(), s)),
|
||||
Some(acc) => Some(absy::UnresolvedType::array(acc.span(span.clone()), s)),
|
||||
})
|
||||
.unwrap()
|
||||
.span(span.clone())
|
||||
}
|
||||
pest::Type::Struct(s) => {
|
||||
absy::UnresolvedType::User(s.id.span.as_str().to_string()).span(s.span)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -565,6 +665,7 @@ impl<'ast> From<pest::Type<'ast>> for Type {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use absy::NodeValue;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
|
@ -572,9 +673,9 @@ mod tests {
|
|||
let source = "def main() -> (field): return 42";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let expected: absy::Module<FieldPrime> = absy::Module {
|
||||
functions: vec![absy::FunctionDeclaration {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: &source[4..8],
|
||||
symbol: absy::FunctionSymbol::Here(
|
||||
symbol: absy::Symbol::HereFunction(
|
||||
absy::Function {
|
||||
arguments: vec![],
|
||||
statements: vec![absy::Statement::Return(
|
||||
|
@ -587,9 +688,9 @@ mod tests {
|
|||
.into(),
|
||||
)
|
||||
.into()],
|
||||
signature: absy::Signature::new()
|
||||
signature: absy::UnresolvedSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![Type::FieldElement]),
|
||||
.outputs(vec![absy::UnresolvedType::FieldElement.mock()]),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
|
@ -605,9 +706,9 @@ mod tests {
|
|||
let source = "def main() -> (bool): return true";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let expected: absy::Module<FieldPrime> = absy::Module {
|
||||
functions: vec![absy::FunctionDeclaration {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: &source[4..8],
|
||||
symbol: absy::FunctionSymbol::Here(
|
||||
symbol: absy::Symbol::HereFunction(
|
||||
absy::Function {
|
||||
arguments: vec![],
|
||||
statements: vec![absy::Statement::Return(
|
||||
|
@ -617,9 +718,9 @@ mod tests {
|
|||
.into(),
|
||||
)
|
||||
.into()],
|
||||
signature: absy::Signature::new()
|
||||
signature: absy::UnresolvedSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![Type::Boolean]),
|
||||
.outputs(vec![absy::UnresolvedType::Boolean.mock()]),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
|
@ -636,17 +737,25 @@ mod tests {
|
|||
let ast = pest::generate_ast(&source).unwrap();
|
||||
|
||||
let expected: absy::Module<FieldPrime> = absy::Module {
|
||||
functions: vec![absy::FunctionDeclaration {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: &source[4..8],
|
||||
symbol: absy::FunctionSymbol::Here(
|
||||
symbol: absy::Symbol::HereFunction(
|
||||
absy::Function {
|
||||
arguments: vec![
|
||||
absy::Parameter::private(
|
||||
absy::Variable::field_element(&source[23..24]).into(),
|
||||
absy::Variable::new(
|
||||
&source[23..24],
|
||||
absy::UnresolvedType::FieldElement.mock(),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.into(),
|
||||
absy::Parameter::public(
|
||||
absy::Variable::boolean(&source[31..32]).into(),
|
||||
absy::Variable::new(
|
||||
&source[31..32],
|
||||
absy::UnresolvedType::Boolean.mock(),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.into(),
|
||||
],
|
||||
|
@ -660,9 +769,12 @@ mod tests {
|
|||
.into(),
|
||||
)
|
||||
.into()],
|
||||
signature: absy::Signature::new()
|
||||
.inputs(vec![Type::FieldElement, Type::Boolean])
|
||||
.outputs(vec![Type::FieldElement]),
|
||||
signature: absy::UnresolvedSignature::new()
|
||||
.inputs(vec![
|
||||
absy::UnresolvedType::FieldElement.mock(),
|
||||
absy::UnresolvedType::Boolean.mock(),
|
||||
])
|
||||
.outputs(vec![absy::UnresolvedType::FieldElement.mock()]),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
|
@ -678,14 +790,14 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
/// Helper method to generate the ast for `def main(private {ty} a) -> (): return` which we use to check ty
|
||||
fn wrap(ty: types::Type) -> absy::Module<'static, FieldPrime> {
|
||||
fn wrap(ty: absy::UnresolvedType) -> absy::Module<'static, FieldPrime> {
|
||||
absy::Module {
|
||||
functions: vec![absy::FunctionDeclaration {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: "main",
|
||||
symbol: absy::FunctionSymbol::Here(
|
||||
symbol: absy::Symbol::HereFunction(
|
||||
absy::Function {
|
||||
arguments: vec![absy::Parameter::private(
|
||||
absy::Variable::new("a", ty.clone()).into(),
|
||||
absy::Variable::new("a", ty.clone().mock()).into(),
|
||||
)
|
||||
.into()],
|
||||
statements: vec![absy::Statement::Return(
|
||||
|
@ -695,7 +807,7 @@ mod tests {
|
|||
.into(),
|
||||
)
|
||||
.into()],
|
||||
signature: absy::Signature::new().inputs(vec![ty]),
|
||||
signature: absy::UnresolvedSignature::new().inputs(vec![ty.mock()]),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
|
@ -708,19 +820,33 @@ mod tests {
|
|||
#[test]
|
||||
fn array() {
|
||||
let vectors = vec![
|
||||
("field", types::Type::FieldElement),
|
||||
("bool", types::Type::Boolean),
|
||||
("field", absy::UnresolvedType::FieldElement),
|
||||
("bool", absy::UnresolvedType::Boolean),
|
||||
(
|
||||
"field[2]",
|
||||
types::Type::Array(box types::Type::FieldElement, 2),
|
||||
absy::UnresolvedType::Array(box absy::UnresolvedType::FieldElement.mock(), 2),
|
||||
),
|
||||
(
|
||||
"field[2][3]",
|
||||
types::Type::Array(box Type::Array(box types::Type::FieldElement, 3), 2),
|
||||
absy::UnresolvedType::Array(
|
||||
box absy::UnresolvedType::Array(
|
||||
box absy::UnresolvedType::FieldElement.mock(),
|
||||
3,
|
||||
)
|
||||
.mock(),
|
||||
2,
|
||||
),
|
||||
),
|
||||
(
|
||||
"bool[2][3]",
|
||||
types::Type::Array(box Type::Array(box types::Type::Boolean, 3), 2),
|
||||
absy::UnresolvedType::Array(
|
||||
box absy::UnresolvedType::Array(
|
||||
box absy::UnresolvedType::Boolean.mock(),
|
||||
3,
|
||||
)
|
||||
.mock(),
|
||||
2,
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -737,9 +863,9 @@ mod tests {
|
|||
use super::*;
|
||||
fn wrap(expression: absy::Expression<'static, FieldPrime>) -> absy::Module<FieldPrime> {
|
||||
absy::Module {
|
||||
functions: vec![absy::FunctionDeclaration {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: "main",
|
||||
symbol: absy::FunctionSymbol::Here(
|
||||
symbol: absy::Symbol::HereFunction(
|
||||
absy::Function {
|
||||
arguments: vec![],
|
||||
statements: vec![absy::Statement::Return(
|
||||
|
@ -749,7 +875,7 @@ mod tests {
|
|||
.into(),
|
||||
)
|
||||
.into()],
|
||||
signature: absy::Signature::new(),
|
||||
signature: absy::UnresolvedSignature::new(),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
|
|
|
@ -8,12 +8,13 @@
|
|||
mod from_ast;
|
||||
mod node;
|
||||
pub mod parameter;
|
||||
pub mod types;
|
||||
pub mod variable;
|
||||
|
||||
pub use crate::absy::node::{Node, NodeValue};
|
||||
pub use crate::absy::parameter::{Parameter, ParameterNode};
|
||||
use crate::absy::types::{FunctionIdentifier, UnresolvedSignature, UnresolvedType, UserTypeId};
|
||||
pub use crate::absy::variable::{Variable, VariableNode};
|
||||
use crate::types::{FunctionIdentifier, Signature};
|
||||
use embed::FlatEmbed;
|
||||
|
||||
use crate::imports::ImportNode;
|
||||
|
@ -31,8 +32,8 @@ pub type ModuleId = String;
|
|||
/// A collection of `Module`s
|
||||
pub type Modules<'ast, T> = HashMap<ModuleId, Module<'ast, T>>;
|
||||
|
||||
/// A collection of `FunctionDeclaration`. Duplicates are allowed here as they are fine syntatically.
|
||||
pub type FunctionDeclarations<'ast, T> = Vec<FunctionDeclarationNode<'ast, T>>;
|
||||
/// A collection of `SymbolDeclaration`. Duplicates are allowed here as they are fine syntactically.
|
||||
pub type Declarations<'ast, T> = Vec<SymbolDeclarationNode<'ast, T>>;
|
||||
|
||||
/// A `Program` is a collection of `Module`s and an id of the main `Module`
|
||||
pub struct Program<'ast, T: Field> {
|
||||
|
@ -42,17 +43,26 @@ pub struct Program<'ast, T: Field> {
|
|||
|
||||
/// A declaration of a `FunctionSymbol`, be it from an import or a function definition
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct FunctionDeclaration<'ast, T: Field> {
|
||||
pub struct SymbolDeclaration<'ast, T: Field> {
|
||||
pub id: Identifier<'ast>,
|
||||
pub symbol: FunctionSymbol<'ast, T>,
|
||||
pub symbol: Symbol<'ast, T>,
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> fmt::Display for FunctionDeclaration<'ast, T> {
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Symbol<'ast, T: Field> {
|
||||
HereType(StructTypeNode<'ast>),
|
||||
HereFunction(FunctionNode<'ast, T>),
|
||||
There(SymbolImportNode<'ast>),
|
||||
Flat(FlatEmbed),
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> fmt::Display for SymbolDeclaration<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.symbol {
|
||||
FunctionSymbol::Here(ref fun) => write!(f, "def {}{}", self.id, fun),
|
||||
FunctionSymbol::There(ref import) => write!(f, "import {} as {}", import, self.id),
|
||||
FunctionSymbol::Flat(ref flat_fun) => write!(
|
||||
Symbol::HereType(ref t) => write!(f, "struct {} {}", self.id, t),
|
||||
Symbol::HereFunction(ref fun) => write!(f, "def {}{}", self.id, fun),
|
||||
Symbol::There(ref import) => write!(f, "import {} as {}", import, self.id),
|
||||
Symbol::Flat(ref flat_fun) => write!(
|
||||
f,
|
||||
"def {}{}:\n\t// hidden",
|
||||
self.id,
|
||||
|
@ -62,50 +72,95 @@ impl<'ast, T: Field> fmt::Display for FunctionDeclaration<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
type FunctionDeclarationNode<'ast, T> = Node<FunctionDeclaration<'ast, T>>;
|
||||
pub type SymbolDeclarationNode<'ast, T> = Node<SymbolDeclaration<'ast, T>>;
|
||||
|
||||
/// A module as a collection of `FunctionDeclaration`s
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct Module<'ast, T: Field> {
|
||||
/// Functions of the module
|
||||
pub functions: FunctionDeclarations<'ast, T>,
|
||||
/// Symbols of the module
|
||||
pub symbols: Declarations<'ast, T>,
|
||||
pub imports: Vec<ImportNode<'ast>>, // we still use `imports` as they are not directly converted into `FunctionDeclaration`s after the importer is done, `imports` is empty
|
||||
}
|
||||
|
||||
/// A function, be it defined in this module, imported from another module or a flat embed
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum FunctionSymbol<'ast, T: Field> {
|
||||
Here(FunctionNode<'ast, T>),
|
||||
There(FunctionImportNode<'ast>),
|
||||
Flat(FlatEmbed),
|
||||
impl<'ast, T: Field> Module<'ast, T> {
|
||||
pub fn with_symbols<I: IntoIterator<Item = SymbolDeclarationNode<'ast, T>>>(i: I) -> Self {
|
||||
Module {
|
||||
symbols: i.into_iter().collect(),
|
||||
imports: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn imports<I: IntoIterator<Item = ImportNode<'ast>>>(mut self, i: I) -> Self {
|
||||
self.imports = i.into_iter().collect();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A function import
|
||||
pub type UnresolvedTypeNode = Node<UnresolvedType>;
|
||||
|
||||
/// A struct type definition
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FunctionImport<'ast> {
|
||||
/// the id of the function in the target module. Note: there may be many candidates as imports statements do not specify the signature
|
||||
pub function_id: Identifier<'ast>,
|
||||
pub struct StructType<'ast> {
|
||||
pub fields: Vec<StructFieldNode<'ast>>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for StructType<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
self.fields
|
||||
.iter()
|
||||
.map(|fi| fi.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub type StructTypeNode<'ast> = Node<StructType<'ast>>;
|
||||
|
||||
/// A struct type definition
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct StructField<'ast> {
|
||||
pub id: Identifier<'ast>,
|
||||
pub ty: UnresolvedTypeNode,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for StructField<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}: {},", self.id, self.ty)
|
||||
}
|
||||
}
|
||||
|
||||
type StructFieldNode<'ast> = Node<StructField<'ast>>;
|
||||
|
||||
/// An import
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct SymbolImport<'ast> {
|
||||
/// the id of the symbol in the target module. Note: there may be many candidates as imports statements do not specify the signature. In that case they must all be functions however.
|
||||
pub symbol_id: Identifier<'ast>,
|
||||
/// the id of the module to import from
|
||||
pub module_id: ModuleId,
|
||||
}
|
||||
|
||||
type FunctionImportNode<'ast> = Node<FunctionImport<'ast>>;
|
||||
type SymbolImportNode<'ast> = Node<SymbolImport<'ast>>;
|
||||
|
||||
impl<'ast> FunctionImport<'ast> {
|
||||
impl<'ast> SymbolImport<'ast> {
|
||||
pub fn with_id_in_module<S: Into<Identifier<'ast>>, U: Into<ModuleId>>(
|
||||
function_id: S,
|
||||
symbol_id: S,
|
||||
module_id: U,
|
||||
) -> Self {
|
||||
FunctionImport {
|
||||
function_id: function_id.into(),
|
||||
SymbolImport {
|
||||
symbol_id: symbol_id.into(),
|
||||
module_id: module_id.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for FunctionImport<'ast> {
|
||||
impl<'ast> fmt::Display for SymbolImport<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} from {}", self.function_id, self.module_id)
|
||||
write!(f, "{} from {}", self.symbol_id, self.module_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +174,7 @@ impl<'ast, T: Field> fmt::Display for Module<'ast, T> {
|
|||
.collect::<Vec<_>>(),
|
||||
);
|
||||
res.extend(
|
||||
self.functions
|
||||
self.symbols
|
||||
.iter()
|
||||
.map(|x| format!("{}", x))
|
||||
.collect::<Vec<_>>(),
|
||||
|
@ -132,13 +187,13 @@ impl<'ast, T: Field> fmt::Debug for Module<'ast, T> {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"module(\n\timports:\n\t\t{}\n\tfunctions:\n\t\t{}\n)",
|
||||
"module(\n\timports:\n\t\t{}\n\tsymbols:\n\t\t{}\n)",
|
||||
self.imports
|
||||
.iter()
|
||||
.map(|x| format!("{:?}", x))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\t\t"),
|
||||
self.functions
|
||||
self.symbols
|
||||
.iter()
|
||||
.map(|x| format!("{:?}", x))
|
||||
.collect::<Vec<_>>()
|
||||
|
@ -155,7 +210,7 @@ pub struct Function<'ast, T: Field> {
|
|||
/// Vector of statements that are executed when running the function
|
||||
pub statements: Vec<StatementNode<'ast, T>>,
|
||||
/// function signature
|
||||
pub signature: Signature,
|
||||
pub signature: UnresolvedSignature,
|
||||
}
|
||||
|
||||
pub type FunctionNode<'ast, T> = Node<Function<'ast, T>>;
|
||||
|
@ -199,6 +254,7 @@ impl<'ast, T: Field> fmt::Debug for Function<'ast, T> {
|
|||
pub enum Assignee<'ast, T: Field> {
|
||||
Identifier(Identifier<'ast>),
|
||||
Select(Box<AssigneeNode<'ast, T>>, Box<RangeOrExpression<'ast, T>>),
|
||||
Member(Box<AssigneeNode<'ast, T>>, Box<Identifier<'ast>>),
|
||||
}
|
||||
|
||||
pub type AssigneeNode<'ast, T> = Node<Assignee<'ast, T>>;
|
||||
|
@ -208,6 +264,7 @@ impl<'ast, T: Field> fmt::Debug for Assignee<'ast, T> {
|
|||
match *self {
|
||||
Assignee::Identifier(ref s) => write!(f, "Identifier({:?})", s),
|
||||
Assignee::Select(ref a, ref e) => write!(f, "Select({:?}[{:?}])", a, e),
|
||||
Assignee::Member(ref s, ref m) => write!(f, "Member({:?}.{:?})", s, m),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,10 +471,12 @@ pub enum Expression<'ast, T: Field> {
|
|||
And(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
|
||||
Not(Box<ExpressionNode<'ast, T>>),
|
||||
InlineArray(Vec<SpreadOrExpression<'ast, T>>),
|
||||
InlineStruct(UserTypeId, Vec<(Identifier<'ast>, ExpressionNode<'ast, T>)>),
|
||||
Select(
|
||||
Box<ExpressionNode<'ast, T>>,
|
||||
Box<RangeOrExpression<'ast, T>>,
|
||||
),
|
||||
Member(Box<ExpressionNode<'ast, T>>, Box<Identifier<'ast>>),
|
||||
Or(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
|
||||
}
|
||||
|
||||
|
@ -466,7 +525,18 @@ impl<'ast, T: Field> fmt::Display for Expression<'ast, T> {
|
|||
}
|
||||
write!(f, "]")
|
||||
}
|
||||
Expression::InlineStruct(ref id, ref members) => {
|
||||
write!(f, "{} {{", id)?;
|
||||
for (i, (member_id, e)) in members.iter().enumerate() {
|
||||
write!(f, "{}: {}", member_id, e)?;
|
||||
if i < members.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
Expression::Select(ref array, ref index) => write!(f, "{}[{}]", array, index),
|
||||
Expression::Member(ref struc, ref id) => write!(f, "{}.{}", struc, id),
|
||||
Expression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs),
|
||||
}
|
||||
}
|
||||
|
@ -505,9 +575,15 @@ impl<'ast, T: Field> fmt::Debug for Expression<'ast, T> {
|
|||
f.debug_list().entries(exprs.iter()).finish()?;
|
||||
write!(f, "]")
|
||||
}
|
||||
Expression::InlineStruct(ref id, ref members) => {
|
||||
write!(f, "InlineStruct({:?}, [", id)?;
|
||||
f.debug_list().entries(members.iter()).finish()?;
|
||||
write!(f, "]")
|
||||
}
|
||||
Expression::Select(ref array, ref index) => {
|
||||
write!(f, "Select({:?}, {:?})", array, index)
|
||||
}
|
||||
Expression::Member(ref struc, ref id) => write!(f, "{}.{}", struc, id),
|
||||
Expression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,10 +74,13 @@ impl<'ast, T: Field> NodeValue for Expression<'ast, T> {}
|
|||
impl<'ast, T: Field> NodeValue for ExpressionList<'ast, T> {}
|
||||
impl<'ast, T: Field> NodeValue for Assignee<'ast, T> {}
|
||||
impl<'ast, T: Field> NodeValue for Statement<'ast, T> {}
|
||||
impl<'ast, T: Field> NodeValue for FunctionDeclaration<'ast, T> {}
|
||||
impl<'ast, T: Field> NodeValue for SymbolDeclaration<'ast, T> {}
|
||||
impl NodeValue for UnresolvedType {}
|
||||
impl<'ast> NodeValue for StructType<'ast> {}
|
||||
impl<'ast> NodeValue for StructField<'ast> {}
|
||||
impl<'ast, T: Field> NodeValue for Function<'ast, T> {}
|
||||
impl<'ast, T: Field> NodeValue for Module<'ast, T> {}
|
||||
impl<'ast> NodeValue for FunctionImport<'ast> {}
|
||||
impl<'ast> NodeValue for SymbolImport<'ast> {}
|
||||
impl<'ast> NodeValue for Variable<'ast> {}
|
||||
impl<'ast> NodeValue for Parameter<'ast> {}
|
||||
impl<'ast> NodeValue for Import<'ast> {}
|
||||
|
|
98
zokrates_core/src/absy/types.rs
Normal file
98
zokrates_core/src/absy/types.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use absy::UnresolvedTypeNode;
|
||||
use std::fmt;
|
||||
|
||||
pub type Identifier<'ast> = &'ast str;
|
||||
|
||||
pub type MemberId = String;
|
||||
|
||||
pub type UserTypeId = String;
|
||||
|
||||
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
|
||||
pub enum UnresolvedType {
|
||||
FieldElement,
|
||||
Boolean,
|
||||
Array(Box<UnresolvedTypeNode>, usize),
|
||||
User(UserTypeId),
|
||||
}
|
||||
|
||||
impl fmt::Display for UnresolvedType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
UnresolvedType::FieldElement => write!(f, "field"),
|
||||
UnresolvedType::Boolean => write!(f, "bool"),
|
||||
UnresolvedType::Array(ref ty, ref size) => write!(f, "{}[{}]", ty, size),
|
||||
UnresolvedType::User(i) => write!(f, "{}", i),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UnresolvedType {
|
||||
pub fn array(ty: UnresolvedTypeNode, size: usize) -> Self {
|
||||
UnresolvedType::Array(box ty, size)
|
||||
}
|
||||
}
|
||||
|
||||
pub type FunctionIdentifier<'ast> = &'ast str;
|
||||
|
||||
pub use self::signature::UnresolvedSignature;
|
||||
|
||||
mod signature {
|
||||
use std::fmt;
|
||||
|
||||
use absy::UnresolvedTypeNode;
|
||||
|
||||
#[derive(Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct UnresolvedSignature {
|
||||
pub inputs: Vec<UnresolvedTypeNode>,
|
||||
pub outputs: Vec<UnresolvedTypeNode>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for UnresolvedSignature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Signature(inputs: {:?}, outputs: {:?})",
|
||||
self.inputs, self.outputs
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for UnresolvedSignature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "(")?;
|
||||
for (i, t) in self.inputs.iter().enumerate() {
|
||||
write!(f, "{}", t)?;
|
||||
if i < self.inputs.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ") -> (")?;
|
||||
for (i, t) in self.outputs.iter().enumerate() {
|
||||
write!(f, "{}", t)?;
|
||||
if i < self.outputs.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl UnresolvedSignature {
|
||||
pub fn new() -> UnresolvedSignature {
|
||||
UnresolvedSignature {
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inputs(mut self, inputs: Vec<UnresolvedTypeNode>) -> Self {
|
||||
self.inputs = inputs;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn outputs(mut self, outputs: Vec<UnresolvedTypeNode>) -> Self {
|
||||
self.outputs = outputs;
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,55 +1,27 @@
|
|||
use crate::absy::Node;
|
||||
use crate::absy::types::UnresolvedType;
|
||||
use crate::absy::{Node, UnresolvedTypeNode};
|
||||
use std::fmt;
|
||||
use types::Type;
|
||||
|
||||
use crate::absy::Identifier;
|
||||
|
||||
#[derive(Clone, PartialEq, Hash, Eq)]
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct Variable<'ast> {
|
||||
pub id: Identifier<'ast>,
|
||||
pub _type: Type,
|
||||
pub _type: UnresolvedTypeNode,
|
||||
}
|
||||
|
||||
pub type VariableNode<'ast> = Node<Variable<'ast>>;
|
||||
|
||||
impl<'ast> Variable<'ast> {
|
||||
pub fn new<S: Into<&'ast str>>(id: S, t: Type) -> Variable<'ast> {
|
||||
pub fn new<S: Into<&'ast str>>(id: S, t: UnresolvedTypeNode) -> Variable<'ast> {
|
||||
Variable {
|
||||
id: id.into(),
|
||||
_type: t,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn field_element<S: Into<&'ast str>>(id: S) -> Variable<'ast> {
|
||||
Variable {
|
||||
id: id.into(),
|
||||
_type: Type::FieldElement,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn boolean<S: Into<&'ast str>>(id: S) -> Variable<'ast> {
|
||||
Variable {
|
||||
id: id.into(),
|
||||
_type: Type::Boolean,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn field_array<S: Into<&'ast str>>(id: S, size: usize) -> Variable<'ast> {
|
||||
Variable {
|
||||
id: id.into(),
|
||||
_type: Type::array(Type::FieldElement, size),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn array<S: Into<&'ast str>>(id: S, inner_ty: Type, size: usize) -> Variable<'ast> {
|
||||
Variable {
|
||||
id: id.into(),
|
||||
_type: Type::array(inner_ty, size),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> Type {
|
||||
self._type.clone()
|
||||
pub fn get_type(&self) -> UnresolvedType {
|
||||
self._type.value.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use flat_absy::{
|
|||
};
|
||||
use reduce::Reduce;
|
||||
use std::collections::HashMap;
|
||||
use types::{FunctionKey, Signature, Type};
|
||||
use typed_absy::types::{FunctionKey, Signature, Type};
|
||||
use zokrates_embed::{generate_sha256_round_constraints, BellmanConstraint};
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
|
@ -419,9 +419,15 @@ mod tests {
|
|||
let prog = crate::ir::Prog {
|
||||
main: f,
|
||||
private: vec![true; 768],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::FieldElement; 768])
|
||||
.outputs(vec![Type::FieldElement; 256]),
|
||||
};
|
||||
|
||||
let input = (0..512).map(|_| 0).chain((0..256).map(|_| 1)).collect();
|
||||
let input = (0..512)
|
||||
.map(|_| FieldPrime::from(0))
|
||||
.chain((0..256).map(|_| FieldPrime::from(1)))
|
||||
.collect();
|
||||
|
||||
prog.execute(&input).unwrap();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ pub use self::flat_parameter::FlatParameter;
|
|||
pub use self::flat_variable::FlatVariable;
|
||||
|
||||
use crate::helpers::DirectiveStatement;
|
||||
use crate::types::Signature;
|
||||
use crate::typed_absy::types::Signature;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use zokrates_field::field::Field;
|
||||
|
|
|
@ -7,12 +7,10 @@
|
|||
|
||||
use crate::flat_absy::*;
|
||||
use crate::helpers::{DirectiveStatement, Helper, RustHelper};
|
||||
use crate::typed_absy::types::{FunctionIdentifier, FunctionKey, MemberId, Signature, Type};
|
||||
use crate::typed_absy::*;
|
||||
use crate::types::Type;
|
||||
use crate::types::{FunctionKey, Signature};
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use types::FunctionIdentifier;
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
/// Flattener, computes flattened program.
|
||||
|
@ -29,7 +27,7 @@ pub struct Flattener<'ast, T: Field> {
|
|||
// We introduce a trait in order to make it possible to make flattening `e` generic over the type of `e`
|
||||
|
||||
trait Flatten<'ast, T: Field>:
|
||||
TryFrom<TypedExpression<'ast, T>, Error = ()> + IfElse<'ast, T> + Select<'ast, T>
|
||||
TryFrom<TypedExpression<'ast, T>, Error = ()> + IfElse<'ast, T> + Select<'ast, T> + Member<'ast, T>
|
||||
{
|
||||
fn flatten(
|
||||
self,
|
||||
|
@ -61,6 +59,17 @@ impl<'ast, T: Field> Flatten<'ast, T> for BooleanExpression<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Flatten<'ast, T> for StructExpression<'ast, T> {
|
||||
fn flatten(
|
||||
self,
|
||||
flattener: &mut Flattener<'ast, T>,
|
||||
symbols: &TypedFunctionSymbols<'ast, T>,
|
||||
statements_flattened: &mut Vec<FlatStatement<T>>,
|
||||
) -> Vec<FlatExpression<T>> {
|
||||
flattener.flatten_struct_expression(symbols, statements_flattened, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Flatten<'ast, T> for ArrayExpression<'ast, T> {
|
||||
fn flatten(
|
||||
self,
|
||||
|
@ -85,6 +94,11 @@ impl<'ast, T: Field> Flatten<'ast, T> for ArrayExpression<'ast, T> {
|
|||
statements_flattened,
|
||||
self,
|
||||
),
|
||||
Type::Struct(..) => flattener.flatten_array_expression::<StructExpression<'ast, T>>(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
self,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,6 +208,163 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
res.into_iter().map(|r| r.into()).collect()
|
||||
}
|
||||
|
||||
fn flatten_member_expression(
|
||||
&mut self,
|
||||
symbols: &TypedFunctionSymbols<'ast, T>,
|
||||
statements_flattened: &mut Vec<FlatStatement<T>>,
|
||||
s: StructExpression<'ast, T>,
|
||||
member_id: MemberId,
|
||||
) -> Vec<FlatExpression<T>> {
|
||||
let members = s.ty().clone();
|
||||
let expected_output_size = members
|
||||
.iter()
|
||||
.find(|(id, _)| *id == member_id)
|
||||
.unwrap()
|
||||
.1
|
||||
.get_primitive_count();
|
||||
|
||||
let res =
|
||||
match s.into_inner() {
|
||||
StructExpressionInner::Value(values) => {
|
||||
// If the struct has an explicit value, we get the value at the given member
|
||||
assert_eq!(values.len(), members.len());
|
||||
values
|
||||
.into_iter()
|
||||
.zip(members.into_iter())
|
||||
.filter(|(_, (id, _))| *id == member_id)
|
||||
.flat_map(|(v, (_, t))| match t {
|
||||
Type::FieldElement => FieldElementExpression::try_from(v)
|
||||
.unwrap()
|
||||
.flatten(self, symbols, statements_flattened),
|
||||
Type::Boolean => BooleanExpression::try_from(v).unwrap().flatten(
|
||||
self,
|
||||
symbols,
|
||||
statements_flattened,
|
||||
),
|
||||
Type::Array(..) => ArrayExpression::try_from(v).unwrap().flatten(
|
||||
self,
|
||||
symbols,
|
||||
statements_flattened,
|
||||
),
|
||||
Type::Struct(..) => StructExpression::try_from(v).unwrap().flatten(
|
||||
self,
|
||||
symbols,
|
||||
statements_flattened,
|
||||
),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
StructExpressionInner::Identifier(id) => {
|
||||
// If the struct is an identifier, we allocated variables in the layout for that identifier. We need to access a subset of these values.
|
||||
// the struct is encoded as a sequence, so we need to identify the offset at which this member starts
|
||||
let offset = members
|
||||
.iter()
|
||||
.take_while(|(id, _)| *id != member_id)
|
||||
.map(|(_, ty)| ty.get_primitive_count())
|
||||
.sum();
|
||||
|
||||
// we also need the size of this member
|
||||
let size = members
|
||||
.iter()
|
||||
.find(|(id, _)| *id == member_id)
|
||||
.unwrap()
|
||||
.1
|
||||
.get_primitive_count();
|
||||
self.layout.get(&id).unwrap()[offset..(offset + size)]
|
||||
.into_iter()
|
||||
.map(|i| i.clone().into())
|
||||
.collect()
|
||||
}
|
||||
StructExpressionInner::Select(box array, box index) => {
|
||||
let offset = members
|
||||
.iter()
|
||||
.take_while(|(id, _)| *id != member_id)
|
||||
.map(|(_, ty)| ty.get_primitive_count())
|
||||
.sum();
|
||||
|
||||
// we also need the size of this member
|
||||
let size = members
|
||||
.iter()
|
||||
.find(|(id, _)| *id == member_id)
|
||||
.unwrap()
|
||||
.1
|
||||
.get_primitive_count();
|
||||
|
||||
self.flatten_select_expression::<StructExpression<'ast, T>>(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
array,
|
||||
index,
|
||||
)[offset..offset + size]
|
||||
.to_vec()
|
||||
}
|
||||
StructExpressionInner::FunctionCall(..) => unreachable!(),
|
||||
StructExpressionInner::IfElse(box condition, box consequence, box alternative) => {
|
||||
// if the struct is `(if c then a else b)`, we want to access `(if c then a else b).member`
|
||||
// we reduce to `if c then a.member else b.member`
|
||||
let ty = members
|
||||
.clone()
|
||||
.into_iter()
|
||||
.find(|(id, _)| *id == member_id)
|
||||
.unwrap()
|
||||
.1;
|
||||
|
||||
match ty {
|
||||
Type::FieldElement => self.flatten_if_else_expression(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
condition.clone(),
|
||||
FieldElementExpression::member(consequence.clone(), member_id.clone()),
|
||||
FieldElementExpression::member(alternative.clone(), member_id),
|
||||
),
|
||||
Type::Boolean => self.flatten_if_else_expression(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
condition.clone(),
|
||||
BooleanExpression::member(consequence.clone(), member_id.clone()),
|
||||
BooleanExpression::member(alternative.clone(), member_id),
|
||||
),
|
||||
Type::Struct(..) => self.flatten_if_else_expression(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
condition.clone(),
|
||||
StructExpression::member(consequence.clone(), member_id.clone()),
|
||||
StructExpression::member(alternative.clone(), member_id),
|
||||
),
|
||||
Type::Array(..) => self.flatten_if_else_expression(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
condition.clone(),
|
||||
ArrayExpression::member(consequence.clone(), member_id.clone()),
|
||||
ArrayExpression::member(alternative.clone(), member_id),
|
||||
),
|
||||
}
|
||||
}
|
||||
StructExpressionInner::Member(box s0, m_id) => {
|
||||
let e = self.flatten_member_expression(symbols, statements_flattened, s0, m_id);
|
||||
|
||||
let offset = members
|
||||
.iter()
|
||||
.take_while(|(id, _)| *id != member_id)
|
||||
.map(|(_, ty)| ty.get_primitive_count())
|
||||
.sum();
|
||||
|
||||
// we also need the size of this member
|
||||
let size = members
|
||||
.iter()
|
||||
.find(|(id, _)| *id == member_id)
|
||||
.unwrap()
|
||||
.1
|
||||
.get_primitive_count();
|
||||
|
||||
e[offset..(offset + size)].into()
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(res.len(), expected_output_size);
|
||||
res
|
||||
}
|
||||
|
||||
/// Flatten an array selection expression
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -244,6 +415,13 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
)
|
||||
.flatten(self, symbols, statements_flattened)
|
||||
}
|
||||
ArrayExpressionInner::Member(box s, id) => {
|
||||
assert!(n < T::from(size));
|
||||
let n = n.to_dec_string().parse::<usize>().unwrap();
|
||||
self.flatten_member_expression(symbols, statements_flattened, s, id)
|
||||
[n * ty.get_primitive_count()..(n + 1) * ty.get_primitive_count()]
|
||||
.to_vec()
|
||||
}
|
||||
ArrayExpressionInner::Select(box array, box index) => {
|
||||
assert!(n < T::from(size));
|
||||
let n = n.to_dec_string().parse::<usize>().unwrap();
|
||||
|
@ -270,6 +448,13 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
array,
|
||||
index,
|
||||
),
|
||||
Type::Struct(..) => self
|
||||
.flatten_select_expression::<StructExpression<'ast, T>>(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
array,
|
||||
index,
|
||||
),
|
||||
};
|
||||
|
||||
e[n * element_size..(n + 1) * element_size]
|
||||
|
@ -333,6 +518,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
),
|
||||
)
|
||||
}
|
||||
ArrayExpressionInner::Member(box s, id) => U::member(s, id),
|
||||
ArrayExpressionInner::Select(box array, box index) => U::select(
|
||||
ArrayExpressionInner::Select(box array, box index)
|
||||
.annotate(ty.clone(), size),
|
||||
|
@ -671,6 +857,9 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
alternative,
|
||||
)[0]
|
||||
.clone(),
|
||||
BooleanExpression::Member(box s, id) => {
|
||||
self.flatten_member_expression(symbols, statements_flattened, s, id)[0].clone()
|
||||
}
|
||||
BooleanExpression::Select(box array, box index) => self
|
||||
.flatten_select_expression::<BooleanExpression<'ast, T>>(
|
||||
symbols,
|
||||
|
@ -826,7 +1015,15 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
statements_flattened,
|
||||
e,
|
||||
),
|
||||
Type::Struct(..) => self.flatten_array_expression::<StructExpression<'ast, T>>(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
e,
|
||||
),
|
||||
},
|
||||
TypedExpression::Struct(e) => {
|
||||
self.flatten_struct_expression(symbols, statements_flattened, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1059,6 +1256,9 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
assert!(exprs_flattened.expressions.len() == 1); // outside of MultipleDefinition, FunctionCalls must return a single value
|
||||
exprs_flattened.expressions[0].clone()
|
||||
}
|
||||
FieldElementExpression::Member(box s, id) => {
|
||||
self.flatten_member_expression(symbols, statements_flattened, s, id)[0].clone()
|
||||
}
|
||||
FieldElementExpression::Select(box array, box index) => self
|
||||
.flatten_select_expression::<FieldElementExpression<'ast, T>>(
|
||||
symbols,
|
||||
|
@ -1070,6 +1270,92 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Flattens an array expression
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `symbols` - Available functions in in this context
|
||||
/// * `statements_flattened` - Vector where new flattened statements can be added.
|
||||
/// * `expr` - `StructExpression` that will be flattened.
|
||||
fn flatten_struct_expression(
|
||||
&mut self,
|
||||
symbols: &TypedFunctionSymbols<'ast, T>,
|
||||
statements_flattened: &mut Vec<FlatStatement<T>>,
|
||||
expr: StructExpression<'ast, T>,
|
||||
) -> Vec<FlatExpression<T>> {
|
||||
let ty = expr.get_type();
|
||||
let expected_output_size = expr.get_type().get_primitive_count();
|
||||
let members = expr.ty().clone();
|
||||
|
||||
let res = match expr.into_inner() {
|
||||
StructExpressionInner::Identifier(x) => self
|
||||
.layout
|
||||
.get(&x)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|v| FlatExpression::Identifier(v.clone()))
|
||||
.collect(),
|
||||
StructExpressionInner::Value(values) => values
|
||||
.into_iter()
|
||||
.flat_map(|v| self.flatten_expression(symbols, statements_flattened, v))
|
||||
.collect(),
|
||||
StructExpressionInner::FunctionCall(key, param_expressions) => {
|
||||
let exprs_flattened = self.flatten_function_call(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
key.id,
|
||||
vec![ty],
|
||||
param_expressions,
|
||||
);
|
||||
exprs_flattened.expressions
|
||||
}
|
||||
StructExpressionInner::IfElse(box condition, box consequence, box alternative) => {
|
||||
members
|
||||
.into_iter()
|
||||
.flat_map(|(id, ty)| match ty {
|
||||
Type::FieldElement => FieldElementExpression::if_else(
|
||||
condition.clone(),
|
||||
FieldElementExpression::member(consequence.clone(), id.clone()),
|
||||
FieldElementExpression::member(alternative.clone(), id.clone()),
|
||||
)
|
||||
.flatten(self, symbols, statements_flattened),
|
||||
Type::Boolean => BooleanExpression::if_else(
|
||||
condition.clone(),
|
||||
BooleanExpression::member(consequence.clone(), id.clone()),
|
||||
BooleanExpression::member(alternative.clone(), id.clone()),
|
||||
)
|
||||
.flatten(self, symbols, statements_flattened),
|
||||
Type::Struct(..) => StructExpression::if_else(
|
||||
condition.clone(),
|
||||
StructExpression::member(consequence.clone(), id.clone()),
|
||||
StructExpression::member(alternative.clone(), id.clone()),
|
||||
)
|
||||
.flatten(self, symbols, statements_flattened),
|
||||
Type::Array(..) => ArrayExpression::if_else(
|
||||
condition.clone(),
|
||||
ArrayExpression::member(consequence.clone(), id.clone()),
|
||||
ArrayExpression::member(alternative.clone(), id.clone()),
|
||||
)
|
||||
.flatten(self, symbols, statements_flattened),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
StructExpressionInner::Member(box s, id) => {
|
||||
self.flatten_member_expression(symbols, statements_flattened, s, id)
|
||||
}
|
||||
StructExpressionInner::Select(box array, box index) => self
|
||||
.flatten_select_expression::<StructExpression<'ast, T>>(
|
||||
symbols,
|
||||
statements_flattened,
|
||||
array,
|
||||
index,
|
||||
),
|
||||
};
|
||||
|
||||
assert_eq!(res.len(), expected_output_size);
|
||||
res
|
||||
}
|
||||
|
||||
/// Flattens an array expression
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -1136,6 +1422,9 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
.flatten(self, symbols, statements_flattened)
|
||||
})
|
||||
.collect(),
|
||||
ArrayExpressionInner::Member(box s, id) => {
|
||||
self.flatten_member_expression(symbols, statements_flattened, s, id)
|
||||
}
|
||||
ArrayExpressionInner::Select(box array, box index) => self
|
||||
.flatten_select_expression::<ArrayExpression<'ast, T>>(
|
||||
symbols,
|
||||
|
@ -1194,6 +1483,9 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
TypedAssignee::Select(..) => unreachable!(
|
||||
"array element redefs should have been replaced by array redefs in unroll"
|
||||
),
|
||||
TypedAssignee::Member(..) => unreachable!(
|
||||
"struct member redefs should have been replaced by struct redef in unroll"
|
||||
),
|
||||
}
|
||||
}
|
||||
TypedStatement::Condition(lhs, rhs) => {
|
||||
|
@ -1280,7 +1572,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
let arguments_flattened = funct
|
||||
.arguments
|
||||
.into_iter()
|
||||
.flat_map(|p| self.use_parameter(&p, &mut statements_flattened))
|
||||
.flat_map(|p| self.use_parameter(&p))
|
||||
.collect();
|
||||
|
||||
// flatten statements in functions and apply substitution
|
||||
|
@ -1328,29 +1620,14 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
///
|
||||
/// * `name` - a String that holds the name of the variable
|
||||
fn use_variable(&mut self, variable: &Variable<'ast>) -> Vec<FlatVariable> {
|
||||
let vars = match variable.get_type() {
|
||||
Type::FieldElement => self.issue_new_variables(1),
|
||||
Type::Boolean => self.issue_new_variables(1),
|
||||
Type::Array(ty, size) => self.issue_new_variables(ty.get_primitive_count() * size),
|
||||
};
|
||||
let vars = self.issue_new_variables(variable.get_type().get_primitive_count());
|
||||
|
||||
self.layout.insert(variable.id.clone(), vars.clone());
|
||||
vars
|
||||
}
|
||||
|
||||
fn use_parameter(
|
||||
&mut self,
|
||||
parameter: &Parameter<'ast>,
|
||||
statements: &mut Vec<FlatStatement<T>>,
|
||||
) -> Vec<FlatParameter> {
|
||||
fn use_parameter(&mut self, parameter: &Parameter<'ast>) -> Vec<FlatParameter> {
|
||||
let variables = self.use_variable(¶meter.id);
|
||||
match parameter.id.get_type() {
|
||||
Type::Boolean => statements.extend(Self::boolean_constraint(&variables)),
|
||||
Type::Array(box Type::Boolean, _) => {
|
||||
statements.extend(Self::boolean_constraint(&variables))
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
variables
|
||||
.into_iter()
|
||||
|
@ -1371,21 +1648,6 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
(0..count).map(|_| self.issue_new_variable()).collect()
|
||||
}
|
||||
|
||||
fn boolean_constraint(variables: &Vec<FlatVariable>) -> Vec<FlatStatement<T>> {
|
||||
variables
|
||||
.iter()
|
||||
.map(|v| {
|
||||
FlatStatement::Condition(
|
||||
FlatExpression::Identifier(*v),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*v),
|
||||
box FlatExpression::Identifier(*v),
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// create an internal variable. We do not register it in the layout
|
||||
fn use_sym(&mut self) -> FlatVariable {
|
||||
self.issue_new_variable()
|
||||
|
@ -1410,62 +1672,10 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::Signature;
|
||||
use crate::types::Type;
|
||||
use crate::typed_absy::types::Signature;
|
||||
use crate::typed_absy::types::Type;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
mod boolean_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn boolean_arg() {
|
||||
// def main(bool a):
|
||||
// return a
|
||||
//
|
||||
// -> should flatten to
|
||||
//
|
||||
// def main(_0) -> (1):
|
||||
// _0 * _0 == _0
|
||||
// return _0
|
||||
|
||||
let function: TypedFunction<FieldPrime> = TypedFunction {
|
||||
arguments: vec![Parameter::private(Variable::boolean("a".into()))],
|
||||
statements: vec![TypedStatement::Return(vec![BooleanExpression::Identifier(
|
||||
"a".into(),
|
||||
)
|
||||
.into()])],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::Boolean])
|
||||
.outputs(vec![Type::Boolean]),
|
||||
};
|
||||
|
||||
let expected = FlatFunction {
|
||||
arguments: vec![FlatParameter::private(FlatVariable::new(0))],
|
||||
statements: vec![
|
||||
FlatStatement::Condition(
|
||||
FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
),
|
||||
),
|
||||
FlatStatement::Return(FlatExpressionList {
|
||||
expressions: vec![FlatExpression::Identifier(FlatVariable::new(0))],
|
||||
}),
|
||||
],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::Boolean])
|
||||
.outputs(vec![Type::Boolean]),
|
||||
};
|
||||
|
||||
let mut flattener = Flattener::new();
|
||||
|
||||
let flat_function = flattener.flatten_function(&mut HashMap::new(), function);
|
||||
|
||||
assert_eq!(flat_function, expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn powers_zero() {
|
||||
// def main():
|
||||
|
|
|
@ -57,15 +57,17 @@ impl From<io::Error> for Error {
|
|||
#[derive(PartialEq, Clone)]
|
||||
pub struct Import<'ast> {
|
||||
source: Identifier<'ast>,
|
||||
symbol: Option<Identifier<'ast>>,
|
||||
alias: Option<Identifier<'ast>>,
|
||||
}
|
||||
|
||||
pub type ImportNode<'ast> = Node<Import<'ast>>;
|
||||
|
||||
impl<'ast> Import<'ast> {
|
||||
pub fn new(source: Identifier<'ast>) -> Import<'ast> {
|
||||
pub fn new(symbol: Option<Identifier<'ast>>, source: Identifier<'ast>) -> Import<'ast> {
|
||||
Import {
|
||||
source: source,
|
||||
symbol,
|
||||
source,
|
||||
alias: None,
|
||||
}
|
||||
}
|
||||
|
@ -74,9 +76,14 @@ impl<'ast> Import<'ast> {
|
|||
&self.alias
|
||||
}
|
||||
|
||||
pub fn new_with_alias(source: Identifier<'ast>, alias: Identifier<'ast>) -> Import<'ast> {
|
||||
pub fn new_with_alias(
|
||||
symbol: Option<Identifier<'ast>>,
|
||||
source: Identifier<'ast>,
|
||||
alias: Identifier<'ast>,
|
||||
) -> Import<'ast> {
|
||||
Import {
|
||||
source: source,
|
||||
symbol,
|
||||
source,
|
||||
alias: Some(alias),
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +131,7 @@ impl Importer {
|
|||
modules: &mut HashMap<ModuleId, Module<'ast, T>>,
|
||||
arena: &'ast Arena<String>,
|
||||
) -> Result<Module<'ast, T>, CompileErrors> {
|
||||
let mut functions: Vec<_> = vec![];
|
||||
let mut symbols: Vec<_> = vec![];
|
||||
|
||||
for import in destination.imports {
|
||||
let pos = import.pos();
|
||||
|
@ -136,10 +143,10 @@ impl Importer {
|
|||
"EMBED/sha256round" => {
|
||||
let alias = alias.unwrap_or("sha256round");
|
||||
|
||||
functions.push(
|
||||
FunctionDeclaration {
|
||||
symbols.push(
|
||||
SymbolDeclaration {
|
||||
id: &alias,
|
||||
symbol: FunctionSymbol::Flat(FlatEmbed::Sha256Round),
|
||||
symbol: Symbol::Flat(FlatEmbed::Sha256Round),
|
||||
}
|
||||
.start_end(pos.0, pos.1),
|
||||
);
|
||||
|
@ -147,10 +154,10 @@ impl Importer {
|
|||
"EMBED/unpack" => {
|
||||
let alias = alias.unwrap_or("unpack");
|
||||
|
||||
functions.push(
|
||||
FunctionDeclaration {
|
||||
symbols.push(
|
||||
SymbolDeclaration {
|
||||
id: &alias,
|
||||
symbol: FunctionSymbol::Flat(FlatEmbed::Unpack),
|
||||
symbol: Symbol::Flat(FlatEmbed::Unpack),
|
||||
}
|
||||
.start_end(pos.0, pos.1),
|
||||
);
|
||||
|
@ -185,12 +192,12 @@ impl Importer {
|
|||
|
||||
modules.insert(import.source.to_string(), compiled);
|
||||
|
||||
functions.push(
|
||||
FunctionDeclaration {
|
||||
symbols.push(
|
||||
SymbolDeclaration {
|
||||
id: &alias,
|
||||
symbol: FunctionSymbol::There(
|
||||
FunctionImport::with_id_in_module(
|
||||
"main",
|
||||
symbol: Symbol::There(
|
||||
SymbolImport::with_id_in_module(
|
||||
import.symbol.unwrap_or("main"),
|
||||
import.source.clone(),
|
||||
)
|
||||
.start_end(pos.0, pos.1),
|
||||
|
@ -218,11 +225,12 @@ impl Importer {
|
|||
}
|
||||
}
|
||||
|
||||
functions.extend(destination.functions);
|
||||
symbols.extend(destination.symbols);
|
||||
|
||||
Ok(Module {
|
||||
imports: vec![],
|
||||
functions: functions,
|
||||
symbols,
|
||||
..destination
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -235,8 +243,9 @@ mod tests {
|
|||
#[test]
|
||||
fn create_with_no_alias() {
|
||||
assert_eq!(
|
||||
Import::new("./foo/bar/baz.zok"),
|
||||
Import::new(None, "./foo/bar/baz.zok"),
|
||||
Import {
|
||||
symbol: None,
|
||||
source: "./foo/bar/baz.zok",
|
||||
alias: None,
|
||||
}
|
||||
|
@ -246,8 +255,9 @@ mod tests {
|
|||
#[test]
|
||||
fn create_with_alias() {
|
||||
assert_eq!(
|
||||
Import::new_with_alias("./foo/bar/baz.zok", &"myalias"),
|
||||
Import::new_with_alias(None, "./foo/bar/baz.zok", &"myalias"),
|
||||
Import {
|
||||
symbol: None,
|
||||
source: "./foo/bar/baz.zok",
|
||||
alias: Some("myalias"),
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ pub trait Folder<T: Field>: Sized {
|
|||
pub fn fold_module<T: Field, F: Folder<T>>(f: &mut F, p: Prog<T>) -> Prog<T> {
|
||||
Prog {
|
||||
main: f.fold_function(p.main),
|
||||
private: p.private,
|
||||
..p
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,12 +66,19 @@ impl<T: Field> From<FlatProg<T>> for Prog<T> {
|
|||
// get the main function
|
||||
let main = flat_prog.main;
|
||||
|
||||
// get the signature to keep high level information in the low level representation
|
||||
let signature = main.signature.clone();
|
||||
|
||||
// get the interface of the program, ie which inputs are private and public
|
||||
let private = main.arguments.iter().map(|p| p.private).collect();
|
||||
|
||||
let main = main.into();
|
||||
|
||||
Prog { private, main }
|
||||
Prog {
|
||||
private,
|
||||
main,
|
||||
signature,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use zokrates_field::field::Field;
|
|||
pub type ExecutionResult<T> = Result<Witness<T>, Error>;
|
||||
|
||||
impl<T: Field> Prog<T> {
|
||||
pub fn execute<U: Into<T> + Clone>(&self, inputs: &Vec<U>) -> ExecutionResult<T> {
|
||||
pub fn execute(&self, inputs: &Vec<T>) -> ExecutionResult<T> {
|
||||
let main = &self.main;
|
||||
self.check_inputs(&inputs)?;
|
||||
let mut witness = BTreeMap::new();
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::flat_absy::flat_parameter::FlatParameter;
|
|||
use crate::flat_absy::FlatVariable;
|
||||
use crate::helpers::Helper;
|
||||
use std::fmt;
|
||||
use typed_absy::types::signature::Signature;
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
mod expression;
|
||||
|
@ -104,6 +105,7 @@ impl<T: Field> fmt::Display for Function<T> {
|
|||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||
pub struct Prog<T: Field> {
|
||||
pub signature: Signature,
|
||||
pub main: Function<T>,
|
||||
pub private: Vec<bool>,
|
||||
}
|
||||
|
@ -120,12 +122,8 @@ impl<T: Field> Prog<T> {
|
|||
.count()
|
||||
}
|
||||
|
||||
pub fn public_arguments_count(&self) -> usize {
|
||||
self.private.iter().filter(|b| !**b).count()
|
||||
}
|
||||
|
||||
pub fn private_arguments_count(&self) -> usize {
|
||||
self.private.iter().filter(|b| **b).count()
|
||||
pub fn arguments_count(&self) -> usize {
|
||||
self.private.len()
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> Vec<FlatParameter> {
|
||||
|
|
|
@ -34,11 +34,10 @@ mod optimizer;
|
|||
mod parser;
|
||||
mod semantics;
|
||||
mod static_analysis;
|
||||
mod typed_absy;
|
||||
mod types;
|
||||
|
||||
pub mod absy;
|
||||
pub mod compile;
|
||||
pub mod flat_absy;
|
||||
pub mod ir;
|
||||
pub mod proof_system;
|
||||
pub mod typed_absy;
|
||||
|
|
|
@ -49,6 +49,7 @@ impl<T: Field> Folder<T> for DuplicateOptimizer {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use flat_absy::FlatVariable;
|
||||
use typed_absy::types::Signature;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
|
@ -78,6 +79,7 @@ mod tests {
|
|||
returns: vec![],
|
||||
arguments: vec![],
|
||||
},
|
||||
signature: Signature::new(),
|
||||
};
|
||||
|
||||
let expected = p.clone();
|
||||
|
@ -117,6 +119,7 @@ mod tests {
|
|||
returns: vec![],
|
||||
arguments: vec![],
|
||||
},
|
||||
signature: Signature::new(),
|
||||
};
|
||||
|
||||
let expected = Prog {
|
||||
|
@ -136,6 +139,7 @@ mod tests {
|
|||
returns: vec![],
|
||||
arguments: vec![],
|
||||
},
|
||||
signature: Signature::new(),
|
||||
};
|
||||
|
||||
assert_eq!(DuplicateOptimizer::optimize(p), expected);
|
||||
|
|
|
@ -338,6 +338,7 @@ mod tests {
|
|||
use crate::flat_absy::FlatVariable;
|
||||
use crate::ir::*;
|
||||
use crate::proof_system::bn128::g16::serialize::serialize_proof;
|
||||
use typed_absy::types::{Signature, Type};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize)]
|
||||
|
@ -367,11 +368,14 @@ mod tests {
|
|||
)],
|
||||
},
|
||||
private: vec![false],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::FieldElement])
|
||||
.outputs(vec![Type::FieldElement]),
|
||||
};
|
||||
|
||||
let witness = program
|
||||
.clone()
|
||||
.execute::<FieldPrime>(&vec![FieldPrime::from(42)])
|
||||
.execute(&vec![FieldPrime::from(42)])
|
||||
.unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
|
|
|
@ -294,6 +294,7 @@ mod parse {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::ir::{Function, LinComb};
|
||||
use typed_absy::types::{Signature, Type};
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
mod prove {
|
||||
|
@ -309,9 +310,10 @@ mod tests {
|
|||
statements: vec![],
|
||||
},
|
||||
private: vec![],
|
||||
signature: Signature::new(),
|
||||
};
|
||||
|
||||
let witness = program.clone().execute::<FieldPrime>(&vec![]).unwrap();
|
||||
let witness = program.clone().execute(&vec![]).unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
|
@ -331,12 +333,12 @@ mod tests {
|
|||
)],
|
||||
},
|
||||
private: vec![true],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::FieldElement])
|
||||
.outputs(vec![Type::FieldElement]),
|
||||
};
|
||||
|
||||
let witness = program
|
||||
.clone()
|
||||
.execute::<FieldPrime>(&vec![FieldPrime::from(0)])
|
||||
.unwrap();
|
||||
let witness = program.clone().execute(&vec![FieldPrime::from(0)]).unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
|
@ -356,12 +358,12 @@ mod tests {
|
|||
)],
|
||||
},
|
||||
private: vec![false],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::FieldElement])
|
||||
.outputs(vec![Type::FieldElement]),
|
||||
};
|
||||
|
||||
let witness = program
|
||||
.clone()
|
||||
.execute::<FieldPrime>(&vec![FieldPrime::from(0)])
|
||||
.unwrap();
|
||||
let witness = program.clone().execute(&vec![FieldPrime::from(0)]).unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
|
@ -381,9 +383,10 @@ mod tests {
|
|||
)],
|
||||
},
|
||||
private: vec![],
|
||||
signature: Signature::new().outputs(vec![Type::FieldElement]),
|
||||
};
|
||||
|
||||
let witness = program.clone().execute::<FieldPrime>(&vec![]).unwrap();
|
||||
let witness = program.clone().execute(&vec![]).unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
|
@ -415,11 +418,14 @@ mod tests {
|
|||
],
|
||||
},
|
||||
private: vec![true, false],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::FieldElement, Type::FieldElement])
|
||||
.outputs(vec![Type::FieldElement, Type::FieldElement]),
|
||||
};
|
||||
|
||||
let witness = program
|
||||
.clone()
|
||||
.execute::<FieldPrime>(&vec![FieldPrime::from(3), FieldPrime::from(4)])
|
||||
.execute(&vec![FieldPrime::from(3), FieldPrime::from(4)])
|
||||
.unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
|
@ -440,12 +446,12 @@ mod tests {
|
|||
)],
|
||||
},
|
||||
private: vec![false],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::FieldElement])
|
||||
.outputs(vec![Type::FieldElement]),
|
||||
};
|
||||
|
||||
let witness = program
|
||||
.clone()
|
||||
.execute::<FieldPrime>(&vec![FieldPrime::from(3)])
|
||||
.unwrap();
|
||||
let witness = program.clone().execute(&vec![FieldPrime::from(3)]).unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
|
@ -467,11 +473,14 @@ mod tests {
|
|||
)],
|
||||
},
|
||||
private: vec![true, false],
|
||||
signature: Signature::new()
|
||||
.inputs(vec![Type::FieldElement, Type::FieldElement])
|
||||
.outputs(vec![Type::FieldElement]),
|
||||
};
|
||||
|
||||
let witness = program
|
||||
.clone()
|
||||
.execute::<FieldPrime>(&vec![FieldPrime::from(3), FieldPrime::from(4)])
|
||||
.execute(&vec![FieldPrime::from(3), FieldPrime::from(4)])
|
||||
.unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
134
zokrates_core/src/static_analysis/constrain_inputs.rs
Normal file
134
zokrates_core/src/static_analysis/constrain_inputs.rs
Normal file
|
@ -0,0 +1,134 @@
|
|||
//! Add runtime boolean checks on user inputs
|
||||
//!
|
||||
//! Example:
|
||||
//! ```zokrates
|
||||
//! struct Foo {
|
||||
//! bar: bool
|
||||
//! }
|
||||
//!
|
||||
//! def main(Foo f) -> ():
|
||||
//! f.bar == f.bar && f.bar
|
||||
//! return
|
||||
//! ```
|
||||
//!
|
||||
//! Becomes
|
||||
//!
|
||||
//! ```zokrates
|
||||
//! struct Foo {
|
||||
//! bar: bool
|
||||
//! }
|
||||
//!
|
||||
//! def main(Foo f) -> ():
|
||||
//! f.bar == f.bar && f.bar
|
||||
//! return
|
||||
//! ```
|
||||
//!
|
||||
//! @file constrain_inputs.rs
|
||||
//! @author Thibaut Schaeffer <thibaut@schaeff.fr>
|
||||
//! @date 2019
|
||||
|
||||
use crate::typed_absy::folder::Folder;
|
||||
use crate::typed_absy::types::Type;
|
||||
use crate::typed_absy::*;
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
pub struct InputConstrainer<'ast, T: Field> {
|
||||
constraints: Vec<TypedStatement<'ast, T>>,
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> InputConstrainer<'ast, T> {
|
||||
fn new() -> Self {
|
||||
InputConstrainer {
|
||||
constraints: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn constrain(p: TypedProgram<T>) -> TypedProgram<T> {
|
||||
InputConstrainer::new().fold_program(p)
|
||||
}
|
||||
|
||||
fn constrain_expression(&mut self, e: TypedExpression<'ast, T>) {
|
||||
match e {
|
||||
TypedExpression::FieldElement(_) => {}
|
||||
TypedExpression::Boolean(b) => self.constraints.push(TypedStatement::Condition(
|
||||
b.clone().into(),
|
||||
BooleanExpression::And(box b.clone(), box b).into(),
|
||||
)),
|
||||
TypedExpression::Array(a) => {
|
||||
for i in 0..a.size() {
|
||||
let e = match a.inner_type() {
|
||||
Type::FieldElement => FieldElementExpression::select(
|
||||
a.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
Type::Boolean => BooleanExpression::select(
|
||||
a.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
Type::Array(..) => ArrayExpression::select(
|
||||
a.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
Type::Struct(..) => StructExpression::select(
|
||||
a.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
};
|
||||
|
||||
self.constrain_expression(e);
|
||||
}
|
||||
}
|
||||
TypedExpression::Struct(s) => {
|
||||
for (id, ty) in s.ty() {
|
||||
let e = match ty {
|
||||
Type::FieldElement => {
|
||||
FieldElementExpression::member(s.clone(), id.clone()).into()
|
||||
}
|
||||
Type::Boolean => BooleanExpression::member(s.clone(), id.clone()).into(),
|
||||
Type::Array(..) => ArrayExpression::member(s.clone(), id.clone()).into(),
|
||||
Type::Struct(..) => StructExpression::member(s.clone(), id.clone()).into(),
|
||||
};
|
||||
|
||||
self.constrain_expression(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Folder<'ast, T> for InputConstrainer<'ast, T> {
|
||||
fn fold_parameter(&mut self, p: Parameter<'ast>) -> Parameter<'ast> {
|
||||
let v = p.id.clone();
|
||||
|
||||
let e = match v.get_type() {
|
||||
Type::FieldElement => FieldElementExpression::Identifier(v.id).into(),
|
||||
Type::Boolean => BooleanExpression::Identifier(v.id).into(),
|
||||
Type::Struct(members) => StructExpressionInner::Identifier(v.id)
|
||||
.annotate(members)
|
||||
.into(),
|
||||
Type::Array(box ty, size) => ArrayExpressionInner::Identifier(v.id)
|
||||
.annotate(ty, size)
|
||||
.into(),
|
||||
};
|
||||
|
||||
self.constrain_expression(e);
|
||||
|
||||
p
|
||||
}
|
||||
|
||||
fn fold_function(&mut self, f: TypedFunction<'ast, T>) -> TypedFunction<'ast, T> {
|
||||
TypedFunction {
|
||||
arguments: f
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|a| self.fold_parameter(a))
|
||||
.collect(),
|
||||
statements: self.constraints.drain(..).chain(f.statements).collect(),
|
||||
..f
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,8 +17,8 @@
|
|||
//! where any call in `main` must be to `_SHA_256_ROUND` or `_UNPACK`
|
||||
|
||||
use std::collections::HashMap;
|
||||
use typed_absy::types::{FunctionKey, MemberId, Type};
|
||||
use typed_absy::{folder::*, *};
|
||||
use types::{FunctionKey, Type};
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
/// An inliner
|
||||
|
@ -260,12 +260,36 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
|
|||
e => fold_array_expression_inner(self, ty, size, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_struct_expression_inner(
|
||||
&mut self,
|
||||
ty: &Vec<(MemberId, Type)>,
|
||||
e: StructExpressionInner<'ast, T>,
|
||||
) -> StructExpressionInner<'ast, T> {
|
||||
match e {
|
||||
StructExpressionInner::FunctionCall(key, exps) => {
|
||||
let exps: Vec<_> = exps.into_iter().map(|e| self.fold_expression(e)).collect();
|
||||
|
||||
match self.try_inline_call(&key, exps) {
|
||||
Ok(mut ret) => match ret.pop().unwrap() {
|
||||
TypedExpression::Struct(e) => e.into_inner(),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
Err((key, expressions)) => {
|
||||
StructExpressionInner::FunctionCall(key, expressions)
|
||||
}
|
||||
}
|
||||
}
|
||||
// default
|
||||
e => fold_struct_expression_inner(self, ty, e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use types::{FunctionKey, Signature, Type};
|
||||
use typed_absy::types::{FunctionKey, Signature, Type};
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
//! @author Thibaut Schaeffer <thibaut@schaeff.fr>
|
||||
//! @date 2018
|
||||
|
||||
mod constrain_inputs;
|
||||
mod flat_propagation;
|
||||
mod inline;
|
||||
mod propagation;
|
||||
mod unroll;
|
||||
|
||||
use self::constrain_inputs::InputConstrainer;
|
||||
use self::inline::Inliner;
|
||||
use self::propagation::Propagator;
|
||||
use self::unroll::Unroller;
|
||||
|
@ -28,6 +30,8 @@ impl<'ast, T: Field> Analyse for TypedProgram<'ast, T> {
|
|||
let r = Inliner::inline(r);
|
||||
// propagate
|
||||
let r = Propagator::propagate(r);
|
||||
// constrain inputs
|
||||
let r = InputConstrainer::constrain(r);
|
||||
r
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::typed_absy::folder::*;
|
|||
use crate::typed_absy::*;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use types::Type;
|
||||
use typed_absy::types::{MemberId, Type};
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
pub struct Propagator<'ast, T: Field> {
|
||||
|
@ -35,6 +35,10 @@ fn is_constant<'ast, T: Field>(e: &TypedExpression<'ast, T>) -> bool {
|
|||
ArrayExpressionInner::Value(v) => v.iter().all(|e| is_constant(e)),
|
||||
_ => false,
|
||||
},
|
||||
TypedExpression::Struct(a) => match a.as_inner() {
|
||||
StructExpressionInner::Value(v) => v.iter().all(|e| is_constant(e)),
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +75,9 @@ impl<'ast, T: Field> Folder<'ast, T> for Propagator<'ast, T> {
|
|||
TypedStatement::Definition(TypedAssignee::Select(..), _) => {
|
||||
unreachable!("array updates should have been replaced with full array redef")
|
||||
}
|
||||
TypedStatement::Definition(TypedAssignee::Member(..), _) => {
|
||||
unreachable!("struct update should have been replaced with full struct redef")
|
||||
}
|
||||
// propagate lhs and rhs for conditions
|
||||
TypedStatement::Condition(e1, e2) => {
|
||||
// could stop execution here if condition is known to fail
|
||||
|
@ -224,6 +231,24 @@ impl<'ast, T: Field> Folder<'ast, T> for Propagator<'ast, T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
FieldElementExpression::Member(box s, m) => {
|
||||
let s = self.fold_struct_expression(s);
|
||||
|
||||
let members = match s.get_type() {
|
||||
Type::Struct(members) => members,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match s.into_inner() {
|
||||
StructExpressionInner::Value(v) => {
|
||||
match members.iter().zip(v).find(|(id, _)| id.0 == m).unwrap().1 {
|
||||
TypedExpression::FieldElement(s) => s,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
inner => FieldElementExpression::Member(box inner.annotate(members), m),
|
||||
}
|
||||
}
|
||||
e => fold_field_expression(self, e),
|
||||
}
|
||||
}
|
||||
|
@ -302,10 +327,124 @@ impl<'ast, T: Field> Folder<'ast, T> for Propagator<'ast, T> {
|
|||
c => ArrayExpressionInner::IfElse(box c, box consequence, box alternative),
|
||||
}
|
||||
}
|
||||
ArrayExpressionInner::Member(box s, m) => {
|
||||
let s = self.fold_struct_expression(s);
|
||||
|
||||
let members = match s.get_type() {
|
||||
Type::Struct(members) => members,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match s.into_inner() {
|
||||
StructExpressionInner::Value(v) => {
|
||||
match members.iter().zip(v).find(|(id, _)| id.0 == m).unwrap().1 {
|
||||
TypedExpression::Array(a) => a.into_inner(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
inner => ArrayExpressionInner::Member(box inner.annotate(members), m),
|
||||
}
|
||||
}
|
||||
e => fold_array_expression_inner(self, ty, size, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_struct_expression_inner(
|
||||
&mut self,
|
||||
ty: &Vec<(MemberId, Type)>,
|
||||
e: StructExpressionInner<'ast, T>,
|
||||
) -> StructExpressionInner<'ast, T> {
|
||||
match e {
|
||||
StructExpressionInner::Identifier(id) => {
|
||||
match self
|
||||
.constants
|
||||
.get(&TypedAssignee::Identifier(Variable::struc(
|
||||
id.clone(),
|
||||
ty.clone(),
|
||||
))) {
|
||||
Some(e) => match e {
|
||||
TypedExpression::Struct(e) => e.as_inner().clone(),
|
||||
_ => panic!("constant stored for an array should be an array"),
|
||||
},
|
||||
None => StructExpressionInner::Identifier(id),
|
||||
}
|
||||
}
|
||||
StructExpressionInner::Select(box array, box index) => {
|
||||
let array = self.fold_array_expression(array);
|
||||
let index = self.fold_field_expression(index);
|
||||
|
||||
let inner_type = array.inner_type().clone();
|
||||
let size = array.size();
|
||||
|
||||
match (array.into_inner(), index) {
|
||||
(ArrayExpressionInner::Value(v), FieldElementExpression::Number(n)) => {
|
||||
let n_as_usize = n.to_dec_string().parse::<usize>().unwrap();
|
||||
if n_as_usize < size {
|
||||
StructExpression::try_from(v[n_as_usize].clone())
|
||||
.unwrap()
|
||||
.into_inner()
|
||||
} else {
|
||||
unreachable!(
|
||||
"out of bounds index ({} >= {}) found during static analysis",
|
||||
n_as_usize, size
|
||||
);
|
||||
}
|
||||
}
|
||||
(ArrayExpressionInner::Identifier(id), FieldElementExpression::Number(n)) => {
|
||||
match self.constants.get(&TypedAssignee::Select(
|
||||
box TypedAssignee::Identifier(Variable::array(
|
||||
id.clone(),
|
||||
inner_type.clone(),
|
||||
size,
|
||||
)),
|
||||
box FieldElementExpression::Number(n.clone()).into(),
|
||||
)) {
|
||||
Some(e) => match e {
|
||||
TypedExpression::Struct(e) => e.clone().into_inner(),
|
||||
_ => unreachable!(""),
|
||||
},
|
||||
None => StructExpressionInner::Select(
|
||||
box ArrayExpressionInner::Identifier(id).annotate(inner_type, size),
|
||||
box FieldElementExpression::Number(n),
|
||||
),
|
||||
}
|
||||
}
|
||||
(a, i) => {
|
||||
StructExpressionInner::Select(box a.annotate(inner_type, size), box i)
|
||||
}
|
||||
}
|
||||
}
|
||||
StructExpressionInner::IfElse(box condition, box consequence, box alternative) => {
|
||||
let consequence = self.fold_struct_expression(consequence);
|
||||
let alternative = self.fold_struct_expression(alternative);
|
||||
match self.fold_boolean_expression(condition) {
|
||||
BooleanExpression::Value(true) => consequence.into_inner(),
|
||||
BooleanExpression::Value(false) => alternative.into_inner(),
|
||||
c => StructExpressionInner::IfElse(box c, box consequence, box alternative),
|
||||
}
|
||||
}
|
||||
StructExpressionInner::Member(box s, m) => {
|
||||
let s = self.fold_struct_expression(s);
|
||||
|
||||
let members = match s.get_type() {
|
||||
Type::Struct(members) => members,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match s.into_inner() {
|
||||
StructExpressionInner::Value(v) => {
|
||||
match members.iter().zip(v).find(|(id, _)| id.0 == m).unwrap().1 {
|
||||
TypedExpression::Struct(s) => s.into_inner(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
inner => StructExpressionInner::Member(box inner.annotate(members), m),
|
||||
}
|
||||
}
|
||||
e => fold_struct_expression_inner(self, ty, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_boolean_expression(
|
||||
&mut self,
|
||||
e: BooleanExpression<'ast, T>,
|
||||
|
@ -430,6 +569,24 @@ impl<'ast, T: Field> Folder<'ast, T> for Propagator<'ast, T> {
|
|||
c => BooleanExpression::IfElse(box c, box consequence, box alternative),
|
||||
}
|
||||
}
|
||||
BooleanExpression::Member(box s, m) => {
|
||||
let s = self.fold_struct_expression(s);
|
||||
|
||||
let members = match s.get_type() {
|
||||
Type::Struct(members) => members,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match s.into_inner() {
|
||||
StructExpressionInner::Value(v) => {
|
||||
match members.iter().zip(v).find(|(id, _)| id.0 == m).unwrap().1 {
|
||||
TypedExpression::Boolean(s) => s,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
inner => BooleanExpression::Member(box inner.annotate(members), m),
|
||||
}
|
||||
}
|
||||
e => fold_boolean_expression(self, e),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
//! @date 2018
|
||||
|
||||
use crate::typed_absy::folder::*;
|
||||
use crate::typed_absy::types::{MemberId, Type};
|
||||
use crate::typed_absy::*;
|
||||
use crate::types::Type;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use zokrates_field::field::Field;
|
||||
|
@ -47,7 +47,7 @@ impl<'ast> Unroller<'ast> {
|
|||
|
||||
fn choose_many<T: Field>(
|
||||
base: TypedExpression<'ast, T>,
|
||||
indices: Vec<FieldElementExpression<'ast, T>>,
|
||||
indices: Vec<Access<'ast, T>>,
|
||||
new_expression: TypedExpression<'ast, T>,
|
||||
statements: &mut HashSet<TypedStatement<'ast, T>>,
|
||||
) -> TypedExpression<'ast, T> {
|
||||
|
@ -55,131 +55,256 @@ impl<'ast> Unroller<'ast> {
|
|||
|
||||
match indices.len() {
|
||||
0 => new_expression,
|
||||
_ => {
|
||||
let base = match base {
|
||||
TypedExpression::Array(e) => e,
|
||||
e => unreachable!("can't take an element on a {}", e.get_type()),
|
||||
};
|
||||
_ => match base {
|
||||
TypedExpression::Array(base) => {
|
||||
let inner_ty = base.inner_type();
|
||||
let size = base.size();
|
||||
|
||||
let inner_ty = base.inner_type();
|
||||
let size = base.size();
|
||||
let head = indices.remove(0);
|
||||
let tail = indices;
|
||||
|
||||
let head = indices.pop().unwrap();
|
||||
let tail = indices;
|
||||
|
||||
statements.insert(TypedStatement::Condition(
|
||||
BooleanExpression::Lt(
|
||||
box head.clone(),
|
||||
box FieldElementExpression::Number(T::from(size)),
|
||||
)
|
||||
.into(),
|
||||
BooleanExpression::Value(true).into(),
|
||||
));
|
||||
|
||||
ArrayExpressionInner::Value(
|
||||
(0..size)
|
||||
.map(|i| match inner_ty {
|
||||
Type::Array(..) => ArrayExpression::if_else(
|
||||
BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
match head {
|
||||
Access::Select(head) => {
|
||||
statements.insert(TypedStatement::Condition(
|
||||
BooleanExpression::Lt(
|
||||
box head.clone(),
|
||||
),
|
||||
match Self::choose_many(
|
||||
ArrayExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
) {
|
||||
TypedExpression::Array(e) => e,
|
||||
e => unreachable!(
|
||||
"the interior was expected to be an array, was {}",
|
||||
e.get_type()
|
||||
),
|
||||
},
|
||||
ArrayExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
box FieldElementExpression::Number(T::from(size)),
|
||||
)
|
||||
.into(),
|
||||
BooleanExpression::Value(true).into(),
|
||||
));
|
||||
|
||||
ArrayExpressionInner::Value(
|
||||
(0..size)
|
||||
.map(|i| match inner_ty {
|
||||
Type::Array(..) => ArrayExpression::if_else(
|
||||
BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
box head.clone(),
|
||||
),
|
||||
match Self::choose_many(
|
||||
ArrayExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
) {
|
||||
TypedExpression::Array(e) => e,
|
||||
e => unreachable!(
|
||||
"the interior was expected to be an array, was {}",
|
||||
e.get_type()
|
||||
),
|
||||
},
|
||||
ArrayExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
Type::Struct(..) => StructExpression::if_else(
|
||||
BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
box head.clone(),
|
||||
),
|
||||
match Self::choose_many(
|
||||
StructExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
) {
|
||||
TypedExpression::Struct(e) => e,
|
||||
e => unreachable!(
|
||||
"the interior was expected to be a struct, was {}",
|
||||
e.get_type()
|
||||
),
|
||||
},
|
||||
StructExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
Type::FieldElement => FieldElementExpression::if_else(
|
||||
BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
box head.clone(),
|
||||
),
|
||||
match Self::choose_many(
|
||||
FieldElementExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
) {
|
||||
TypedExpression::FieldElement(e) => e,
|
||||
e => unreachable!(
|
||||
"the interior was expected to be a field, was {}",
|
||||
e.get_type()
|
||||
),
|
||||
},
|
||||
FieldElementExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
Type::Boolean => BooleanExpression::if_else(
|
||||
BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
box head.clone(),
|
||||
),
|
||||
match Self::choose_many(
|
||||
BooleanExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
) {
|
||||
TypedExpression::Boolean(e) => e,
|
||||
e => unreachable!(
|
||||
"the interior was expected to be a boolean, was {}",
|
||||
e.get_type()
|
||||
),
|
||||
},
|
||||
BooleanExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.into(),
|
||||
Type::FieldElement => FieldElementExpression::if_else(
|
||||
BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
box head.clone(),
|
||||
),
|
||||
match Self::choose_many(
|
||||
FieldElementExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
) {
|
||||
TypedExpression::FieldElement(e) => e,
|
||||
e => unreachable!(
|
||||
"the interior was expected to be a field, was {}",
|
||||
e.get_type()
|
||||
),
|
||||
},
|
||||
FieldElementExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
Type::Boolean => BooleanExpression::if_else(
|
||||
BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
box head.clone(),
|
||||
),
|
||||
match Self::choose_many(
|
||||
BooleanExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
) {
|
||||
TypedExpression::Boolean(e) => e,
|
||||
e => unreachable!(
|
||||
"the interior was expected to be a boolean, was {}",
|
||||
e.get_type()
|
||||
),
|
||||
},
|
||||
BooleanExpression::select(
|
||||
base.clone(),
|
||||
FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.annotate(inner_ty.clone(), size)
|
||||
.into()
|
||||
}
|
||||
.annotate(inner_ty.clone(), size)
|
||||
.into()
|
||||
}
|
||||
Access::Member(..) => unreachable!("can't get a member from an array"),
|
||||
}
|
||||
}
|
||||
TypedExpression::Struct(base) => {
|
||||
let members = match base.get_type() {
|
||||
Type::Struct(members) => members.clone(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let head = indices.remove(0);
|
||||
let tail = indices;
|
||||
|
||||
match head {
|
||||
Access::Member(head) => StructExpressionInner::Value(
|
||||
members
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|(id, t)| match t {
|
||||
Type::FieldElement => {
|
||||
if id == head {
|
||||
Self::choose_many(
|
||||
FieldElementExpression::member(
|
||||
base.clone(),
|
||||
head.clone(),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
)
|
||||
} else {
|
||||
FieldElementExpression::member(base.clone(), id.clone())
|
||||
.into()
|
||||
}
|
||||
}
|
||||
Type::Boolean => {
|
||||
if id == head {
|
||||
Self::choose_many(
|
||||
BooleanExpression::member(
|
||||
base.clone(),
|
||||
head.clone(),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
)
|
||||
} else {
|
||||
BooleanExpression::member(base.clone(), id.clone())
|
||||
.into()
|
||||
}
|
||||
}
|
||||
Type::Array(..) => {
|
||||
if id == head {
|
||||
Self::choose_many(
|
||||
ArrayExpression::member(base.clone(), head.clone())
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
)
|
||||
} else {
|
||||
ArrayExpression::member(base.clone(), id.clone()).into()
|
||||
}
|
||||
}
|
||||
Type::Struct(..) => {
|
||||
if id == head {
|
||||
Self::choose_many(
|
||||
StructExpression::member(
|
||||
base.clone(),
|
||||
head.clone(),
|
||||
)
|
||||
.into(),
|
||||
tail.clone(),
|
||||
new_expression.clone(),
|
||||
statements,
|
||||
)
|
||||
} else {
|
||||
StructExpression::member(base.clone(), id.clone())
|
||||
.into()
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.annotate(members)
|
||||
.into(),
|
||||
Access::Select(..) => unreachable!("can't get a element from a struct"),
|
||||
}
|
||||
}
|
||||
e => unreachable!("can't make an access on a {}", e.get_type()),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Turn an assignee into its representation as a base variable and a list of indices
|
||||
#[derive(Clone, Debug)]
|
||||
enum Access<'ast, T: Field> {
|
||||
Select(FieldElementExpression<'ast, T>),
|
||||
Member(MemberId),
|
||||
}
|
||||
/// Turn an assignee into its representation as a base variable and a list accesses
|
||||
/// a[2][3][4] -> (a, [2, 3, 4])
|
||||
fn linear<'ast, T: Field>(
|
||||
a: TypedAssignee<'ast, T>,
|
||||
) -> (Variable, Vec<FieldElementExpression<'ast, T>>) {
|
||||
fn linear<'ast, T: Field>(a: TypedAssignee<'ast, T>) -> (Variable, Vec<Access<'ast, T>>) {
|
||||
match a {
|
||||
TypedAssignee::Identifier(v) => (v, vec![]),
|
||||
TypedAssignee::Select(box array, box index) => {
|
||||
let (v, mut indices) = linear(array);
|
||||
indices.push(index);
|
||||
indices.push(Access::Select(index));
|
||||
(v, indices)
|
||||
}
|
||||
TypedAssignee::Member(box s, m) => {
|
||||
let (v, mut indices) = linear(s);
|
||||
indices.push(Access::Member(m));
|
||||
(v, indices)
|
||||
}
|
||||
}
|
||||
|
@ -206,12 +331,20 @@ impl<'ast, T: Field> Folder<'ast, T> for Unroller<'ast> {
|
|||
.annotate(ty, size)
|
||||
.into()
|
||||
}
|
||||
Type::Struct(members) => {
|
||||
StructExpressionInner::Identifier(variable.id.clone().into())
|
||||
.annotate(members)
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
let base = self.fold_expression(base);
|
||||
let indices = indices
|
||||
.into_iter()
|
||||
.map(|i| self.fold_field_expression(i))
|
||||
.map(|a| match a {
|
||||
Access::Select(i) => Access::Select(self.fold_field_expression(i)),
|
||||
a => a,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut range_checks = HashSet::new();
|
||||
|
@ -298,7 +431,12 @@ mod tests {
|
|||
|
||||
let index = FieldElementExpression::Number(FieldPrime::from(1));
|
||||
|
||||
let a1 = Unroller::choose_many(a0.clone().into(), vec![index], e, &mut HashSet::new());
|
||||
let a1 = Unroller::choose_many(
|
||||
a0.clone().into(),
|
||||
vec![Access::Select(index)],
|
||||
e,
|
||||
&mut HashSet::new(),
|
||||
);
|
||||
|
||||
// a[1] = 42
|
||||
// -> a = [0 == 1 ? 42 : a[0], 1 == 1 ? 42 : a[1], 2 == 1 ? 42 : a[2]]
|
||||
|
@ -356,7 +494,7 @@ mod tests {
|
|||
|
||||
let a1 = Unroller::choose_many(
|
||||
a0.clone().into(),
|
||||
vec![index],
|
||||
vec![Access::Select(index)],
|
||||
e.clone().into(),
|
||||
&mut HashSet::new(),
|
||||
);
|
||||
|
@ -414,8 +552,8 @@ mod tests {
|
|||
let e = FieldElementExpression::Number(FieldPrime::from(42));
|
||||
|
||||
let indices = vec![
|
||||
FieldElementExpression::Number(FieldPrime::from(0)),
|
||||
FieldElementExpression::Number(FieldPrime::from(0)),
|
||||
Access::Select(FieldElementExpression::Number(FieldPrime::from(0))),
|
||||
Access::Select(FieldElementExpression::Number(FieldPrime::from(0))),
|
||||
];
|
||||
|
||||
let a1 = Unroller::choose_many(
|
||||
|
@ -528,7 +666,7 @@ mod tests {
|
|||
#[cfg(test)]
|
||||
mod statement {
|
||||
use super::*;
|
||||
use crate::types::{FunctionKey, Signature};
|
||||
use crate::typed_absy::types::{FunctionKey, Signature};
|
||||
|
||||
#[test]
|
||||
fn for_loop() {
|
||||
|
@ -709,7 +847,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn incremental_multiple_definition() {
|
||||
use crate::types::Type;
|
||||
use crate::typed_absy::types::Type;
|
||||
|
||||
// field a
|
||||
// a = 2
|
||||
|
|
|
@ -48,6 +48,7 @@ pub trait Folder<'ast, T: Field>: Sized {
|
|||
box self.fold_assignee(a),
|
||||
box self.fold_field_expression(index),
|
||||
),
|
||||
TypedAssignee::Member(box s, m) => TypedAssignee::Member(box self.fold_assignee(s), m),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,6 +61,7 @@ pub trait Folder<'ast, T: Field>: Sized {
|
|||
TypedExpression::FieldElement(e) => self.fold_field_expression(e).into(),
|
||||
TypedExpression::Boolean(e) => self.fold_boolean_expression(e).into(),
|
||||
TypedExpression::Array(e) => self.fold_array_expression(e).into(),
|
||||
TypedExpression::Struct(e) => self.fold_struct_expression(e).into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +69,13 @@ pub trait Folder<'ast, T: Field>: Sized {
|
|||
fold_array_expression(self, e)
|
||||
}
|
||||
|
||||
fn fold_struct_expression(
|
||||
&mut self,
|
||||
e: StructExpression<'ast, T>,
|
||||
) -> StructExpression<'ast, T> {
|
||||
fold_struct_expression(self, e)
|
||||
}
|
||||
|
||||
fn fold_expression_list(
|
||||
&mut self,
|
||||
es: TypedExpressionList<'ast, T>,
|
||||
|
@ -105,6 +114,13 @@ pub trait Folder<'ast, T: Field>: Sized {
|
|||
) -> ArrayExpressionInner<'ast, T> {
|
||||
fold_array_expression_inner(self, ty, size, e)
|
||||
}
|
||||
fn fold_struct_expression_inner(
|
||||
&mut self,
|
||||
ty: &Vec<(MemberId, Type)>,
|
||||
e: StructExpressionInner<'ast, T>,
|
||||
) -> StructExpressionInner<'ast, T> {
|
||||
fold_struct_expression_inner(self, ty, e)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_module<'ast, T: Field, F: Folder<'ast, T>>(
|
||||
|
@ -178,6 +194,10 @@ pub fn fold_array_expression_inner<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
box f.fold_array_expression(alternative),
|
||||
)
|
||||
}
|
||||
ArrayExpressionInner::Member(box s, id) => {
|
||||
let s = f.fold_struct_expression(s);
|
||||
ArrayExpressionInner::Member(box s, id)
|
||||
}
|
||||
ArrayExpressionInner::Select(box array, box index) => {
|
||||
let array = f.fold_array_expression(array);
|
||||
let index = f.fold_field_expression(index);
|
||||
|
@ -186,6 +206,39 @@ pub fn fold_array_expression_inner<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fold_struct_expression_inner<'ast, T: Field, F: Folder<'ast, T>>(
|
||||
f: &mut F,
|
||||
_: &Vec<(MemberId, Type)>,
|
||||
e: StructExpressionInner<'ast, T>,
|
||||
) -> StructExpressionInner<'ast, T> {
|
||||
match e {
|
||||
StructExpressionInner::Identifier(id) => StructExpressionInner::Identifier(f.fold_name(id)),
|
||||
StructExpressionInner::Value(exprs) => {
|
||||
StructExpressionInner::Value(exprs.into_iter().map(|e| f.fold_expression(e)).collect())
|
||||
}
|
||||
StructExpressionInner::FunctionCall(id, exps) => {
|
||||
let exps = exps.into_iter().map(|e| f.fold_expression(e)).collect();
|
||||
StructExpressionInner::FunctionCall(id, exps)
|
||||
}
|
||||
StructExpressionInner::IfElse(box condition, box consequence, box alternative) => {
|
||||
StructExpressionInner::IfElse(
|
||||
box f.fold_boolean_expression(condition),
|
||||
box f.fold_struct_expression(consequence),
|
||||
box f.fold_struct_expression(alternative),
|
||||
)
|
||||
}
|
||||
StructExpressionInner::Member(box s, id) => {
|
||||
let s = f.fold_struct_expression(s);
|
||||
StructExpressionInner::Member(box s, id)
|
||||
}
|
||||
StructExpressionInner::Select(box array, box index) => {
|
||||
let array = f.fold_array_expression(array);
|
||||
let index = f.fold_field_expression(index);
|
||||
StructExpressionInner::Select(box array, box index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
||||
f: &mut F,
|
||||
e: FieldElementExpression<'ast, T>,
|
||||
|
@ -230,6 +283,10 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
let exps = exps.into_iter().map(|e| f.fold_expression(e)).collect();
|
||||
FieldElementExpression::FunctionCall(key, exps)
|
||||
}
|
||||
FieldElementExpression::Member(box s, id) => {
|
||||
let s = f.fold_struct_expression(s);
|
||||
FieldElementExpression::Member(box s, id)
|
||||
}
|
||||
FieldElementExpression::Select(box array, box index) => {
|
||||
let array = f.fold_array_expression(array);
|
||||
let index = f.fold_field_expression(index);
|
||||
|
@ -295,6 +352,10 @@ pub fn fold_boolean_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
let alt = f.fold_boolean_expression(alt);
|
||||
BooleanExpression::IfElse(box cond, box cons, box alt)
|
||||
}
|
||||
BooleanExpression::Member(box s, id) => {
|
||||
let s = f.fold_struct_expression(s);
|
||||
BooleanExpression::Member(box s, id)
|
||||
}
|
||||
BooleanExpression::Select(box array, box index) => {
|
||||
let array = f.fold_array_expression(array);
|
||||
let index = f.fold_field_expression(index);
|
||||
|
@ -332,6 +393,16 @@ pub fn fold_array_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fold_struct_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
||||
f: &mut F,
|
||||
e: StructExpression<'ast, T>,
|
||||
) -> StructExpression<'ast, T> {
|
||||
StructExpression {
|
||||
inner: f.fold_struct_expression_inner(&e.ty, e.inner),
|
||||
..e
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_function_symbol<'ast, T: Field, F: Folder<'ast, T>>(
|
||||
f: &mut F,
|
||||
s: TypedFunctionSymbol<'ast, T>,
|
||||
|
|
|
@ -7,11 +7,14 @@
|
|||
|
||||
pub mod folder;
|
||||
mod parameter;
|
||||
pub mod types;
|
||||
mod variable;
|
||||
|
||||
pub use crate::typed_absy::parameter::Parameter;
|
||||
pub use crate::typed_absy::types::Type;
|
||||
pub use crate::typed_absy::variable::Variable;
|
||||
use crate::types::{FunctionKey, Signature, Type};
|
||||
|
||||
use crate::typed_absy::types::{FunctionKey, MemberId, Signature};
|
||||
use embed::FlatEmbed;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -72,7 +75,7 @@ impl<'ast, T: Field> fmt::Display for TypedProgram<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A
|
||||
/// A typed program as a collection of functions. Types have been resolved during semantic checking.
|
||||
#[derive(PartialEq, Clone)]
|
||||
pub struct TypedModule<'ast, T: Field> {
|
||||
/// Functions of the program
|
||||
|
@ -239,6 +242,7 @@ pub enum TypedAssignee<'ast, T: Field> {
|
|||
Box<TypedAssignee<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
),
|
||||
Member(Box<TypedAssignee<'ast, T>>, MemberId),
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Typed for TypedAssignee<'ast, T> {
|
||||
|
@ -252,6 +256,15 @@ impl<'ast, T: Field> Typed for TypedAssignee<'ast, T> {
|
|||
_ => unreachable!("an array element should only be defined over arrays"),
|
||||
}
|
||||
}
|
||||
TypedAssignee::Member(ref s, ref m) => {
|
||||
let s_type = s.get_type();
|
||||
match s_type {
|
||||
Type::Struct(members) => {
|
||||
members.iter().find(|(id, _)| id == m).unwrap().1.clone()
|
||||
}
|
||||
_ => unreachable!("a struct access should only be defined over structs"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,6 +274,7 @@ impl<'ast, T: Field> fmt::Debug for TypedAssignee<'ast, T> {
|
|||
match *self {
|
||||
TypedAssignee::Identifier(ref s) => write!(f, "{}", s.id),
|
||||
TypedAssignee::Select(ref a, ref e) => write!(f, "{}[{}]", a, e),
|
||||
TypedAssignee::Member(ref s, ref m) => write!(f, "{}.{}", s, m),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -362,6 +376,7 @@ pub enum TypedExpression<'ast, T: Field> {
|
|||
Boolean(BooleanExpression<'ast, T>),
|
||||
FieldElement(FieldElementExpression<'ast, T>),
|
||||
Array(ArrayExpression<'ast, T>),
|
||||
Struct(StructExpression<'ast, T>),
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> From<BooleanExpression<'ast, T>> for TypedExpression<'ast, T> {
|
||||
|
@ -382,12 +397,19 @@ impl<'ast, T: Field> From<ArrayExpression<'ast, T>> for TypedExpression<'ast, T>
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> From<StructExpression<'ast, T>> for TypedExpression<'ast, T> {
|
||||
fn from(e: StructExpression<'ast, T>) -> TypedExpression<T> {
|
||||
TypedExpression::Struct(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> fmt::Display for TypedExpression<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
TypedExpression::Boolean(ref e) => write!(f, "{}", e),
|
||||
TypedExpression::FieldElement(ref e) => write!(f, "{}", e),
|
||||
TypedExpression::Array(ref e) => write!(f, "{}", e.inner),
|
||||
TypedExpression::Array(ref e) => write!(f, "{}", e),
|
||||
TypedExpression::Struct(ref s) => write!(f, "{}", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -398,6 +420,7 @@ impl<'ast, T: Field> fmt::Debug for TypedExpression<'ast, T> {
|
|||
TypedExpression::Boolean(ref e) => write!(f, "{:?}", e),
|
||||
TypedExpression::FieldElement(ref e) => write!(f, "{:?}", e),
|
||||
TypedExpression::Array(ref e) => write!(f, "{:?}", e),
|
||||
TypedExpression::Struct(ref s) => write!(f, "{}", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,12 +437,57 @@ impl<'ast, T: Field> fmt::Debug for ArrayExpression<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> fmt::Display for StructExpression<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.inner {
|
||||
StructExpressionInner::Identifier(ref var) => write!(f, "{}", var),
|
||||
StructExpressionInner::Value(ref values) => write!(
|
||||
f,
|
||||
"{{{}}}",
|
||||
self.ty
|
||||
.iter()
|
||||
.map(|(id, _)| id)
|
||||
.zip(values.iter())
|
||||
.map(|(id, o)| format!("{}: {}", id, o.to_string()))
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
),
|
||||
StructExpressionInner::FunctionCall(ref key, ref p) => {
|
||||
write!(f, "{}(", key.id,)?;
|
||||
for (i, param) in p.iter().enumerate() {
|
||||
write!(f, "{}", param)?;
|
||||
if i < p.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
StructExpressionInner::IfElse(ref condition, ref consequent, ref alternative) => {
|
||||
write!(
|
||||
f,
|
||||
"if {} then {} else {} fi",
|
||||
condition, consequent, alternative
|
||||
)
|
||||
}
|
||||
StructExpressionInner::Member(ref struc, ref id) => write!(f, "{}.{}", struc, id),
|
||||
StructExpressionInner::Select(ref id, ref index) => write!(f, "{}[{}]", id, index),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> fmt::Debug for StructExpression<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}", self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Typed for TypedExpression<'ast, T> {
|
||||
fn get_type(&self) -> Type {
|
||||
match *self {
|
||||
TypedExpression::Boolean(ref e) => e.get_type(),
|
||||
TypedExpression::FieldElement(ref e) => e.get_type(),
|
||||
TypedExpression::Array(ref e) => e.get_type(),
|
||||
TypedExpression::Struct(ref s) => s.get_type(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -430,6 +498,12 @@ impl<'ast, T: Field> Typed for ArrayExpression<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Typed for StructExpression<'ast, T> {
|
||||
fn get_type(&self) -> Type {
|
||||
Type::Struct(self.ty.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Typed for FieldElementExpression<'ast, T> {
|
||||
fn get_type(&self) -> Type {
|
||||
Type::FieldElement
|
||||
|
@ -490,6 +564,7 @@ pub enum FieldElementExpression<'ast, T: Field> {
|
|||
Box<FieldElementExpression<'ast, T>>,
|
||||
),
|
||||
FunctionCall(FunctionKey<'ast>, Vec<TypedExpression<'ast, T>>),
|
||||
Member(Box<StructExpression<'ast, T>>, MemberId),
|
||||
Select(
|
||||
Box<ArrayExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
|
@ -539,6 +614,7 @@ pub enum BooleanExpression<'ast, T: Field> {
|
|||
Box<BooleanExpression<'ast, T>>,
|
||||
Box<BooleanExpression<'ast, T>>,
|
||||
),
|
||||
Member(Box<StructExpression<'ast, T>>, MemberId),
|
||||
Select(
|
||||
Box<ArrayExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
|
@ -567,6 +643,7 @@ pub enum ArrayExpressionInner<'ast, T: Field> {
|
|||
Box<ArrayExpression<'ast, T>>,
|
||||
Box<ArrayExpression<'ast, T>>,
|
||||
),
|
||||
Member(Box<StructExpression<'ast, T>>, MemberId),
|
||||
Select(
|
||||
Box<ArrayExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
|
@ -601,6 +678,49 @@ impl<'ast, T: Field> ArrayExpression<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Hash, Eq)]
|
||||
pub struct StructExpression<'ast, T: Field> {
|
||||
ty: Vec<(MemberId, Type)>,
|
||||
inner: StructExpressionInner<'ast, T>,
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> StructExpression<'ast, T> {
|
||||
pub fn ty(&self) -> &Vec<(MemberId, Type)> {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
pub fn as_inner(&self) -> &StructExpressionInner<'ast, T> {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> StructExpressionInner<'ast, T> {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Hash, Eq)]
|
||||
pub enum StructExpressionInner<'ast, T: Field> {
|
||||
Identifier(Identifier<'ast>),
|
||||
Value(Vec<TypedExpression<'ast, T>>),
|
||||
FunctionCall(FunctionKey<'ast>, Vec<TypedExpression<'ast, T>>),
|
||||
IfElse(
|
||||
Box<BooleanExpression<'ast, T>>,
|
||||
Box<StructExpression<'ast, T>>,
|
||||
Box<StructExpression<'ast, T>>,
|
||||
),
|
||||
Member(Box<StructExpression<'ast, T>>, MemberId),
|
||||
Select(
|
||||
Box<ArrayExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
),
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> StructExpressionInner<'ast, T> {
|
||||
pub fn annotate(self, ty: Vec<(MemberId, Type)>) -> StructExpression<'ast, T> {
|
||||
StructExpression { ty, inner: self }
|
||||
}
|
||||
}
|
||||
|
||||
// Downcasts
|
||||
// Due to the fact that we keep TypedExpression simple, we end up with ArrayExpressionInner::Value whose elements are any TypedExpression, but we enforce by
|
||||
// construction that these elements are of the type declared in the corresponding ArrayExpression. As we know this by construction, we can downcast the TypedExpression to the correct type
|
||||
|
@ -640,6 +760,17 @@ impl<'ast, T: Field> TryFrom<TypedExpression<'ast, T>> for ArrayExpression<'ast,
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> TryFrom<TypedExpression<'ast, T>> for StructExpression<'ast, T> {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(te: TypedExpression<'ast, T>) -> Result<StructExpression<'ast, T>, Self::Error> {
|
||||
match te {
|
||||
TypedExpression::Struct(e) => Ok(e),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> fmt::Display for FieldElementExpression<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
@ -667,6 +798,7 @@ impl<'ast, T: Field> fmt::Display for FieldElementExpression<'ast, T> {
|
|||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
FieldElementExpression::Member(ref struc, ref id) => write!(f, "{}.{}", struc, id),
|
||||
FieldElementExpression::Select(ref id, ref index) => write!(f, "{}[{}]", id, index),
|
||||
}
|
||||
}
|
||||
|
@ -691,6 +823,7 @@ impl<'ast, T: Field> fmt::Display for BooleanExpression<'ast, T> {
|
|||
"if {} then {} else {} fi",
|
||||
condition, consequent, alternative
|
||||
),
|
||||
BooleanExpression::Member(ref struc, ref id) => write!(f, "{}.{}", struc, id),
|
||||
BooleanExpression::Select(ref id, ref index) => write!(f, "{}[{}]", id, index),
|
||||
}
|
||||
}
|
||||
|
@ -724,6 +857,7 @@ impl<'ast, T: Field> fmt::Display for ArrayExpressionInner<'ast, T> {
|
|||
"if {} then {} else {} fi",
|
||||
condition, consequent, alternative
|
||||
),
|
||||
ArrayExpressionInner::Member(ref s, ref id) => write!(f, "{}.{}", s, id),
|
||||
ArrayExpressionInner::Select(ref id, ref index) => write!(f, "{}[{}]", id, index),
|
||||
}
|
||||
}
|
||||
|
@ -759,6 +893,9 @@ impl<'ast, T: Field> fmt::Debug for FieldElementExpression<'ast, T> {
|
|||
f.debug_list().entries(p.iter()).finish()?;
|
||||
write!(f, ")")
|
||||
}
|
||||
FieldElementExpression::Member(ref struc, ref id) => {
|
||||
write!(f, "Member({:?}, {:?})", struc, id)
|
||||
}
|
||||
FieldElementExpression::Select(ref id, ref index) => {
|
||||
write!(f, "Select({:?}, {:?})", id, index)
|
||||
}
|
||||
|
@ -781,6 +918,9 @@ impl<'ast, T: Field> fmt::Debug for ArrayExpressionInner<'ast, T> {
|
|||
"IfElse({:?}, {:?}, {:?})",
|
||||
condition, consequent, alternative
|
||||
),
|
||||
ArrayExpressionInner::Member(ref struc, ref id) => {
|
||||
write!(f, "Member({:?}, {:?})", struc, id)
|
||||
}
|
||||
ArrayExpressionInner::Select(ref id, ref index) => {
|
||||
write!(f, "Select({:?}, {:?})", id, index)
|
||||
}
|
||||
|
@ -788,6 +928,33 @@ impl<'ast, T: Field> fmt::Debug for ArrayExpressionInner<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> fmt::Debug for StructExpressionInner<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
StructExpressionInner::Identifier(ref var) => write!(f, "{:?}", var),
|
||||
StructExpressionInner::Value(ref values) => write!(f, "{:?}", values),
|
||||
StructExpressionInner::FunctionCall(ref i, ref p) => {
|
||||
write!(f, "FunctionCall({:?}, (", i)?;
|
||||
f.debug_list().entries(p.iter()).finish()?;
|
||||
write!(f, ")")
|
||||
}
|
||||
StructExpressionInner::IfElse(ref condition, ref consequent, ref alternative) => {
|
||||
write!(
|
||||
f,
|
||||
"IfElse({:?}, {:?}, {:?})",
|
||||
condition, consequent, alternative
|
||||
)
|
||||
}
|
||||
StructExpressionInner::Member(ref struc, ref id) => {
|
||||
write!(f, "Member({:?}, {:?})", struc, id)
|
||||
}
|
||||
StructExpressionInner::Select(ref id, ref index) => {
|
||||
write!(f, "Select({:?}, {:?})", id, index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> fmt::Display for TypedExpressionList<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
@ -857,6 +1024,17 @@ impl<'ast, T: Field> IfElse<'ast, T> for ArrayExpression<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> IfElse<'ast, T> for StructExpression<'ast, T> {
|
||||
fn if_else(
|
||||
condition: BooleanExpression<'ast, T>,
|
||||
consequence: Self,
|
||||
alternative: Self,
|
||||
) -> Self {
|
||||
let ty = consequence.ty().clone();
|
||||
StructExpressionInner::IfElse(box condition, box consequence, box alternative).annotate(ty)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Select<'ast, T: Field> {
|
||||
fn select(array: ArrayExpression<'ast, T>, index: FieldElementExpression<'ast, T>) -> Self;
|
||||
}
|
||||
|
@ -883,3 +1061,68 @@ impl<'ast, T: Field> Select<'ast, T> for ArrayExpression<'ast, T> {
|
|||
ArrayExpressionInner::Select(box array, box index).annotate(*ty, size)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Select<'ast, T> for StructExpression<'ast, T> {
|
||||
fn select(array: ArrayExpression<'ast, T>, index: FieldElementExpression<'ast, T>) -> Self {
|
||||
let members = match array.inner_type().clone() {
|
||||
Type::Struct(members) => members,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
StructExpressionInner::Select(box array, box index).annotate(members)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Member<'ast, T: Field> {
|
||||
fn member(s: StructExpression<'ast, T>, member_id: MemberId) -> Self;
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Member<'ast, T> for FieldElementExpression<'ast, T> {
|
||||
fn member(s: StructExpression<'ast, T>, member_id: MemberId) -> Self {
|
||||
FieldElementExpression::Member(box s, member_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Member<'ast, T> for BooleanExpression<'ast, T> {
|
||||
fn member(s: StructExpression<'ast, T>, member_id: MemberId) -> Self {
|
||||
BooleanExpression::Member(box s, member_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Member<'ast, T> for ArrayExpression<'ast, T> {
|
||||
fn member(s: StructExpression<'ast, T>, member_id: MemberId) -> Self {
|
||||
let members = s.ty().clone();
|
||||
|
||||
let ty = members
|
||||
.into_iter()
|
||||
.find(|(id, _)| *id == member_id)
|
||||
.unwrap()
|
||||
.1;
|
||||
|
||||
let (ty, size) = match ty {
|
||||
Type::Array(box ty, size) => (ty, size),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
ArrayExpressionInner::Member(box s, member_id).annotate(ty, size)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Member<'ast, T> for StructExpression<'ast, T> {
|
||||
fn member(s: StructExpression<'ast, T>, member_id: MemberId) -> Self {
|
||||
let members = s.ty().clone();
|
||||
|
||||
let ty = members
|
||||
.into_iter()
|
||||
.find(|(id, _)| *id == member_id)
|
||||
.unwrap()
|
||||
.1;
|
||||
|
||||
let members = match ty {
|
||||
Type::Struct(members) => members,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
StructExpressionInner::Member(box s, member_id).annotate(members)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::absy;
|
||||
use crate::typed_absy::Variable;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -30,12 +29,3 @@ impl<'ast> fmt::Debug for Parameter<'ast> {
|
|||
write!(f, "Parameter(variable: {:?})", self.id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<absy::Parameter<'ast>> for Parameter<'ast> {
|
||||
fn from(p: absy::Parameter<'ast>) -> Parameter {
|
||||
Parameter {
|
||||
private: p.private,
|
||||
id: p.id.value.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
290
zokrates_core/src/typed_absy/types.rs
Normal file
290
zokrates_core/src/typed_absy/types.rs
Normal file
|
@ -0,0 +1,290 @@
|
|||
use std::fmt;
|
||||
|
||||
pub type Identifier<'ast> = &'ast str;
|
||||
|
||||
pub type MemberId = String;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
|
||||
pub enum Type {
|
||||
FieldElement,
|
||||
Boolean,
|
||||
Array(Box<Type>, usize),
|
||||
Struct(Vec<(MemberId, Type)>),
|
||||
}
|
||||
|
||||
impl fmt::Display for Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Type::FieldElement => write!(f, "field"),
|
||||
Type::Boolean => write!(f, "bool"),
|
||||
Type::Array(ref ty, ref size) => write!(f, "{}[{}]", ty, size),
|
||||
Type::Struct(ref members) => write!(
|
||||
f,
|
||||
"{{{}}}",
|
||||
members
|
||||
.iter()
|
||||
.map(|(id, t)| format!("{}: {}", id, t))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Type::FieldElement => write!(f, "field"),
|
||||
Type::Boolean => write!(f, "bool"),
|
||||
Type::Array(ref ty, ref size) => write!(f, "{}[{}]", ty, size),
|
||||
Type::Struct(ref members) => write!(
|
||||
f,
|
||||
"{{{}}}",
|
||||
members
|
||||
.iter()
|
||||
.map(|(id, t)| format!("{}: {}", id, t))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Type {
|
||||
pub fn array(ty: Type, size: usize) -> Self {
|
||||
Type::Array(box ty, size)
|
||||
}
|
||||
|
||||
fn to_slug(&self) -> String {
|
||||
match self {
|
||||
Type::FieldElement => String::from("f"),
|
||||
Type::Boolean => String::from("b"),
|
||||
Type::Array(box ty, size) => format!("{}[{}]", ty.to_slug(), size),
|
||||
Type::Struct(members) => format!(
|
||||
"{{{}}}",
|
||||
members
|
||||
.iter()
|
||||
.map(|(id, ty)| format!("{}:{}", id, ty))
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// the number of field elements the type maps to
|
||||
pub fn get_primitive_count(&self) -> usize {
|
||||
match self {
|
||||
Type::FieldElement => 1,
|
||||
Type::Boolean => 1,
|
||||
Type::Array(ty, size) => size * ty.get_primitive_count(),
|
||||
Type::Struct(members) => members.iter().map(|(_, t)| t.get_primitive_count()).sum(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type FunctionIdentifier<'ast> = &'ast str;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
|
||||
pub struct FunctionKey<'ast> {
|
||||
pub id: FunctionIdentifier<'ast>,
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
impl<'ast> FunctionKey<'ast> {
|
||||
pub fn with_id<S: Into<Identifier<'ast>>>(id: S) -> Self {
|
||||
FunctionKey {
|
||||
id: id.into(),
|
||||
signature: Signature::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signature(mut self, signature: Signature) -> Self {
|
||||
self.signature = signature;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn id<S: Into<Identifier<'ast>>>(mut self, id: S) -> Self {
|
||||
self.id = id.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn to_slug(&self) -> String {
|
||||
format!("{}_{}", self.id, self.signature.to_slug())
|
||||
}
|
||||
}
|
||||
|
||||
pub use self::signature::Signature;
|
||||
|
||||
pub mod signature {
|
||||
use super::*;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Ord, PartialOrd)]
|
||||
pub struct Signature {
|
||||
pub inputs: Vec<Type>,
|
||||
pub outputs: Vec<Type>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Signature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Signature(inputs: {:?}, outputs: {:?})",
|
||||
self.inputs, self.outputs
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Signature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "(")?;
|
||||
for (i, t) in self.inputs.iter().enumerate() {
|
||||
write!(f, "{}", t)?;
|
||||
if i < self.inputs.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ") -> (")?;
|
||||
for (i, t) in self.outputs.iter().enumerate() {
|
||||
write!(f, "{}", t)?;
|
||||
if i < self.outputs.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Signature {
|
||||
/// Returns a slug for a signature, with the following encoding:
|
||||
/// i{inputs}o{outputs} where {inputs} and {outputs} each encode a list of types.
|
||||
/// A list of types is encoded by compressing sequences of the same type like so:
|
||||
///
|
||||
/// [field, field, field] -> 3f
|
||||
/// [field] -> f
|
||||
/// [field, bool, field] -> fbf
|
||||
/// [field, field, bool, field] -> 2fbf
|
||||
///
|
||||
pub fn to_slug(&self) -> String {
|
||||
let to_slug = |types| {
|
||||
let mut res = vec![];
|
||||
for t in types {
|
||||
let len = res.len();
|
||||
if len == 0 {
|
||||
res.push((1, t))
|
||||
} else {
|
||||
if res[len - 1].1 == t {
|
||||
res[len - 1].0 += 1;
|
||||
} else {
|
||||
res.push((1, t))
|
||||
}
|
||||
}
|
||||
}
|
||||
res.into_iter()
|
||||
.map(|(n, t): (usize, &Type)| {
|
||||
let mut r = String::new();
|
||||
|
||||
if n > 1 {
|
||||
r.push_str(&format!("{}", n));
|
||||
}
|
||||
r.push_str(&t.to_slug());
|
||||
r
|
||||
})
|
||||
.fold(String::new(), |mut acc, e| {
|
||||
acc.push_str(&e);
|
||||
acc
|
||||
})
|
||||
};
|
||||
|
||||
format!("i{}o{}", to_slug(&self.inputs), to_slug(&self.outputs))
|
||||
}
|
||||
|
||||
pub fn new() -> Signature {
|
||||
Signature {
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inputs(mut self, inputs: Vec<Type>) -> Self {
|
||||
self.inputs = inputs;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn outputs(mut self, outputs: Vec<Type>) -> Self {
|
||||
self.outputs = outputs;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn signature() {
|
||||
let s = Signature::new()
|
||||
.inputs(vec![Type::FieldElement, Type::Boolean])
|
||||
.outputs(vec![Type::Boolean]);
|
||||
|
||||
assert_eq!(s.to_string(), String::from("(field, bool) -> (bool)"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slug_0() {
|
||||
let s = Signature::new().inputs(vec![]).outputs(vec![]);
|
||||
|
||||
assert_eq!(s.to_slug(), String::from("io"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slug_1() {
|
||||
let s = Signature::new()
|
||||
.inputs(vec![Type::FieldElement, Type::Boolean])
|
||||
.outputs(vec![
|
||||
Type::FieldElement,
|
||||
Type::FieldElement,
|
||||
Type::Boolean,
|
||||
Type::FieldElement,
|
||||
]);
|
||||
|
||||
assert_eq!(s.to_slug(), String::from("ifbo2fbf"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slug_2() {
|
||||
let s = Signature::new()
|
||||
.inputs(vec![
|
||||
Type::FieldElement,
|
||||
Type::FieldElement,
|
||||
Type::FieldElement,
|
||||
])
|
||||
.outputs(vec![Type::FieldElement, Type::Boolean, Type::FieldElement]);
|
||||
|
||||
assert_eq!(s.to_slug(), String::from("i3fofbf"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_slug() {
|
||||
let s = Signature::new()
|
||||
.inputs(vec![
|
||||
Type::array(Type::FieldElement, 42),
|
||||
Type::array(Type::FieldElement, 21),
|
||||
])
|
||||
.outputs(vec![]);
|
||||
|
||||
assert_eq!(s.to_slug(), String::from("if[42]f[21]o"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn array() {
|
||||
let t = Type::Array(box Type::FieldElement, 42);
|
||||
assert_eq!(t.get_primitive_count(), 42);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
use crate::absy;
|
||||
use crate::typed_absy::types::{MemberId, Type};
|
||||
use crate::typed_absy::Identifier;
|
||||
use crate::types::Type;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Hash, Eq)]
|
||||
|
@ -27,6 +26,10 @@ impl<'ast> Variable<'ast> {
|
|||
Self::with_id_and_type(id, Type::array(ty, size))
|
||||
}
|
||||
|
||||
pub fn struc(id: Identifier<'ast>, ty: Vec<(MemberId, Type)>) -> Variable<'ast> {
|
||||
Self::with_id_and_type(id, Type::Struct(ty))
|
||||
}
|
||||
|
||||
pub fn with_id_and_type(id: Identifier<'ast>, _type: Type) -> Variable<'ast> {
|
||||
Variable { id, _type }
|
||||
}
|
||||
|
@ -48,15 +51,15 @@ impl<'ast> fmt::Debug for Variable<'ast> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<absy::Variable<'ast>> for Variable<'ast> {
|
||||
fn from(v: absy::Variable) -> Variable {
|
||||
Variable::with_id_and_type(
|
||||
Identifier {
|
||||
id: v.id,
|
||||
version: 0,
|
||||
stack: vec![],
|
||||
},
|
||||
v._type,
|
||||
)
|
||||
}
|
||||
}
|
||||
// impl<'ast> From<absy::Variable<'ast>> for Variable<'ast> {
|
||||
// fn from(v: absy::Variable) -> Variable {
|
||||
// Variable::with_id_and_type(
|
||||
// Identifier {
|
||||
// id: v.id,
|
||||
// version: 0,
|
||||
// stack: vec![],
|
||||
// },
|
||||
// v._type,
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
pub use crate::types::signature::Signature;
|
||||
use std::fmt;
|
||||
|
||||
pub type Identifier<'ast> = &'ast str;
|
||||
|
||||
mod signature;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Type {
|
||||
FieldElement,
|
||||
Boolean,
|
||||
Array(Box<Type>, usize),
|
||||
}
|
||||
|
||||
impl fmt::Display for Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Type::FieldElement => write!(f, "field"),
|
||||
Type::Boolean => write!(f, "bool"),
|
||||
Type::Array(ref ty, ref size) => write!(f, "{}[{}]", ty, size),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Type::FieldElement => write!(f, "field"),
|
||||
Type::Boolean => write!(f, "bool"),
|
||||
Type::Array(ref ty, ref size) => write!(f, "{}[{}]", ty, size),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Type {
|
||||
pub fn array(ty: Type, size: usize) -> Self {
|
||||
Type::Array(box ty, size)
|
||||
}
|
||||
|
||||
fn to_slug(&self) -> String {
|
||||
match self {
|
||||
Type::FieldElement => String::from("f"),
|
||||
Type::Boolean => String::from("b"),
|
||||
Type::Array(box ty, size) => format!("{}[{}]", ty.to_slug(), size),
|
||||
}
|
||||
}
|
||||
|
||||
// the number of field elements the type maps to
|
||||
pub fn get_primitive_count(&self) -> usize {
|
||||
match self {
|
||||
Type::FieldElement => 1,
|
||||
Type::Boolean => 1,
|
||||
Type::Array(ty, size) => size * ty.get_primitive_count(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Hash, Eq)]
|
||||
pub struct Variable<'ast> {
|
||||
pub id: Identifier<'ast>,
|
||||
pub _type: Type,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Variable<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} {}", self._type, self.id,)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Debug for Variable<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Variable(type: {:?}, id: {:?})", self._type, self.id,)
|
||||
}
|
||||
}
|
||||
|
||||
pub type FunctionIdentifier<'ast> = &'ast str;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
|
||||
pub struct FunctionKey<'ast> {
|
||||
pub id: FunctionIdentifier<'ast>,
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
impl<'ast> FunctionKey<'ast> {
|
||||
pub fn with_id<S: Into<Identifier<'ast>>>(id: S) -> Self {
|
||||
FunctionKey {
|
||||
id: id.into(),
|
||||
signature: Signature::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signature(mut self, signature: Signature) -> Self {
|
||||
self.signature = signature;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn to_slug(&self) -> String {
|
||||
format!("{}_{}", self.id, self.signature.to_slug())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn array() {
|
||||
let t = Type::Array(box Type::FieldElement, 42);
|
||||
assert_eq!(t.get_primitive_count(), 42);
|
||||
}
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
use crate::types::Type;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Signature {
|
||||
pub inputs: Vec<Type>,
|
||||
pub outputs: Vec<Type>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Signature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Signature(inputs: {:?}, outputs: {:?})",
|
||||
self.inputs, self.outputs
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Signature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "(")?;
|
||||
for (i, t) in self.inputs.iter().enumerate() {
|
||||
write!(f, "{}", t)?;
|
||||
if i < self.inputs.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ") -> (")?;
|
||||
for (i, t) in self.outputs.iter().enumerate() {
|
||||
write!(f, "{}", t)?;
|
||||
if i < self.outputs.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Signature {
|
||||
/// Returns a slug for a signature, with the following encoding:
|
||||
/// i{inputs}o{outputs} where {inputs} and {outputs} each encode a list of types.
|
||||
/// A list of types is encoded by compressing sequences of the same type like so:
|
||||
///
|
||||
/// [field, field, field] -> 3f
|
||||
/// [field] -> f
|
||||
/// [field, bool, field] -> fbf
|
||||
/// [field, field, bool, field] -> 2fbf
|
||||
///
|
||||
pub fn to_slug(&self) -> String {
|
||||
let to_slug = |types| {
|
||||
let mut res = vec![];
|
||||
for t in types {
|
||||
let len = res.len();
|
||||
if len == 0 {
|
||||
res.push((1, t))
|
||||
} else {
|
||||
if res[len - 1].1 == t {
|
||||
res[len - 1].0 += 1;
|
||||
} else {
|
||||
res.push((1, t))
|
||||
}
|
||||
}
|
||||
}
|
||||
res.into_iter()
|
||||
.map(|(n, t): (usize, &Type)| {
|
||||
let mut r = String::new();
|
||||
|
||||
if n > 1 {
|
||||
r.push_str(&format!("{}", n));
|
||||
}
|
||||
r.push_str(&t.to_slug());
|
||||
r
|
||||
})
|
||||
.fold(String::new(), |mut acc, e| {
|
||||
acc.push_str(&e);
|
||||
acc
|
||||
})
|
||||
};
|
||||
|
||||
format!("i{}o{}", to_slug(&self.inputs), to_slug(&self.outputs))
|
||||
}
|
||||
|
||||
pub fn new() -> Signature {
|
||||
Signature {
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inputs(mut self, inputs: Vec<Type>) -> Self {
|
||||
self.inputs = inputs;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn outputs(mut self, outputs: Vec<Type>) -> Self {
|
||||
self.outputs = outputs;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn signature() {
|
||||
let s = Signature::new()
|
||||
.inputs(vec![Type::FieldElement, Type::Boolean])
|
||||
.outputs(vec![Type::Boolean]);
|
||||
|
||||
assert_eq!(s.to_string(), String::from("(field, bool) -> (bool)"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slug_0() {
|
||||
let s = Signature::new().inputs(vec![]).outputs(vec![]);
|
||||
|
||||
assert_eq!(s.to_slug(), String::from("io"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slug_1() {
|
||||
let s = Signature::new()
|
||||
.inputs(vec![Type::FieldElement, Type::Boolean])
|
||||
.outputs(vec![
|
||||
Type::FieldElement,
|
||||
Type::FieldElement,
|
||||
Type::Boolean,
|
||||
Type::FieldElement,
|
||||
]);
|
||||
|
||||
assert_eq!(s.to_slug(), String::from("ifbo2fbf"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slug_2() {
|
||||
let s = Signature::new()
|
||||
.inputs(vec![
|
||||
Type::FieldElement,
|
||||
Type::FieldElement,
|
||||
Type::FieldElement,
|
||||
])
|
||||
.outputs(vec![Type::FieldElement, Type::Boolean, Type::FieldElement]);
|
||||
|
||||
assert_eq!(s.to_slug(), String::from("i3fofbf"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_slug() {
|
||||
let s = Signature::new()
|
||||
.inputs(vec![
|
||||
Type::array(Type::FieldElement, 42),
|
||||
Type::array(Type::FieldElement, 21),
|
||||
])
|
||||
.outputs(vec![]);
|
||||
|
||||
assert_eq!(s.to_slug(), String::from("if[42]f[21]o"));
|
||||
}
|
||||
}
|
2
zokrates_core_test/tests/tests/arrays/identity.code
Normal file
2
zokrates_core_test/tests/tests/arrays/identity.code
Normal file
|
@ -0,0 +1,2 @@
|
|||
def main(bool[3] a) -> (bool[3]):
|
||||
return a
|
38
zokrates_core_test/tests/tests/arrays/identity.json
Normal file
38
zokrates_core_test/tests/tests/arrays/identity.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/arrays/identity.code",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["0", "0", "0"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["0", "0", "0"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["1", "0", "1"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["1", "0", "1"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["2", "1", "1"]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "4",
|
||||
"right": "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
19
zokrates_core_test/tests/tests/precedence.json
Normal file
19
zokrates_core_test/tests/tests/precedence.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/precedence.zok",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": [
|
||||
"12"
|
||||
]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": [
|
||||
"12"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
16
zokrates_core_test/tests/tests/precedence.zok
Normal file
16
zokrates_core_test/tests/tests/precedence.zok
Normal file
|
@ -0,0 +1,16 @@
|
|||
def main(field g) -> (field):
|
||||
9 == 1 + 2 * 2 ** 2 // Checks precedence of arithmetic operators (expecting transitiv behaviour)
|
||||
9 == 2 ** 2 * 2 + 1
|
||||
7 == 2 ** 2 * 2 - 1
|
||||
3 == 2 ** 2 / 2 + 1
|
||||
|
||||
field a = if 3 == 2 ** 2 / 2 + 1 && true then 1 else 0 fi // combines arithmetic with boolean operators
|
||||
field b = if 3 == 3 && 4 < 5 then 1 else 0 fi // checks precedence of boolean operators
|
||||
field c = if 4 < 5 && 3 == 3 then 1 else 0 fi
|
||||
field d = if 4 > 5 && 2 >= 1 || 1 == 1 then 1 else 0 fi
|
||||
field e = if 2 >= 1 && 4 > 5 || 1 == 1 then 1 else 0 fi
|
||||
field f = if 1 < 2 && false || 4 < 5 && 2 >= 1 then 1 else 0 fi
|
||||
|
||||
//check if all statements have evalutated to true
|
||||
a * b * c * d * e * f == 1
|
||||
return g
|
7
zokrates_core_test/tests/tests/structs/identity.code
Normal file
7
zokrates_core_test/tests/tests/structs/identity.code
Normal file
|
@ -0,0 +1,7 @@
|
|||
struct A {
|
||||
field a
|
||||
bool b
|
||||
}
|
||||
|
||||
def main(A a) -> (A):
|
||||
return a
|
38
zokrates_core_test/tests/tests/structs/identity.json
Normal file
38
zokrates_core_test/tests/tests/structs/identity.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/structs/identity.code",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["42", "0"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["42", "0"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["42", "1"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["42", "1"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["42", "3"]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "9",
|
||||
"right": "3"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -113,6 +113,26 @@ mod tests {
|
|||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_single_def_to_multi() {
|
||||
parses_to! {
|
||||
parser: ZoKratesParser,
|
||||
input: r#"a = foo()
|
||||
"#,
|
||||
rule: Rule::statement,
|
||||
tokens: [
|
||||
statement(0, 22, [
|
||||
multi_assignment_statement(0, 9, [
|
||||
optionally_typed_identifier(0, 1, [
|
||||
identifier(0, 1)
|
||||
]),
|
||||
identifier(4, 7),
|
||||
])
|
||||
])
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_invalid_identifier() {
|
||||
fails_with! {
|
||||
|
@ -125,6 +145,50 @@ mod tests {
|
|||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_struct_def() {
|
||||
parses_to! {
|
||||
parser: ZoKratesParser,
|
||||
input: "struct Foo { field foo\n field[2] bar }
|
||||
",
|
||||
rule: Rule::ty_struct_definition,
|
||||
tokens: [
|
||||
ty_struct_definition(0, 39, [
|
||||
identifier(7, 10),
|
||||
struct_field(13, 22, [
|
||||
ty(13, 18, [
|
||||
ty_basic(13, 18, [
|
||||
ty_field(13, 18)
|
||||
])
|
||||
]),
|
||||
identifier(19, 22)
|
||||
]),
|
||||
struct_field(24, 36, [
|
||||
ty(24, 33, [
|
||||
ty_array(24, 33, [
|
||||
ty_basic_or_struct(24, 29, [
|
||||
ty_basic(24, 29, [
|
||||
ty_field(24, 29)
|
||||
])
|
||||
]),
|
||||
expression(30, 31, [
|
||||
term(30, 31, [
|
||||
primary_expression(30, 31, [
|
||||
constant(30, 31, [
|
||||
decimal_number(30, 31)
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
]),
|
||||
identifier(33, 36)
|
||||
])
|
||||
])
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_invalid_identifier_because_keyword() {
|
||||
fails_with! {
|
||||
|
|
|
@ -3,8 +3,11 @@
|
|||
* Author: Jacob Eberhardt, Thibaut Schaeffer
|
||||
*/
|
||||
|
||||
file = { SOI ~ NEWLINE* ~ import_directive* ~ NEWLINE* ~ function_definition* ~ EOI }
|
||||
import_directive = {"import" ~ "\"" ~ import_source ~ "\"" ~ ("as" ~ identifier)? ~ NEWLINE+}
|
||||
file = { SOI ~ NEWLINE* ~ import_directive* ~ NEWLINE* ~ ty_struct_definition* ~ NEWLINE* ~ function_definition* ~ EOI }
|
||||
|
||||
import_directive = { main_import_directive | from_import_directive }
|
||||
from_import_directive = { "from" ~ "\"" ~ import_source ~ "\"" ~ "import" ~ identifier ~ ("as" ~ identifier)? ~ NEWLINE*}
|
||||
main_import_directive = {"import" ~ "\"" ~ import_source ~ "\"" ~ ("as" ~ identifier)? ~ NEWLINE+}
|
||||
import_source = @{(!"\"" ~ ANY)*}
|
||||
function_definition = {"def" ~ identifier ~ "(" ~ parameter_list ~ ")" ~ "->" ~ "(" ~ type_list ~ ")" ~ ":" ~ NEWLINE* ~ statement* }
|
||||
|
||||
|
@ -15,10 +18,16 @@ parameter = {vis? ~ ty ~ identifier}
|
|||
ty_field = {"field"}
|
||||
ty_bool = {"bool"}
|
||||
ty_basic = { ty_field | ty_bool }
|
||||
// (unidimensional for now) arrays of (basic for now) types
|
||||
ty_array = { ty_basic ~ ("[" ~ expression ~ "]")+ }
|
||||
ty = { ty_array | ty_basic }
|
||||
ty_basic_or_struct = { ty_basic | ty_struct }
|
||||
ty_array = { ty_basic_or_struct ~ ("[" ~ expression ~ "]")+ }
|
||||
ty = { ty_array | ty_basic | ty_struct }
|
||||
type_list = _{(ty ~ ("," ~ ty)*)?}
|
||||
// structs
|
||||
ty_struct = { identifier }
|
||||
// type definitions
|
||||
ty_struct_definition = { "struct" ~ identifier ~ "{" ~ NEWLINE* ~ struct_field_list ~ NEWLINE* ~ "}" ~ NEWLINE* }
|
||||
struct_field_list = _{(struct_field ~ (NEWLINE+ ~ struct_field)*)? }
|
||||
struct_field = { ty ~ identifier }
|
||||
|
||||
vis_private = {"private"}
|
||||
vis_public = {"public"}
|
||||
|
@ -42,13 +51,13 @@ assignment_statement = {assignee ~ "=" ~ expression } // TODO: Is this optimal?
|
|||
expression_statement = {expression}
|
||||
|
||||
optionally_typed_identifier_list = _{ optionally_typed_identifier ~ ("," ~ optionally_typed_identifier)* }
|
||||
optionally_typed_identifier = { ty? ~ identifier }
|
||||
optionally_typed_identifier = { (identifier) | (ty ~ identifier) } // we don't use { ty? ~ identifier } as with a single token, it gets parsed as `ty` but we want `identifier`
|
||||
|
||||
// Expressions
|
||||
expression_list = _{(expression ~ ("," ~ expression)*)?}
|
||||
|
||||
expression = { term ~ (op_binary ~ term)* }
|
||||
term = { ("(" ~ expression ~ ")") | conditional_expression | postfix_expression | primary_expression | inline_array_expression | array_initializer_expression | unary_expression }
|
||||
term = { ("(" ~ expression ~ ")") | inline_struct_expression | conditional_expression | postfix_expression | primary_expression | inline_array_expression | array_initializer_expression | unary_expression }
|
||||
spread = { "..." ~ expression }
|
||||
range = { from_expression? ~ ".." ~ to_expression? }
|
||||
from_expression = { expression }
|
||||
|
@ -57,16 +66,21 @@ to_expression = { expression }
|
|||
conditional_expression = { "if" ~ expression ~ "then" ~ expression ~ "else" ~ expression ~ "fi"}
|
||||
|
||||
postfix_expression = { identifier ~ access+ } // we force there to be at least one access, otherwise this matches single identifiers. Not sure that's what we want.
|
||||
access = { array_access | call_access }
|
||||
access = { array_access | call_access | member_access }
|
||||
array_access = { "[" ~ range_or_expression ~ "]" }
|
||||
call_access = { "(" ~ expression_list ~ ")" }
|
||||
member_access = { "." ~ identifier }
|
||||
|
||||
primary_expression = { identifier
|
||||
| constant
|
||||
}
|
||||
|
||||
inline_array_expression = { "[" ~ inline_array_inner ~ "]" }
|
||||
inline_array_inner = _{(spread_or_expression ~ ("," ~ spread_or_expression)*)?}
|
||||
inline_struct_expression = { identifier ~ "{" ~ NEWLINE* ~ inline_struct_member_list ~ NEWLINE* ~ "}" }
|
||||
inline_struct_member_list = _{(inline_struct_member ~ ("," ~ NEWLINE* ~ inline_struct_member)*)? ~ ","? }
|
||||
inline_struct_member = { identifier ~ ":" ~ expression }
|
||||
|
||||
inline_array_expression = { "[" ~ NEWLINE* ~ inline_array_inner ~ NEWLINE* ~ "]" }
|
||||
inline_array_inner = _{(spread_or_expression ~ ("," ~ NEWLINE* ~ spread_or_expression)*)?}
|
||||
spread_or_expression = { spread | expression }
|
||||
range_or_expression = { range | expression }
|
||||
array_initializer_expression = { "[" ~ expression ~ ";" ~ constant ~ "]" }
|
||||
|
@ -75,7 +89,8 @@ unary_expression = { op_unary ~ term }
|
|||
|
||||
// End Expressions
|
||||
|
||||
assignee = { identifier ~ ("[" ~ range_or_expression ~ "]")* }
|
||||
assignee = { identifier ~ assignee_access* }
|
||||
assignee_access = { array_access | member_access }
|
||||
identifier = @{ ((!keyword ~ ASCII_ALPHA) | (keyword ~ (ASCII_ALPHANUMERIC | "_"))) ~ (ASCII_ALPHANUMERIC | "_")* }
|
||||
constant = { decimal_number | boolean_literal }
|
||||
decimal_number = @{ "0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
|
||||
|
|
|
@ -9,12 +9,13 @@ extern crate lazy_static;
|
|||
|
||||
pub use ast::{
|
||||
Access, ArrayAccess, ArrayInitializerExpression, ArrayType, AssertionStatement, Assignee,
|
||||
AssignmentStatement, BasicType, BinaryExpression, BinaryOperator, BooleanType, CallAccess,
|
||||
ConstantExpression, DefinitionStatement, Expression, FieldType, File, FromExpression, Function,
|
||||
IdentifierExpression, ImportDirective, ImportSource, InlineArrayExpression, IterationStatement,
|
||||
AssigneeAccess, AssignmentStatement, BasicOrStructType, BasicType, BinaryExpression,
|
||||
BinaryOperator, CallAccess, ConstantExpression, DefinitionStatement, Expression, File,
|
||||
FromExpression, Function, IdentifierExpression, ImportDirective, ImportSource,
|
||||
InlineArrayExpression, InlineStructExpression, InlineStructMember, IterationStatement,
|
||||
MultiAssignmentStatement, Parameter, PostfixExpression, Range, RangeOrExpression,
|
||||
ReturnStatement, Span, Spread, SpreadOrExpression, Statement, TernaryExpression, ToExpression,
|
||||
Type, UnaryExpression, UnaryOperator, Visibility,
|
||||
ReturnStatement, Span, Spread, SpreadOrExpression, Statement, StructDefinition, StructField,
|
||||
TernaryExpression, ToExpression, Type, UnaryExpression, UnaryOperator, Visibility,
|
||||
};
|
||||
|
||||
mod ast {
|
||||
|
@ -121,6 +122,9 @@ mod ast {
|
|||
Rule::postfix_expression => Expression::Postfix(
|
||||
PostfixExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
),
|
||||
Rule::inline_struct_expression => Expression::InlineStruct(
|
||||
InlineStructExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
),
|
||||
Rule::inline_array_expression => Expression::InlineArray(
|
||||
InlineArrayExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
),
|
||||
|
@ -155,12 +159,31 @@ mod ast {
|
|||
#[pest_ast(rule(Rule::file))]
|
||||
pub struct File<'ast> {
|
||||
pub imports: Vec<ImportDirective<'ast>>,
|
||||
pub structs: Vec<StructDefinition<'ast>>,
|
||||
pub functions: Vec<Function<'ast>>,
|
||||
pub eoi: EOI,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty_struct_definition))]
|
||||
pub struct StructDefinition<'ast> {
|
||||
pub id: IdentifierExpression<'ast>,
|
||||
pub fields: Vec<StructField<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::struct_field))]
|
||||
pub struct StructField<'ast> {
|
||||
pub ty: Type<'ast>,
|
||||
pub id: IdentifierExpression<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::function_definition))]
|
||||
pub struct Function<'ast> {
|
||||
|
@ -174,13 +197,30 @@ mod ast {
|
|||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::import_directive))]
|
||||
pub struct ImportDirective<'ast> {
|
||||
pub enum ImportDirective<'ast> {
|
||||
Main(MainImportDirective<'ast>),
|
||||
From(FromImportDirective<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::main_import_directive))]
|
||||
pub struct MainImportDirective<'ast> {
|
||||
pub source: ImportSource<'ast>,
|
||||
pub alias: Option<IdentifierExpression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::from_import_directive))]
|
||||
pub struct FromImportDirective<'ast> {
|
||||
pub source: ImportSource<'ast>,
|
||||
pub symbol: IdentifierExpression<'ast>,
|
||||
pub alias: Option<IdentifierExpression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::import_source))]
|
||||
pub struct ImportSource<'ast> {
|
||||
|
@ -193,33 +233,55 @@ mod ast {
|
|||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty))]
|
||||
pub enum Type<'ast> {
|
||||
Basic(BasicType),
|
||||
Basic(BasicType<'ast>),
|
||||
Array(ArrayType<'ast>),
|
||||
Struct(StructType<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty_basic))]
|
||||
pub enum BasicType {
|
||||
Field(FieldType),
|
||||
Boolean(BooleanType),
|
||||
pub enum BasicType<'ast> {
|
||||
Field(FieldType<'ast>),
|
||||
Boolean(BooleanType<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty_field))]
|
||||
pub struct FieldType;
|
||||
pub struct FieldType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty_array))]
|
||||
pub struct ArrayType<'ast> {
|
||||
pub ty: BasicType,
|
||||
pub ty: BasicOrStructType<'ast>,
|
||||
pub dimensions: Vec<Expression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty_basic_or_struct))]
|
||||
pub enum BasicOrStructType<'ast> {
|
||||
Struct(StructType<'ast>),
|
||||
Basic(BasicType<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty_bool))]
|
||||
pub struct BooleanType;
|
||||
pub struct BooleanType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty_struct))]
|
||||
pub struct StructType<'ast> {
|
||||
pub id: IdentifierExpression<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::parameter))]
|
||||
|
@ -353,6 +415,7 @@ mod ast {
|
|||
Identifier(IdentifierExpression<'ast>),
|
||||
Constant(ConstantExpression<'ast>),
|
||||
InlineArray(InlineArrayExpression<'ast>),
|
||||
InlineStruct(InlineStructExpression<'ast>),
|
||||
ArrayInitializer(ArrayInitializerExpression<'ast>),
|
||||
Unary(UnaryExpression<'ast>),
|
||||
}
|
||||
|
@ -422,6 +485,24 @@ mod ast {
|
|||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::inline_struct_expression))]
|
||||
pub struct InlineStructExpression<'ast> {
|
||||
pub ty: IdentifierExpression<'ast>,
|
||||
pub members: Vec<InlineStructMember<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::inline_struct_member))]
|
||||
pub struct InlineStructMember<'ast> {
|
||||
pub id: IdentifierExpression<'ast>,
|
||||
pub expression: Expression<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::array_initializer_expression))]
|
||||
pub struct ArrayInitializerExpression<'ast> {
|
||||
|
@ -445,6 +526,14 @@ mod ast {
|
|||
pub enum Access<'ast> {
|
||||
Call(CallAccess<'ast>),
|
||||
Select(ArrayAccess<'ast>),
|
||||
Member(MemberAccess<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::assignee_access))]
|
||||
pub enum AssigneeAccess<'ast> {
|
||||
Select(ArrayAccess<'ast>),
|
||||
Member(MemberAccess<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
|
@ -463,6 +552,14 @@ mod ast {
|
|||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::member_access))]
|
||||
pub struct MemberAccess<'ast> {
|
||||
pub id: IdentifierExpression<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct BinaryExpression<'ast> {
|
||||
pub op: BinaryOperator,
|
||||
|
@ -518,6 +615,7 @@ mod ast {
|
|||
Expression::Ternary(t) => &t.span,
|
||||
Expression::Postfix(p) => &p.span,
|
||||
Expression::InlineArray(a) => &a.span,
|
||||
Expression::InlineStruct(s) => &s.span,
|
||||
Expression::ArrayInitializer(a) => &a.span,
|
||||
Expression::Unary(u) => &u.span,
|
||||
}
|
||||
|
@ -593,8 +691,8 @@ mod ast {
|
|||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::assignee))]
|
||||
pub struct Assignee<'ast> {
|
||||
pub id: IdentifierExpression<'ast>, // a
|
||||
pub indices: Vec<RangeOrExpression<'ast>>, // [42 + x][31][7]
|
||||
pub id: IdentifierExpression<'ast>, // a
|
||||
pub accesses: Vec<AssigneeAccess<'ast>>, // [42 + x].foo[7]
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
@ -696,13 +794,16 @@ mod tests {
|
|||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
Ok(File {
|
||||
structs: vec![],
|
||||
functions: vec![Function {
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {}))],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::add(
|
||||
Expression::Constant(ConstantExpression::DecimalNumber(
|
||||
|
@ -723,14 +824,14 @@ mod tests {
|
|||
})],
|
||||
span: Span::new(&source, 29, source.len()).unwrap(),
|
||||
}],
|
||||
imports: vec![ImportDirective {
|
||||
imports: vec![ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
}],
|
||||
})],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 65).unwrap()
|
||||
})
|
||||
|
@ -745,13 +846,16 @@ mod tests {
|
|||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
Ok(File {
|
||||
structs: vec![],
|
||||
functions: vec![Function {
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {}))],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::add(
|
||||
Expression::Constant(ConstantExpression::DecimalNumber(
|
||||
|
@ -790,14 +894,14 @@ mod tests {
|
|||
})],
|
||||
span: Span::new(&source, 29, 74).unwrap(),
|
||||
}],
|
||||
imports: vec![ImportDirective {
|
||||
imports: vec![ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
}],
|
||||
})],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 74).unwrap()
|
||||
})
|
||||
|
@ -812,13 +916,16 @@ mod tests {
|
|||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
Ok(File {
|
||||
structs: vec![],
|
||||
functions: vec![Function {
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {}))],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::if_else(
|
||||
Expression::Constant(ConstantExpression::DecimalNumber(
|
||||
|
@ -845,14 +952,14 @@ mod tests {
|
|||
})],
|
||||
span: Span::new(&source, 29, 81).unwrap(),
|
||||
}],
|
||||
imports: vec![ImportDirective {
|
||||
imports: vec![ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
}],
|
||||
})],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 81).unwrap()
|
||||
})
|
||||
|
@ -866,13 +973,16 @@ mod tests {
|
|||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
Ok(File {
|
||||
structs: vec![],
|
||||
functions: vec![Function {
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 4, 8).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {}))],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 15, 20).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::Constant(ConstantExpression::DecimalNumber(
|
||||
DecimalNumberExpression {
|
||||
|
@ -898,13 +1008,16 @@ mod tests {
|
|||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
Ok(File {
|
||||
structs: vec![],
|
||||
functions: vec![Function {
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 4, 8).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {}))],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 15, 20).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::MultiAssignment(MultiAssignmentStatement {
|
||||
function_id: IdentifierExpression {
|
||||
value: String::from("foo"),
|
||||
|
@ -912,7 +1025,9 @@ mod tests {
|
|||
},
|
||||
lhs: vec![
|
||||
OptionallyTypedIdentifier {
|
||||
ty: Some(Type::Basic(BasicType::Field(FieldType {}))),
|
||||
ty: Some(Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 23, 28).unwrap()
|
||||
}))),
|
||||
id: IdentifierExpression {
|
||||
value: String::from("a"),
|
||||
span: Span::new(&source, 29, 30).unwrap(),
|
||||
|
@ -965,13 +1080,19 @@ mod tests {
|
|||
#[test]
|
||||
fn playground() {
|
||||
let source = r#"import "heyman" as yo
|
||||
|
||||
struct Foo {
|
||||
field[2] foo
|
||||
Bar bar
|
||||
}
|
||||
|
||||
def main(private field[23] a) -> (bool[234 + 6]):
|
||||
field a = 1
|
||||
a[32 + x][55] = y
|
||||
for field i in 0..3 do
|
||||
a == 1 + 2 + 3+ 4+ 5+ 6+ 6+ 7+ 8 + 4+ 5+ 3+ 4+ 2+ 3
|
||||
endfor
|
||||
a == 1
|
||||
a.member == 1
|
||||
return a
|
||||
"#;
|
||||
let res = generate_ast(&source);
|
||||
|
|
Loading…
Reference in a new issue