mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-24 19:03:27 +03:00
pull master
This commit is contained in:
commit
e1f4fe1846
149
.github/workflows/release.yml
vendored
Normal file
149
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
name: Leo Release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*.*.*'
|
||||||
|
|
||||||
|
env:
|
||||||
|
RUST_BACKTRACE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ubuntu:
|
||||||
|
name: Ubuntu
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Load snarkOS
|
||||||
|
run: |
|
||||||
|
mkdir ~/.ssh
|
||||||
|
echo "${{ secrets.SNARKOS_DEPLOY_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
eval $(ssh-agent -s)
|
||||||
|
ssh-add -k ~/.ssh/id_rsa
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: stable
|
||||||
|
override: true
|
||||||
|
components: rustfmt
|
||||||
|
|
||||||
|
- name: Build Leo
|
||||||
|
run: |
|
||||||
|
cargo build --all --release && strip target/release/leo
|
||||||
|
env:
|
||||||
|
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||||
|
|
||||||
|
- id: get_version
|
||||||
|
uses: battila7/get-version-action@v2
|
||||||
|
|
||||||
|
- name: Zip
|
||||||
|
run: |
|
||||||
|
mkdir leo_${{ steps.get_version.outputs.version }}_ubuntu
|
||||||
|
mv target/release/leo leo_${{ steps.get_version.outputs.version }}_ubuntu
|
||||||
|
zip -r leo_${{ steps.get_version.outputs.version }}_ubuntu.zip leo_${{ steps.get_version.outputs.version }}_ubuntu
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
leo_${{ steps.get_version.outputs.version }}_ubuntu.zip
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
macos:
|
||||||
|
name: macOS
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Load snarkOS
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.SNARKOS_DEPLOY_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
eval $(ssh-agent -s)
|
||||||
|
ssh-add -k ~/.ssh/id_rsa
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: stable
|
||||||
|
override: true
|
||||||
|
components: rustfmt
|
||||||
|
|
||||||
|
- name: Build Leo
|
||||||
|
run: |
|
||||||
|
cargo build --all --release && strip target/release/leo
|
||||||
|
env:
|
||||||
|
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||||
|
|
||||||
|
- id: get_version
|
||||||
|
uses: battila7/get-version-action@v2
|
||||||
|
|
||||||
|
- name: Zip
|
||||||
|
run: |
|
||||||
|
mkdir leo_${{ steps.get_version.outputs.version }}_mac
|
||||||
|
mv target/release/leo leo_${{ steps.get_version.outputs.version }}_mac
|
||||||
|
zip -r leo_${{ steps.get_version.outputs.version }}_mac.zip leo_${{ steps.get_version.outputs.version }}_mac
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
leo_${{ steps.get_version.outputs.version }}_mac.zip
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
windows:
|
||||||
|
name: Windows
|
||||||
|
runs-on: windows-latest
|
||||||
|
continue-on-error: true
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Install SSH key
|
||||||
|
uses: shimataro/ssh-key-action@v1
|
||||||
|
with:
|
||||||
|
private-key: ${{ secrets.SNARKOS_DEPLOY_KEY_WINDOWS }}
|
||||||
|
public-key: ${{ secrets.SNARKOS_DEPLOY_KEY_WINDOWS_PUBLIC }}
|
||||||
|
name: id_rsa
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: stable
|
||||||
|
override: true
|
||||||
|
components: rustfmt
|
||||||
|
|
||||||
|
- name: Build Leo
|
||||||
|
run: |
|
||||||
|
cargo build --all --release
|
||||||
|
env:
|
||||||
|
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||||
|
|
||||||
|
- id: get_version
|
||||||
|
uses: battila7/get-version-action@v2
|
||||||
|
|
||||||
|
- name: Zip
|
||||||
|
run: |
|
||||||
|
mkdir leo_${{ steps.get_version.outputs.version }}_windows
|
||||||
|
mv target/release/leo.exe leo_${{ steps.get_version.outputs.version }}_windows
|
||||||
|
Compress-Archive leo_${{ steps.get_version.outputs.version }}_windows leo_${{ steps.get_version.outputs.version }}_windows.zip
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
leo_${{ steps.get_version.outputs.version }}_windows.zip
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
577
Cargo.lock
generated
577
Cargo.lock
generated
@ -33,12 +33,6 @@ dependencies = [
|
|||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arc-swap"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
@ -158,7 +152,7 @@ version = "0.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.14.3",
|
"generic-array 0.14.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -262,9 +256,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.13"
|
version = "0.4.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6"
|
checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@ -294,9 +288,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.1"
|
version = "2.33.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"atty",
|
"atty",
|
||||||
@ -512,7 +506,7 @@ checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -530,7 +524,7 @@ version = "0.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.14.3",
|
"generic-array 0.14.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -541,9 +535,9 @@ checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.5.3"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
@ -595,7 +589,7 @@ checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -769,9 +763,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.3"
|
version = "0.14.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63"
|
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
"version_check",
|
"version_check",
|
||||||
@ -836,9 +830,9 @@ checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb"
|
checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
@ -944,9 +938,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.5.0"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7"
|
checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
@ -1066,9 +1060,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazycell"
|
name = "lazycell"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leo"
|
name = "leo"
|
||||||
@ -1086,18 +1080,19 @@ dependencies = [
|
|||||||
"leo-state",
|
"leo-state",
|
||||||
"log",
|
"log",
|
||||||
"notify",
|
"notify",
|
||||||
|
"num-bigint",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rusty-hook",
|
"rusty-hook",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"snarkos-algorithms 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-algorithms",
|
||||||
"snarkos-curves 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-curves",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-gadgets 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-gadgets",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
@ -1135,13 +1130,13 @@ dependencies = [
|
|||||||
"rand_xorshift",
|
"rand_xorshift",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"snarkos-curves 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-curves",
|
||||||
"snarkos-dpc 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-dpc",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-gadgets 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-gadgets",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-objects 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-objects",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1151,9 +1146,9 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"rand_xorshift",
|
"rand_xorshift",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1165,11 +1160,11 @@ dependencies = [
|
|||||||
"pest",
|
"pest",
|
||||||
"pest-ast",
|
"pest-ast",
|
||||||
"pest_derive",
|
"pest_derive",
|
||||||
"snarkos-algorithms 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-algorithms",
|
||||||
"snarkos-curves 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-curves",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-gadgets 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-gadgets",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1198,14 +1193,14 @@ dependencies = [
|
|||||||
"leo-typed",
|
"leo-typed",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_xorshift",
|
"rand_xorshift",
|
||||||
"snarkos-algorithms 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-algorithms",
|
||||||
"snarkos-curves 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-curves",
|
||||||
"snarkos-dpc 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-dpc",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-objects 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-objects",
|
||||||
"snarkos-testing",
|
"snarkos-storage",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1219,8 +1214,8 @@ dependencies = [
|
|||||||
"pest",
|
"pest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1253,9 +1248,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libz-sys"
|
name = "libz-sys"
|
||||||
version = "1.0.25"
|
version = "1.0.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
checksum = "6ca8894883d250240341478bf987467332fbdd5da5c42426c69a8f93dbc302f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@ -1352,7 +1347,7 @@ dependencies = [
|
|||||||
"kernel32-sys",
|
"kernel32-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"miow 0.2.1",
|
"miow",
|
||||||
"net2",
|
"net2",
|
||||||
"slab",
|
"slab",
|
||||||
"winapi 0.2.8",
|
"winapi 0.2.8",
|
||||||
@ -1370,29 +1365,6 @@ dependencies = [
|
|||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mio-named-pipes"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
|
|
||||||
dependencies = [
|
|
||||||
"log",
|
|
||||||
"mio",
|
|
||||||
"miow 0.3.5",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mio-uds"
|
|
||||||
version = "0.6.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
|
|
||||||
dependencies = [
|
|
||||||
"iovec",
|
|
||||||
"libc",
|
|
||||||
"mio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miow"
|
name = "miow"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -1405,16 +1377,6 @@ dependencies = [
|
|||||||
"ws2_32-sys",
|
"ws2_32-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "miow"
|
|
||||||
version = "0.3.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e"
|
|
||||||
dependencies = [
|
|
||||||
"socket2",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-tls"
|
name = "native-tls"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@ -1661,7 +1623,7 @@ dependencies = [
|
|||||||
"pest_meta",
|
"pest_meta",
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1692,7 +1654,7 @@ checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2046,9 +2008,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.114"
|
version = "1.0.115"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
|
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
@ -2065,13 +2027,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.114"
|
version = "1.0.115"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
|
checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2128,16 +2090,6 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook-registry"
|
|
||||||
version = "1.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035"
|
|
||||||
dependencies = [
|
|
||||||
"arc-swap",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "single"
|
name = "single"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -2155,14 +2107,14 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.4.1"
|
version = "1.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f"
|
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-algorithms"
|
name = "snarkos-algorithms"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2",
|
"blake2",
|
||||||
"derivative",
|
"derivative",
|
||||||
@ -2173,161 +2125,62 @@ dependencies = [
|
|||||||
"rayon",
|
"rayon",
|
||||||
"sha2",
|
"sha2",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-profiler 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-profiler",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-algorithms"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"blake2",
|
|
||||||
"derivative",
|
|
||||||
"digest 0.8.1",
|
|
||||||
"itertools 0.9.0",
|
|
||||||
"rand",
|
|
||||||
"rand_chacha",
|
|
||||||
"rayon",
|
|
||||||
"sha2",
|
|
||||||
"smallvec",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-profiler 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-consensus"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"bincode",
|
|
||||||
"chrono",
|
|
||||||
"hex",
|
|
||||||
"log",
|
|
||||||
"rand",
|
|
||||||
"serde",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-curves 0.8.0",
|
|
||||||
"snarkos-dpc 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-objects 0.8.0",
|
|
||||||
"snarkos-posw",
|
|
||||||
"snarkos-profiler 0.8.0",
|
|
||||||
"snarkos-storage",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
"tokio",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-curves"
|
name = "snarkos-curves"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derivative",
|
"derivative",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_xorshift",
|
"rand_xorshift",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"serde",
|
"serde",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-curves"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"derivative",
|
|
||||||
"rand",
|
|
||||||
"rand_xorshift",
|
|
||||||
"rustc_version",
|
|
||||||
"serde",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-derives"
|
name = "snarkos-derives"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-derives"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 1.0.19",
|
|
||||||
"quote 1.0.7",
|
|
||||||
"syn 1.0.36",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-dpc"
|
name = "snarkos-dpc"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2",
|
"blake2",
|
||||||
"derivative",
|
"derivative",
|
||||||
"hex",
|
"hex",
|
||||||
"itertools 0.9.0",
|
"itertools 0.9.0",
|
||||||
"rand",
|
"rand",
|
||||||
"snarkos-algorithms 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-algorithms",
|
||||||
"snarkos-curves 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-curves",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-gadgets 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-gadgets",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-objects 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-objects",
|
||||||
"snarkos-parameters 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-parameters",
|
||||||
"snarkos-profiler 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-profiler",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-dpc"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"blake2",
|
|
||||||
"derivative",
|
|
||||||
"hex",
|
|
||||||
"itertools 0.9.0",
|
|
||||||
"rand",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-curves 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-gadgets 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-objects 0.8.0",
|
|
||||||
"snarkos-parameters 0.8.0",
|
|
||||||
"snarkos-profiler 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-errors"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
|
||||||
dependencies = [
|
|
||||||
"base58",
|
|
||||||
"bech32",
|
|
||||||
"bincode",
|
|
||||||
"curl",
|
|
||||||
"hex",
|
|
||||||
"jsonrpc-core",
|
|
||||||
"rocksdb",
|
|
||||||
"thiserror",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-errors"
|
name = "snarkos-errors"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base58",
|
"base58",
|
||||||
"bech32",
|
"bech32",
|
||||||
@ -2337,60 +2190,28 @@ dependencies = [
|
|||||||
"jsonrpc-core",
|
"jsonrpc-core",
|
||||||
"rocksdb",
|
"rocksdb",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-gadgets"
|
name = "snarkos-gadgets"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derivative",
|
"derivative",
|
||||||
"digest 0.8.1",
|
"digest 0.8.1",
|
||||||
"itertools 0.9.0",
|
"itertools 0.9.0",
|
||||||
"snarkos-algorithms 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-algorithms",
|
||||||
"snarkos-curves 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-curves",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-gadgets"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"derivative",
|
|
||||||
"digest 0.8.1",
|
|
||||||
"itertools 0.9.0",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-curves 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-marlin"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"blake2",
|
|
||||||
"derivative",
|
|
||||||
"digest 0.8.1",
|
|
||||||
"rand_chacha",
|
|
||||||
"rand_core",
|
|
||||||
"rayon",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-gadgets 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-polycommit",
|
|
||||||
"snarkos-profiler 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-models"
|
name = "snarkos-models"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"derivative",
|
"derivative",
|
||||||
@ -2399,51 +2220,14 @@ dependencies = [
|
|||||||
"rand_xorshift",
|
"rand_xorshift",
|
||||||
"serde",
|
"serde",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-models"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"bincode",
|
|
||||||
"derivative",
|
|
||||||
"itertools 0.9.0",
|
|
||||||
"rand",
|
|
||||||
"rand_xorshift",
|
|
||||||
"serde",
|
|
||||||
"smallvec",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-network"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"bincode",
|
|
||||||
"byteorder",
|
|
||||||
"chrono",
|
|
||||||
"hex",
|
|
||||||
"log",
|
|
||||||
"rand",
|
|
||||||
"serde",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-consensus",
|
|
||||||
"snarkos-dpc 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-objects 0.8.0",
|
|
||||||
"snarkos-storage",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
"tokio",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-objects"
|
name = "snarkos-objects"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base58",
|
"base58",
|
||||||
"bech32",
|
"bech32",
|
||||||
@ -2454,103 +2238,35 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"snarkos-algorithms 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-algorithms",
|
||||||
"snarkos-curves 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-curves",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-models",
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-utilities",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-objects"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"base58",
|
|
||||||
"bech32",
|
|
||||||
"chrono",
|
|
||||||
"derivative",
|
|
||||||
"hex",
|
|
||||||
"once_cell",
|
|
||||||
"rand",
|
|
||||||
"serde",
|
|
||||||
"sha2",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-curves 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-parameters"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
|
||||||
dependencies = [
|
|
||||||
"hex",
|
|
||||||
"snarkos-algorithms 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
|
||||||
"snarkos-models 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
|
||||||
"snarkos-utilities 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-parameters"
|
name = "snarkos-parameters"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"curl",
|
"curl",
|
||||||
"hex",
|
"hex",
|
||||||
"snarkos-algorithms 0.8.0",
|
"snarkos-algorithms",
|
||||||
"snarkos-errors 0.8.0",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0",
|
"snarkos-models",
|
||||||
"snarkos-utilities 0.8.0",
|
"snarkos-utilities",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-polycommit"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"derivative",
|
|
||||||
"digest 0.8.1",
|
|
||||||
"rand_core",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-profiler 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-posw"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"blake2",
|
|
||||||
"rand",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-curves 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-gadgets 0.8.0",
|
|
||||||
"snarkos-marlin",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-objects 0.8.0",
|
|
||||||
"snarkos-parameters 0.8.0",
|
|
||||||
"snarkos-polycommit",
|
|
||||||
"snarkos-profiler 0.8.0",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
"thiserror",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-profiler"
|
name = "snarkos-profiler"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-profiler"
|
|
||||||
version = "0.8.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-storage"
|
name = "snarkos-storage"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"hex",
|
"hex",
|
||||||
@ -2558,55 +2274,23 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"rocksdb",
|
"rocksdb",
|
||||||
"serde",
|
"serde",
|
||||||
"snarkos-algorithms 0.8.0",
|
"snarkos-algorithms",
|
||||||
"snarkos-errors 0.8.0",
|
"snarkos-errors",
|
||||||
"snarkos-models 0.8.0",
|
"snarkos-models",
|
||||||
"snarkos-objects 0.8.0",
|
"snarkos-objects",
|
||||||
"snarkos-parameters 0.8.0",
|
"snarkos-parameters",
|
||||||
"snarkos-utilities 0.8.0",
|
"snarkos-utilities",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-testing"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
"rand",
|
|
||||||
"rand_xorshift",
|
|
||||||
"snarkos-algorithms 0.8.0",
|
|
||||||
"snarkos-consensus",
|
|
||||||
"snarkos-curves 0.8.0",
|
|
||||||
"snarkos-dpc 0.8.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
"snarkos-models 0.8.0",
|
|
||||||
"snarkos-network",
|
|
||||||
"snarkos-objects 0.8.0",
|
|
||||||
"snarkos-parameters 0.8.0",
|
|
||||||
"snarkos-posw",
|
|
||||||
"snarkos-storage",
|
|
||||||
"snarkos-utilities 0.8.0",
|
|
||||||
"tokio",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snarkos-utilities"
|
name = "snarkos-utilities"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#8d84d89f6b6c3b4693d3c08758cce28139910807"
|
source = "git+ssh://git@github.com/AleoHQ/snarkOS.git#66243c33e7df47c7d5f5cb1b181c1f8140c660c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"rand",
|
"rand",
|
||||||
"snarkos-derives 0.1.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-derives",
|
||||||
"snarkos-errors 0.8.0 (git+ssh://git@github.com/AleoHQ/snarkOS.git)",
|
"snarkos-errors",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snarkos-utilities"
|
|
||||||
version = "0.8.0"
|
|
||||||
dependencies = [
|
|
||||||
"bincode",
|
|
||||||
"rand",
|
|
||||||
"snarkos-derives 0.1.0",
|
|
||||||
"snarkos-errors 0.8.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2646,9 +2330,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.36"
|
version = "1.0.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250"
|
checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
@ -2663,7 +2347,7 @@ checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
"unicode-xid 0.2.1",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2716,7 +2400,7 @@ checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2765,28 +2449,11 @@ dependencies = [
|
|||||||
"futures-core",
|
"futures-core",
|
||||||
"iovec",
|
"iovec",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
|
||||||
"memchr",
|
"memchr",
|
||||||
"mio",
|
"mio",
|
||||||
"mio-named-pipes",
|
|
||||||
"mio-uds",
|
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
|
||||||
"slab",
|
"slab",
|
||||||
"tokio-macros",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio-macros"
|
|
||||||
version = "0.2.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 1.0.19",
|
|
||||||
"quote 1.0.7",
|
|
||||||
"syn 1.0.36",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2996,7 +2663,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3030,7 +2697,7 @@ checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.36",
|
"syn 1.0.38",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
@ -29,13 +29,14 @@ snarkos-gadgets = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", package = "
|
|||||||
snarkos-models = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", package = "snarkos-models", default-features = false }
|
snarkos-models = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", package = "snarkos-models", default-features = false }
|
||||||
snarkos-utilities = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", package = "snarkos-utilities" }
|
snarkos-utilities = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", package = "snarkos-utilities" }
|
||||||
|
|
||||||
clap = { version = "2.33.0" }
|
clap = { version = "2.33.3" }
|
||||||
colored = { version = "2.0" }
|
colored = { version = "2.0" }
|
||||||
env_logger = { version = "0.7" }
|
env_logger = { version = "0.7" }
|
||||||
from-pest = { version = "0.3.1" }
|
from-pest = { version = "0.3.1" }
|
||||||
lazy_static = { version = "1.4.0" }
|
lazy_static = { version = "1.4.0" }
|
||||||
log = { version = "0.4" }
|
log = { version = "0.4" }
|
||||||
notify= { version = "4.0.15" }
|
notify= { version = "4.0.15" }
|
||||||
|
num-bigint = { version = "0.3" }
|
||||||
rand = { version = "0.7" }
|
rand = { version = "0.7" }
|
||||||
rand_core = { version = "0.5.1" }
|
rand_core = { version = "0.5.1" }
|
||||||
reqwest = { version = "0.10.7", features = ["blocking", "json"] }
|
reqwest = { version = "0.10.7", features = ["blocking", "json"] }
|
||||||
|
26
FAQ.md
Normal file
26
FAQ.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# FAQs
|
||||||
|
|
||||||
|
#### For some given code, changing the value in a constant variable changes the number of constraints in the generated circuit. Is this behavior correct?
|
||||||
|
|
||||||
|
**Yes**, take the integers as an example. In Leo, integers are represented as its binary decomposition,
|
||||||
|
with each bit occupying one field element (that takes on 0 or 1). Then, for an expression such as `a == 4u32`, the operation to evaluate equality
|
||||||
|
would comprise a linear pass of bitwise `AND` operations, comparing every bit in the **variable** value with each bit in the **constant** value.
|
||||||
|
|
||||||
|
As the constant value is already known to the compiler during circuit synthesis, the compiler is already able to complete part of the equality evaluation,
|
||||||
|
by assuming that any bit in the constant value that is `0` will clearly evaluate to `0`. As such, depending on the value of the constant integer in your code,
|
||||||
|
the total number of constraints in the generate circuit can vary.
|
||||||
|
|
||||||
|
To illustrate this, here are two examples to show the difference:
|
||||||
|
```
|
||||||
|
const = 00000001
|
||||||
|
variable = abcdefgh
|
||||||
|
---------------------------------
|
||||||
|
output = 0000000h (1 constraint)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
const = 01110001
|
||||||
|
variable = abcdefgh
|
||||||
|
---------------------------------
|
||||||
|
output = 0bcd000h (4 constraints)
|
||||||
|
```
|
@ -3,6 +3,8 @@
|
|||||||
![CI](https://github.com/AleoHQ/leo/workflows/CI/badge.svg)
|
![CI](https://github.com/AleoHQ/leo/workflows/CI/badge.svg)
|
||||||
[![codecov](https://codecov.io/gh/AleoHQ/leo/branch/master/graph/badge.svg?token=S6MWO60SYL)](https://codecov.io/gh/AleoHQ/leo)
|
[![codecov](https://codecov.io/gh/AleoHQ/leo/branch/master/graph/badge.svg?token=S6MWO60SYL)](https://codecov.io/gh/AleoHQ/leo)
|
||||||
|
|
||||||
|
# Overview
|
||||||
|
|
||||||
## Compiler Architecture
|
## Compiler Architecture
|
||||||
|
|
||||||
<!-- generated by mermaid compile action - START -->
|
<!-- generated by mermaid compile action - START -->
|
||||||
|
@ -7,6 +7,7 @@ use serde::Serialize;
|
|||||||
#[pest_ast(rule(Rule::access))]
|
#[pest_ast(rule(Rule::access))]
|
||||||
pub enum Access<'ast> {
|
pub enum Access<'ast> {
|
||||||
Array(ArrayAccess<'ast>),
|
Array(ArrayAccess<'ast>),
|
||||||
|
Tuple(TupleAccess<'ast>),
|
||||||
Call(CallAccess<'ast>),
|
Call(CallAccess<'ast>),
|
||||||
Object(MemberAccess<'ast>),
|
Object(MemberAccess<'ast>),
|
||||||
StaticObject(StaticMemberAccess<'ast>),
|
StaticObject(StaticMemberAccess<'ast>),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
access::{ArrayAccess, MemberAccess},
|
access::{ArrayAccess, MemberAccess, TupleAccess},
|
||||||
ast::Rule,
|
ast::Rule,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -11,6 +11,7 @@ use std::fmt;
|
|||||||
#[pest_ast(rule(Rule::access_assignee))]
|
#[pest_ast(rule(Rule::access_assignee))]
|
||||||
pub enum AssigneeAccess<'ast> {
|
pub enum AssigneeAccess<'ast> {
|
||||||
Array(ArrayAccess<'ast>),
|
Array(ArrayAccess<'ast>),
|
||||||
|
Tuple(TupleAccess<'ast>),
|
||||||
Member(MemberAccess<'ast>),
|
Member(MemberAccess<'ast>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ impl<'ast> fmt::Display for AssigneeAccess<'ast> {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
AssigneeAccess::Array(ref array) => write!(f, "[{}]", array.expression),
|
AssigneeAccess::Array(ref array) => write!(f, "[{}]", array.expression),
|
||||||
|
AssigneeAccess::Tuple(ref tuple) => write!(f, ".{}", tuple.number),
|
||||||
AssigneeAccess::Member(ref member) => write!(f, ".{}", member.identifier),
|
AssigneeAccess::Member(ref member) => write!(f, ".{}", member.identifier),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{ast::Rule, expressions::Expression, SpanDef};
|
use crate::{ast::Rule, expressions::TupleExpression, SpanDef};
|
||||||
|
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
use pest_ast::FromPest;
|
use pest_ast::FromPest;
|
||||||
@ -7,7 +7,7 @@ use serde::Serialize;
|
|||||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||||
#[pest_ast(rule(Rule::access_call))]
|
#[pest_ast(rule(Rule::access_call))]
|
||||||
pub struct CallAccess<'ast> {
|
pub struct CallAccess<'ast> {
|
||||||
pub expressions: Vec<Expression<'ast>>,
|
pub expressions: TupleExpression<'ast>,
|
||||||
#[pest_ast(outer())]
|
#[pest_ast(outer())]
|
||||||
#[serde(with = "SpanDef")]
|
#[serde(with = "SpanDef")]
|
||||||
pub span: Span<'ast>,
|
pub span: Span<'ast>,
|
||||||
|
@ -15,3 +15,6 @@ pub use member_access::*;
|
|||||||
|
|
||||||
pub mod static_member_access;
|
pub mod static_member_access;
|
||||||
pub use static_member_access::*;
|
pub use static_member_access::*;
|
||||||
|
|
||||||
|
pub mod tuple_access;
|
||||||
|
pub use tuple_access::*;
|
||||||
|
14
ast/src/access/tuple_access.rs
Normal file
14
ast/src/access/tuple_access.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use crate::{ast::Rule, values::PositiveNumber, SpanDef};
|
||||||
|
|
||||||
|
use pest::Span;
|
||||||
|
use pest_ast::FromPest;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||||
|
#[pest_ast(rule(Rule::access_tuple))]
|
||||||
|
pub struct TupleAccess<'ast> {
|
||||||
|
pub number: PositiveNumber<'ast>,
|
||||||
|
#[pest_ast(outer())]
|
||||||
|
#[serde(with = "SpanDef")]
|
||||||
|
pub span: Span<'ast>,
|
||||||
|
}
|
@ -14,6 +14,7 @@ use crate::{
|
|||||||
values::Value,
|
values::Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::expressions::TupleExpression;
|
||||||
use from_pest::{ConversionError, FromPest, Void};
|
use from_pest::{ConversionError, FromPest, Void};
|
||||||
use pest::{
|
use pest::{
|
||||||
error::Error,
|
error::Error,
|
||||||
@ -64,6 +65,9 @@ fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
|
|||||||
let next = clone.into_inner().next().unwrap();
|
let next = clone.into_inner().next().unwrap();
|
||||||
match next.as_rule() {
|
match next.as_rule() {
|
||||||
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
|
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
|
||||||
|
Rule::expression_tuple => {
|
||||||
|
Expression::Tuple(TupleExpression::from_pest(&mut pair.into_inner()).unwrap())
|
||||||
|
}
|
||||||
Rule::expression_array_inline => {
|
Rule::expression_array_inline => {
|
||||||
Expression::ArrayInline(ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap())
|
Expression::ArrayInline(ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,6 @@ pub use range::*;
|
|||||||
pub mod range_or_expression;
|
pub mod range_or_expression;
|
||||||
pub use range_or_expression::*;
|
pub use range_or_expression::*;
|
||||||
|
|
||||||
pub mod return_;
|
|
||||||
pub use return_::*;
|
|
||||||
|
|
||||||
pub mod return_tuple;
|
|
||||||
pub use return_tuple::*;
|
|
||||||
|
|
||||||
pub mod spread;
|
pub mod spread;
|
||||||
pub use spread::*;
|
pub use spread::*;
|
||||||
|
|
||||||
@ -37,5 +31,8 @@ pub use spread_or_expression::*;
|
|||||||
pub mod static_;
|
pub mod static_;
|
||||||
pub use static_::*;
|
pub use static_::*;
|
||||||
|
|
||||||
pub mod variable;
|
pub mod variables;
|
||||||
pub use variable::*;
|
pub use variables::*;
|
||||||
|
|
||||||
|
pub mod variable_name;
|
||||||
|
pub use variable_name::*;
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
use crate::{ast::Rule, common::ReturnTuple, expressions::Expression};
|
|
||||||
|
|
||||||
use pest_ast::FromPest;
|
|
||||||
use serde::Serialize;
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
|
||||||
#[pest_ast(rule(Rule::return_))]
|
|
||||||
pub enum Return<'ast> {
|
|
||||||
Single(Expression<'ast>),
|
|
||||||
Tuple(ReturnTuple<'ast>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> fmt::Display for Return<'ast> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
Return::Single(ref expression) => write!(f, "{}", expression),
|
|
||||||
Return::Tuple(ref expressions) => write!(f, "{}", expressions),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
use crate::{ast::Rule, expressions::Expression, SpanDef};
|
|
||||||
|
|
||||||
use pest::Span;
|
|
||||||
use pest_ast::FromPest;
|
|
||||||
use serde::Serialize;
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
|
||||||
#[pest_ast(rule(Rule::return_tuple))]
|
|
||||||
pub struct ReturnTuple<'ast> {
|
|
||||||
pub expressions: Vec<Expression<'ast>>,
|
|
||||||
#[pest_ast(outer())]
|
|
||||||
#[serde(with = "SpanDef")]
|
|
||||||
pub span: Span<'ast>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> fmt::Display for ReturnTuple<'ast> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
for (i, expression) in self.expressions.iter().enumerate() {
|
|
||||||
write!(f, "{}", expression)?;
|
|
||||||
if i < self.expressions.len() - 1 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(f, "")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ast::Rule,
|
ast::Rule,
|
||||||
common::{Identifier, Mutable},
|
common::{Identifier, Mutable},
|
||||||
types::Type,
|
|
||||||
SpanDef,
|
SpanDef,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -11,28 +10,21 @@ use serde::Serialize;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||||
#[pest_ast(rule(Rule::variable))]
|
#[pest_ast(rule(Rule::variable_name))]
|
||||||
pub struct Variable<'ast> {
|
pub struct VariableName<'ast> {
|
||||||
pub mutable: Option<Mutable>,
|
pub mutable: Option<Mutable>,
|
||||||
pub identifier: Identifier<'ast>,
|
pub identifier: Identifier<'ast>,
|
||||||
pub _type: Option<Type<'ast>>,
|
|
||||||
#[pest_ast(outer())]
|
#[pest_ast(outer())]
|
||||||
#[serde(with = "SpanDef")]
|
#[serde(with = "SpanDef")]
|
||||||
pub span: Span<'ast>,
|
pub span: Span<'ast>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> fmt::Display for Variable<'ast> {
|
impl<'ast> fmt::Display for VariableName<'ast> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if let Some(ref _mutable) = self.mutable {
|
if let Some(ref _mutable) = self.mutable {
|
||||||
write!(f, "mut ")?;
|
write!(f, "mut ")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, "{}", self.identifier)?;
|
write!(f, "{}", self.identifier)
|
||||||
|
|
||||||
if let Some(ref _type) = self._type {
|
|
||||||
write!(f, ": {}", _type)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
write!(f, "")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
41
ast/src/common/variables.rs
Normal file
41
ast/src/common/variables.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
use crate::{ast::Rule, common::VariableName, types::Type, SpanDef};
|
||||||
|
|
||||||
|
use pest::Span;
|
||||||
|
use pest_ast::FromPest;
|
||||||
|
use serde::Serialize;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||||
|
#[pest_ast(rule(Rule::variables))]
|
||||||
|
pub struct Variables<'ast> {
|
||||||
|
pub names: Vec<VariableName<'ast>>,
|
||||||
|
pub type_: Option<Type<'ast>>,
|
||||||
|
#[pest_ast(outer())]
|
||||||
|
#[serde(with = "SpanDef")]
|
||||||
|
pub span: Span<'ast>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast> fmt::Display for Variables<'ast> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
if self.names.len() == 1 {
|
||||||
|
// mut a
|
||||||
|
write!(f, "{}", self.names[0])?;
|
||||||
|
} else {
|
||||||
|
// (a, mut b)
|
||||||
|
let names = self
|
||||||
|
.names
|
||||||
|
.iter()
|
||||||
|
.map(|x| format!("{}", x))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(",");
|
||||||
|
|
||||||
|
write!(f, "({})", names)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.type_.is_some() {
|
||||||
|
write!(f, ": {}", self.type_.as_ref().unwrap())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(f, "")
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ pub enum Expression<'ast> {
|
|||||||
ArrayInitializer(ArrayInitializerExpression<'ast>),
|
ArrayInitializer(ArrayInitializerExpression<'ast>),
|
||||||
CircuitInline(CircuitInlineExpression<'ast>),
|
CircuitInline(CircuitInlineExpression<'ast>),
|
||||||
Postfix(PostfixExpression<'ast>),
|
Postfix(PostfixExpression<'ast>),
|
||||||
|
Tuple(TupleExpression<'ast>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> Expression<'ast> {
|
impl<'ast> Expression<'ast> {
|
||||||
@ -57,6 +58,7 @@ impl<'ast> Expression<'ast> {
|
|||||||
Expression::ArrayInitializer(expression) => &expression.span,
|
Expression::ArrayInitializer(expression) => &expression.span,
|
||||||
Expression::CircuitInline(expression) => &expression.span,
|
Expression::CircuitInline(expression) => &expression.span,
|
||||||
Expression::Postfix(expression) => &expression.span,
|
Expression::Postfix(expression) => &expression.span,
|
||||||
|
Expression::Tuple(expression) => &expression.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,10 +87,9 @@ impl<'ast> fmt::Display for Expression<'ast> {
|
|||||||
Expression::ArrayInitializer(ref expression) => {
|
Expression::ArrayInitializer(ref expression) => {
|
||||||
write!(f, "[{} ; {}]", expression.expression, expression.count)
|
write!(f, "[{} ; {}]", expression.expression, expression.count)
|
||||||
}
|
}
|
||||||
Expression::CircuitInline(ref expression) => {
|
Expression::CircuitInline(ref expression) => write!(f, "{}", expression.span.as_str()),
|
||||||
write!(f, "inline circuit display not impl {}", expression.identifier)
|
Expression::Postfix(ref expression) => write!(f, "{}", expression.span.as_str()),
|
||||||
}
|
Expression::Tuple(ref expression) => write!(f, "{}", expression.span.as_str()),
|
||||||
Expression::Postfix(ref expression) => write!(f, "Postfix display not impl {}", expression.identifier),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,3 +21,6 @@ pub use postfix_expression::*;
|
|||||||
|
|
||||||
pub mod ternary_expression;
|
pub mod ternary_expression;
|
||||||
pub use ternary_expression::*;
|
pub use ternary_expression::*;
|
||||||
|
|
||||||
|
pub mod tuple_expression;
|
||||||
|
pub use tuple_expression::*;
|
||||||
|
14
ast/src/expressions/tuple_expression.rs
Normal file
14
ast/src/expressions/tuple_expression.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use crate::{ast::Rule, expressions::Expression, SpanDef};
|
||||||
|
|
||||||
|
use pest::Span;
|
||||||
|
use pest_ast::FromPest;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||||
|
#[pest_ast(rule(Rule::expression_tuple))]
|
||||||
|
pub struct TupleExpression<'ast> {
|
||||||
|
pub expressions: Vec<Expression<'ast>>,
|
||||||
|
#[pest_ast(outer())]
|
||||||
|
#[serde(with = "SpanDef")]
|
||||||
|
pub span: Span<'ast>,
|
||||||
|
}
|
@ -9,7 +9,7 @@ use serde::Serialize;
|
|||||||
pub struct Function<'ast> {
|
pub struct Function<'ast> {
|
||||||
pub identifier: Identifier<'ast>,
|
pub identifier: Identifier<'ast>,
|
||||||
pub parameters: Vec<Input<'ast>>,
|
pub parameters: Vec<Input<'ast>>,
|
||||||
pub returns: Vec<Type<'ast>>,
|
pub returns: Option<Type<'ast>>,
|
||||||
pub statements: Vec<Statement<'ast>>,
|
pub statements: Vec<Statement<'ast>>,
|
||||||
#[pest_ast(outer())]
|
#[pest_ast(outer())]
|
||||||
#[serde(with = "SpanDef")]
|
#[serde(with = "SpanDef")]
|
||||||
|
@ -57,17 +57,16 @@ spread = { "..." ~ expression }
|
|||||||
// Declared in common/spread_or_expression.rs
|
// Declared in common/spread_or_expression.rs
|
||||||
spread_or_expression = { spread | expression }
|
spread_or_expression = { spread | expression }
|
||||||
|
|
||||||
// Declared in common/return_.rs
|
|
||||||
return_ = { return_tuple | expression }
|
|
||||||
|
|
||||||
// Declared in common/return_tuple.rs
|
|
||||||
return_tuple = {"(" ~ expression ~ ("," ~ expression)+ ~ ")"}
|
|
||||||
|
|
||||||
// Declared in common/static_.rs
|
// Declared in common/static_.rs
|
||||||
static_ = { "static " }
|
static_ = { "static " }
|
||||||
|
|
||||||
// Declared in common/variable.rs
|
// Declared in common/variable_name.rs
|
||||||
variable = { mutable? ~ identifier ~ (":" ~ type_)? }
|
|
||||||
|
variable_name = {mutable? ~ identifier}
|
||||||
|
variable_name_tuple = _{"(" ~ variable_name ~ ("," ~ variable_name)+ ~ ")"}
|
||||||
|
|
||||||
|
// Declared in common/variables.rs
|
||||||
|
variables = { ( variable_name_tuple | variable_name ) ~ (":" ~ type_ )? }
|
||||||
|
|
||||||
// Declared in common/declare.rs
|
// Declared in common/declare.rs
|
||||||
declare = { let_ | const_ }
|
declare = { let_ | const_ }
|
||||||
@ -124,7 +123,7 @@ operation_pow_assign = { "**=" }
|
|||||||
/// Types
|
/// Types
|
||||||
|
|
||||||
// Declared in types/type_.rs
|
// Declared in types/type_.rs
|
||||||
type_ = { type_self | type_array | type_data | type_circuit }
|
type_ = { type_self | type_tuple | type_array | type_data | type_circuit }
|
||||||
|
|
||||||
// Declared in types/integer_type.rs
|
// Declared in types/integer_type.rs
|
||||||
type_integer = {
|
type_integer = {
|
||||||
@ -192,7 +191,7 @@ type_circuit = { identifier }
|
|||||||
// Declared in types/array_type.rs
|
// Declared in types/array_type.rs
|
||||||
type_array = { type_data ~ ("[" ~ number_positive ~ "]")+ }
|
type_array = { type_data ~ ("[" ~ number_positive ~ "]")+ }
|
||||||
|
|
||||||
type_list = _{ (type_ ~ ("," ~ type_)*)? }
|
type_tuple = { "(" ~ NEWLINE* ~ type_ ~ ("," ~ NEWLINE* ~ type_)+ ~ ","? ~ NEWLINE* ~ ")" }
|
||||||
|
|
||||||
/// Values
|
/// Values
|
||||||
|
|
||||||
@ -244,16 +243,19 @@ value_address = ${ type_address ~ "(" ~ address ~ ")" }
|
|||||||
/// Access
|
/// Access
|
||||||
|
|
||||||
// Declared in access/access.rs
|
// Declared in access/access.rs
|
||||||
access = { access_array | access_call | access_member | access_static_member}
|
access = { access_array | access_tuple | access_call | access_member | access_static_member}
|
||||||
|
|
||||||
// Declared in access/array_access.rs
|
// Declared in access/array_access.rs
|
||||||
access_array = !{ "[" ~ range_or_expression ~ "]" }
|
access_array = !{ "[" ~ range_or_expression ~ "]" }
|
||||||
|
|
||||||
|
// Declared in access/tuple_access.rs
|
||||||
|
access_tuple = ${ "." ~ number_positive }
|
||||||
|
|
||||||
// Declared in access/assignee_access.rs
|
// Declared in access/assignee_access.rs
|
||||||
access_assignee = { access_array | access_member }
|
access_assignee = { access_array | access_tuple | access_member }
|
||||||
|
|
||||||
// Declared in access/call_access.rs
|
// Declared in access/call_access.rs
|
||||||
access_call = !{ "(" ~ expression_tuple ~ ")" }
|
access_call = !{ expression_tuple }
|
||||||
|
|
||||||
// Declared in access/member_access.rs
|
// Declared in access/member_access.rs
|
||||||
access_member = ${ "." ~ identifier }
|
access_member = ${ "." ~ identifier }
|
||||||
@ -285,22 +287,25 @@ expression_conditional = { "if " ~ expression ~ "? " ~ expression ~ ": " ~ expre
|
|||||||
/// Expressions
|
/// Expressions
|
||||||
|
|
||||||
expression_term = {
|
expression_term = {
|
||||||
("(" ~ expression ~ ")")
|
value
|
||||||
|
| ("(" ~ expression ~ ")")
|
||||||
|
| expression_tuple
|
||||||
|
| expression_conditional
|
||||||
| expression_array_initializer
|
| expression_array_initializer
|
||||||
| expression_array_inline
|
| expression_array_inline
|
||||||
| expression_circuit_inline
|
| expression_circuit_inline
|
||||||
| expression_conditional
|
| expression_unary
|
||||||
| value
|
|
||||||
| expression_unary // must be defined below value to avoid conflicts with negative values
|
|
||||||
| expression_postfix
|
| expression_postfix
|
||||||
| identifier
|
| identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
|
||||||
|
|
||||||
// Declared in expressions/expression.rs
|
// Declared in expressions/expression.rs
|
||||||
expression = { expression_term ~ (operation_binary ~ expression_term)* }
|
expression = { expression_term ~ (operation_binary ~ expression_term)* }
|
||||||
|
|
||||||
|
// Declared in expressions/expression_tuple.rs
|
||||||
|
expression_tuple = { "(" ~ (expression ~ ("," ~ expression)*)? ~ ")" }
|
||||||
|
|
||||||
// Declared in expressions/array_initializer_expression.rs
|
// Declared in expressions/array_initializer_expression.rs
|
||||||
expression_array_initializer = { "[" ~ spread_or_expression ~ ";" ~ number_positive ~ "]" }
|
expression_array_initializer = { "[" ~ spread_or_expression ~ ";" ~ number_positive ~ "]" }
|
||||||
|
|
||||||
@ -325,7 +330,6 @@ statement = {
|
|||||||
(statement_return
|
(statement_return
|
||||||
| statement_conditional
|
| statement_conditional
|
||||||
| statement_for
|
| statement_for
|
||||||
| statement_multiple_assignment
|
|
||||||
| statement_macro
|
| statement_macro
|
||||||
| statement_definition
|
| statement_definition
|
||||||
| statement_assign
|
| statement_assign
|
||||||
@ -347,7 +351,7 @@ statement_conditional = {"if " ~ (expression | "(" ~ expression ~ ")") ~ "{" ~ N
|
|||||||
conditional_nested_or_end_statement = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
conditional_nested_or_end_statement = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||||
|
|
||||||
// Declared in statements/definition_statement.rs
|
// Declared in statements/definition_statement.rs
|
||||||
statement_definition = { declare ~ variable ~ "=" ~ expression ~ LINE_END}
|
statement_definition = { declare ~ variables ~ "=" ~ expression ~ LINE_END}
|
||||||
|
|
||||||
// Declared in statements/expression_statement.rs
|
// Declared in statements/expression_statement.rs
|
||||||
statement_expression = { expression ~ LINE_END }
|
statement_expression = { expression ~ LINE_END }
|
||||||
@ -355,12 +359,8 @@ statement_expression = { expression ~ LINE_END }
|
|||||||
// Declared in statements/for_statement.rs
|
// Declared in statements/for_statement.rs
|
||||||
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||||
|
|
||||||
// Declared in statements/multiple_assignment_statement.rs
|
|
||||||
statement_multiple_assignment = { declare ~ "(" ~ variable_tuple ~ ")" ~ "=" ~ identifier ~ "(" ~ expression_tuple ~ ")" ~ LINE_END}
|
|
||||||
variable_tuple = _{ variable ~ ("," ~ variable)* }
|
|
||||||
|
|
||||||
// Declared in statements/return_statement.rs
|
// Declared in statements/return_statement.rs
|
||||||
statement_return = { "return " ~ return_}
|
statement_return = { "return " ~ expression}
|
||||||
|
|
||||||
/// Functions
|
/// Functions
|
||||||
|
|
||||||
@ -368,7 +368,7 @@ statement_return = { "return " ~ return_}
|
|||||||
test_function = { "test " ~ function }
|
test_function = { "test " ~ function }
|
||||||
|
|
||||||
// Declared in functions/function.rs
|
// Declared in functions/function.rs
|
||||||
function = { "function " ~ identifier ~ "(" ~ NEWLINE* ~ input_list ~ NEWLINE* ~ ")" ~ ("->" ~ (type_ | "(" ~ type_list ~ ")"))? ~ "{" ~ NEWLINE* ~ statement* ~ NEWLINE* ~ "}" ~ NEWLINE* }
|
function = { "function " ~ identifier ~ input_tuple ~ ("->" ~ type_)? ~ "{" ~ NEWLINE* ~ statement* ~ NEWLINE* ~ "}" ~ NEWLINE* }
|
||||||
|
|
||||||
// Declared in functions/input/function_input.rs
|
// Declared in functions/input/function_input.rs
|
||||||
function_input = { mutable? ~ identifier ~ ":" ~ type_ }
|
function_input = { mutable? ~ identifier ~ ":" ~ type_ }
|
||||||
@ -381,7 +381,7 @@ input = {
|
|||||||
function_input
|
function_input
|
||||||
| input_keyword
|
| input_keyword
|
||||||
}
|
}
|
||||||
input_list = _{ (input ~ ("," ~ NEWLINE* ~ input)*)? }
|
input_tuple = _{ "(" ~ NEWLINE* ~ (input ~ ("," ~ NEWLINE* ~ input)* ~ ","?)? ~ NEWLINE* ~ ")"}
|
||||||
|
|
||||||
|
|
||||||
/// Imports
|
/// Imports
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ast::Rule,
|
ast::Rule,
|
||||||
common::{Declare, LineEnd, Variable},
|
common::{Declare, LineEnd, Variables},
|
||||||
expressions::Expression,
|
expressions::Expression,
|
||||||
SpanDef,
|
SpanDef,
|
||||||
};
|
};
|
||||||
@ -14,8 +14,8 @@ use std::fmt;
|
|||||||
#[pest_ast(rule(Rule::statement_definition))]
|
#[pest_ast(rule(Rule::statement_definition))]
|
||||||
pub struct DefinitionStatement<'ast> {
|
pub struct DefinitionStatement<'ast> {
|
||||||
pub declare: Declare,
|
pub declare: Declare,
|
||||||
pub variable: Variable<'ast>,
|
pub variables: Variables<'ast>,
|
||||||
pub expression: Expression<'ast>,
|
pub expressions: Vec<Expression<'ast>>,
|
||||||
pub line_end: LineEnd,
|
pub line_end: LineEnd,
|
||||||
#[pest_ast(outer())]
|
#[pest_ast(outer())]
|
||||||
#[serde(with = "SpanDef")]
|
#[serde(with = "SpanDef")]
|
||||||
@ -24,6 +24,13 @@ pub struct DefinitionStatement<'ast> {
|
|||||||
|
|
||||||
impl<'ast> fmt::Display for DefinitionStatement<'ast> {
|
impl<'ast> fmt::Display for DefinitionStatement<'ast> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "let {} = {};", self.variable, self.expression)
|
let expressions = self
|
||||||
|
.expressions
|
||||||
|
.iter()
|
||||||
|
.map(|x| format!("{}", x))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(",");
|
||||||
|
|
||||||
|
write!(f, "let {} = {};", self.variables, expressions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,6 @@ pub use expression_statement::*;
|
|||||||
pub mod for_statement;
|
pub mod for_statement;
|
||||||
pub use for_statement::*;
|
pub use for_statement::*;
|
||||||
|
|
||||||
pub mod multiple_assignment_statement;
|
|
||||||
pub use multiple_assignment_statement::*;
|
|
||||||
|
|
||||||
pub mod return_statement;
|
pub mod return_statement;
|
||||||
pub use return_statement::*;
|
pub use return_statement::*;
|
||||||
|
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
use crate::{
|
|
||||||
ast::Rule,
|
|
||||||
common::{Declare, Identifier, LineEnd, Variable},
|
|
||||||
expressions::Expression,
|
|
||||||
SpanDef,
|
|
||||||
};
|
|
||||||
|
|
||||||
use pest::Span;
|
|
||||||
use pest_ast::FromPest;
|
|
||||||
use serde::Serialize;
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
|
||||||
#[pest_ast(rule(Rule::statement_multiple_assignment))]
|
|
||||||
pub struct MultipleAssignmentStatement<'ast> {
|
|
||||||
pub declare: Declare,
|
|
||||||
pub variables: Vec<Variable<'ast>>,
|
|
||||||
pub function_name: Identifier<'ast>,
|
|
||||||
pub arguments: Vec<Expression<'ast>>,
|
|
||||||
pub line_end: LineEnd,
|
|
||||||
#[pest_ast(outer())]
|
|
||||||
#[serde(with = "SpanDef")]
|
|
||||||
pub span: Span<'ast>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> fmt::Display for MultipleAssignmentStatement<'ast> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
for (i, id) in self.variables.iter().enumerate() {
|
|
||||||
write!(f, "{}", id)?;
|
|
||||||
if i < self.variables.len() - 1 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(f, " = {}", self.function_name)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{ast::Rule, common::Return, SpanDef};
|
use crate::{ast::Rule, expressions::Expression, SpanDef};
|
||||||
|
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
use pest_ast::FromPest;
|
use pest_ast::FromPest;
|
||||||
@ -8,7 +8,7 @@ use std::fmt;
|
|||||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||||
#[pest_ast(rule(Rule::statement_return))]
|
#[pest_ast(rule(Rule::statement_return))]
|
||||||
pub struct ReturnStatement<'ast> {
|
pub struct ReturnStatement<'ast> {
|
||||||
pub return_: Return<'ast>,
|
pub expression: Expression<'ast>,
|
||||||
#[pest_ast(outer())]
|
#[pest_ast(outer())]
|
||||||
#[serde(with = "SpanDef")]
|
#[serde(with = "SpanDef")]
|
||||||
pub span: Span<'ast>,
|
pub span: Span<'ast>,
|
||||||
@ -16,6 +16,6 @@ pub struct ReturnStatement<'ast> {
|
|||||||
|
|
||||||
impl<'ast> fmt::Display for ReturnStatement<'ast> {
|
impl<'ast> fmt::Display for ReturnStatement<'ast> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.return_)
|
write!(f, "return {}", self.expression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ pub enum Statement<'ast> {
|
|||||||
Return(ReturnStatement<'ast>),
|
Return(ReturnStatement<'ast>),
|
||||||
Definition(DefinitionStatement<'ast>),
|
Definition(DefinitionStatement<'ast>),
|
||||||
Assign(AssignStatement<'ast>),
|
Assign(AssignStatement<'ast>),
|
||||||
MultipleAssignment(MultipleAssignmentStatement<'ast>),
|
|
||||||
Conditional(ConditionalStatement<'ast>),
|
Conditional(ConditionalStatement<'ast>),
|
||||||
Iteration(ForStatement<'ast>),
|
Iteration(ForStatement<'ast>),
|
||||||
Assert(MacroStatement<'ast>),
|
Assert(MacroStatement<'ast>),
|
||||||
@ -23,7 +22,6 @@ impl<'ast> fmt::Display for Statement<'ast> {
|
|||||||
Statement::Return(ref statement) => write!(f, "{}", statement),
|
Statement::Return(ref statement) => write!(f, "{}", statement),
|
||||||
Statement::Definition(ref statement) => write!(f, "{}", statement),
|
Statement::Definition(ref statement) => write!(f, "{}", statement),
|
||||||
Statement::Assign(ref statement) => write!(f, "{}", statement),
|
Statement::Assign(ref statement) => write!(f, "{}", statement),
|
||||||
Statement::MultipleAssignment(ref statement) => write!(f, "{}", statement),
|
|
||||||
Statement::Conditional(ref statement) => write!(f, "{}", statement),
|
Statement::Conditional(ref statement) => write!(f, "{}", statement),
|
||||||
Statement::Iteration(ref statement) => write!(f, "{}", statement),
|
Statement::Iteration(ref statement) => write!(f, "{}", statement),
|
||||||
Statement::Assert(ref statement) => write!(f, "{}", statement),
|
Statement::Assert(ref statement) => write!(f, "{}", statement),
|
||||||
|
@ -28,6 +28,9 @@ pub use self_type::*;
|
|||||||
pub mod signed_integer_type;
|
pub mod signed_integer_type;
|
||||||
pub use signed_integer_type::*;
|
pub use signed_integer_type::*;
|
||||||
|
|
||||||
|
pub mod tuple_type;
|
||||||
|
pub use tuple_type::*;
|
||||||
|
|
||||||
pub mod type_;
|
pub mod type_;
|
||||||
pub use type_::*;
|
pub use type_::*;
|
||||||
|
|
||||||
|
14
ast/src/types/tuple_type.rs
Normal file
14
ast/src/types/tuple_type.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use crate::{ast::Rule, types::Type, SpanDef};
|
||||||
|
|
||||||
|
use pest::Span;
|
||||||
|
use pest_ast::FromPest;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||||
|
#[pest_ast(rule(Rule::type_tuple))]
|
||||||
|
pub struct TupleType<'ast> {
|
||||||
|
pub types: Vec<Type<'ast>>,
|
||||||
|
#[pest_ast(outer())]
|
||||||
|
#[serde(with = "SpanDef")]
|
||||||
|
pub span: Span<'ast>,
|
||||||
|
}
|
@ -9,6 +9,7 @@ use std::fmt;
|
|||||||
pub enum Type<'ast> {
|
pub enum Type<'ast> {
|
||||||
Basic(DataType),
|
Basic(DataType),
|
||||||
Array(ArrayType<'ast>),
|
Array(ArrayType<'ast>),
|
||||||
|
Tuple(TupleType<'ast>),
|
||||||
Circuit(CircuitType<'ast>),
|
Circuit(CircuitType<'ast>),
|
||||||
SelfType(SelfType),
|
SelfType(SelfType),
|
||||||
}
|
}
|
||||||
@ -18,6 +19,7 @@ impl<'ast> fmt::Display for Type<'ast> {
|
|||||||
match *self {
|
match *self {
|
||||||
Type::Basic(ref _type) => write!(f, "basic"),
|
Type::Basic(ref _type) => write!(f, "basic"),
|
||||||
Type::Array(ref _type) => write!(f, "array"),
|
Type::Array(ref _type) => write!(f, "array"),
|
||||||
|
Type::Tuple(ref _type) => write!(f, "tuple"),
|
||||||
Type::Circuit(ref _type) => write!(f, "struct"),
|
Type::Circuit(ref _type) => write!(f, "struct"),
|
||||||
Type::SelfType(ref _type) => write!(f, "Self"),
|
Type::SelfType(ref _type) => write!(f, "Self"),
|
||||||
}
|
}
|
||||||
|
@ -11,47 +11,45 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"parameters": [],
|
"parameters": [],
|
||||||
"returns": [],
|
"returns": null,
|
||||||
"statements": [
|
"statements": [
|
||||||
{
|
{
|
||||||
"Return": {
|
"Return": {
|
||||||
"return_": {
|
"expression": {
|
||||||
"Single": {
|
"Binary": {
|
||||||
"Binary": {
|
"operation": "Add",
|
||||||
"operation": "Add",
|
"left": {
|
||||||
"left": {
|
"Value": {
|
||||||
"Value": {
|
"Implicit": {
|
||||||
"Implicit": {
|
"Positive": {
|
||||||
"Positive": {
|
"value": "1",
|
||||||
"value": "1",
|
"span": {
|
||||||
"span": {
|
"input": "1",
|
||||||
"input": "1",
|
"start": 29,
|
||||||
"start": 29,
|
"end": 30
|
||||||
"end": 30
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"right": {
|
|
||||||
"Value": {
|
|
||||||
"Implicit": {
|
|
||||||
"Positive": {
|
|
||||||
"value": "1",
|
|
||||||
"span": {
|
|
||||||
"input": "1",
|
|
||||||
"start": 33,
|
|
||||||
"end": 34
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"span": {
|
|
||||||
"input": "1 + 1",
|
|
||||||
"start": 29,
|
|
||||||
"end": 34
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"Value": {
|
||||||
|
"Implicit": {
|
||||||
|
"Positive": {
|
||||||
|
"value": "1",
|
||||||
|
"span": {
|
||||||
|
"input": "1",
|
||||||
|
"start": 33,
|
||||||
|
"end": 34
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"span": {
|
||||||
|
"input": "1 + 1",
|
||||||
|
"start": 29,
|
||||||
|
"end": 34
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -140,13 +140,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
|||||||
/// Synthesizes the circuit without program input to verify correctness.
|
/// Synthesizes the circuit without program input to verify correctness.
|
||||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(self, cs: &mut CS) -> Result<OutputBytes, CompilerError> {
|
pub fn compile_constraints<CS: ConstraintSystem<F>>(self, cs: &mut CS) -> Result<OutputBytes, CompilerError> {
|
||||||
let path = self.main_file_path;
|
let path = self.main_file_path;
|
||||||
let input = self.program_input.empty();
|
|
||||||
|
|
||||||
generate_constraints::<F, G, CS>(cs, self.program, input, &self.imported_programs).map_err(|mut error| {
|
generate_constraints::<F, G, CS>(cs, self.program, self.program_input, &self.imported_programs).map_err(
|
||||||
error.set_path(path);
|
|mut error| {
|
||||||
|
error.set_path(path);
|
||||||
|
|
||||||
error
|
error
|
||||||
})
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Synthesizes the circuit for test functions with program input.
|
/// Synthesizes the circuit for test functions with program input.
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
value::ConstrainedValue,
|
value::ConstrainedValue,
|
||||||
GroupType,
|
GroupType,
|
||||||
};
|
};
|
||||||
use leo_typed::Variable;
|
use leo_typed::Identifier;
|
||||||
|
|
||||||
use snarkos_models::curves::{Field, PrimeField};
|
use snarkos_models::curves::{Field, PrimeField};
|
||||||
|
|
||||||
@ -13,15 +13,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
pub fn store_definition(
|
pub fn store_definition(
|
||||||
&mut self,
|
&mut self,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
variable: Variable,
|
mutable: bool,
|
||||||
|
identifier: Identifier,
|
||||||
mut value: ConstrainedValue<F, G>,
|
mut value: ConstrainedValue<F, G>,
|
||||||
) -> () {
|
) -> () {
|
||||||
// Store with given mutability
|
// Store with given mutability
|
||||||
if variable.mutable {
|
if mutable {
|
||||||
value = ConstrainedValue::Mutable(Box::new(value));
|
value = ConstrainedValue::Mutable(Box::new(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
let variable_program_identifier = new_scope(function_scope, variable.identifier.name);
|
let variable_program_identifier = new_scope(function_scope, identifier.name);
|
||||||
|
|
||||||
self.store(variable_program_identifier, value);
|
self.store(variable_program_identifier, value);
|
||||||
}
|
}
|
||||||
|
@ -70,14 +70,14 @@ impl ExpressionError {
|
|||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unexpected_array(expected: String, actual: String, span: Span) -> Self {
|
pub fn incompatible_types(operation: String, span: Span) -> Self {
|
||||||
let message = format!("expected type `{}`, found array with elements `{}`", expected, actual);
|
let message = format!("no implementation for `{}`", operation);
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn incompatible_types(operation: String, span: Span) -> Self {
|
pub fn index_out_of_bounds(index: usize, span: Span) -> Self {
|
||||||
let message = format!("no implementation for `{}`", operation);
|
let message = format!("cannot access index {} of tuple out of bounds", index);
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
@ -159,4 +159,16 @@ impl ExpressionError {
|
|||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unexpected_array(expected: String, actual: String, span: Span) -> Self {
|
||||||
|
let message = format!("expected type `{}`, found array with elements `{}`", expected, actual);
|
||||||
|
|
||||||
|
Self::new_from_span(message, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unexpected_tuple(expected: String, actual: String, span: Span) -> Self {
|
||||||
|
let message = format!("expected type `{}`, found tuple with values `{}`", expected, actual);
|
||||||
|
|
||||||
|
Self::new_from_span(message, span)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,12 @@ impl FunctionError {
|
|||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn invalid_tuple(actual: String, span: Span) -> Self {
|
||||||
|
let message = format!("Expected function input tuple, found `{}`", actual);
|
||||||
|
|
||||||
|
Self::new_from_span(message, span)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn return_arguments_length(expected: usize, actual: usize, span: Span) -> Self {
|
pub fn return_arguments_length(expected: usize, actual: usize, span: Span) -> Self {
|
||||||
let message = format!("function expected {} returns, found {} returns", expected, actual);
|
let message = format!("function expected {} returns, found {} returns", expected, actual);
|
||||||
|
|
||||||
|
@ -19,12 +19,6 @@ impl OutputBytesError {
|
|||||||
OutputBytesError::Error(FormattedError::new_from_span(message, span))
|
OutputBytesError::Error(FormattedError::new_from_span(message, span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn illegal_return(value: String, span: Span) -> Self {
|
|
||||||
let message = format!("program return must be a return value, found `{}`", value);
|
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_enough_registers(span: Span) -> Self {
|
pub fn not_enough_registers(span: Span) -> Self {
|
||||||
let message = format!("number of input registers must be greater than or equal to output registers");
|
let message = format!("number of input registers must be greater than or equal to output registers");
|
||||||
|
|
||||||
|
@ -113,6 +113,12 @@ impl StatementError {
|
|||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn multiple_definition(value: String, span: Span) -> Self {
|
||||||
|
let message = format!("cannot assign multiple variables to a single value: {}", value,);
|
||||||
|
|
||||||
|
Self::new_from_span(message, span)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn select_fail(first: String, second: String, span: Span) -> Self {
|
pub fn select_fail(first: String, second: String, span: Span) -> Self {
|
||||||
let message = format!(
|
let message = format!(
|
||||||
"Conditional select gadget failed to select between `{}` or `{}`",
|
"Conditional select gadget failed to select between `{}` or `{}`",
|
||||||
@ -122,6 +128,18 @@ impl StatementError {
|
|||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tuple_assign_index(span: Span) -> Self {
|
||||||
|
let message = format!("Cannot assign single index to tuple of values");
|
||||||
|
|
||||||
|
Self::new_from_span(message, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tuple_type(type_: String, span: Span) -> Self {
|
||||||
|
let message = format!("Expected tuple type, found type `{}`", type_);
|
||||||
|
|
||||||
|
Self::new_from_span(message, span)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unassigned(name: String, span: Span) -> Self {
|
pub fn unassigned(name: String, span: Span) -> Self {
|
||||||
let message = format!("Expected assignment of return values for expression `{}`", name);
|
let message = format!("Expected assignment of return values for expression `{}`", name);
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
array: Box<Expression>,
|
array: Box<Expression>,
|
||||||
index: RangeOrExpression,
|
index: RangeOrExpression,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -23,7 +23,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*array,
|
*array,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)? {
|
)? {
|
||||||
|
@ -20,23 +20,22 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
mut expected_type: Option<Type>,
|
||||||
array: Vec<Box<SpreadOrExpression>>,
|
array: Vec<Box<SpreadOrExpression>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
// Check explicit array type dimension if given
|
// Check explicit array type dimension if given
|
||||||
let mut expected_types = expected_types.clone();
|
|
||||||
let expected_dimensions = vec![];
|
let expected_dimensions = vec![];
|
||||||
|
|
||||||
if !expected_types.is_empty() {
|
if expected_type.is_some() {
|
||||||
match expected_types[0] {
|
match expected_type.unwrap() {
|
||||||
Type::Array(ref _type, ref dimensions) => {
|
Type::Array(ref type_, ref dimensions) => {
|
||||||
expected_types = vec![expected_types[0].inner_dimension(dimensions)];
|
expected_type = Some(type_.inner_dimension(dimensions).clone());
|
||||||
}
|
}
|
||||||
ref _type => {
|
ref _type => {
|
||||||
return Err(ExpressionError::unexpected_array(
|
return Err(ExpressionError::unexpected_array(
|
||||||
expected_types[0].to_string(),
|
|
||||||
_type.to_string(),
|
_type.to_string(),
|
||||||
|
format!("{:?}", array),
|
||||||
span,
|
span,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -66,7 +65,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&expected_types,
|
expected_type.clone(),
|
||||||
expression,
|
expression,
|
||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
index: Expression,
|
index: Expression,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<usize, ExpressionError> {
|
) -> Result<usize, ExpressionError> {
|
||||||
let expected_types = vec![Type::IntegerType(IntegerType::U32)];
|
let expected_type = Some(Type::IntegerType(IntegerType::U32));
|
||||||
match self.enforce_operand(
|
match self.enforce_operand(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&expected_types,
|
expected_type,
|
||||||
index,
|
index,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)? {
|
)? {
|
||||||
|
@ -14,7 +14,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
left: Expression,
|
left: Expression,
|
||||||
right: Expression,
|
right: Expression,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -23,7 +23,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type.clone(),
|
||||||
left,
|
left,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
@ -31,12 +31,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type.clone(),
|
||||||
right,
|
right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
resolved_left.resolve_types(&mut resolved_right, expected_types, span)?;
|
resolved_left.resolve_types(&mut resolved_right, expected_type, span)?;
|
||||||
|
|
||||||
Ok((resolved_left, resolved_right))
|
Ok((resolved_left, resolved_right))
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
let mut branch = self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
|
let mut branch = self.enforce_expression(cs, file_scope, function_scope, expected_type.clone(), expression)?;
|
||||||
|
|
||||||
branch.get_inner_mut();
|
branch.get_inner_mut();
|
||||||
branch.resolve_type(expected_types, span)?;
|
branch.resolve_type(expected_type, span)?;
|
||||||
|
|
||||||
Ok(branch)
|
Ok(branch)
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
circuit_identifier: Box<Expression>,
|
circuit_identifier: Box<Expression>,
|
||||||
circuit_member: Identifier,
|
circuit_member: Identifier,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let self_function_scope = new_scope(self_file_scope.clone(), identifier.name.to_string());
|
let self_function_scope = new_scope(self_file_scope.clone(), identifier.name.to_string());
|
||||||
|
|
||||||
let member_value =
|
let member_value =
|
||||||
self.evaluate_identifier(self_file_scope, self_function_scope, &vec![], circuit_member.clone())?;
|
self.evaluate_identifier(self_file_scope, self_function_scope, None, circuit_member.clone())?;
|
||||||
|
|
||||||
return Ok(member_value);
|
return Ok(member_value);
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*circuit_identifier.clone(),
|
*circuit_identifier.clone(),
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)? {
|
)? {
|
||||||
|
@ -51,7 +51,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![_type.clone()],
|
Some(_type.clone()),
|
||||||
field.expression,
|
field.expression,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
circuit_identifier: Box<Expression>,
|
circuit_identifier: Box<Expression>,
|
||||||
circuit_member: Identifier,
|
circuit_member: Identifier,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -24,7 +24,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*circuit_identifier.clone(),
|
*circuit_identifier.clone(),
|
||||||
)? {
|
)? {
|
||||||
ConstrainedValue::CircuitDefinition(circuit_definition) => circuit_definition,
|
ConstrainedValue::CircuitDefinition(circuit_definition) => circuit_definition,
|
||||||
|
@ -15,7 +15,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
conditional: Expression,
|
conditional: Expression,
|
||||||
first: Expression,
|
first: Expression,
|
||||||
second: Expression,
|
second: Expression,
|
||||||
@ -25,7 +25,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![Type::Boolean],
|
Some(Type::Boolean),
|
||||||
conditional,
|
conditional,
|
||||||
)? {
|
)? {
|
||||||
ConstrainedValue::Boolean(resolved) => resolved,
|
ConstrainedValue::Boolean(resolved) => resolved,
|
||||||
@ -36,7 +36,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type.clone(),
|
||||||
first,
|
first,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
@ -45,7 +45,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
second,
|
second,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -25,13 +25,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
match expression {
|
match expression {
|
||||||
// Variables
|
// Variables
|
||||||
Expression::Identifier(unresolved_variable) => {
|
Expression::Identifier(unresolved_variable) => {
|
||||||
self.evaluate_identifier(file_scope, function_scope, expected_types, unresolved_variable)
|
self.evaluate_identifier(file_scope, function_scope, expected_type, unresolved_variable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values
|
// Values
|
||||||
@ -39,7 +39,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Expression::Boolean(boolean, span) => Ok(ConstrainedValue::Boolean(new_bool_constant(boolean, span)?)),
|
Expression::Boolean(boolean, span) => Ok(ConstrainedValue::Boolean(new_bool_constant(boolean, span)?)),
|
||||||
Expression::Field(field, span) => Ok(ConstrainedValue::Field(FieldType::constant(field, span)?)),
|
Expression::Field(field, span) => Ok(ConstrainedValue::Field(FieldType::constant(field, span)?)),
|
||||||
Expression::Group(group_affine, span) => Ok(ConstrainedValue::Group(G::constant(group_affine, span)?)),
|
Expression::Group(group_affine, span) => Ok(ConstrainedValue::Group(G::constant(group_affine, span)?)),
|
||||||
Expression::Implicit(value, span) => Ok(enforce_number_implicit(expected_types, value, span)?),
|
Expression::Implicit(value, span) => Ok(enforce_number_implicit(expected_type, value, span)?),
|
||||||
Expression::Integer(type_, integer, span) => {
|
Expression::Integer(type_, integer, span) => {
|
||||||
Ok(ConstrainedValue::Integer(Integer::new_constant(&type_, integer, span)?))
|
Ok(ConstrainedValue::Integer(Integer::new_constant(&type_, integer, span)?))
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
// Binary operations
|
// Binary operations
|
||||||
Expression::Negate(expression, span) => {
|
Expression::Negate(expression, span) => {
|
||||||
let resolved_value =
|
let resolved_value =
|
||||||
self.enforce_expression(cs, file_scope, function_scope, expected_types, *expression)?;
|
self.enforce_expression(cs, file_scope, function_scope, expected_type, *expression)?;
|
||||||
|
|
||||||
enforce_negate(cs, resolved_value, span)
|
enforce_negate(cs, resolved_value, span)
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -69,7 +69,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -82,7 +82,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -95,7 +95,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -108,7 +108,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -119,7 +119,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
// Boolean operations
|
// Boolean operations
|
||||||
Expression::Not(expression, span) => Ok(evaluate_not(
|
Expression::Not(expression, span) => Ok(evaluate_not(
|
||||||
self.enforce_expression(cs, file_scope, function_scope, expected_types, *expression)?,
|
self.enforce_expression(cs, file_scope, function_scope, expected_type, *expression)?,
|
||||||
span,
|
span,
|
||||||
)?),
|
)?),
|
||||||
Expression::Or(left, right, span) => {
|
Expression::Or(left, right, span) => {
|
||||||
@ -127,7 +127,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -140,7 +140,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -153,7 +153,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![],
|
None,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -166,7 +166,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![],
|
None,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -179,7 +179,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![],
|
None,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -192,7 +192,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![],
|
None,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -205,7 +205,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![],
|
None,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
@ -219,7 +219,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope,
|
file_scope,
|
||||||
function_scope,
|
function_scope,
|
||||||
expected_types,
|
expected_type,
|
||||||
*conditional,
|
*conditional,
|
||||||
*first,
|
*first,
|
||||||
*second,
|
*second,
|
||||||
@ -228,10 +228,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
// Arrays
|
// Arrays
|
||||||
Expression::Array(array, span) => {
|
Expression::Array(array, span) => {
|
||||||
self.enforce_array(cs, file_scope, function_scope, expected_types, array, span)
|
self.enforce_array(cs, file_scope, function_scope, expected_type, array, span)
|
||||||
}
|
}
|
||||||
Expression::ArrayAccess(array, index, span) => {
|
Expression::ArrayAccess(array, index, span) => {
|
||||||
self.enforce_array_access(cs, file_scope, function_scope, expected_types, array, *index, span)
|
self.enforce_array_access(cs, file_scope, function_scope, expected_type, array, *index, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuples
|
||||||
|
Expression::Tuple(tuple, span) => {
|
||||||
|
self.enforce_tuple(cs, file_scope, function_scope, expected_type, tuple, span)
|
||||||
|
}
|
||||||
|
Expression::TupleAccess(tuple, index, span) => {
|
||||||
|
self.enforce_tuple_access(cs, file_scope, function_scope, expected_type, tuple, index, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Circuits
|
// Circuits
|
||||||
@ -242,7 +250,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope,
|
file_scope,
|
||||||
function_scope,
|
function_scope,
|
||||||
expected_types,
|
expected_type,
|
||||||
circuit_variable,
|
circuit_variable,
|
||||||
circuit_member,
|
circuit_member,
|
||||||
span,
|
span,
|
||||||
@ -252,7 +260,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope,
|
file_scope,
|
||||||
function_scope,
|
function_scope,
|
||||||
expected_types,
|
expected_type,
|
||||||
circuit_identifier,
|
circuit_identifier,
|
||||||
circuit_member,
|
circuit_member,
|
||||||
span,
|
span,
|
||||||
@ -263,7 +271,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope,
|
file_scope,
|
||||||
function_scope,
|
function_scope,
|
||||||
expected_types,
|
expected_type,
|
||||||
function,
|
function,
|
||||||
arguments,
|
arguments,
|
||||||
span,
|
span,
|
||||||
|
@ -14,7 +14,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
function: Box<Expression>,
|
function: Box<Expression>,
|
||||||
arguments: Vec<Expression>,
|
arguments: Vec<Expression>,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -23,7 +23,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
expected_types,
|
expected_type,
|
||||||
*function.clone(),
|
*function.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -36,22 +36,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span.start,
|
span.start,
|
||||||
);
|
);
|
||||||
|
|
||||||
match self.enforce_function(
|
self.enforce_function(
|
||||||
&mut cs.ns(|| name_unique),
|
&mut cs.ns(|| name_unique),
|
||||||
outer_scope,
|
outer_scope,
|
||||||
function_scope,
|
function_scope,
|
||||||
function_call,
|
function_call,
|
||||||
arguments,
|
arguments,
|
||||||
) {
|
)
|
||||||
Ok(ConstrainedValue::Return(return_values)) => {
|
.map_err(|error| ExpressionError::from(Box::new(error)))
|
||||||
if return_values.len() == 1 {
|
|
||||||
Ok(return_values[0].clone())
|
|
||||||
} else {
|
|
||||||
Ok(ConstrainedValue::Return(return_values))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(_) => Err(ExpressionError::function_no_return(function.to_string(), span)),
|
|
||||||
Err(error) => Err(ExpressionError::from(Box::new(error))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
unresolved_identifier: Identifier,
|
unresolved_identifier: Identifier,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
// Evaluate the identifier name in the current function scope
|
// Evaluate the identifier name in the current function scope
|
||||||
@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
} else if let Some(value) = self.get(&unresolved_identifier.name) {
|
} else if let Some(value) = self.get(&unresolved_identifier.name) {
|
||||||
// Check imported file scope
|
// Check imported file scope
|
||||||
value.clone()
|
value.clone()
|
||||||
} else if expected_types.contains(&Type::Address) {
|
} else if expected_type.is_some() && expected_type.unwrap() == Type::Address {
|
||||||
// If we expect an address type, try to return an address
|
// If we expect an address type, try to return an address
|
||||||
let address = Address::new(unresolved_identifier.name, unresolved_identifier.span)?;
|
let address = Address::new(unresolved_identifier.name, unresolved_identifier.span)?;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
|
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
|
||||||
};
|
};
|
||||||
|
|
||||||
result_value.resolve_type(expected_types, unresolved_identifier.span.clone())?;
|
result_value.resolve_type(expected_type, unresolved_identifier.span.clone())?;
|
||||||
|
|
||||||
Ok(result_value)
|
Ok(result_value)
|
||||||
}
|
}
|
||||||
|
@ -29,3 +29,6 @@ pub use self::logical::*;
|
|||||||
|
|
||||||
pub mod relational;
|
pub mod relational;
|
||||||
pub use self::relational::*;
|
pub use self::relational::*;
|
||||||
|
|
||||||
|
pub mod tuple;
|
||||||
|
pub use self::tuple::*;
|
||||||
|
40
compiler/src/expression/tuple/access.rs
Normal file
40
compiler/src/expression/tuple/access.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//! Enforces array access in a compiled Leo program.
|
||||||
|
|
||||||
|
use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||||
|
use leo_typed::{Expression, Span, Type};
|
||||||
|
|
||||||
|
use snarkos_models::{
|
||||||
|
curves::{Field, PrimeField},
|
||||||
|
gadgets::r1cs::ConstraintSystem,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
pub fn enforce_tuple_access<CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
file_scope: String,
|
||||||
|
function_scope: String,
|
||||||
|
expected_type: Option<Type>,
|
||||||
|
tuple: Box<Expression>,
|
||||||
|
index: usize,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
|
let tuple = match self.enforce_operand(
|
||||||
|
cs,
|
||||||
|
file_scope.clone(),
|
||||||
|
function_scope.clone(),
|
||||||
|
expected_type,
|
||||||
|
*tuple,
|
||||||
|
span.clone(),
|
||||||
|
)? {
|
||||||
|
ConstrainedValue::Tuple(tuple) => tuple,
|
||||||
|
value => return Err(ExpressionError::undefined_array(value.to_string(), span.clone())),
|
||||||
|
};
|
||||||
|
|
||||||
|
if index > tuple.len() - 1 {
|
||||||
|
return Err(ExpressionError::index_out_of_bounds(index, span));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(tuple[index].to_owned())
|
||||||
|
}
|
||||||
|
}
|
7
compiler/src/expression/tuple/mod.rs
Normal file
7
compiler/src/expression/tuple/mod.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
//! Methods to enforce tuple expressions in a compiled Leo program.
|
||||||
|
|
||||||
|
pub mod access;
|
||||||
|
pub use self::access::*;
|
||||||
|
|
||||||
|
pub mod tuple;
|
||||||
|
pub use self::tuple::*;
|
53
compiler/src/expression/tuple/tuple.rs
Normal file
53
compiler/src/expression/tuple/tuple.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//! Enforces an tuple expression in a compiled Leo program.
|
||||||
|
|
||||||
|
use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||||
|
use leo_typed::{Expression, Span, Type};
|
||||||
|
|
||||||
|
use snarkos_models::{
|
||||||
|
curves::{Field, PrimeField},
|
||||||
|
gadgets::r1cs::ConstraintSystem,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
/// Enforce tuple expressions
|
||||||
|
pub fn enforce_tuple<CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
file_scope: String,
|
||||||
|
function_scope: String,
|
||||||
|
expected_type: Option<Type>,
|
||||||
|
tuple: Vec<Expression>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
|
// Check explicit tuple type dimension if given
|
||||||
|
let mut expected_types = vec![];
|
||||||
|
|
||||||
|
if expected_type.is_some() {
|
||||||
|
match expected_type.unwrap() {
|
||||||
|
Type::Tuple(ref types) => {
|
||||||
|
expected_types = types.clone();
|
||||||
|
}
|
||||||
|
ref type_ => {
|
||||||
|
return Err(ExpressionError::unexpected_tuple(
|
||||||
|
type_.to_string(),
|
||||||
|
format!("{:?}", tuple),
|
||||||
|
span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = vec![];
|
||||||
|
for (i, expression) in tuple.into_iter().enumerate() {
|
||||||
|
let type_ = if expected_types.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(expected_types[i].clone())
|
||||||
|
};
|
||||||
|
|
||||||
|
result.push(self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), type_, expression)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ConstrainedValue::Tuple(result))
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
GroupType,
|
GroupType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use leo_typed::{Expression, Function, InputVariable, Span};
|
use leo_typed::{Expression, Function, InputVariable, Span, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
@ -46,7 +46,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
scope.clone(),
|
scope.clone(),
|
||||||
caller_scope.clone(),
|
caller_scope.clone(),
|
||||||
function_name.clone(),
|
function_name.clone(),
|
||||||
vec![],
|
None,
|
||||||
input_expression,
|
input_expression,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
scope.clone(),
|
scope.clone(),
|
||||||
caller_scope.clone(),
|
caller_scope.clone(),
|
||||||
function_name.clone(),
|
function_name.clone(),
|
||||||
vec![input_model.type_.clone()],
|
Some(input_model.type_.clone()),
|
||||||
input_expression,
|
input_expression,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -93,14 +93,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Conditionally select a result based on returned indicators
|
// Conditionally select a result based on returned indicators
|
||||||
let mut return_values = ConstrainedValue::Return(vec![]);
|
let mut return_values = ConstrainedValue::Tuple(vec![]);
|
||||||
|
|
||||||
Self::conditionally_select_result(cs, &mut return_values, results, function.span.clone())?;
|
Self::conditionally_select_result(cs, &mut return_values, results, function.span.clone())?;
|
||||||
|
|
||||||
if let ConstrainedValue::Return(ref returns) = return_values {
|
if let ConstrainedValue::Tuple(ref returns) = return_values {
|
||||||
if function.returns.len() != returns.len() {
|
let return_types = match function.returns {
|
||||||
|
Some(Type::Tuple(types)) => types.len(),
|
||||||
|
Some(_) => 1usize,
|
||||||
|
None => 0usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
if return_types != returns.len() {
|
||||||
return Err(FunctionError::return_arguments_length(
|
return Err(FunctionError::return_arguments_length(
|
||||||
function.returns.len(),
|
return_types,
|
||||||
returns.len(),
|
returns.len(),
|
||||||
function.span.clone(),
|
function.span.clone(),
|
||||||
));
|
));
|
||||||
|
@ -16,16 +16,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
scope: String,
|
scope: String,
|
||||||
caller_scope: String,
|
caller_scope: String,
|
||||||
function_name: String,
|
function_name: String,
|
||||||
expected_types: Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
input: Expression,
|
input: Expression,
|
||||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||||
// Evaluate the function input value as pass by value from the caller or
|
// Evaluate the function input value as pass by value from the caller or
|
||||||
// evaluate as an expression in the current function scope
|
// evaluate as an expression in the current function scope
|
||||||
match input {
|
match input {
|
||||||
Expression::Identifier(identifier) => {
|
Expression::Identifier(identifier) => {
|
||||||
Ok(self.evaluate_identifier(caller_scope, function_name, &expected_types, identifier)?)
|
Ok(self.evaluate_identifier(caller_scope, function_name, expected_type, identifier)?)
|
||||||
}
|
}
|
||||||
expression => Ok(self.enforce_expression(cs, scope, function_name, &expected_types, expression)?),
|
expression => Ok(self.enforce_expression(cs, scope, function_name, expected_type, expression)?),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
input_option,
|
input_option,
|
||||||
span,
|
span,
|
||||||
)?)),
|
)?)),
|
||||||
Type::Array(_type, dimensions) => self.allocate_array(cs, name, *_type, dimensions, input_option, span),
|
Type::Array(type_, dimensions) => self.allocate_array(cs, name, *type_, dimensions, input_option, span),
|
||||||
|
Type::Tuple(types) => self.allocate_tuple(cs, name, types, input_option, span),
|
||||||
_ => unimplemented!("main function input not implemented for type"),
|
_ => unimplemented!("main function input not implemented for type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,3 +14,6 @@ pub use self::input_keyword::*;
|
|||||||
|
|
||||||
pub mod input_section;
|
pub mod input_section;
|
||||||
pub use self::input_section::*;
|
pub use self::input_section::*;
|
||||||
|
|
||||||
|
pub mod tuple;
|
||||||
|
pub use self::tuple::*;
|
||||||
|
56
compiler/src/function/input/tuple.rs
Normal file
56
compiler/src/function/input/tuple.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//! Allocates an array as a main function input parameter in a compiled Leo program.
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
errors::FunctionError,
|
||||||
|
program::{new_scope, ConstrainedProgram},
|
||||||
|
value::ConstrainedValue,
|
||||||
|
GroupType,
|
||||||
|
};
|
||||||
|
|
||||||
|
use leo_typed::{InputValue, Span, Type};
|
||||||
|
|
||||||
|
use snarkos_models::{
|
||||||
|
curves::{Field, PrimeField},
|
||||||
|
gadgets::r1cs::ConstraintSystem,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
pub fn allocate_tuple<CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
name: String,
|
||||||
|
types: Vec<Type>,
|
||||||
|
input_value: Option<InputValue>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||||
|
let mut tuple_values = vec![];
|
||||||
|
|
||||||
|
match input_value {
|
||||||
|
Some(InputValue::Tuple(values)) => {
|
||||||
|
// Allocate each value in the tuple
|
||||||
|
for (i, (value, type_)) in values.into_iter().zip(types.into_iter()).enumerate() {
|
||||||
|
let value_name = new_scope(name.clone(), i.to_string());
|
||||||
|
|
||||||
|
tuple_values.push(self.allocate_main_function_input(
|
||||||
|
cs,
|
||||||
|
type_,
|
||||||
|
value_name,
|
||||||
|
Some(value),
|
||||||
|
span.clone(),
|
||||||
|
)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// Allocate all tuple values as none
|
||||||
|
for (i, type_) in types.into_iter().enumerate() {
|
||||||
|
let value_name = new_scope(name.clone(), i.to_string());
|
||||||
|
|
||||||
|
tuple_values.push(self.allocate_main_function_input(cs, type_, value_name, None, span.clone())?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return Err(FunctionError::invalid_tuple(input_value.unwrap().to_string(), span)),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ConstrainedValue::Tuple(tuple_values))
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![],
|
None,
|
||||||
parameter.expression,
|
parameter.expression,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ impl OutputBytes {
|
|||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<Self, OutputBytesError> {
|
) -> Result<Self, OutputBytesError> {
|
||||||
let return_values = match value {
|
let return_values = match value {
|
||||||
ConstrainedValue::Return(values) => values,
|
ConstrainedValue::Tuple(values) => values,
|
||||||
value => return Err(OutputBytesError::illegal_return(value.to_string(), span)),
|
value => vec![value],
|
||||||
};
|
};
|
||||||
let register_hashmap = registers.values();
|
let register_hashmap = registers.values();
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
// Modify the single value of the array in place
|
// Modify the single value of the array in place
|
||||||
match self.get_mutable_assignee(name, span.clone())? {
|
match self.get_mutable_assignee(name, span.clone())? {
|
||||||
ConstrainedValue::Array(old) => {
|
ConstrainedValue::Array(old) => {
|
||||||
new_value.resolve_type(&vec![old[index].to_type(span.clone())?], span.clone())?;
|
new_value.resolve_type(Some(old[index].to_type(span.clone())?), span.clone())?;
|
||||||
|
|
||||||
let name_unique = format!("select {} {}:{}", new_value, span.line, span.start);
|
let name_unique = format!("select {} {}:{}", new_value, span.line, span.start);
|
||||||
let selected_value = ConstrainedValue::conditionally_select(
|
let selected_value = ConstrainedValue::conditionally_select(
|
||||||
|
@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
// Evaluate new value
|
// Evaluate new value
|
||||||
let mut new_value =
|
let mut new_value =
|
||||||
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), &vec![], expression)?;
|
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), None, expression)?;
|
||||||
|
|
||||||
// Mutate the old value into the new value
|
// Mutate the old value into the new value
|
||||||
match assignee {
|
match assignee {
|
||||||
@ -41,7 +41,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||||
let old_value = self.get_mutable_assignee(variable_name.clone(), span.clone())?;
|
let old_value = self.get_mutable_assignee(variable_name.clone(), span.clone())?;
|
||||||
|
|
||||||
new_value.resolve_type(&vec![old_value.to_type(span.clone())?], span.clone())?;
|
new_value.resolve_type(Some(old_value.to_type(span.clone())?), span.clone())?;
|
||||||
|
|
||||||
let name_unique = format!("select {} {}:{}", new_value, span.line, span.start);
|
let name_unique = format!("select {} {}:{}", new_value, span.line, span.start);
|
||||||
let selected_value =
|
let selected_value =
|
||||||
@ -62,6 +62,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
new_value,
|
new_value,
|
||||||
span,
|
span,
|
||||||
),
|
),
|
||||||
|
Assignee::Tuple(_tuple, index) => self.assign_tuple(cs, indicator, variable_name, index, new_value, span),
|
||||||
Assignee::CircuitField(_assignee, object_name) => {
|
Assignee::CircuitField(_assignee, object_name) => {
|
||||||
self.mutute_circuit_field(cs, indicator, variable_name, object_name, new_value, span)
|
self.mutute_circuit_field(cs, indicator, variable_name, object_name, new_value, span)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ pub fn resolve_assignee(scope: String, assignee: Assignee) -> String {
|
|||||||
match assignee {
|
match assignee {
|
||||||
Assignee::Identifier(name) => new_scope(scope, name.to_string()),
|
Assignee::Identifier(name) => new_scope(scope, name.to_string()),
|
||||||
Assignee::Array(array, _index) => resolve_assignee(scope, *array),
|
Assignee::Array(array, _index) => resolve_assignee(scope, *array),
|
||||||
|
Assignee::Tuple(tuple, _index) => resolve_assignee(scope, *tuple),
|
||||||
Assignee::CircuitField(circuit_name, _member) => resolve_assignee(scope, *circuit_name),
|
Assignee::CircuitField(circuit_name, _member) => resolve_assignee(scope, *circuit_name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
return Err(StatementError::immutable_circuit_function("static".into(), span));
|
return Err(StatementError::immutable_circuit_function("static".into(), span));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
new_value.resolve_type(&vec![object.1.to_type(span.clone())?], span.clone())?;
|
new_value.resolve_type(Some(object.1.to_type(span.clone())?), span.clone())?;
|
||||||
|
|
||||||
let name_unique = format!("select {} {}:{}", new_value, span.line, span.start);
|
let name_unique = format!("select {} {}:{}", new_value, span.line, span.start);
|
||||||
let selected_value = ConstrainedValue::conditionally_select(
|
let selected_value = ConstrainedValue::conditionally_select(
|
||||||
|
@ -11,3 +11,6 @@ pub use self::assignee::*;
|
|||||||
|
|
||||||
pub mod circuit_field;
|
pub mod circuit_field;
|
||||||
pub use self::circuit_field::*;
|
pub use self::circuit_field::*;
|
||||||
|
|
||||||
|
pub mod tuple;
|
||||||
|
pub use self::tuple::*;
|
||||||
|
45
compiler/src/statement/assign/tuple.rs
Normal file
45
compiler/src/statement/assign/tuple.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//! Enforces a tuple assignment statement in a compiled Leo program.
|
||||||
|
|
||||||
|
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||||
|
use leo_typed::Span;
|
||||||
|
|
||||||
|
use snarkos_models::{
|
||||||
|
curves::{Field, PrimeField},
|
||||||
|
gadgets::{
|
||||||
|
r1cs::ConstraintSystem,
|
||||||
|
utilities::{boolean::Boolean, select::CondSelectGadget},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
pub fn assign_tuple<CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
indicator: Option<Boolean>,
|
||||||
|
name: String,
|
||||||
|
index: usize,
|
||||||
|
mut new_value: ConstrainedValue<F, G>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<(), StatementError> {
|
||||||
|
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||||
|
|
||||||
|
// Modify the single value of the tuple in place
|
||||||
|
match self.get_mutable_assignee(name, span.clone())? {
|
||||||
|
ConstrainedValue::Tuple(old) => {
|
||||||
|
new_value.resolve_type(Some(old[index].to_type(span.clone())?), span.clone())?;
|
||||||
|
|
||||||
|
let name_unique = format!("select {} {}:{}", new_value, span.line, span.start);
|
||||||
|
let selected_value =
|
||||||
|
ConstrainedValue::conditionally_select(cs.ns(|| name_unique), &condition, &new_value, &old[index])
|
||||||
|
.map_err(|_| {
|
||||||
|
StatementError::select_fail(new_value.to_string(), old[index].to_string(), span)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
old[index] = selected_value;
|
||||||
|
}
|
||||||
|
_ => return Err(StatementError::tuple_assign_index(span)),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope: String,
|
function_scope: String,
|
||||||
indicator: Option<Boolean>,
|
indicator: Option<Boolean>,
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
return_types: Vec<Type>,
|
return_type: Option<Type>,
|
||||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
// Evaluate statements. Only allow a single return argument to be returned.
|
// Evaluate statements. Only allow a single return argument to be returned.
|
||||||
@ -27,7 +27,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
indicator.clone(),
|
indicator.clone(),
|
||||||
statement.clone(),
|
statement.clone(),
|
||||||
return_types.clone(),
|
return_type.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
results.append(&mut value);
|
results.append(&mut value);
|
||||||
|
@ -27,7 +27,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope: String,
|
function_scope: String,
|
||||||
indicator: Option<Boolean>,
|
indicator: Option<Boolean>,
|
||||||
statement: ConditionalStatement,
|
statement: ConditionalStatement,
|
||||||
return_types: Vec<Type>,
|
return_type: Option<Type>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
||||||
let statement_string = statement.to_string();
|
let statement_string = statement.to_string();
|
||||||
@ -40,7 +40,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
&vec![Type::Boolean],
|
Some(Type::Boolean),
|
||||||
statement.condition.clone(),
|
statement.condition.clone(),
|
||||||
)? {
|
)? {
|
||||||
ConstrainedValue::Boolean(resolved) => resolved,
|
ConstrainedValue::Boolean(resolved) => resolved,
|
||||||
@ -70,7 +70,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
Some(branch_1_indicator),
|
Some(branch_1_indicator),
|
||||||
statement.statements,
|
statement.statements,
|
||||||
return_types.clone(),
|
return_type.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
results.append(&mut branch_1_result);
|
results.append(&mut branch_1_result);
|
||||||
@ -98,7 +98,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope,
|
function_scope,
|
||||||
Some(branch_2_indicator),
|
Some(branch_2_indicator),
|
||||||
*nested,
|
*nested,
|
||||||
return_types,
|
return_type,
|
||||||
span,
|
span,
|
||||||
)?,
|
)?,
|
||||||
ConditionalNestedOrEndStatement::End(statements) => self.evaluate_branch(
|
ConditionalNestedOrEndStatement::End(statements) => self.evaluate_branch(
|
||||||
@ -107,7 +107,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope,
|
function_scope,
|
||||||
Some(branch_2_indicator),
|
Some(branch_2_indicator),
|
||||||
statements,
|
statements,
|
||||||
return_types,
|
return_type,
|
||||||
)?,
|
)?,
|
||||||
},
|
},
|
||||||
None => vec![],
|
None => vec![],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Enforces a definition statement in a compiled Leo program.
|
//! Enforces a definition statement in a compiled Leo program.
|
||||||
|
|
||||||
use crate::{errors::StatementError, program::ConstrainedProgram, GroupType};
|
use crate::{errors::StatementError, program::ConstrainedProgram, ConstrainedValue, GroupType};
|
||||||
use leo_typed::{Declare, Expression, Span, Variable};
|
use leo_typed::{Declare, Expression, Span, Type, VariableName, Variables};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
@ -9,39 +9,186 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
fn enforce_single_definition<CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
function_scope: String,
|
||||||
|
is_constant: bool,
|
||||||
|
variable_name: VariableName,
|
||||||
|
mut value: ConstrainedValue<F, G>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<(), StatementError> {
|
||||||
|
if is_constant && variable_name.mutable {
|
||||||
|
return Err(StatementError::immutable_assign(variable_name.to_string(), span));
|
||||||
|
} else {
|
||||||
|
value.allocate_value(cs, span)?
|
||||||
|
}
|
||||||
|
|
||||||
|
self.store_definition(function_scope, variable_name.mutable, variable_name.identifier, value);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enforce_expressions<CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
file_scope: String,
|
||||||
|
function_scope: String,
|
||||||
|
type_: Option<Type>,
|
||||||
|
expressions: Vec<Expression>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<Vec<ConstrainedValue<F, G>>, StatementError> {
|
||||||
|
let types = match type_ {
|
||||||
|
Some(Type::Tuple(types)) => types,
|
||||||
|
Some(type_) => return Err(StatementError::tuple_type(type_.to_string(), span.clone())),
|
||||||
|
None => vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
let implicit_types = types.is_empty();
|
||||||
|
let mut expected_types = vec![];
|
||||||
|
|
||||||
|
for i in 0..expressions.len() {
|
||||||
|
let expected_type = if implicit_types { None } else { Some(types[i].clone()) };
|
||||||
|
|
||||||
|
expected_types.push(expected_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut values = vec![];
|
||||||
|
|
||||||
|
for (expression, expected_type) in expressions.into_iter().zip(expected_types.into_iter()) {
|
||||||
|
let value = self.enforce_expression(
|
||||||
|
cs,
|
||||||
|
file_scope.clone(),
|
||||||
|
function_scope.clone(),
|
||||||
|
expected_type,
|
||||||
|
expression,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enforce_tuple_definition<CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
file_scope: String,
|
||||||
|
function_scope: String,
|
||||||
|
is_constant: bool,
|
||||||
|
variables: Variables,
|
||||||
|
expressions: Vec<Expression>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<(), StatementError> {
|
||||||
|
let values = self.enforce_expressions(
|
||||||
|
cs,
|
||||||
|
file_scope,
|
||||||
|
function_scope.clone(),
|
||||||
|
variables.type_.clone(),
|
||||||
|
expressions,
|
||||||
|
span.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let tuple = ConstrainedValue::Tuple(values);
|
||||||
|
let variable = variables.names[0].clone();
|
||||||
|
|
||||||
|
self.enforce_single_definition(cs, function_scope, is_constant, variable, tuple, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enforce_multiple_definition<CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
function_scope: String,
|
||||||
|
is_constant: bool,
|
||||||
|
variables: Variables,
|
||||||
|
values: Vec<ConstrainedValue<F, G>>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<(), StatementError> {
|
||||||
|
if values.len() != variables.names.len() {
|
||||||
|
return Err(StatementError::invalid_number_of_definitions(
|
||||||
|
values.len(),
|
||||||
|
variables.names.len(),
|
||||||
|
span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (variable, value) in variables.names.into_iter().zip(values.into_iter()) {
|
||||||
|
self.enforce_single_definition(cs, function_scope.clone(), is_constant, variable, value, span.clone())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn enforce_definition_statement<CS: ConstraintSystem<F>>(
|
pub fn enforce_definition_statement<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
declare: Declare,
|
declare: Declare,
|
||||||
variable: Variable,
|
variables: Variables,
|
||||||
expression: Expression,
|
expressions: Vec<Expression>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<(), StatementError> {
|
) -> Result<(), StatementError> {
|
||||||
let mut expected_types = vec![];
|
let num_variables = variables.names.len();
|
||||||
if let Some(ref _type) = variable._type {
|
let num_values = expressions.len();
|
||||||
expected_types.push(_type.clone());
|
let is_constant = match declare {
|
||||||
|
Declare::Let => false,
|
||||||
|
Declare::Const => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if num_variables == 1 && num_values == 1 {
|
||||||
|
// Define a single variable with a single value
|
||||||
|
|
||||||
|
let variable = variables.names[0].clone();
|
||||||
|
let expression = self.enforce_expression(
|
||||||
|
cs,
|
||||||
|
file_scope.clone(),
|
||||||
|
function_scope.clone(),
|
||||||
|
variables.type_,
|
||||||
|
expressions[0].clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
self.enforce_single_definition(cs, function_scope, is_constant, variable, expression, span)
|
||||||
|
} else if num_variables == 1 && num_values > 1 {
|
||||||
|
// Define a tuple (single variable with multiple values)
|
||||||
|
|
||||||
|
self.enforce_tuple_definition(
|
||||||
|
cs,
|
||||||
|
file_scope,
|
||||||
|
function_scope,
|
||||||
|
is_constant,
|
||||||
|
variables,
|
||||||
|
expressions,
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
} else if num_variables > 1 && num_values == 1 {
|
||||||
|
// Define multiple variables for an expression that returns multiple results (multiple definition)
|
||||||
|
|
||||||
|
let values = match self.enforce_expression(
|
||||||
|
cs,
|
||||||
|
file_scope.clone(),
|
||||||
|
function_scope.clone(),
|
||||||
|
variables.type_.clone(),
|
||||||
|
expressions[0].clone(),
|
||||||
|
)? {
|
||||||
|
// ConstrainedValue::Return(values) => values,
|
||||||
|
ConstrainedValue::Tuple(values) => values,
|
||||||
|
value => return Err(StatementError::multiple_definition(value.to_string(), span.clone())),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.enforce_multiple_definition(cs, function_scope, is_constant, variables, values, span)
|
||||||
|
} else {
|
||||||
|
// Define multiple variables for multiple expressions
|
||||||
|
let values = self.enforce_expressions(
|
||||||
|
cs,
|
||||||
|
file_scope,
|
||||||
|
function_scope.clone(),
|
||||||
|
variables.type_.clone(),
|
||||||
|
expressions,
|
||||||
|
span.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
self.enforce_multiple_definition(cs, function_scope, is_constant, variables, values, span)
|
||||||
}
|
}
|
||||||
let mut value = self.enforce_expression(
|
|
||||||
cs,
|
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
&expected_types,
|
|
||||||
expression,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
match declare {
|
|
||||||
Declare::Let => value.allocate_value(cs, span)?,
|
|
||||||
Declare::Const => {
|
|
||||||
if variable.mutable {
|
|
||||||
return Err(StatementError::immutable_assign(variable.to_string(), span));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.store_definition(function_scope, variable, value);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,3 @@
|
|||||||
|
|
||||||
pub mod definition;
|
pub mod definition;
|
||||||
pub use self::definition::*;
|
pub use self::definition::*;
|
||||||
|
|
||||||
pub mod multiple;
|
|
||||||
pub use self::multiple::*;
|
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
//! Enforces a multiple definition statement in a compiled Leo program.
|
|
||||||
|
|
||||||
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
|
||||||
use leo_typed::{Expression, Span, Variable};
|
|
||||||
|
|
||||||
use snarkos_models::{
|
|
||||||
curves::{Field, PrimeField},
|
|
||||||
gadgets::r1cs::ConstraintSystem,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|
||||||
pub fn enforce_multiple_definition_statement<CS: ConstraintSystem<F>>(
|
|
||||||
&mut self,
|
|
||||||
cs: &mut CS,
|
|
||||||
file_scope: String,
|
|
||||||
function_scope: String,
|
|
||||||
variables: Vec<Variable>,
|
|
||||||
function: Expression,
|
|
||||||
span: Span,
|
|
||||||
) -> Result<(), StatementError> {
|
|
||||||
let mut expected_types = vec![];
|
|
||||||
for variable in variables.iter() {
|
|
||||||
if let Some(ref _type) = variable._type {
|
|
||||||
expected_types.push(_type.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expect return values from function
|
|
||||||
let return_values = match self.enforce_expression(
|
|
||||||
cs,
|
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
&expected_types,
|
|
||||||
function,
|
|
||||||
)? {
|
|
||||||
ConstrainedValue::Return(values) => values,
|
|
||||||
value => unimplemented!("multiple assignment only implemented for functions, got {}", value),
|
|
||||||
};
|
|
||||||
|
|
||||||
if variables.len() != return_values.len() {
|
|
||||||
return Err(StatementError::invalid_number_of_definitions(
|
|
||||||
variables.len(),
|
|
||||||
return_values.len(),
|
|
||||||
span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (variable, value) in variables.into_iter().zip(return_values.into_iter()) {
|
|
||||||
self.store_definition(function_scope.clone(), variable, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,7 +29,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
start: Expression,
|
start: Expression,
|
||||||
stop: Expression,
|
stop: Expression,
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
return_types: Vec<Type>,
|
return_type: Option<Type>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
@ -40,6 +40,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
for i in from..to {
|
for i in from..to {
|
||||||
// Store index in current function scope.
|
// Store index in current function scope.
|
||||||
// For loop scope is not implemented.
|
// For loop scope is not implemented.
|
||||||
|
|
||||||
let index_name = new_scope(function_scope.clone(), index.to_string());
|
let index_name = new_scope(function_scope.clone(), index.to_string());
|
||||||
|
|
||||||
self.store(
|
self.store(
|
||||||
@ -55,7 +56,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
indicator,
|
indicator,
|
||||||
statements.clone(),
|
statements.clone(),
|
||||||
return_types.clone(),
|
return_type.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
results.append(&mut result);
|
results.append(&mut result);
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
//! Enforces a return statement in a compiled Leo program.
|
//! Enforces a return statement in a compiled Leo program.
|
||||||
|
|
||||||
use crate::{
|
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||||
errors::{StatementError, ValueError},
|
|
||||||
program::ConstrainedProgram,
|
|
||||||
value::ConstrainedValue,
|
|
||||||
GroupType,
|
|
||||||
};
|
|
||||||
use leo_typed::{Expression, Span, Type};
|
use leo_typed::{Expression, Span, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
@ -13,25 +8,20 @@ use snarkos_models::{
|
|||||||
gadgets::r1cs::ConstraintSystem,
|
gadgets::r1cs::ConstraintSystem,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn check_return_types(expected: &Vec<Type>, actual: &Vec<Type>, span: Span) -> Result<(), StatementError> {
|
fn check_return_type(expected: Option<Type>, actual: Type, span: Span) -> Result<(), StatementError> {
|
||||||
expected
|
match expected {
|
||||||
.iter()
|
Some(expected) => {
|
||||||
.zip(actual.iter())
|
if expected.ne(&actual) {
|
||||||
.map(|(type_1, type_2)| {
|
if expected.is_self() && actual.is_circuit() {
|
||||||
if type_1.ne(type_2) {
|
return Ok(());
|
||||||
// catch return Self type
|
|
||||||
if type_1.is_self() && type_2.is_circuit() {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
} else {
|
||||||
Err(StatementError::arguments_type(type_1, type_2, span.clone()))
|
return Err(StatementError::arguments_type(&expected, &actual, span));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
})
|
Ok(())
|
||||||
.collect::<Result<Vec<()>, StatementError>>()?;
|
}
|
||||||
|
None => Ok(()),
|
||||||
Ok(())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
@ -40,41 +30,23 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
expressions: Vec<Expression>,
|
expression: Expression,
|
||||||
return_types: Vec<Type>,
|
return_type: Option<Type>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, StatementError> {
|
) -> Result<ConstrainedValue<F, G>, StatementError> {
|
||||||
// Make sure we return the correct number of values
|
// Make sure we return the correct number of values
|
||||||
if return_types.len() != expressions.len() {
|
|
||||||
return Err(StatementError::invalid_number_of_returns(
|
|
||||||
return_types.len(),
|
|
||||||
expressions.len(),
|
|
||||||
span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut returns = vec![];
|
let result = self.enforce_operand(
|
||||||
for (expression, ty) in expressions.into_iter().zip(return_types.clone().into_iter()) {
|
cs,
|
||||||
let expected_types = vec![ty.clone()];
|
file_scope.clone(),
|
||||||
let result = self.enforce_operand(
|
function_scope.clone(),
|
||||||
cs,
|
return_type.clone(),
|
||||||
file_scope.clone(),
|
expression,
|
||||||
function_scope.clone(),
|
span.clone(),
|
||||||
&expected_types,
|
)?;
|
||||||
expression,
|
|
||||||
span.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
returns.push(result);
|
check_return_type(return_type, result.to_type(span.clone())?, span)?;
|
||||||
}
|
|
||||||
|
|
||||||
let actual_types = returns
|
Ok(result)
|
||||||
.iter()
|
|
||||||
.map(|value| value.to_type(span.clone()))
|
|
||||||
.collect::<Result<Vec<Type>, ValueError>>()?;
|
|
||||||
|
|
||||||
check_return_types(&return_types, &actual_types, span)?;
|
|
||||||
|
|
||||||
Ok(ConstrainedValue::Return(returns))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
/// Enforce a program statement.
|
/// Enforce a program statement.
|
||||||
/// Returns a Vector of (indicator, value) tuples.
|
/// Returns a Vector of (indicator, value) tuples.
|
||||||
/// Each evaluated statement may execute of one or more statements that may return early.
|
/// Each evaluated statement may execute of one or more statements that may return early.
|
||||||
/// To indicate which of these return values to take,
|
/// To indicate which of these return values to take we conditionally select the value according
|
||||||
/// we conditionally select the value according the `indicator` bit that evaluates to true.
|
/// to the `indicator` bit that evaluates to true.
|
||||||
pub fn enforce_statement<CS: ConstraintSystem<F>>(
|
pub fn enforce_statement<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -21,24 +21,29 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope: String,
|
function_scope: String,
|
||||||
indicator: Option<Boolean>,
|
indicator: Option<Boolean>,
|
||||||
statement: Statement,
|
statement: Statement,
|
||||||
return_types: Vec<Type>,
|
return_type: Option<Type>,
|
||||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
|
|
||||||
match statement {
|
match statement {
|
||||||
Statement::Return(expressions, span) => {
|
Statement::Return(expression, span) => {
|
||||||
let return_value = (
|
let return_value = (
|
||||||
indicator,
|
indicator,
|
||||||
self.enforce_return_statement(cs, file_scope, function_scope, expressions, return_types, span)?,
|
self.enforce_return_statement(cs, file_scope, function_scope, expression, return_type, span)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
results.push(return_value);
|
results.push(return_value);
|
||||||
}
|
}
|
||||||
Statement::Definition(declare, variable, expression, span) => {
|
Statement::Definition(declare, variables, expressions, span) => {
|
||||||
self.enforce_definition_statement(cs, file_scope, function_scope, declare, variable, expression, span)?;
|
self.enforce_definition_statement(
|
||||||
}
|
cs,
|
||||||
Statement::MultipleDefinition(variables, function, span) => {
|
file_scope,
|
||||||
self.enforce_multiple_definition_statement(cs, file_scope, function_scope, variables, function, span)?;
|
function_scope,
|
||||||
|
declare,
|
||||||
|
variables,
|
||||||
|
expressions,
|
||||||
|
span,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
Statement::Assign(variable, expression, span) => {
|
Statement::Assign(variable, expression, span) => {
|
||||||
self.enforce_assign_statement(cs, file_scope, function_scope, indicator, variable, expression, span)?;
|
self.enforce_assign_statement(cs, file_scope, function_scope, indicator, variable, expression, span)?;
|
||||||
@ -50,7 +55,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope,
|
function_scope,
|
||||||
indicator,
|
indicator,
|
||||||
statement,
|
statement,
|
||||||
return_types,
|
return_type,
|
||||||
span,
|
span,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -66,7 +71,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
start,
|
start,
|
||||||
stop,
|
stop,
|
||||||
statements,
|
statements,
|
||||||
return_types,
|
return_type,
|
||||||
span,
|
span,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -74,7 +79,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
}
|
}
|
||||||
Statement::AssertEq(left, right, span) => {
|
Statement::AssertEq(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) =
|
let (resolved_left, resolved_right) =
|
||||||
self.enforce_binary_expression(cs, file_scope, function_scope, &vec![], left, right, span.clone())?;
|
self.enforce_binary_expression(cs, file_scope, function_scope, None, left, right, span.clone())?;
|
||||||
|
|
||||||
self.enforce_assert_eq_statement(cs, indicator, &resolved_left, &resolved_right, span)?;
|
self.enforce_assert_eq_statement(cs, indicator, &resolved_left, &resolved_right, span)?;
|
||||||
}
|
}
|
||||||
@ -83,11 +88,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
}
|
}
|
||||||
Statement::Expression(expression, span) => {
|
Statement::Expression(expression, span) => {
|
||||||
let expression_string = expression.to_string();
|
let expression_string = expression.to_string();
|
||||||
let value = self.enforce_expression(cs, file_scope, function_scope, &vec![], expression)?;
|
let value = self.enforce_expression(cs, file_scope, function_scope, None, expression)?;
|
||||||
|
|
||||||
// handle empty return value cases
|
// handle empty return value cases
|
||||||
match &value {
|
match &value {
|
||||||
ConstrainedValue::Return(values) => {
|
ConstrainedValue::Tuple(values) => {
|
||||||
if !values.is_empty() {
|
if !values.is_empty() {
|
||||||
return Err(StatementError::unassigned(expression_string, span));
|
return Err(StatementError::unassigned(expression_string, span));
|
||||||
}
|
}
|
||||||
|
@ -209,17 +209,10 @@ impl<F: Field + PrimeField> PartialOrd for FieldType<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field + PrimeField> EvaluateEqGadget<F> for FieldType<F> {
|
impl<F: Field + PrimeField> EvaluateEqGadget<F> for FieldType<F> {
|
||||||
fn evaluate_equal<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
fn evaluate_equal<CS: ConstraintSystem<F>>(&self, _cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(FieldType::Constant(first), FieldType::Constant(second)) => Ok(Boolean::constant(first.eq(second))),
|
(FieldType::Constant(first), FieldType::Constant(second)) => Ok(Boolean::constant(first.eq(second))),
|
||||||
(FieldType::Allocated(allocated), FieldType::Constant(constant))
|
_ => unimplemented!(),
|
||||||
| (FieldType::Constant(constant), FieldType::Allocated(allocated)) => {
|
|
||||||
let bool_option = allocated.value.map(|f| f.eq(constant));
|
|
||||||
Boolean::alloc(&mut cs.ns(|| "evaluate_equal"), || {
|
|
||||||
bool_option.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
(FieldType::Allocated(first), FieldType::Allocated(second)) => first.evaluate_equal(cs, second),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,35 +237,12 @@ impl PartialEq for EdwardsGroupType {
|
|||||||
impl Eq for EdwardsGroupType {}
|
impl Eq for EdwardsGroupType {}
|
||||||
|
|
||||||
impl EvaluateEqGadget<Fq> for EdwardsGroupType {
|
impl EvaluateEqGadget<Fq> for EdwardsGroupType {
|
||||||
fn evaluate_equal<CS: ConstraintSystem<Fq>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
fn evaluate_equal<CS: ConstraintSystem<Fq>>(&self, _cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||||
Ok(Boolean::Constant(self_value == other_value))
|
Ok(Boolean::constant(self_value.eq(other_value)))
|
||||||
}
|
|
||||||
|
|
||||||
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
|
||||||
let bool_option =
|
|
||||||
<EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(self_value)
|
|
||||||
.and_then(|a| {
|
|
||||||
<EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(
|
|
||||||
other_value,
|
|
||||||
)
|
|
||||||
.map(|b| a.eq(&b))
|
|
||||||
});
|
|
||||||
Boolean::alloc(&mut cs.ns(|| "evaluate_equal"), || {
|
|
||||||
bool_option.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
|
||||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
|
||||||
let bool_option =
|
|
||||||
<EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(allocated_value)
|
|
||||||
.map(|a| a.eq(constant_value));
|
|
||||||
Boolean::alloc(&mut cs.ns(|| "evaluate_equal"), || {
|
|
||||||
bool_option.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,12 @@ use leo_typed::{Span, Type};
|
|||||||
use snarkos_models::curves::{Field, PrimeField};
|
use snarkos_models::curves::{Field, PrimeField};
|
||||||
|
|
||||||
pub fn enforce_number_implicit<F: Field + PrimeField, G: GroupType<F>>(
|
pub fn enforce_number_implicit<F: Field + PrimeField, G: GroupType<F>>(
|
||||||
expected_types: &Vec<Type>,
|
expected_type: Option<Type>,
|
||||||
value: String,
|
value: String,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ValueError> {
|
) -> Result<ConstrainedValue<F, G>, ValueError> {
|
||||||
if expected_types.len() == 1 {
|
match expected_type {
|
||||||
return Ok(ConstrainedValue::from_type(value, &expected_types[0], span)?);
|
Some(type_) => Ok(ConstrainedValue::from_type(value, &type_, span)?),
|
||||||
|
None => Ok(ConstrainedValue::Unresolved(value)),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ConstrainedValue::Unresolved(value))
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Conversion of integer declarations to constraints in Leo.
|
//! Conversion of integer declarations to constraints in Leo.
|
||||||
use crate::{errors::IntegerError, integer::macros::IntegerTrait};
|
use crate::{errors::IntegerError, IntegerTrait};
|
||||||
use leo_gadgets::{
|
use leo_gadgets::{
|
||||||
arithmetic::*,
|
arithmetic::*,
|
||||||
bits::comparator::{ComparatorGadget, EvaluateLtGadget},
|
bits::comparator::{ComparatorGadget, EvaluateLtGadget},
|
||||||
@ -17,7 +17,7 @@ use snarkos_models::{
|
|||||||
boolean::Boolean,
|
boolean::Boolean,
|
||||||
eq::{ConditionalEqGadget, EqGadget, EvaluateEqGadget},
|
eq::{ConditionalEqGadget, EqGadget, EvaluateEqGadget},
|
||||||
select::CondSelectGadget,
|
select::CondSelectGadget,
|
||||||
uint::{UInt, UInt128, UInt16, UInt32, UInt64, UInt8},
|
uint::*,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -489,7 +489,7 @@ impl<F: Field + PrimeField> ConditionalEqGadget<F> for Integer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cost() -> usize {
|
fn cost() -> usize {
|
||||||
<UInt128 as ConditionalEqGadget<F>>::cost() // upper bound. change trait to increase accuracy
|
unimplemented!() // cannot determine which integer we are enforcing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,6 +517,6 @@ impl<F: Field + PrimeField> CondSelectGadget<F> for Integer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cost() -> usize {
|
fn cost() -> usize {
|
||||||
<UInt128 as CondSelectGadget<F>>::cost() // upper bound. change trait to increase accuracy
|
unimplemented!() // cannot determine which integer we are enforcing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,13 +37,15 @@ pub enum ConstrainedValue<F: Field + PrimeField, G: GroupType<F>> {
|
|||||||
// Arrays
|
// Arrays
|
||||||
Array(Vec<ConstrainedValue<F, G>>),
|
Array(Vec<ConstrainedValue<F, G>>),
|
||||||
|
|
||||||
|
// Tuples
|
||||||
|
Tuple(Vec<ConstrainedValue<F, G>>),
|
||||||
|
|
||||||
// Circuits
|
// Circuits
|
||||||
CircuitDefinition(Circuit),
|
CircuitDefinition(Circuit),
|
||||||
CircuitExpression(Identifier, Vec<ConstrainedCircuitMember<F, G>>),
|
CircuitExpression(Identifier, Vec<ConstrainedCircuitMember<F, G>>),
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
Function(Option<Identifier>, Function), // (optional circuit identifier, function definition)
|
Function(Option<Identifier>, Function), // (optional circuit identifier, function definition)
|
||||||
Return(Vec<ConstrainedValue<F, G>>),
|
|
||||||
|
|
||||||
// Modifiers
|
// Modifiers
|
||||||
Mutable(Box<ConstrainedValue<F, G>>),
|
Mutable(Box<ConstrainedValue<F, G>>),
|
||||||
@ -61,8 +63,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
ConstrainedValue::from_type(value, &other_type, span)
|
ConstrainedValue::from_type(value, &other_type, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_type(value: String, _type: &Type, span: Span) -> Result<Self, ValueError> {
|
pub(crate) fn from_type(value: String, type_: &Type, span: Span) -> Result<Self, ValueError> {
|
||||||
match _type {
|
match type_ {
|
||||||
// Data types
|
// Data types
|
||||||
Type::Address => Ok(ConstrainedValue::Address(Address::new(value, span)?)),
|
Type::Address => Ok(ConstrainedValue::Address(Address::new(value, span)?)),
|
||||||
Type::Boolean => Ok(ConstrainedValue::Boolean(new_bool_constant(value, span)?)),
|
Type::Boolean => Ok(ConstrainedValue::Boolean(new_bool_constant(value, span)?)),
|
||||||
@ -103,15 +105,25 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
|
|
||||||
Type::Array(Box::new(array_type), vec![count])
|
Type::Array(Box::new(array_type), vec![count])
|
||||||
}
|
}
|
||||||
|
ConstrainedValue::Tuple(tuple) => {
|
||||||
|
let mut types = vec![];
|
||||||
|
|
||||||
|
for value in tuple {
|
||||||
|
let type_ = value.to_type(span.clone())?;
|
||||||
|
types.push(type_)
|
||||||
|
}
|
||||||
|
|
||||||
|
Type::Tuple(types)
|
||||||
|
}
|
||||||
ConstrainedValue::CircuitExpression(id, _members) => Type::Circuit(id.clone()),
|
ConstrainedValue::CircuitExpression(id, _members) => Type::Circuit(id.clone()),
|
||||||
value => return Err(ValueError::implicit(value.to_string(), span)),
|
value => return Err(ValueError::implicit(value.to_string(), span)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resolve_type(&mut self, types: &Vec<Type>, span: Span) -> Result<(), ValueError> {
|
pub(crate) fn resolve_type(&mut self, type_: Option<Type>, span: Span) -> Result<(), ValueError> {
|
||||||
if let ConstrainedValue::Unresolved(ref string) = self {
|
if let ConstrainedValue::Unresolved(ref string) = self {
|
||||||
if !types.is_empty() {
|
if type_.is_some() {
|
||||||
*self = ConstrainedValue::from_type(string.clone(), &types[0], span)?
|
*self = ConstrainedValue::from_type(string.clone(), &type_.unwrap(), span)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,16 +131,21 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Expect both `self` and `other` to resolve to the same type
|
/// Expect both `self` and `other` to resolve to the same type
|
||||||
pub(crate) fn resolve_types(&mut self, other: &mut Self, types: &Vec<Type>, span: Span) -> Result<(), ValueError> {
|
pub(crate) fn resolve_types(
|
||||||
if !types.is_empty() {
|
&mut self,
|
||||||
self.resolve_type(types, span.clone())?;
|
other: &mut Self,
|
||||||
return other.resolve_type(types, span);
|
type_: Option<Type>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<(), ValueError> {
|
||||||
|
if type_.is_some() {
|
||||||
|
self.resolve_type(type_.clone(), span.clone())?;
|
||||||
|
return other.resolve_type(type_, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
match (&self, &other) {
|
match (&self, &other) {
|
||||||
(ConstrainedValue::Unresolved(_), ConstrainedValue::Unresolved(_)) => Ok(()),
|
(ConstrainedValue::Unresolved(_), ConstrainedValue::Unresolved(_)) => Ok(()),
|
||||||
(ConstrainedValue::Unresolved(_), _) => self.resolve_type(&vec![other.to_type(span.clone())?], span),
|
(ConstrainedValue::Unresolved(_), _) => self.resolve_type(Some(other.to_type(span.clone())?), span),
|
||||||
(_, ConstrainedValue::Unresolved(_)) => other.resolve_type(&vec![self.to_type(span.clone())?], span),
|
(_, ConstrainedValue::Unresolved(_)) => other.resolve_type(Some(self.to_type(span.clone())?), span),
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,6 +225,17 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
})
|
})
|
||||||
.collect::<Result<(), ValueError>>()?;
|
.collect::<Result<(), ValueError>>()?;
|
||||||
}
|
}
|
||||||
|
ConstrainedValue::Tuple(tuple) => {
|
||||||
|
tuple
|
||||||
|
.iter_mut()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, value)| {
|
||||||
|
let unique_name = format!("allocate tuple member {} {}:{}", i, span.line, span.start);
|
||||||
|
|
||||||
|
value.allocate_value(cs.ns(|| unique_name), span.clone())
|
||||||
|
})
|
||||||
|
.collect::<Result<(), ValueError>>()?;
|
||||||
|
}
|
||||||
ConstrainedValue::CircuitExpression(_id, members) => {
|
ConstrainedValue::CircuitExpression(_id, members) => {
|
||||||
members
|
members
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@ -219,17 +247,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
})
|
})
|
||||||
.collect::<Result<(), ValueError>>()?;
|
.collect::<Result<(), ValueError>>()?;
|
||||||
}
|
}
|
||||||
ConstrainedValue::Return(array) => {
|
|
||||||
array
|
|
||||||
.iter_mut()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, value)| {
|
|
||||||
let unique_name = format!("allocate return member {} {}:{}", i, span.line, span.start);
|
|
||||||
|
|
||||||
value.allocate_value(cs.ns(|| unique_name), span.clone())
|
|
||||||
})
|
|
||||||
.collect::<Result<(), ValueError>>()?;
|
|
||||||
}
|
|
||||||
ConstrainedValue::Mutable(value) => {
|
ConstrainedValue::Mutable(value) => {
|
||||||
value.allocate_value(cs, span)?;
|
value.allocate_value(cs, span)?;
|
||||||
}
|
}
|
||||||
@ -280,6 +297,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F
|
|||||||
}
|
}
|
||||||
write!(f, "]")
|
write!(f, "]")
|
||||||
}
|
}
|
||||||
|
ConstrainedValue::Tuple(ref tuple) => {
|
||||||
|
let values = tuple.iter().map(|x| format!("{}", x)).collect::<Vec<_>>().join(", ");
|
||||||
|
|
||||||
|
write!(f, "({})", values)
|
||||||
|
}
|
||||||
ConstrainedValue::CircuitExpression(ref identifier, ref members) => {
|
ConstrainedValue::CircuitExpression(ref identifier, ref members) => {
|
||||||
write!(f, "{} {{", identifier)?;
|
write!(f, "{} {{", identifier)?;
|
||||||
for (i, member) in members.iter().enumerate() {
|
for (i, member) in members.iter().enumerate() {
|
||||||
@ -290,16 +312,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F
|
|||||||
}
|
}
|
||||||
write!(f, "}}")
|
write!(f, "}}")
|
||||||
}
|
}
|
||||||
ConstrainedValue::Return(ref values) => {
|
|
||||||
write!(f, "Program output: [")?;
|
|
||||||
for (i, value) in values.iter().enumerate() {
|
|
||||||
write!(f, "{}", value)?;
|
|
||||||
if i < values.len() - 1 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(f, "]")
|
|
||||||
}
|
|
||||||
ConstrainedValue::CircuitDefinition(ref circuit) => write!(f, "circuit {{ {} }}", circuit.circuit_name),
|
ConstrainedValue::CircuitDefinition(ref circuit) => write!(f, "circuit {{ {} }}", circuit.circuit_name),
|
||||||
ConstrainedValue::Function(ref _circuit_option, ref function) => {
|
ConstrainedValue::Function(ref _circuit_option, ref function) => {
|
||||||
write!(f, "function {{ {}() }}", function.identifier)
|
write!(f, "function {{ {}() }}", function.identifier)
|
||||||
@ -347,6 +359,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConditionalEqGadget<F> for Constrai
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Tuple(tuple_2)) => {
|
||||||
|
for (i, (left, right)) in tuple_1.into_iter().zip(tuple_2.into_iter()).enumerate() {
|
||||||
|
left.conditional_enforce_equal(cs.ns(|| format!("tuple index {}", i)), right, condition)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
(_, _) => return Err(SynthesisError::Unsatisfiable),
|
(_, _) => return Err(SynthesisError::Unsatisfiable),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,6 +411,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
|
|||||||
|
|
||||||
ConstrainedValue::Array(array)
|
ConstrainedValue::Array(array)
|
||||||
}
|
}
|
||||||
|
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Array(tuple_2)) => {
|
||||||
|
let mut array = vec![];
|
||||||
|
|
||||||
|
for (i, (first, second)) in tuple_1.into_iter().zip(tuple_2.into_iter()).enumerate() {
|
||||||
|
array.push(Self::conditionally_select(
|
||||||
|
cs.ns(|| format!("tuple index {}", i)),
|
||||||
|
cond,
|
||||||
|
first,
|
||||||
|
second,
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedValue::Tuple(array)
|
||||||
|
}
|
||||||
(ConstrainedValue::Function(identifier_1, function_1), ConstrainedValue::Function(_, _)) => {
|
(ConstrainedValue::Function(identifier_1, function_1), ConstrainedValue::Function(_, _)) => {
|
||||||
// This is a no-op. functions cannot hold circuit values
|
// This is a no-op. functions cannot hold circuit values
|
||||||
// However, we must return a result here
|
// However, we must return a result here
|
||||||
@ -415,20 +447,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
|
|||||||
|
|
||||||
ConstrainedValue::CircuitExpression(identifier.clone(), members)
|
ConstrainedValue::CircuitExpression(identifier.clone(), members)
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Return(returns_1), ConstrainedValue::Return(returns_2)) => {
|
|
||||||
let mut returns = vec![];
|
|
||||||
|
|
||||||
for (i, (first, second)) in returns_1.into_iter().zip(returns_2.into_iter()).enumerate() {
|
|
||||||
returns.push(Self::conditionally_select(
|
|
||||||
cs.ns(|| format!("return[{}]", i)),
|
|
||||||
cond,
|
|
||||||
first,
|
|
||||||
second,
|
|
||||||
)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstrainedValue::Return(returns)
|
|
||||||
}
|
|
||||||
(ConstrainedValue::Static(first), ConstrainedValue::Static(second)) => {
|
(ConstrainedValue::Static(first), ConstrainedValue::Static(second)) => {
|
||||||
let value = Self::conditionally_select(cs, cond, first, second)?;
|
let value = Self::conditionally_select(cs, cond, first, second)?;
|
||||||
|
|
||||||
|
@ -169,6 +169,7 @@ fn test_mul() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn test_eq() {
|
fn test_eq() {
|
||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
|
7
compiler/tests/function/input/newlines.in
Normal file
7
compiler/tests/function/input/newlines.in
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[main]
|
||||||
|
a: u32 = 0;
|
||||||
|
b: u32 = 0;
|
||||||
|
|
||||||
|
[registers]
|
||||||
|
a: u32 = 0;
|
||||||
|
b: u32 = 0;
|
@ -41,6 +41,20 @@ fn test_iteration_repeated() {
|
|||||||
assert_satisfied(program);
|
assert_satisfied(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_newlines() {
|
||||||
|
let input_bytes = include_bytes!("input/newlines.in");
|
||||||
|
let program_bytes = include_bytes!("newlines.leo");
|
||||||
|
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||||
|
|
||||||
|
let expected_bytes = include_bytes!("output_/newlines.out");
|
||||||
|
let expected = std::str::from_utf8(expected_bytes).unwrap();
|
||||||
|
let actual_bytes = get_output(program);
|
||||||
|
let actual = std::str::from_utf8(actual_bytes.bytes().as_slice()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_multiple_returns() {
|
fn test_multiple_returns() {
|
||||||
let bytes = include_bytes!("multiple.leo");
|
let bytes = include_bytes!("multiple.leo");
|
||||||
|
9
compiler/tests/function/newlines.leo
Normal file
9
compiler/tests/function/newlines.leo
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
function main(
|
||||||
|
a: u32,
|
||||||
|
b: u32,
|
||||||
|
) -> (
|
||||||
|
u32,
|
||||||
|
u32,
|
||||||
|
) {
|
||||||
|
return (a, b)
|
||||||
|
}
|
3
compiler/tests/function/output_/newlines.out
Normal file
3
compiler/tests/function/output_/newlines.out
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[registers]
|
||||||
|
a: u32 = 0u32;
|
||||||
|
b: u32 = 0u32;
|
2
compiler/tests/group/input/point.in
Normal file
2
compiler/tests/group/input/point.in
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[main]
|
||||||
|
a: group = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
@ -44,6 +44,16 @@ fn test_point() {
|
|||||||
assert_satisfied(program);
|
assert_satisfied(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_point_input() {
|
||||||
|
let program_bytes = include_bytes!("point_input.leo");
|
||||||
|
let input_bytes = include_bytes!("input/point.in");
|
||||||
|
|
||||||
|
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||||
|
|
||||||
|
assert_satisfied(program);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_input() {
|
fn test_input() {
|
||||||
let program_bytes = include_bytes!("input.leo");
|
let program_bytes = include_bytes!("input.leo");
|
||||||
@ -196,6 +206,7 @@ fn test_assert_eq_fail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn test_eq() {
|
fn test_eq() {
|
||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
|
3
compiler/tests/group/point_input.leo
Normal file
3
compiler/tests/group/point_input.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: group) {
|
||||||
|
let b = a;
|
||||||
|
}
|
@ -81,6 +81,11 @@ fn test_i128_eq() {
|
|||||||
TestI128::test_eq();
|
TestI128::test_eq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i128_ne() {
|
||||||
|
TestI128::test_ne();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i128_ge() {
|
fn test_i128_ge() {
|
||||||
TestI128::test_ge();
|
TestI128::test_ge();
|
||||||
|
3
compiler/tests/integers/i128/ne.leo
Normal file
3
compiler/tests/integers/i128/ne.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i128, b: i128, c: bool) {
|
||||||
|
assert_eq!(a != b, c);
|
||||||
|
}
|
@ -80,6 +80,11 @@ fn test_i16_eq() {
|
|||||||
TestI16::test_eq();
|
TestI16::test_eq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i16_ne() {
|
||||||
|
TestI16::test_ne();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i16_ge() {
|
fn test_i16_ge() {
|
||||||
TestI16::test_ge();
|
TestI16::test_ge();
|
||||||
|
3
compiler/tests/integers/i16/ne.leo
Normal file
3
compiler/tests/integers/i16/ne.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i16, b: i16, c: bool) {
|
||||||
|
assert_eq!(a != b, c);
|
||||||
|
}
|
@ -80,6 +80,11 @@ fn test_i32_eq() {
|
|||||||
TestI32::test_eq();
|
TestI32::test_eq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i32_ne() {
|
||||||
|
TestI32::test_ne();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i32_ge() {
|
fn test_i32_ge() {
|
||||||
TestI32::test_ge();
|
TestI32::test_ge();
|
||||||
|
3
compiler/tests/integers/i32/ne.leo
Normal file
3
compiler/tests/integers/i32/ne.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i32, b: i32, c: bool) {
|
||||||
|
assert_eq!(a != b, c);
|
||||||
|
}
|
@ -81,6 +81,11 @@ fn test_i64_eq() {
|
|||||||
TestI64::test_eq();
|
TestI64::test_eq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i64_ne() {
|
||||||
|
TestI64::test_ne();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64_ge() {
|
fn test_i64_ge() {
|
||||||
TestI64::test_ge();
|
TestI64::test_ge();
|
||||||
|
3
compiler/tests/integers/i64/ne.leo
Normal file
3
compiler/tests/integers/i64/ne.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i64, b: i64, c: bool) {
|
||||||
|
assert_eq!(a != b, c);
|
||||||
|
}
|
@ -80,6 +80,11 @@ fn test_i8_eq() {
|
|||||||
TestI8::test_eq();
|
TestI8::test_eq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_ne() {
|
||||||
|
TestI8::test_ne();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i8_ge() {
|
fn test_i8_ge() {
|
||||||
TestI8::test_ge();
|
TestI8::test_ge();
|
||||||
|
3
compiler/tests/integers/i8/ne.leo
Normal file
3
compiler/tests/integers/i8/ne.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8, c: bool) {
|
||||||
|
assert_eq!(a != b, c);
|
||||||
|
}
|
@ -257,6 +257,44 @@ macro_rules! test_int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_ne() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let a: $type_ = rand::random();
|
||||||
|
let b: $type_ = rand::random();
|
||||||
|
|
||||||
|
// test a != a == false
|
||||||
|
|
||||||
|
let bytes = include_bytes!("ne.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
let main_input = generate_main_input(vec![
|
||||||
|
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||||
|
("b", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||||
|
("c", Some(InputValue::Boolean(false))),
|
||||||
|
]);
|
||||||
|
|
||||||
|
program.set_main_input(main_input);
|
||||||
|
|
||||||
|
assert_satisfied(program);
|
||||||
|
|
||||||
|
// test not equal
|
||||||
|
|
||||||
|
let c = a.ne(&b);
|
||||||
|
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
let main_input = generate_main_input(vec![
|
||||||
|
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||||
|
("b", Some(InputValue::Integer($integer_type, b.to_string()))),
|
||||||
|
("c", Some(InputValue::Boolean(c))),
|
||||||
|
]);
|
||||||
|
|
||||||
|
program.set_main_input(main_input);
|
||||||
|
|
||||||
|
assert_satisfied(program);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn test_ge() {
|
fn test_ge() {
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let a: $type_ = rand::random();
|
let a: $type_ = rand::random();
|
||||||
|
@ -32,6 +32,9 @@ pub trait IntegerTester {
|
|||||||
/// Tests == evaluation
|
/// Tests == evaluation
|
||||||
fn test_eq();
|
fn test_eq();
|
||||||
|
|
||||||
|
/// Tests != evaluation
|
||||||
|
fn test_ne();
|
||||||
|
|
||||||
/// Tests >= evaluation
|
/// Tests >= evaluation
|
||||||
fn test_ge();
|
fn test_ge();
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ pub mod integer_tester;
|
|||||||
pub use self::integer_tester::*;
|
pub use self::integer_tester::*;
|
||||||
|
|
||||||
// must be below macro definitions!
|
// must be below macro definitions!
|
||||||
pub mod u128;
|
// pub mod u128;
|
||||||
pub mod u16;
|
pub mod u16;
|
||||||
pub mod u32;
|
pub mod u32;
|
||||||
pub mod u64;
|
pub mod u64;
|
||||||
|
@ -65,6 +65,11 @@ fn test_u128_eq() {
|
|||||||
TestU128::test_eq();
|
TestU128::test_eq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_u128_ne() {
|
||||||
|
TestU128::test_ne();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_u128_ge() {
|
fn test_u128_ge() {
|
||||||
TestU128::test_ge();
|
TestU128::test_ge();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user