Merge branch 'master' into feature/opti-cli-flag

This commit is contained in:
damirka 2021-04-26 23:39:10 +03:00
commit a1326d386e
888 changed files with 34810 additions and 5644 deletions

View File

@ -158,6 +158,19 @@ jobs:
export LEO=/home/circleci/project/project/bin/leo
./project/.circleci/leo-add-remove.sh
leo-check-constraints:
docker:
- image: cimg/rust:1.50.0
resource_class: xlarge
steps:
- attach_workspace:
at: /home/circleci/project/
- run:
name: leo check constraints for Pedersen Hash
command: |
export LEO=/home/circleci/project/project/bin/leo
./project/.circleci/leo-check-constraints.sh
leo-login-logout:
docker:
- image: cimg/rust:1.51.0
@ -219,6 +232,9 @@ workflows:
- leo-add-remove:
requires:
- leo-executable
- leo-check-constraints:
requires:
- leo-executable
- leo-login-logout:
requires:
- leo-executable

View File

@ -0,0 +1,16 @@
# leo new hello-world
cd ./project/examples/pedersen-hash
export PEDERSEN_HASH_CONSTRAINTS=1539;
# line that we're searching for is:
# `Build Number of constraints - 1539`
export ACTUAL_CONSTRAINTS=$($LEO build | grep constraints | awk '{print $NF}')
# if else expression with only else block
[[ PEDERSEN_HASH_CONSTRAINTS -eq ACTUAL_CONSTRAINTS ]] || {
echo >&2 "Number of constraints for Pedersen Hash is not $PEDERSEN_HASH_CONSTRAINTS";
echo >&2 "Real number of constraints is $ACTUAL_CONSTRAINTS";
exit 1;
}

View File

@ -1,7 +1,15 @@
# leo login & logout
$LEO new my-app && cd my-app || exit 1
$LEO login -u "$ALEO_PM_USERNAME" -p "$ALEO_PM_PASSWORD"
$LEO new my-app && cd my-app || exit 1
cat Leo.toml
# verify that in Leo.toml there's no line with [AUTHOR];
# since CI does not allow showing credentials, we won't see it in the file;
# so the only way to test is to make sure that there's just no [AUTHOR] there
[[ $(cat Leo.toml | grep "\[AUTHOR\]" | wc -l) -eq 0 ]] || exit 1
$LEO add howard/silly-sudoku
$LEO remove silly-sudoku
$LEO logout

View File

@ -1,4 +1,9 @@
$LEO new hello-world
ls -la
cd hello-world && ls -la
# verify that in Leo.toml there's a placeholder for author
# because at the time of calling `leo new` user is not logged in
[[ $(cat Leo.toml | grep "\[AUTHOR\]" | wc -l) -eq 1 ]] || exit 1
$LEO run

0
.circleci/r Normal file
View File

View File

@ -1 +1 @@
v1.3.0
v1.4.0

256
Cargo.lock generated
View File

@ -4,9 +4,9 @@ version = 3
[[package]]
name = "abnf"
version = "0.10.2"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd8863e7db43447ad50376e19b0549343b72ad45cbd394b3fc8fe3ede961facc"
checksum = "96e669320c520d87931e752d603dd442b4709c73b1b8b1fcba838f9c5acc1791"
dependencies = [
"abnf-core",
"nom 6.1.2",
@ -87,6 +87,20 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "assert_cmd"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2475b58cd94eb4f70159f4fd8844ba3b807532fe3131b3373fae060bbe30396"
dependencies = [
"bstr",
"doc-comment",
"predicates",
"predicates-core",
"predicates-tree",
"wait-timeout",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -138,11 +152,10 @@ checksum = "58946044516aa9dc922182e0d6e9d124a31aafe6b421614654eb27cf90cec09c"
[[package]]
name = "bincode"
version = "1.3.2"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"byteorder",
"serde",
]
@ -602,6 +615,12 @@ dependencies = [
"syn 1.0.64",
]
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "digest"
version = "0.8.1"
@ -640,6 +659,18 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "dtoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
[[package]]
name = "either"
version = "1.6.1"
@ -1241,7 +1272,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "leo-abnf"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"abnf",
"anyhow",
@ -1249,7 +1280,7 @@ dependencies = [
[[package]]
name = "leo-asg"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"criterion",
"indexmap",
@ -1265,14 +1296,14 @@ dependencies = [
[[package]]
name = "leo-asg-passes"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"leo-asg",
]
[[package]]
name = "leo-ast"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"anyhow",
"criterion",
@ -1287,7 +1318,7 @@ dependencies = [
[[package]]
name = "leo-compiler"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"bincode",
"hex",
@ -1302,8 +1333,8 @@ dependencies = [
"leo-state",
"num-bigint",
"pest",
"rand",
"rand_core",
"rand 0.8.3",
"rand_core 0.6.2",
"rand_xorshift",
"serde",
"sha2",
@ -1315,13 +1346,14 @@ dependencies = [
"snarkvm-r1cs",
"snarkvm-utilities",
"tempfile",
"tendril",
"thiserror",
"tracing",
]
[[package]]
name = "leo-imports"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"indexmap",
"leo-asg",
@ -1333,7 +1365,7 @@ dependencies = [
[[package]]
name = "leo-input"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"from-pest",
"pest",
@ -1345,9 +1377,11 @@ dependencies = [
[[package]]
name = "leo-lang"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"ansi_term 0.12.1",
"anyhow",
"assert_cmd",
"clap",
"colored",
"console",
@ -1362,8 +1396,8 @@ dependencies = [
"leo-state",
"leo-synthesizer",
"notify",
"rand",
"rand_core",
"rand 0.8.3",
"rand_core 0.6.2",
"reqwest",
"rusty-hook",
"self_update",
@ -1375,6 +1409,7 @@ dependencies = [
"snarkvm-r1cs",
"snarkvm-utilities",
"structopt",
"test_dir",
"thiserror",
"toml",
"tracing",
@ -1384,11 +1419,11 @@ dependencies = [
[[package]]
name = "leo-linter"
version = "1.3.0"
version = "1.4.0"
[[package]]
name = "leo-package"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"lazy_static",
"serde",
@ -1401,14 +1436,16 @@ dependencies = [
[[package]]
name = "leo-parser"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"criterion",
"indexmap",
"lazy_static",
"leo-ast",
"leo-test-framework",
"serde",
"serde_json",
"serde_yaml",
"tendril",
"thiserror",
"tracing",
@ -1416,13 +1453,13 @@ dependencies = [
[[package]]
name = "leo-state"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"indexmap",
"leo-ast",
"leo-input",
"rand",
"rand_core",
"rand 0.8.3",
"rand_core 0.6.2",
"rand_xorshift",
"snarkvm-algorithms",
"snarkvm-curves",
@ -1434,7 +1471,7 @@ dependencies = [
[[package]]
name = "leo-synthesizer"
version = "1.3.0"
version = "1.4.0"
dependencies = [
"num-bigint",
"serde",
@ -1445,6 +1482,15 @@ dependencies = [
"snarkvm-r1cs",
]
[[package]]
name = "leo-test-framework"
version = "1.4.0"
dependencies = [
"serde",
"serde_json",
"serde_yaml",
]
[[package]]
name = "lexical-core"
version = "0.7.5"
@ -1498,6 +1544,12 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "lock_api"
version = "0.4.2"
@ -1725,9 +1777,9 @@ dependencies = [
[[package]]
name = "notify"
version = "4.0.15"
version = "4.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
checksum = "2599080e87c9bd051ddb11b10074f4da7b1223298df65d4c2ec5bcf309af1533"
dependencies = [
"bitflags",
"filetime",
@ -2024,6 +2076,32 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "predicates"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eeb433456c1a57cc93554dea3ce40b4c19c4057e41c55d4a0f3d84ea71c325aa"
dependencies = [
"difference",
"predicates-core",
]
[[package]]
name = "predicates-core"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
[[package]]
name = "predicates-tree"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2"
dependencies = [
"predicates-core",
"treeline",
]
[[package]]
name = "proc-macro-crate"
version = "0.1.5"
@ -2114,6 +2192,19 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc 0.2.0",
]
[[package]]
name = "rand"
version = "0.8.3"
@ -2121,9 +2212,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
"rand_chacha 0.3.0",
"rand_core 0.6.2",
"rand_hc 0.3.0",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]]
@ -2133,7 +2234,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.2",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
@ -2145,13 +2255,22 @@ dependencies = [
"getrandom 0.2.2",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
"rand_core",
"rand_core 0.6.2",
]
[[package]]
@ -2160,7 +2279,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
dependencies = [
"rand_core",
"rand_core 0.6.2",
]
[[package]]
@ -2252,9 +2371,9 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.11.2"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf12057f289428dbf5c591c74bf10392e4a8003f993405a902f20117019022d4"
checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124"
dependencies = [
"base64",
"bytes",
@ -2508,6 +2627,18 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23"
dependencies = [
"dtoa",
"linked-hash-map",
"serde",
"yaml-rust",
]
[[package]]
name = "sha-1"
version = "0.8.2"
@ -2579,8 +2710,8 @@ dependencies = [
"derivative",
"digest 0.9.0",
"itertools 0.10.0",
"rand",
"rand_chacha",
"rand 0.8.3",
"rand_chacha 0.3.0",
"rayon",
"sha2",
"smallvec",
@ -2599,7 +2730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64610b135b8b1152439d5dfa4f745515933366082f08651961344aa0bb5abfca"
dependencies = [
"derivative",
"rand",
"rand 0.8.3",
"rand_xorshift",
"rustc_version 0.3.3",
"serde",
@ -2634,7 +2765,7 @@ dependencies = [
"derivative",
"hex",
"itertools 0.10.0",
"rand",
"rand 0.8.3",
"snarkvm-algorithms",
"snarkvm-curves",
"snarkvm-fields",
@ -2655,7 +2786,7 @@ checksum = "8c49c69d02df11be58e07f626c9d6f5804c6dd4ccf42e425f2be8d79fe6e5bb7"
dependencies = [
"bincode",
"derivative",
"rand",
"rand 0.8.3",
"rand_xorshift",
"serde",
"snarkvm-utilities",
@ -2690,7 +2821,7 @@ dependencies = [
"chrono",
"hex",
"once_cell",
"rand",
"rand 0.8.3",
"serde",
"sha2",
"snarkvm-algorithms",
@ -2744,7 +2875,7 @@ dependencies = [
"bincode",
"hex",
"parking_lot",
"rand",
"rand 0.8.3",
"rocksdb",
"serde",
"snarkvm-algorithms",
@ -2762,7 +2893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c763843fa67a3aa4ce68173c8cd96b4f04aaa135a5792bc051c36eec0fe1cd73"
dependencies = [
"bincode",
"rand",
"rand 0.8.3",
"snarkvm-derives",
"thiserror",
]
@ -2868,7 +2999,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
"cfg-if 1.0.0",
"libc",
"rand",
"rand 0.8.3",
"redox_syscall 0.2.5",
"remove_dir_all",
"winapi 0.3.9",
@ -2904,6 +3035,15 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "test_dir"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e571ebf9127a9da821890a9fa8a8ef777fce3e0f959ff6949cf06ca8b736381d"
dependencies = [
"rand 0.7.3",
]
[[package]]
name = "textwrap"
version = "0.11.0"
@ -3116,6 +3256,12 @@ dependencies = [
"tracing-serde",
]
[[package]]
name = "treeline"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
[[package]]
name = "try-lock"
version = "0.2.3"
@ -3233,6 +3379,15 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "wait-timeout"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
dependencies = [
"libc",
]
[[package]]
name = "walkdir"
version = "2.3.2"
@ -3422,10 +3577,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
[[package]]
name = "zip"
version = "0.5.10"
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a8977234acab718eb2820494b2f96cbb16004c19dddf88b7445b27381450997"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "zip"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c83dc9b784d252127720168abd71ea82bf8c3d96b17dc565b5e2a02854f2b27"
dependencies = [
"byteorder",
"bzip2",

View File

@ -1,6 +1,6 @@
[package]
name = "leo-lang"
version = "1.3.0"
version = "1.4.0"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "The Leo programming language"
homepage = "https://aleo.org"
@ -37,36 +37,37 @@ members = [
"package",
"parser",
"state",
"synthesizer"
"synthesizer",
"test-framework"
]
[dependencies.leo-ast]
path = "./ast"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-compiler]
path = "./compiler"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-imports]
path = "./imports"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-input]
path = "./input"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-package]
path = "./package"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-state]
path = "./state"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-synthesizer]
path = "./synthesizer"
version = "1.3.0"
version = "1.4.0"
[dependencies.snarkvm-algorithms]
version = "0.2.2"
@ -111,7 +112,7 @@ version = "0.3.1"
version = "1.4.0"
[dependencies.notify]
version = "4.0.15"
version = "4.0.16"
[dependencies.rand]
version = "0.8"
@ -120,7 +121,7 @@ version = "0.8"
version = "0.6.2"
[dependencies.reqwest]
version = "0.11.2"
version = "0.11.3"
features = [ "blocking", "json", "multipart" ]
[dependencies.self_update]
@ -150,9 +151,18 @@ features = [ "fmt" ]
[dependencies.zip]
version = "0.5"
[target."cfg(windows)".dependencies.ansi_term]
version = "0.12.1"
[dev-dependencies.rusty-hook]
version = "0.11.2"
[dev-dependencies.assert_cmd]
version = "1.0.3"
[dev-dependencies.test_dir]
version = "0.1.0"
[features]
default = [ ]
ci_skip = [ "leo-compiler/ci_skip" ]

View File

@ -95,9 +95,9 @@ This will generate an executable under the `./target/release` directory. To run
Use the Leo CLI to create a new project
```bash
# create a new `hello_world` Leo project
leo new hello_world
cd hello_world
# create a new `hello-world` Leo project
leo new hello-world
cd hello-world
# build & setup & prove & verify
leo run
@ -113,6 +113,7 @@ Congratulations! You've just run your first Leo program.
* [Hello World - Next Steps](https://developer.aleo.org/developer/getting_started/hello_world)
* [Leo Language Documentation](https://developer.aleo.org/developer/language/layout)
* [Leo ABNF Grammar](./grammar/README.md)
* [Leo CLI Documentation](https://developer.aleo.org/developer/cli/new)
* [Homepage](https://developer.aleo.org/developer/getting_started/overview)

View File

@ -1,6 +1,6 @@
[package]
name = "leo-asg-passes"
version = "1.3.0"
version = "1.4.0"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "The Leo programming language"
homepage = "https://aleo.org"
@ -22,4 +22,4 @@ path = "src/lib.rs"
[dependencies.leo-asg]
path = "../asg"
version = "1.3.0"
version = "1.4.0"

View File

@ -1,6 +1,6 @@
[package]
name = "leo-asg"
version = "1.3.0"
version = "1.4.0"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "ASG of the Leo programming language"
homepage = "https://aleo.org"
@ -30,11 +30,11 @@ version = "1.6"
version = "1.0"
[dependencies.leo-ast]
version = "1.3.0"
version = "1.4.0"
path = "../ast"
[dependencies.leo-parser]
version = "1.3.0"
version = "1.4.0"
path = "../parser"
[dependencies.num-bigint]

View File

@ -92,7 +92,7 @@ impl<'a> MonoidalReducerStatement<'a, BoolAnd> for ReturnPathReducer {
if_true.append(if_false.unwrap_or(BoolAnd(false)))
}
fn reduce_formatted_string(&mut self, input: &FormattedString, parameters: Vec<BoolAnd>) -> BoolAnd {
fn reduce_formatted_string(&mut self, input: &FormatString, parameters: Vec<BoolAnd>) -> BoolAnd {
BoolAnd(false)
}

View File

@ -71,7 +71,7 @@ impl<'a> ExpressionNode<'a> for CallExpression<'a> {
}
fn is_mut_ref(&self) -> bool {
false
true
}
fn const_value(&self) -> Option<ConstValue> {

View File

@ -137,13 +137,6 @@ impl<'a> FromAst<'a, leo_ast::Identifier> for &'a Expression<'a> {
expected_type: Option<PartialType<'a>>,
) -> Result<&'a Expression<'a>, AsgConvertError> {
let variable = if value.name.as_ref() == "input" {
if let Some(function) = scope.resolve_current_function() {
if !function.has_input {
return Err(AsgConvertError::unresolved_reference(&value.name, &value.span));
}
} else {
return Err(AsgConvertError::unresolved_reference(&value.name, &value.span));
}
if let Some(input) = scope.resolve_input() {
input.container
} else {

View File

@ -29,7 +29,7 @@ pub fn resolve_core_module<'a>(context: AsgContext<'a>, module: &str) -> Result<
r#"
circuit Blake2s {
function hash(seed: [u8; 32], message: [u8; 32]) -> [u8; 32] {
return [0; 32]
return [0; 32];
}
}
"#,

View File

@ -47,7 +47,6 @@ pub struct Function<'a> {
pub id: u32,
pub name: RefCell<Identifier>,
pub output: Type<'a>,
pub has_input: bool,
pub arguments: IndexMap<String, Cell<&'a Variable<'a>>>,
pub circuit: Cell<Option<&'a Circuit<'a>>>,
pub span: Option<Span>,
@ -77,16 +76,12 @@ impl<'a> Function<'a> {
.transpose()?
.unwrap_or_else(|| Type::Tuple(vec![]));
let mut qualifier = FunctionQualifier::Static;
let mut has_input = false;
let new_scope = scope.make_subscope();
let mut arguments = IndexMap::new();
{
for input in value.input.iter() {
match input {
FunctionInput::InputKeyword(_) => {
has_input = true;
}
FunctionInput::SelfKeyword(_) => {
qualifier = FunctionQualifier::SelfRef;
}
@ -125,7 +120,6 @@ impl<'a> Function<'a> {
id: scope.context.get_id(),
name: RefCell::new(value.identifier.clone()),
output,
has_input,
arguments,
circuit: Cell::new(None),
body: Cell::new(None),

View File

@ -225,7 +225,7 @@ impl<'a, T: Monoid, R: MonoidalReducerStatement<'a, T>> MonoidalDirector<'a, T,
.reduce_conditional_statement(input, condition, if_true, if_false)
}
pub fn reduce_formatted_string(&mut self, input: &FormattedString<'a>) -> T {
pub fn reduce_formatted_string(&mut self, input: &FormatString<'a>) -> T {
let parameters = input
.parameters
.iter()

View File

@ -118,7 +118,7 @@ pub trait MonoidalReducerStatement<'a, T: Monoid>: MonoidalReducerExpression<'a,
condition.append(if_true).append_option(if_false)
}
fn reduce_formatted_string(&mut self, input: &FormattedString<'a>, parameters: Vec<T>) -> T {
fn reduce_formatted_string(&mut self, input: &FormatString<'a>, parameters: Vec<T>) -> T {
T::default().append_all(parameters.into_iter())
}

View File

@ -243,7 +243,7 @@ impl<'a, R: ReconstructingReducerStatement<'a>> ReconstructingDirector<'a, R> {
.reduce_conditional_statement(input, condition, if_true, if_false)
}
pub fn reduce_formatted_string(&mut self, input: FormattedString<'a>) -> FormattedString<'a> {
pub fn reduce_formatted_string(&mut self, input: FormatString<'a>) -> FormatString<'a> {
let parameters = input
.parameters
.iter()

View File

@ -274,10 +274,10 @@ pub trait ReconstructingReducerStatement<'a>: ReconstructingReducerExpression<'a
fn reduce_formatted_string(
&mut self,
input: FormattedString<'a>,
input: FormatString<'a>,
parameters: Vec<&'a Expression<'a>>,
) -> FormattedString<'a> {
FormattedString {
) -> FormatString<'a> {
FormatString {
span: input.span,
parts: input.parts,
parameters: parameters.into_iter().map(Cell::new).collect(),
@ -293,7 +293,7 @@ pub trait ReconstructingReducerStatement<'a>: ReconstructingReducerExpression<'a
})
}
fn reduce_console_log(&mut self, input: ConsoleStatement<'a>, argument: FormattedString<'a>) -> Statement<'a> {
fn reduce_console_log(&mut self, input: ConsoleStatement<'a>, argument: FormatString<'a>) -> Statement<'a> {
assert!(!matches!(input.function, ConsoleFunction::Assert(_)));
Statement::Console(ConsoleStatement {
parent: input.parent,

View File

@ -120,7 +120,7 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
Default::default()
}
fn visit_formatted_string(&mut self, input: &FormattedString<'a>) -> VisitResult {
fn visit_formatted_string(&mut self, input: &FormatString<'a>) -> VisitResult {
Default::default()
}

View File

@ -319,7 +319,7 @@ impl<'a, R: StatementVisitor<'a>> VisitorDirector<'a, R> {
}
}
pub fn visit_formatted_string(&mut self, input: &FormattedString<'a>) -> ConcreteVisitResult {
pub fn visit_formatted_string(&mut self, input: &FormatString<'a>) -> ConcreteVisitResult {
match self.visitor.visit_formatted_string(input) {
VisitResult::VisitChildren => {
for parameter in input.parameters.iter() {

View File

@ -70,13 +70,6 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
let (name, span) = (&statement.assignee.identifier.name, &statement.assignee.identifier.span);
let variable = if name.as_ref() == "input" {
if let Some(function) = scope.resolve_current_function() {
if !function.has_input {
return Err(AsgConvertError::unresolved_reference(name, &span));
}
} else {
return Err(AsgConvertError::unresolved_reference(name, &span));
}
if let Some(input) = scope.resolve_input() {
input.container
} else {

View File

@ -15,14 +15,14 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{AsgConvertError, Expression, FromAst, Node, PartialType, Scope, Span, Statement, Type};
use leo_ast::{ConsoleFunction as AstConsoleFunction, FormattedStringPart};
use leo_ast::{ConsoleFunction as AstConsoleFunction, FormatStringPart};
use std::cell::Cell;
// TODO (protryon): Refactor to not require/depend on span
#[derive(Clone)]
pub struct FormattedString<'a> {
pub parts: Vec<FormattedStringPart>,
pub struct FormatString<'a> {
pub parts: Vec<FormatStringPart>,
pub parameters: Vec<Cell<&'a Expression<'a>>>,
pub span: Span,
}
@ -30,9 +30,9 @@ pub struct FormattedString<'a> {
#[derive(Clone)]
pub enum ConsoleFunction<'a> {
Assert(Cell<&'a Expression<'a>>),
Debug(FormattedString<'a>),
Error(FormattedString<'a>),
Log(FormattedString<'a>),
Debug(FormatString<'a>),
Error(FormatString<'a>),
Log(FormatString<'a>),
}
#[derive(Clone)]
@ -48,16 +48,16 @@ impl<'a> Node for ConsoleStatement<'a> {
}
}
impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> {
impl<'a> FromAst<'a, leo_ast::FormatString> for FormatString<'a> {
fn from_ast(
scope: &'a Scope<'a>,
value: &leo_ast::FormattedString,
value: &leo_ast::FormatString,
_expected_type: Option<PartialType<'a>>,
) -> Result<Self, AsgConvertError> {
let expected_param_len = value
.parts
.iter()
.filter(|x| matches!(x, FormattedStringPart::Container))
.filter(|x| matches!(x, FormatStringPart::Container))
.count();
if value.parameters.len() != expected_param_len {
// + 1 for formatting string as to not confuse user
@ -71,7 +71,7 @@ impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> {
for parameter in value.parameters.iter() {
parameters.push(Cell::new(<&Expression<'a>>::from_ast(scope, parameter, None)?));
}
Ok(FormattedString {
Ok(FormatString {
parts: value.parts.clone(),
parameters,
span: value.span.clone(),
@ -79,9 +79,9 @@ impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> {
}
}
impl<'a> Into<leo_ast::FormattedString> for &FormattedString<'a> {
fn into(self) -> leo_ast::FormattedString {
leo_ast::FormattedString {
impl<'a> Into<leo_ast::FormatString> for &FormatString<'a> {
fn into(self) -> leo_ast::FormatString {
leo_ast::FormatString {
parts: self.parts.clone(),
parameters: self.parameters.iter().map(|e| e.get().into()).collect(),
span: self.span.clone(),
@ -103,13 +103,13 @@ impl<'a> FromAst<'a, leo_ast::ConsoleStatement> for ConsoleStatement<'a> {
<&Expression<'a>>::from_ast(scope, expression, Some(Type::Boolean.into()))?,
)),
AstConsoleFunction::Debug(formatted_string) => {
ConsoleFunction::Debug(FormattedString::from_ast(scope, formatted_string, None)?)
ConsoleFunction::Debug(FormatString::from_ast(scope, formatted_string, None)?)
}
AstConsoleFunction::Error(formatted_string) => {
ConsoleFunction::Error(FormattedString::from_ast(scope, formatted_string, None)?)
ConsoleFunction::Error(FormatString::from_ast(scope, formatted_string, None)?)
}
AstConsoleFunction::Log(formatted_string) => {
ConsoleFunction::Log(FormattedString::from_ast(scope, formatted_string, None)?)
ConsoleFunction::Log(FormatString::from_ast(scope, formatted_string, None)?)
}
},
})

View File

@ -54,7 +54,7 @@ impl<'a> FromAst<'a, leo_ast::IterationStatement> for &'a Statement<'a> {
statement: &leo_ast::IterationStatement,
_expected_type: Option<PartialType<'a>>,
) -> Result<Self, AsgConvertError> {
let expected_index_type = Some(PartialType::Integer(None, Some(IntegerType::U32)));
let expected_index_type = Some(PartialType::Integer(Some(IntegerType::U32), None));
let start = <&Expression<'a>>::from_ast(scope, &statement.start, expected_index_type.clone())?;
let stop = <&Expression<'a>>::from_ast(scope, &statement.stop, expected_index_type)?;

View File

@ -1,6 +1,6 @@
circuit Foo {
function echo(x: u32) -> u32 {
return x
return x;
}
}

View File

@ -1,6 +1,6 @@
circuit Foo {
function echo(x: u32) -> u32 {
return x
return x;
}
}

View File

@ -1,6 +1,6 @@
circuit Foo {
function echo(x: u32) -> u32 {
return x
return x;
}
}

View File

@ -1,6 +1,6 @@
circuit Foo {
function echo(x: u32) -> u32 {
return x
return x;
}
}

View File

@ -55,7 +55,7 @@ fn test_mut_member_function_fail() {
let program_string = r#"
circuit Foo {
function echo(mut self, x: u32) -> u32 {
return x
return x;
}
}

View File

@ -2,7 +2,7 @@ circuit Foo {
f: u32,
function bar() -> u32 {
return f
return f;
}
}

View File

@ -1,6 +1,6 @@
circuit Foo {
function bar() -> u32 {
return self.f
return self.f;
}
}

View File

@ -1,7 +1,7 @@
function main () -> i8 {
if true {
return 1i8 //ignored
return 1i8; //ignored
}
return 2i8 //ignored
return 3i8 //returns
return 2i8; //ignored
return 3i8; //returns
}

View File

@ -2,8 +2,8 @@ function main () -> u16 {
if false {
const a = 1u16;
const b = a + 1u16;
return b
return b;
} else if false {
return 0u16
return 0u16;
}
}

View File

@ -1,7 +1,7 @@
function main(input) -> u32 {
if input.registers.a == 0 {
return 0u32
return 0u32;
} else {
return 1u32
return 1u32;
}
}

View File

@ -1,5 +1,5 @@
function foo() -> field {
return myGlobal
return myGlobal;
}
function main() {

View File

@ -1,3 +1,3 @@
function main() -> (bool, bool) {
return true
return true;
}

View File

@ -1,6 +1,6 @@
function main() {
const address_1 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8);
const address_2 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8);
const address_1 = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
const address_2 = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
console.assert(address_1 == address_2);
}

View File

@ -1,5 +1,5 @@
function main(owner: address) {
const sender = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8);
const sender = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
console.assert(owner == sender);
}

View File

@ -1,6 +1,6 @@
function main(s: bool, c: address) {
const a = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8);
const b = address(aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r);
const a = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
const b = aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r;
const r = s? a: b;

View File

@ -1,3 +1,3 @@
function main() {
const public_key_string = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8);
const public_key_string = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
}

View File

@ -1,3 +1,3 @@
function main(input) -> [u8; 3] {
return input.registers.r
}
function main() -> [u8; 3] {
return input.registers.r;
}

View File

@ -1,3 +1,3 @@
function main(input) -> bool {
return input.registers.r
}
function main() -> bool {
return input.registers.r;
}

View File

@ -1,6 +1,6 @@
circuit Foo {
function echo(self, x: u32) -> u32 {
return x
return x;
}
}

View File

@ -2,11 +2,11 @@ circuit Foo {
x: u32,
function add_x(self, y: u32) -> u32 {
return self.x + y
return self.x + y;
}
function call_add_x(self, y: u32) -> u32 {
return self.add_x(y)
return self.add_x(y);
}
}

View File

@ -1,6 +1,6 @@
circuit Foo {
function echo(x: u32) -> u32 {
return x
return x;
}
}

View File

@ -2,7 +2,7 @@ circuit Foo {
foo: u32,
function bar() -> u32 {
return 1u32
return 1u32;
}
}

View File

@ -49,7 +49,7 @@ fn test_mut_member_function() {
let program_string = r#"
circuit Foo {
function echo(mut self, x: u32) -> u32 {
return x
return x;
}
}

View File

@ -2,7 +2,7 @@ circuit PedersenHash {
parameters: [u32; 512]
function new(parameters: [u32; 512]) -> Self {
return Self { parameters: parameters }
return Self { parameters: parameters };
}
function hash(self, bits: [bool; 512]) -> u32 {
@ -11,7 +11,7 @@ circuit PedersenHash {
const base = bits[i] ? self.parameters[i] : 0u32;
digest += base;
}
return digest
return digest;
}
}

View File

@ -1,6 +1,6 @@
circuit Foo {
static function new() -> Self {
return Self { }
return Self { };
}
}

View File

@ -2,7 +2,7 @@ circuit Foo {
f: u32,
function bar(self) -> u32 {
return self.f
return self.f;
}
}

View File

@ -1,5 +1,5 @@
import core.unstable.blake2s.Blake2s;
function main(seed: [u8; 32], message: [u8; 32]) -> [u8; 32] {
return Blake2s::hash(seed, message)
return Blake2s::hash(seed, message);
}

View File

@ -36,7 +36,7 @@ fn test_function_rename() {
a += 1;
}
return a
return a;
}
function main() {
@ -63,7 +63,7 @@ fn test_imports() {
}
function foo() -> u32 {
return 1u32
return 1u32;
}
"#;
imports

View File

@ -1,5 +1,5 @@
function one() -> u32 {
return 1u32
return 1u32;
}
function main() {

View File

@ -5,7 +5,7 @@ function iteration() -> u32 {
a += 1;
}
return a
return a;
}
function main() {

View File

@ -32,7 +32,7 @@ fn test_iteration() {
fn test_const_args() {
let program_string = r#"
function one(const value: u32) -> u32 {
return value + 1
return value + 1;
}
function main() {
@ -52,7 +52,7 @@ fn test_const_args() {
fn test_const_args_used() {
let program_string = r#"
function index(arr: [u8; 3], const value: u32) -> u8 {
return arr[value]
return arr[value];
}
function main() {
@ -73,7 +73,7 @@ fn test_const_args_used() {
fn test_const_args_fail() {
let program_string = r#"
function index(arr: [u8; 3], const value: u32) -> u8 {
return arr[value]
return arr[value];
}
function main(x_value: u32) {

View File

@ -1,5 +1,5 @@
function tuple() -> (bool, bool) {
return (true, false)
return (true, false);
}
function main() {

View File

@ -1,3 +1,3 @@
function main(input) -> (bool, bool) {
return (input.registers.a, input.registers.b)
}
function main() -> (bool, bool) {
return (input.registers.a, input.registers.b);
}

View File

@ -5,5 +5,5 @@ function main(
u32,
u32,
) {
return (a, b)
return (a, b);
}

View File

@ -1,5 +1,5 @@
function one() -> bool {
return true
return true;
}
function main() {

View File

@ -1,5 +1,5 @@
function one() -> u32 {
return 1u32
return 1u32;
}
function main() {

View File

@ -1,9 +1,9 @@
function array_3x2_nested() -> [[u8; 2]; 3] {
return [[0u8; 2]; 3]
return [[0u8; 2]; 3];
}
function array_3x2_tuple() -> [[u8; 2]; 3] {
return [0u8; (3, 2)]
return [0u8; (3, 2)];
}
function main() {

View File

@ -1,9 +1,9 @@
function array_3x2_nested() -> [u8; (3, 2)] {
return [[0u8; 2]; 3]
return [[0u8; 2]; 3];
}
function array_3x2_tuple() -> [u8; (3, 2)] {
return [0u8; (3, 2)]
return [0u8; (3, 2)];
}
function main() {

View File

@ -3,7 +3,7 @@ function tuples() -> ((u8, u8), u32) {
const a: (u8, u8) = (1, 2);
const b: u32 = 3;
return (a, b)
return (a, b);
}
function main() {

View File

@ -4,9 +4,9 @@ function tuple_conditional () -> (
i64
) {
if true {
return (1, 1)
return (1, 1);
} else {
return (2, 2)
return (2, 2);
}
}

View File

@ -4,5 +4,5 @@ circuit Point {
}
function foo() -> u32 {
return 1u32
return 1u32;
}

View File

@ -1,4 +1,4 @@
function main(input, data: [u8; 32]) {
function main(data: [u8; 32]) {
console.assert(input.registers.value_balance == 0u64);
console.assert(input.state.leaf_index == 0u32);

View File

@ -1,4 +1,4 @@
function main(input) {
function main() {
console.assert(input.state.root == [0u8; 32]);
const expected: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;

View File

@ -1,3 +1,3 @@
function main(input) {
function main() {
console.assert(input.state.root == [0u8; 32]);
}

View File

@ -3,7 +3,7 @@ function swap(a: [u32; 2], const i: u32, const j: u32) -> [u32; 2] {
const t = a[i];
a[i] = a[j];
a[j] = t;
return a
return a;
}
function main() {

View File

@ -1,7 +1,7 @@
function main(input) -> u32 {
function main() -> u32 {
if input.registers.a == 0u32 {
return 0u32
return 0u32;
} else {
return 1u32
return 1u32;
}
}

View File

@ -1,5 +1,5 @@
function foo() -> (bool, bool) {
return (true, false)
return (true, false);
}
function main() {

View File

@ -1,5 +1,5 @@
function foo() -> (bool, bool) {
return (true, false)
return (true, false);
}
function main() {

View File

@ -1,5 +1,5 @@
function foo() -> (bool, bool) {
return (true, false)
return (true, false);
}
function main() {

View File

@ -1,6 +1,6 @@
[package]
name = "leo-ast"
version = "1.3.0"
version = "1.4.0"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Core AST of the Leo programming language"
homepage = "https://aleo.org"
@ -19,7 +19,7 @@ edition = "2018"
[dependencies.leo-input]
path = "../input"
version = "1.3.0"
version = "1.4.0"
[dependencies.indexmap]
version = "1.6.2"

View File

@ -23,9 +23,6 @@ pub use const_self_keyword::*;
pub mod identifier;
pub use identifier::*;
pub mod input_keyword;
pub use input_keyword::*;
pub mod mut_self_keyword;
pub use mut_self_keyword::*;

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{FormattedError, Span};
use crate::{FormattedError, LeoError, Span};
#[derive(Debug, Error)]
pub enum CanonicalizeError {
@ -22,6 +22,8 @@ pub enum CanonicalizeError {
Error(#[from] FormattedError),
}
impl LeoError for CanonicalizeError {}
impl CanonicalizeError {
fn new_from_span(message: String, span: &Span) -> Self {
CanonicalizeError::Error(FormattedError::new_from_span(message, span))

View File

@ -14,31 +14,30 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{Identifier, Node, Span};
use crate::{FormattedError, LeoError, Span};
use serde::{Deserialize, Serialize};
use std::fmt;
/// The `input` keyword can view program register, record, and state values.
/// Values cannot be modified. The `input` keyword cannot be made mutable.
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[serde(transparent)]
pub struct InputKeyword {
pub identifier: Identifier,
#[derive(Debug, Error)]
pub enum CombinerError {
#[error("{}", _0)]
Error(#[from] FormattedError),
}
impl fmt::Display for InputKeyword {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "input")
}
}
impl LeoError for CombinerError {}
impl Node for InputKeyword {
fn span(&self) -> &Span {
&self.identifier.span
impl CombinerError {
fn new_from_span(message: String, span: &Span) -> Self {
CombinerError::Error(FormattedError::new_from_span(message, span))
}
fn set_span(&mut self, span: Span) {
self.identifier.span = span;
pub fn asg_statement_not_block(span: &Span) -> Self {
let message = "AstStatement should be be a block".to_string();
Self::new_from_span(message, span)
}
pub fn illegal_compound_array_range(span: &Span) -> Self {
let message = "Illegal compound assignement with array range".to_string();
Self::new_from_span(message, span)
}
}

View File

@ -75,11 +75,11 @@ fn underline(mut start: usize, mut end: usize) -> String {
impl fmt::Display for FormattedError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let underline = underline(self.col_start - 1, self.col_stop - 1);
let underline = underline(self.col_start, self.col_stop);
write!(
f,
"{indent }--> {path}: {line_start}:{start}\n\
"{indent }--> {path}:{line_start}:{start}\n\
{indent } |\n",
indent = INDENT,
path = &*self.path,
@ -99,7 +99,7 @@ impl fmt::Display for FormattedError {
write!(
f,
"{indent } | {underline}\n\
"{indent } |{underline}\n\
{indent } |\n\
{indent } = {message}",
indent = INDENT,
@ -121,8 +121,8 @@ fn test_error() {
path: std::sync::Arc::new("file.leo".to_string()),
line_start: 2,
line_stop: 2,
col_start: 8,
col_stop: 9,
col_start: 9,
col_stop: 10,
content: "let a = x;".into(),
message: "undefined value `x`".to_string(),
};
@ -130,7 +130,7 @@ fn test_error() {
assert_eq!(
err.to_string(),
vec![
" --> file.leo: 2:8",
" --> file.leo:2:9",
" |",
" 2 | let a = x;",
" | ^",

View File

@ -14,7 +14,16 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
pub mod canonicalization;
pub use canonicalization::*;
pub mod combiner;
pub use combiner::*;
pub mod error;
pub use error::*;
pub mod reducer;
pub use reducer::*;
pub trait LeoError {}

43
ast/src/errors/reducer.rs Normal file
View File

@ -0,0 +1,43 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{CanonicalizeError, CombinerError, FormattedError, LeoError, Span};
#[derive(Debug, Error)]
pub enum ReducerError {
#[error("{}", _0)]
Error(#[from] FormattedError),
#[error("{}", _0)]
CanonicalizeError(#[from] CanonicalizeError),
#[error("{}", _0)]
CombinerError(#[from] CombinerError),
}
impl LeoError for ReducerError {}
impl ReducerError {
fn new_from_span(message: String, span: &Span) -> Self {
ReducerError::Error(FormattedError::new_from_span(message, span))
}
pub fn impossible_console_assert_call(span: &Span) -> Self {
let message = "Console::Assert cannot be matched here, its handled in another case.".to_string();
Self::new_from_span(message, span)
}
}

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{ConstSelfKeyword, FunctionInputVariable, InputKeyword, MutSelfKeyword, Node, SelfKeyword, Span};
use crate::{ConstSelfKeyword, FunctionInputVariable, MutSelfKeyword, Node, SelfKeyword, Span};
use serde::{Deserialize, Serialize};
use std::fmt;
@ -22,7 +22,6 @@ use std::fmt;
/// Enumerates the possible inputs to a function.
#[derive(Clone, Serialize, Deserialize)]
pub enum FunctionInput {
InputKeyword(InputKeyword),
SelfKeyword(SelfKeyword),
ConstSelfKeyword(ConstSelfKeyword),
MutSelfKeyword(MutSelfKeyword),
@ -36,7 +35,6 @@ impl FunctionInput {
///
pub fn is_self(&self) -> bool {
match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => true,
FunctionInput::ConstSelfKeyword(_) => true,
FunctionInput::MutSelfKeyword(_) => true,
@ -50,7 +48,6 @@ impl FunctionInput {
///
pub fn is_const_self(&self) -> bool {
match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => false,
FunctionInput::ConstSelfKeyword(_) => true,
FunctionInput::MutSelfKeyword(_) => false,
@ -64,7 +61,6 @@ impl FunctionInput {
///
pub fn is_mut_self(&self) -> bool {
match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => false,
FunctionInput::ConstSelfKeyword(_) => false,
FunctionInput::MutSelfKeyword(_) => true,
@ -74,7 +70,6 @@ impl FunctionInput {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionInput::InputKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::SelfKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::ConstSelfKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::MutSelfKeyword(keyword) => write!(f, "{}", keyword),
@ -99,7 +94,6 @@ impl PartialEq for FunctionInput {
/// Returns true if `self == other`. Does not compare spans.
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(FunctionInput::InputKeyword(_), FunctionInput::InputKeyword(_)) => true,
(FunctionInput::SelfKeyword(_), FunctionInput::SelfKeyword(_)) => true,
(FunctionInput::ConstSelfKeyword(_), FunctionInput::ConstSelfKeyword(_)) => true,
(FunctionInput::MutSelfKeyword(_), FunctionInput::MutSelfKeyword(_)) => true,
@ -115,7 +109,6 @@ impl Node for FunctionInput {
fn span(&self) -> &Span {
use FunctionInput::*;
match self {
InputKeyword(keyword) => &keyword.identifier.span,
SelfKeyword(keyword) => &keyword.identifier.span,
ConstSelfKeyword(keyword) => &keyword.identifier.span,
MutSelfKeyword(keyword) => &keyword.identifier.span,
@ -126,7 +119,6 @@ impl Node for FunctionInput {
fn set_span(&mut self, span: Span) {
use FunctionInput::*;
match self {
InputKeyword(keyword) => keyword.identifier.span = span,
SelfKeyword(keyword) => keyword.identifier.span = span,
ConstSelfKeyword(keyword) => keyword.identifier.span = span,
MutSelfKeyword(keyword) => keyword.identifier.span = span,

View File

@ -71,7 +71,7 @@ pub use node::*;
/// These data types form a tree that begins from a [`Program`] type root.
///
/// A new [`Ast`] can be created from a [`Grammar`] generated by the pest parser in the `grammar` module.
#[derive(Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Ast {
ast: Program,
}
@ -83,7 +83,7 @@ impl Ast {
}
/// Mutates the program ast by preforming canonicalization on it.
pub fn canonicalize(&mut self) -> Result<(), CanonicalizeError> {
pub fn canonicalize(&mut self) -> Result<(), ReducerError> {
self.ast = ReconstructingDirector::new(Canonicalizer::default()).reduce_program(self.as_repr())?;
Ok(())
}

View File

@ -25,11 +25,78 @@ use crate::*;
pub struct Canonicalizer {
// If we are in a circuit keep track of the circuit name.
circuit_name: Option<Identifier>,
in_circuit: bool,
}
impl Default for Canonicalizer {
fn default() -> Self {
Self {
circuit_name: None,
in_circuit: false,
}
}
}
impl Canonicalizer {
pub fn default() -> Self {
Self { circuit_name: None }
pub fn canonicalize_accesses(
&mut self,
start: Expression,
accesses: &[AssigneeAccess],
span: &Span,
) -> Result<Box<Expression>, ReducerError> {
let mut left = Box::new(start);
for access in accesses.iter() {
match self.canonicalize_assignee_access(&access) {
AssigneeAccess::ArrayIndex(index) => {
left = Box::new(Expression::ArrayAccess(ArrayAccessExpression {
array: left,
index: Box::new(index),
span: span.clone(),
}));
}
AssigneeAccess::Tuple(positive_number, _) => {
left = Box::new(Expression::TupleAccess(TupleAccessExpression {
tuple: left,
index: positive_number,
span: span.clone(),
}));
}
AssigneeAccess::Member(identifier) => {
left = Box::new(Expression::CircuitMemberAccess(CircuitMemberAccessExpression {
circuit: left,
name: identifier,
span: span.clone(),
}));
}
_ => return Err(ReducerError::from(CombinerError::illegal_compound_array_range(&span))),
}
}
Ok(left)
}
pub fn compound_operation_converstion(
&mut self,
operation: &AssignOperation,
) -> Result<BinaryOperation, ReducerError> {
match operation {
AssignOperation::Assign => unreachable!(),
AssignOperation::Add => Ok(BinaryOperation::Add),
AssignOperation::Sub => Ok(BinaryOperation::Sub),
AssignOperation::Mul => Ok(BinaryOperation::Mul),
AssignOperation::Div => Ok(BinaryOperation::Div),
AssignOperation::Pow => Ok(BinaryOperation::Pow),
AssignOperation::Or => Ok(BinaryOperation::Or),
AssignOperation::And => Ok(BinaryOperation::And),
AssignOperation::BitOr => Ok(BinaryOperation::BitOr),
AssignOperation::BitAnd => Ok(BinaryOperation::BitAnd),
AssignOperation::BitXor => Ok(BinaryOperation::BitXor),
AssignOperation::Shr => Ok(BinaryOperation::Shr),
AssignOperation::ShrSigned => Ok(BinaryOperation::ShrSigned),
AssignOperation::Shl => Ok(BinaryOperation::Shl),
AssignOperation::Mod => Ok(BinaryOperation::Mod),
}
}
fn is_self_type(&mut self, type_option: Option<&Type>) -> bool {
@ -324,7 +391,7 @@ impl Canonicalizer {
.map(|parameter| self.canonicalize_expression(parameter))
.collect();
let formatted = FormattedString {
let formatted = FormatString {
parts: format.parts.clone(),
parameters,
span: format.span.clone(),
@ -380,17 +447,21 @@ impl Canonicalizer {
}
impl ReconstructingReducer for Canonicalizer {
fn reduce_type(
&mut self,
_type_: &Type,
new: Type,
in_circuit: bool,
span: &Span,
) -> Result<Type, CanonicalizeError> {
fn in_circuit(&self) -> bool {
self.in_circuit
}
fn swap_in_circuit(&mut self) {
self.in_circuit = !self.in_circuit;
}
fn reduce_type(&mut self, _type_: &Type, new: Type, span: &Span) -> Result<Type, ReducerError> {
match new {
Type::Array(type_, mut dimensions) => {
if dimensions.is_zero() {
return Err(CanonicalizeError::invalid_array_dimension_size(span));
return Err(ReducerError::from(CanonicalizeError::invalid_array_dimension_size(
span,
)));
}
let mut next = Type::Array(type_, ArrayDimensions(vec![dimensions.remove_last().unwrap()]));
@ -407,7 +478,9 @@ impl ReconstructingReducer for Canonicalizer {
Ok(array)
}
Type::SelfType if !in_circuit => Err(CanonicalizeError::big_self_outside_of_circuit(span)),
Type::SelfType if !self.in_circuit => {
Err(ReducerError::from(CanonicalizeError::big_self_outside_of_circuit(span)))
}
_ => Ok(new.clone()),
}
}
@ -416,10 +489,11 @@ impl ReconstructingReducer for Canonicalizer {
&mut self,
array_init: &ArrayInitExpression,
element: Expression,
_in_circuit: bool,
) -> Result<ArrayInitExpression, CanonicalizeError> {
) -> Result<ArrayInitExpression, ReducerError> {
if array_init.dimensions.is_zero() {
return Err(CanonicalizeError::invalid_array_dimension_size(&array_init.span));
return Err(ReducerError::from(CanonicalizeError::invalid_array_dimension_size(
&array_init.span,
)));
}
let element = Box::new(element);
@ -466,58 +540,39 @@ impl ReconstructingReducer for Canonicalizer {
assign: &AssignStatement,
assignee: Assignee,
value: Expression,
_in_circuit: bool,
) -> Result<AssignStatement, CanonicalizeError> {
) -> Result<AssignStatement, ReducerError> {
match value {
Expression::Binary(binary_expr) if assign.operation != AssignOperation::Assign => {
let left = self.canonicalize_accesses(
Expression::Identifier(assignee.identifier.clone()),
&assignee.accesses,
&assign.span,
)?;
let right = Box::new(Expression::Binary(binary_expr));
let op = self.compound_operation_converstion(&assign.operation)?;
let new_value = Expression::Binary(BinaryExpression {
left,
right,
op,
span: assign.span.clone(),
});
Ok(AssignStatement {
operation: AssignOperation::Assign,
assignee,
value: new_value,
span: assign.span.clone(),
})
}
Expression::Value(value_expr) if assign.operation != AssignOperation::Assign => {
let mut left = Box::new(Expression::Identifier(assignee.identifier.clone()));
for access in assignee.accesses.iter().rev() {
match self.canonicalize_assignee_access(&access) {
AssigneeAccess::ArrayIndex(index) => {
left = Box::new(Expression::ArrayAccess(ArrayAccessExpression {
array: left,
index: Box::new(index),
span: assign.span.clone(),
}));
}
AssigneeAccess::Tuple(positive_number, _) => {
left = Box::new(Expression::TupleAccess(TupleAccessExpression {
tuple: left,
index: positive_number,
span: assign.span.clone(),
}));
}
AssigneeAccess::Member(identifier) => {
left = Box::new(Expression::CircuitMemberAccess(CircuitMemberAccessExpression {
circuit: left,
name: identifier,
span: assign.span.clone(),
}));
}
_ => unimplemented!(), // No reason for someone to compute ArrayRanges.
}
}
let left = self.canonicalize_accesses(
Expression::Identifier(assignee.identifier.clone()),
&assignee.accesses,
&assign.span,
)?;
let right = Box::new(Expression::Value(value_expr));
let op = match assign.operation {
AssignOperation::Assign => unimplemented!(), // Imposible
AssignOperation::Add => BinaryOperation::Add,
AssignOperation::Sub => BinaryOperation::Sub,
AssignOperation::Mul => BinaryOperation::Mul,
AssignOperation::Div => BinaryOperation::Div,
AssignOperation::Pow => BinaryOperation::Pow,
AssignOperation::Or => BinaryOperation::Or,
AssignOperation::And => BinaryOperation::And,
AssignOperation::BitOr => BinaryOperation::BitOr,
AssignOperation::BitAnd => BinaryOperation::BitAnd,
AssignOperation::BitXor => BinaryOperation::BitXor,
AssignOperation::Shr => BinaryOperation::Shr,
AssignOperation::ShrSigned => BinaryOperation::ShrSigned,
AssignOperation::Shl => BinaryOperation::Shl,
AssignOperation::Mod => BinaryOperation::Mod,
};
let op = self.compound_operation_converstion(&assign.operation)?;
let new_value = Expression::Binary(BinaryExpression {
left,
@ -545,8 +600,7 @@ impl ReconstructingReducer for Canonicalizer {
input: Vec<FunctionInput>,
output: Option<Type>,
block: Block,
_in_circuit: bool,
) -> Result<Function, CanonicalizeError> {
) -> Result<Function, ReducerError> {
let new_output = match output {
None => Some(Type::Tuple(vec![])),
_ => output,
@ -567,7 +621,7 @@ impl ReconstructingReducer for Canonicalizer {
_circuit: &Circuit,
circuit_name: Identifier,
members: Vec<CircuitMember>,
) -> Result<Circuit, CanonicalizeError> {
) -> Result<Circuit, ReducerError> {
self.circuit_name = Some(circuit_name.clone());
let circ = Circuit {
circuit_name,

View File

@ -17,9 +17,6 @@
mod canonicalization;
pub use canonicalization::*;
mod errors;
pub use errors::*;
mod reconstructing_reducer;
pub use reconstructing_reducer::*;

View File

@ -22,18 +22,14 @@ use indexmap::IndexMap;
pub struct ReconstructingDirector<R: ReconstructingReducer> {
reducer: R,
in_circuit: bool,
}
impl<R: ReconstructingReducer> ReconstructingDirector<R> {
pub fn new(reducer: R) -> Self {
Self {
reducer,
in_circuit: false,
}
Self { reducer }
}
pub fn reduce_type(&mut self, type_: &Type, span: &Span) -> Result<Type, CanonicalizeError> {
pub fn reduce_type(&mut self, type_: &Type, span: &Span) -> Result<Type, ReducerError> {
let new = match type_ {
Type::Array(type_, dimensions) => Type::Array(Box::new(self.reduce_type(type_, span)?), dimensions.clone()),
Type::Tuple(types) => {
@ -48,11 +44,11 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
_ => type_.clone(),
};
self.reducer.reduce_type(type_, new, self.in_circuit, span)
self.reducer.reduce_type(type_, new, span)
}
// Expressions
pub fn reduce_expression(&mut self, expression: &Expression) -> Result<Expression, CanonicalizeError> {
pub fn reduce_expression(&mut self, expression: &Expression) -> Result<Expression, ReducerError> {
let new = match expression {
Expression::Identifier(identifier) => Expression::Identifier(self.reduce_identifier(&identifier)?),
Expression::Value(value) => Expression::Value(self.reduce_value(&value)?),
@ -84,18 +80,18 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
Expression::Call(call) => Expression::Call(self.reduce_call(&call)?),
};
self.reducer.reduce_expression(expression, new, self.in_circuit)
self.reducer.reduce_expression(expression, new)
}
pub fn reduce_identifier(&mut self, identifier: &Identifier) -> Result<Identifier, CanonicalizeError> {
pub fn reduce_identifier(&mut self, identifier: &Identifier) -> Result<Identifier, ReducerError> {
self.reducer.reduce_identifier(identifier)
}
pub fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> Result<GroupTuple, CanonicalizeError> {
pub fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> Result<GroupTuple, ReducerError> {
self.reducer.reduce_group_tuple(group_tuple)
}
pub fn reduce_group_value(&mut self, group_value: &GroupValue) -> Result<GroupValue, CanonicalizeError> {
pub fn reduce_group_value(&mut self, group_value: &GroupValue) -> Result<GroupValue, ReducerError> {
let new = match group_value {
GroupValue::Tuple(group_tuple) => GroupValue::Tuple(self.reduce_group_tuple(&group_tuple)?),
_ => group_value.clone(),
@ -104,7 +100,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
self.reducer.reduce_group_value(group_value, new)
}
pub fn reduce_value(&mut self, value: &ValueExpression) -> Result<ValueExpression, CanonicalizeError> {
pub fn reduce_value(&mut self, value: &ValueExpression) -> Result<ValueExpression, ReducerError> {
let new = match value {
ValueExpression::Group(group_value) => {
ValueExpression::Group(Box::new(self.reduce_group_value(&group_value)?))
@ -115,41 +111,38 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
self.reducer.reduce_value(value, new)
}
pub fn reduce_binary(&mut self, binary: &BinaryExpression) -> Result<BinaryExpression, CanonicalizeError> {
pub fn reduce_binary(&mut self, binary: &BinaryExpression) -> Result<BinaryExpression, ReducerError> {
let left = self.reduce_expression(&binary.left)?;
let right = self.reduce_expression(&binary.right)?;
self.reducer
.reduce_binary(binary, left, right, binary.op.clone(), self.in_circuit)
self.reducer.reduce_binary(binary, left, right, binary.op.clone())
}
pub fn reduce_unary(&mut self, unary: &UnaryExpression) -> Result<UnaryExpression, CanonicalizeError> {
pub fn reduce_unary(&mut self, unary: &UnaryExpression) -> Result<UnaryExpression, ReducerError> {
let inner = self.reduce_expression(&unary.inner)?;
self.reducer
.reduce_unary(unary, inner, unary.op.clone(), self.in_circuit)
self.reducer.reduce_unary(unary, inner, unary.op.clone())
}
pub fn reduce_ternary(&mut self, ternary: &TernaryExpression) -> Result<TernaryExpression, CanonicalizeError> {
pub fn reduce_ternary(&mut self, ternary: &TernaryExpression) -> Result<TernaryExpression, ReducerError> {
let condition = self.reduce_expression(&ternary.condition)?;
let if_true = self.reduce_expression(&ternary.if_true)?;
let if_false = self.reduce_expression(&ternary.if_false)?;
self.reducer
.reduce_ternary(ternary, condition, if_true, if_false, self.in_circuit)
self.reducer.reduce_ternary(ternary, condition, if_true, if_false)
}
pub fn reduce_cast(&mut self, cast: &CastExpression) -> Result<CastExpression, CanonicalizeError> {
pub fn reduce_cast(&mut self, cast: &CastExpression) -> Result<CastExpression, ReducerError> {
let inner = self.reduce_expression(&cast.inner)?;
let target_type = self.reduce_type(&cast.target_type, &cast.span)?;
self.reducer.reduce_cast(cast, inner, target_type, self.in_circuit)
self.reducer.reduce_cast(cast, inner, target_type)
}
pub fn reduce_array_inline(
&mut self,
array_inline: &ArrayInlineExpression,
) -> Result<ArrayInlineExpression, CanonicalizeError> {
) -> Result<ArrayInlineExpression, ReducerError> {
let mut elements = vec![];
for element in array_inline.elements.iter() {
let reduced_element = match element {
@ -164,34 +157,29 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
elements.push(reduced_element);
}
self.reducer
.reduce_array_inline(array_inline, elements, self.in_circuit)
self.reducer.reduce_array_inline(array_inline, elements)
}
pub fn reduce_array_init(
&mut self,
array_init: &ArrayInitExpression,
) -> Result<ArrayInitExpression, CanonicalizeError> {
pub fn reduce_array_init(&mut self, array_init: &ArrayInitExpression) -> Result<ArrayInitExpression, ReducerError> {
let element = self.reduce_expression(&array_init.element)?;
self.reducer.reduce_array_init(array_init, element, self.in_circuit)
self.reducer.reduce_array_init(array_init, element)
}
pub fn reduce_array_access(
&mut self,
array_access: &ArrayAccessExpression,
) -> Result<ArrayAccessExpression, CanonicalizeError> {
) -> Result<ArrayAccessExpression, ReducerError> {
let array = self.reduce_expression(&array_access.array)?;
let index = self.reduce_expression(&array_access.index)?;
self.reducer
.reduce_array_access(array_access, array, index, self.in_circuit)
self.reducer.reduce_array_access(array_access, array, index)
}
pub fn reduce_array_range_access(
&mut self,
array_range_access: &ArrayRangeAccessExpression,
) -> Result<ArrayRangeAccessExpression, CanonicalizeError> {
) -> Result<ArrayRangeAccessExpression, ReducerError> {
let array = self.reduce_expression(&array_range_access.array)?;
let left = array_range_access
.left
@ -205,34 +193,31 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
.transpose()?;
self.reducer
.reduce_array_range_access(array_range_access, array, left, right, self.in_circuit)
.reduce_array_range_access(array_range_access, array, left, right)
}
pub fn reduce_tuple_init(
&mut self,
tuple_init: &TupleInitExpression,
) -> Result<TupleInitExpression, CanonicalizeError> {
pub fn reduce_tuple_init(&mut self, tuple_init: &TupleInitExpression) -> Result<TupleInitExpression, ReducerError> {
let mut elements = vec![];
for element in tuple_init.elements.iter() {
elements.push(self.reduce_expression(element)?);
}
self.reducer.reduce_tuple_init(tuple_init, elements, self.in_circuit)
self.reducer.reduce_tuple_init(tuple_init, elements)
}
pub fn reduce_tuple_access(
&mut self,
tuple_access: &TupleAccessExpression,
) -> Result<TupleAccessExpression, CanonicalizeError> {
) -> Result<TupleAccessExpression, ReducerError> {
let tuple = self.reduce_expression(&tuple_access.tuple)?;
self.reducer.reduce_tuple_access(tuple_access, tuple, self.in_circuit)
self.reducer.reduce_tuple_access(tuple_access, tuple)
}
pub fn reduce_circuit_implied_variable_definition(
&mut self,
variable: &CircuitImpliedVariableDefinition,
) -> Result<CircuitImpliedVariableDefinition, CanonicalizeError> {
) -> Result<CircuitImpliedVariableDefinition, ReducerError> {
let identifier = self.reduce_identifier(&variable.identifier)?;
let expression = variable
.expression
@ -241,13 +226,13 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
.transpose()?;
self.reducer
.reduce_circuit_implied_variable_definition(variable, identifier, expression, self.in_circuit)
.reduce_circuit_implied_variable_definition(variable, identifier, expression)
}
pub fn reduce_circuit_init(
&mut self,
circuit_init: &CircuitInitExpression,
) -> Result<CircuitInitExpression, CanonicalizeError> {
) -> Result<CircuitInitExpression, ReducerError> {
let name = self.reduce_identifier(&circuit_init.name)?;
let mut members = vec![];
@ -255,33 +240,32 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
members.push(self.reduce_circuit_implied_variable_definition(member)?);
}
self.reducer
.reduce_circuit_init(circuit_init, name, members, self.in_circuit)
self.reducer.reduce_circuit_init(circuit_init, name, members)
}
pub fn reduce_circuit_member_access(
&mut self,
circuit_member_access: &CircuitMemberAccessExpression,
) -> Result<CircuitMemberAccessExpression, CanonicalizeError> {
) -> Result<CircuitMemberAccessExpression, ReducerError> {
let circuit = self.reduce_expression(&circuit_member_access.circuit)?;
let name = self.reduce_identifier(&circuit_member_access.name)?;
self.reducer
.reduce_circuit_member_access(circuit_member_access, circuit, name, self.in_circuit)
.reduce_circuit_member_access(circuit_member_access, circuit, name)
}
pub fn reduce_circuit_static_fn_access(
&mut self,
circuit_static_fn_access: &CircuitStaticFunctionAccessExpression,
) -> Result<CircuitStaticFunctionAccessExpression, CanonicalizeError> {
) -> Result<CircuitStaticFunctionAccessExpression, ReducerError> {
let circuit = self.reduce_expression(&circuit_static_fn_access.circuit)?;
let name = self.reduce_identifier(&circuit_static_fn_access.name)?;
self.reducer
.reduce_circuit_static_fn_access(circuit_static_fn_access, circuit, name, self.in_circuit)
.reduce_circuit_static_fn_access(circuit_static_fn_access, circuit, name)
}
pub fn reduce_call(&mut self, call: &CallExpression) -> Result<CallExpression, CanonicalizeError> {
pub fn reduce_call(&mut self, call: &CallExpression) -> Result<CallExpression, ReducerError> {
let function = self.reduce_expression(&call.function)?;
let mut arguments = vec![];
@ -289,11 +273,11 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
arguments.push(self.reduce_expression(argument)?);
}
self.reducer.reduce_call(call, function, arguments, self.in_circuit)
self.reducer.reduce_call(call, function, arguments)
}
// Statements
pub fn reduce_statement(&mut self, statement: &Statement) -> Result<Statement, CanonicalizeError> {
pub fn reduce_statement(&mut self, statement: &Statement) -> Result<Statement, ReducerError> {
let new = match statement {
Statement::Return(return_statement) => Statement::Return(self.reduce_return(&return_statement)?),
Statement::Definition(definition) => Statement::Definition(self.reduce_definition(&definition)?),
@ -305,26 +289,22 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
Statement::Block(block) => Statement::Block(self.reduce_block(&block)?),
};
self.reducer.reduce_statement(statement, new, self.in_circuit)
self.reducer.reduce_statement(statement, new)
}
pub fn reduce_return(&mut self, return_statement: &ReturnStatement) -> Result<ReturnStatement, CanonicalizeError> {
pub fn reduce_return(&mut self, return_statement: &ReturnStatement) -> Result<ReturnStatement, ReducerError> {
let expression = self.reduce_expression(&return_statement.expression)?;
self.reducer
.reduce_return(return_statement, expression, self.in_circuit)
self.reducer.reduce_return(return_statement, expression)
}
pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> Result<VariableName, CanonicalizeError> {
pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> Result<VariableName, ReducerError> {
let identifier = self.reduce_identifier(&variable_name.identifier)?;
self.reducer.reduce_variable_name(variable_name, identifier)
}
pub fn reduce_definition(
&mut self,
definition: &DefinitionStatement,
) -> Result<DefinitionStatement, CanonicalizeError> {
pub fn reduce_definition(&mut self, definition: &DefinitionStatement) -> Result<DefinitionStatement, ReducerError> {
let mut variable_names = vec![];
for variable_name in definition.variable_names.iter() {
variable_names.push(self.reduce_variable_name(variable_name)?);
@ -338,11 +318,10 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
let value = self.reduce_expression(&definition.value)?;
self.reducer
.reduce_definition(definition, variable_names, type_, value, self.in_circuit)
self.reducer.reduce_definition(definition, variable_names, type_, value)
}
pub fn reduce_assignee_access(&mut self, access: &AssigneeAccess) -> Result<AssigneeAccess, CanonicalizeError> {
pub fn reduce_assignee_access(&mut self, access: &AssigneeAccess) -> Result<AssigneeAccess, ReducerError> {
let new = match access {
AssigneeAccess::ArrayRange(left, right) => {
let left = left.as_ref().map(|left| self.reduce_expression(left)).transpose()?;
@ -355,10 +334,10 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
_ => access.clone(),
};
self.reducer.reduce_assignee_access(access, new, self.in_circuit)
self.reducer.reduce_assignee_access(access, new)
}
pub fn reduce_assignee(&mut self, assignee: &Assignee) -> Result<Assignee, CanonicalizeError> {
pub fn reduce_assignee(&mut self, assignee: &Assignee) -> Result<Assignee, ReducerError> {
let identifier = self.reduce_identifier(&assignee.identifier)?;
let mut accesses = vec![];
@ -366,21 +345,20 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
accesses.push(self.reduce_assignee_access(access)?);
}
self.reducer
.reduce_assignee(assignee, identifier, accesses, self.in_circuit)
self.reducer.reduce_assignee(assignee, identifier, accesses)
}
pub fn reduce_assign(&mut self, assign: &AssignStatement) -> Result<AssignStatement, CanonicalizeError> {
pub fn reduce_assign(&mut self, assign: &AssignStatement) -> Result<AssignStatement, ReducerError> {
let assignee = self.reduce_assignee(&assign.assignee)?;
let value = self.reduce_expression(&assign.value)?;
self.reducer.reduce_assign(assign, assignee, value, self.in_circuit)
self.reducer.reduce_assign(assign, assignee, value)
}
pub fn reduce_conditional(
&mut self,
conditional: &ConditionalStatement,
) -> Result<ConditionalStatement, CanonicalizeError> {
) -> Result<ConditionalStatement, ReducerError> {
let condition = self.reduce_expression(&conditional.condition)?;
let block = self.reduce_block(&conditional.block)?;
let next = conditional
@ -389,27 +367,22 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
.map(|condition| self.reduce_statement(condition))
.transpose()?;
self.reducer
.reduce_conditional(conditional, condition, block, next, self.in_circuit)
self.reducer.reduce_conditional(conditional, condition, block, next)
}
pub fn reduce_iteration(
&mut self,
iteration: &IterationStatement,
) -> Result<IterationStatement, CanonicalizeError> {
pub fn reduce_iteration(&mut self, iteration: &IterationStatement) -> Result<IterationStatement, ReducerError> {
let variable = self.reduce_identifier(&iteration.variable)?;
let start = self.reduce_expression(&iteration.start)?;
let stop = self.reduce_expression(&iteration.stop)?;
let block = self.reduce_block(&iteration.block)?;
self.reducer
.reduce_iteration(iteration, variable, start, stop, block, self.in_circuit)
self.reducer.reduce_iteration(iteration, variable, start, stop, block)
}
pub fn reduce_console(
&mut self,
console_function_call: &ConsoleStatement,
) -> Result<ConsoleStatement, CanonicalizeError> {
) -> Result<ConsoleStatement, ReducerError> {
let function = match &console_function_call.function {
ConsoleFunction::Assert(expression) => ConsoleFunction::Assert(self.reduce_expression(expression)?),
ConsoleFunction::Debug(format) | ConsoleFunction::Error(format) | ConsoleFunction::Log(format) => {
@ -418,7 +391,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
parameters.push(self.reduce_expression(parameter)?);
}
let formatted = FormattedString {
let formatted = FormatString {
parts: format.parts.clone(),
parameters,
span: format.span.clone(),
@ -428,35 +401,33 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
ConsoleFunction::Debug(_) => ConsoleFunction::Debug(formatted),
ConsoleFunction::Error(_) => ConsoleFunction::Error(formatted),
ConsoleFunction::Log(_) => ConsoleFunction::Log(formatted),
_ => unimplemented!(), // impossible
_ => return Err(ReducerError::impossible_console_assert_call(&format.span)),
}
}
};
self.reducer
.reduce_console(console_function_call, function, self.in_circuit)
self.reducer.reduce_console(console_function_call, function)
}
pub fn reduce_expression_statement(
&mut self,
expression: &ExpressionStatement,
) -> Result<ExpressionStatement, CanonicalizeError> {
) -> Result<ExpressionStatement, ReducerError> {
let inner_expression = self.reduce_expression(&expression.expression)?;
self.reducer
.reduce_expression_statement(expression, inner_expression, self.in_circuit)
self.reducer.reduce_expression_statement(expression, inner_expression)
}
pub fn reduce_block(&mut self, block: &Block) -> Result<Block, CanonicalizeError> {
pub fn reduce_block(&mut self, block: &Block) -> Result<Block, ReducerError> {
let mut statements = vec![];
for statement in block.statements.iter() {
statements.push(self.reduce_statement(statement)?);
}
self.reducer.reduce_block(block, statements, self.in_circuit)
self.reducer.reduce_block(block, statements)
}
// Program
pub fn reduce_program(&mut self, program: &Program) -> Result<Program, CanonicalizeError> {
pub fn reduce_program(&mut self, program: &Program) -> Result<Program, ReducerError> {
let mut inputs = vec![];
for input in program.expected_input.iter() {
inputs.push(self.reduce_function_input(input)?);
@ -468,9 +439,11 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
}
let mut circuits = IndexMap::new();
self.reducer.swap_in_circuit();
for (identifier, circuit) in program.circuits.iter() {
circuits.insert(self.reduce_identifier(identifier)?, self.reduce_circuit(circuit)?);
}
self.reducer.swap_in_circuit();
let mut functions = IndexMap::new();
for (identifier, function) in program.functions.iter() {
@ -484,15 +457,14 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
pub fn reduce_function_input_variable(
&mut self,
variable: &FunctionInputVariable,
) -> Result<FunctionInputVariable, CanonicalizeError> {
) -> Result<FunctionInputVariable, ReducerError> {
let identifier = self.reduce_identifier(&variable.identifier)?;
let type_ = self.reduce_type(&variable.type_, &variable.span)?;
self.reducer
.reduce_function_input_variable(variable, identifier, type_, self.in_circuit)
self.reducer.reduce_function_input_variable(variable, identifier, type_)
}
pub fn reduce_function_input(&mut self, input: &FunctionInput) -> Result<FunctionInput, CanonicalizeError> {
pub fn reduce_function_input(&mut self, input: &FunctionInput) -> Result<FunctionInput, ReducerError> {
let new = match input {
FunctionInput::Variable(function_input_variable) => {
FunctionInput::Variable(self.reduce_function_input_variable(function_input_variable)?)
@ -500,13 +472,13 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
_ => input.clone(),
};
self.reducer.reduce_function_input(input, new, self.in_circuit)
self.reducer.reduce_function_input(input, new)
}
pub fn reduce_package_or_packages(
&mut self,
package_or_packages: &PackageOrPackages,
) -> Result<PackageOrPackages, CanonicalizeError> {
) -> Result<PackageOrPackages, ReducerError> {
let new = match package_or_packages {
PackageOrPackages::Package(package) => PackageOrPackages::Package(Package {
name: self.reduce_identifier(&package.name)?,
@ -523,17 +495,13 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
self.reducer.reduce_package_or_packages(package_or_packages, new)
}
pub fn reduce_import(&mut self, import: &ImportStatement) -> Result<ImportStatement, CanonicalizeError> {
pub fn reduce_import(&mut self, import: &ImportStatement) -> Result<ImportStatement, ReducerError> {
let package_or_packages = self.reduce_package_or_packages(&import.package_or_packages)?;
self.reducer.reduce_import(import, package_or_packages)
}
pub fn reduce_circuit_member(
&mut self,
circuit_member: &CircuitMember,
) -> Result<CircuitMember, CanonicalizeError> {
self.in_circuit = !self.in_circuit;
pub fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember) -> Result<CircuitMember, ReducerError> {
let new = match circuit_member {
CircuitMember::CircuitVariable(identifier, type_) => CircuitMember::CircuitVariable(
self.reduce_identifier(&identifier)?,
@ -543,12 +511,11 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
CircuitMember::CircuitFunction(self.reduce_function(&function)?)
}
};
self.in_circuit = !self.in_circuit;
self.reducer.reduce_circuit_member(circuit_member, new)
}
pub fn reduce_circuit(&mut self, circuit: &Circuit) -> Result<Circuit, CanonicalizeError> {
pub fn reduce_circuit(&mut self, circuit: &Circuit) -> Result<Circuit, ReducerError> {
let circuit_name = self.reduce_identifier(&circuit.circuit_name)?;
let mut members = vec![];
@ -559,13 +526,13 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
self.reducer.reduce_circuit(circuit, circuit_name, members)
}
fn reduce_annotation(&mut self, annotation: &Annotation) -> Result<Annotation, CanonicalizeError> {
fn reduce_annotation(&mut self, annotation: &Annotation) -> Result<Annotation, ReducerError> {
let name = self.reduce_identifier(&annotation.name)?;
self.reducer.reduce_annotation(annotation, name)
}
pub fn reduce_function(&mut self, function: &Function) -> Result<Function, CanonicalizeError> {
pub fn reduce_function(&mut self, function: &Function) -> Result<Function, ReducerError> {
let identifier = self.reduce_identifier(&function.identifier)?;
let mut annotations = vec![];
@ -586,14 +553,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
let block = self.reduce_block(&function.block)?;
self.reducer.reduce_function(
function,
identifier,
annotations,
inputs,
output,
block,
self.in_circuit,
)
self.reducer
.reduce_function(function, identifier, annotations, inputs, output, block)
}
}

View File

@ -20,34 +20,26 @@ use indexmap::IndexMap;
// Needed to fix clippy bug.
#[allow(clippy::redundant_closure)]
pub trait ReconstructingReducer {
fn reduce_type(
&mut self,
_type_: &Type,
new: Type,
_in_circuit: bool,
_span: &Span,
) -> Result<Type, CanonicalizeError> {
fn in_circuit(&self) -> bool;
fn swap_in_circuit(&mut self);
fn reduce_type(&mut self, _type_: &Type, new: Type, _span: &Span) -> Result<Type, ReducerError> {
Ok(new)
}
// Expressions
fn reduce_expression(
&mut self,
_expression: &Expression,
new: Expression,
_in_circuit: bool,
) -> Result<Expression, CanonicalizeError> {
fn reduce_expression(&mut self, _expression: &Expression, new: Expression) -> Result<Expression, ReducerError> {
Ok(new)
}
fn reduce_identifier(&mut self, identifier: &Identifier) -> Result<Identifier, CanonicalizeError> {
fn reduce_identifier(&mut self, identifier: &Identifier) -> Result<Identifier, ReducerError> {
Ok(Identifier {
name: identifier.name.clone(),
span: identifier.span.clone(),
})
}
fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> Result<GroupTuple, CanonicalizeError> {
fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> Result<GroupTuple, ReducerError> {
Ok(GroupTuple {
x: group_tuple.x.clone(),
y: group_tuple.y.clone(),
@ -55,11 +47,7 @@ pub trait ReconstructingReducer {
})
}
fn reduce_group_value(
&mut self,
_group_value: &GroupValue,
new: GroupValue,
) -> Result<GroupValue, CanonicalizeError> {
fn reduce_group_value(&mut self, _group_value: &GroupValue, new: GroupValue) -> Result<GroupValue, ReducerError> {
Ok(new)
}
@ -67,7 +55,7 @@ pub trait ReconstructingReducer {
&mut self,
_value: &ValueExpression,
new: ValueExpression,
) -> Result<ValueExpression, CanonicalizeError> {
) -> Result<ValueExpression, ReducerError> {
Ok(new)
}
@ -77,8 +65,7 @@ pub trait ReconstructingReducer {
left: Expression,
right: Expression,
op: BinaryOperation,
_in_circuit: bool,
) -> Result<BinaryExpression, CanonicalizeError> {
) -> Result<BinaryExpression, ReducerError> {
Ok(BinaryExpression {
left: Box::new(left),
right: Box::new(right),
@ -92,8 +79,7 @@ pub trait ReconstructingReducer {
unary: &UnaryExpression,
inner: Expression,
op: UnaryOperation,
_in_circuit: bool,
) -> Result<UnaryExpression, CanonicalizeError> {
) -> Result<UnaryExpression, ReducerError> {
Ok(UnaryExpression {
inner: Box::new(inner),
op,
@ -107,8 +93,7 @@ pub trait ReconstructingReducer {
condition: Expression,
if_true: Expression,
if_false: Expression,
_in_circuit: bool,
) -> Result<TernaryExpression, CanonicalizeError> {
) -> Result<TernaryExpression, ReducerError> {
Ok(TernaryExpression {
condition: Box::new(condition),
if_true: Box::new(if_true),
@ -122,8 +107,7 @@ pub trait ReconstructingReducer {
cast: &CastExpression,
inner: Expression,
target_type: Type,
_in_circuit: bool,
) -> Result<CastExpression, CanonicalizeError> {
) -> Result<CastExpression, ReducerError> {
Ok(CastExpression {
inner: Box::new(inner),
target_type,
@ -135,8 +119,7 @@ pub trait ReconstructingReducer {
&mut self,
array_inline: &ArrayInlineExpression,
elements: Vec<SpreadOrExpression>,
_in_circuit: bool,
) -> Result<ArrayInlineExpression, CanonicalizeError> {
) -> Result<ArrayInlineExpression, ReducerError> {
Ok(ArrayInlineExpression {
elements,
span: array_inline.span.clone(),
@ -147,8 +130,7 @@ pub trait ReconstructingReducer {
&mut self,
array_init: &ArrayInitExpression,
element: Expression,
_in_circuit: bool,
) -> Result<ArrayInitExpression, CanonicalizeError> {
) -> Result<ArrayInitExpression, ReducerError> {
Ok(ArrayInitExpression {
element: Box::new(element),
dimensions: array_init.dimensions.clone(),
@ -161,8 +143,7 @@ pub trait ReconstructingReducer {
array_access: &ArrayAccessExpression,
array: Expression,
index: Expression,
_in_circuit: bool,
) -> Result<ArrayAccessExpression, CanonicalizeError> {
) -> Result<ArrayAccessExpression, ReducerError> {
Ok(ArrayAccessExpression {
array: Box::new(array),
index: Box::new(index),
@ -176,8 +157,7 @@ pub trait ReconstructingReducer {
array: Expression,
left: Option<Expression>,
right: Option<Expression>,
_in_circuit: bool,
) -> Result<ArrayRangeAccessExpression, CanonicalizeError> {
) -> Result<ArrayRangeAccessExpression, ReducerError> {
Ok(ArrayRangeAccessExpression {
array: Box::new(array),
left: left.map(|expr| Box::new(expr)),
@ -190,8 +170,7 @@ pub trait ReconstructingReducer {
&mut self,
tuple_init: &TupleInitExpression,
elements: Vec<Expression>,
_in_circuit: bool,
) -> Result<TupleInitExpression, CanonicalizeError> {
) -> Result<TupleInitExpression, ReducerError> {
Ok(TupleInitExpression {
elements,
span: tuple_init.span.clone(),
@ -202,8 +181,7 @@ pub trait ReconstructingReducer {
&mut self,
tuple_access: &TupleAccessExpression,
tuple: Expression,
_in_circuit: bool,
) -> Result<TupleAccessExpression, CanonicalizeError> {
) -> Result<TupleAccessExpression, ReducerError> {
Ok(TupleAccessExpression {
tuple: Box::new(tuple),
index: tuple_access.index.clone(),
@ -216,8 +194,7 @@ pub trait ReconstructingReducer {
_variable: &CircuitImpliedVariableDefinition,
identifier: Identifier,
expression: Option<Expression>,
_in_circuit: bool,
) -> Result<CircuitImpliedVariableDefinition, CanonicalizeError> {
) -> Result<CircuitImpliedVariableDefinition, ReducerError> {
Ok(CircuitImpliedVariableDefinition { identifier, expression })
}
@ -226,8 +203,7 @@ pub trait ReconstructingReducer {
circuit_init: &CircuitInitExpression,
name: Identifier,
members: Vec<CircuitImpliedVariableDefinition>,
_in_circuit: bool,
) -> Result<CircuitInitExpression, CanonicalizeError> {
) -> Result<CircuitInitExpression, ReducerError> {
Ok(CircuitInitExpression {
name,
members,
@ -240,8 +216,7 @@ pub trait ReconstructingReducer {
circuit_member_access: &CircuitMemberAccessExpression,
circuit: Expression,
name: Identifier,
_in_circuit: bool,
) -> Result<CircuitMemberAccessExpression, CanonicalizeError> {
) -> Result<CircuitMemberAccessExpression, ReducerError> {
Ok(CircuitMemberAccessExpression {
circuit: Box::new(circuit),
name,
@ -254,8 +229,7 @@ pub trait ReconstructingReducer {
circuit_static_fn_access: &CircuitStaticFunctionAccessExpression,
circuit: Expression,
name: Identifier,
_in_circuit: bool,
) -> Result<CircuitStaticFunctionAccessExpression, CanonicalizeError> {
) -> Result<CircuitStaticFunctionAccessExpression, ReducerError> {
Ok(CircuitStaticFunctionAccessExpression {
circuit: Box::new(circuit),
name,
@ -268,8 +242,7 @@ pub trait ReconstructingReducer {
call: &CallExpression,
function: Expression,
arguments: Vec<Expression>,
_in_circuit: bool,
) -> Result<CallExpression, CanonicalizeError> {
) -> Result<CallExpression, ReducerError> {
Ok(CallExpression {
function: Box::new(function),
arguments,
@ -278,12 +251,7 @@ pub trait ReconstructingReducer {
}
// Statements
fn reduce_statement(
&mut self,
_statement: &Statement,
new: Statement,
_in_circuit: bool,
) -> Result<Statement, CanonicalizeError> {
fn reduce_statement(&mut self, _statement: &Statement, new: Statement) -> Result<Statement, ReducerError> {
Ok(new)
}
@ -291,8 +259,7 @@ pub trait ReconstructingReducer {
&mut self,
return_statement: &ReturnStatement,
expression: Expression,
_in_circuit: bool,
) -> Result<ReturnStatement, CanonicalizeError> {
) -> Result<ReturnStatement, ReducerError> {
Ok(ReturnStatement {
expression,
span: return_statement.span.clone(),
@ -303,7 +270,7 @@ pub trait ReconstructingReducer {
&mut self,
variable_name: &VariableName,
identifier: Identifier,
) -> Result<VariableName, CanonicalizeError> {
) -> Result<VariableName, ReducerError> {
Ok(VariableName {
mutable: variable_name.mutable,
identifier,
@ -317,8 +284,7 @@ pub trait ReconstructingReducer {
variable_names: Vec<VariableName>,
type_: Option<Type>,
value: Expression,
_in_circuit: bool,
) -> Result<DefinitionStatement, CanonicalizeError> {
) -> Result<DefinitionStatement, ReducerError> {
Ok(DefinitionStatement {
declaration_type: definition.declaration_type.clone(),
variable_names,
@ -332,8 +298,7 @@ pub trait ReconstructingReducer {
&mut self,
_access: &AssigneeAccess,
new: AssigneeAccess,
_in_circuit: bool,
) -> Result<AssigneeAccess, CanonicalizeError> {
) -> Result<AssigneeAccess, ReducerError> {
Ok(new)
}
@ -342,8 +307,7 @@ pub trait ReconstructingReducer {
assignee: &Assignee,
identifier: Identifier,
accesses: Vec<AssigneeAccess>,
_in_circuit: bool,
) -> Result<Assignee, CanonicalizeError> {
) -> Result<Assignee, ReducerError> {
Ok(Assignee {
identifier,
accesses,
@ -356,8 +320,7 @@ pub trait ReconstructingReducer {
assign: &AssignStatement,
assignee: Assignee,
value: Expression,
_in_circuit: bool,
) -> Result<AssignStatement, CanonicalizeError> {
) -> Result<AssignStatement, ReducerError> {
Ok(AssignStatement {
operation: assign.operation.clone(),
assignee,
@ -372,8 +335,7 @@ pub trait ReconstructingReducer {
condition: Expression,
block: Block,
statement: Option<Statement>,
_in_circuit: bool,
) -> Result<ConditionalStatement, CanonicalizeError> {
) -> Result<ConditionalStatement, ReducerError> {
Ok(ConditionalStatement {
condition,
block,
@ -389,8 +351,7 @@ pub trait ReconstructingReducer {
start: Expression,
stop: Expression,
block: Block,
_in_circuit: bool,
) -> Result<IterationStatement, CanonicalizeError> {
) -> Result<IterationStatement, ReducerError> {
Ok(IterationStatement {
variable,
start,
@ -404,8 +365,7 @@ pub trait ReconstructingReducer {
&mut self,
console: &ConsoleStatement,
function: ConsoleFunction,
_in_circuit: bool,
) -> Result<ConsoleStatement, CanonicalizeError> {
) -> Result<ConsoleStatement, ReducerError> {
Ok(ConsoleStatement {
function,
span: console.span.clone(),
@ -416,20 +376,14 @@ pub trait ReconstructingReducer {
&mut self,
expression_statement: &ExpressionStatement,
expression: Expression,
_in_circuit: bool,
) -> Result<ExpressionStatement, CanonicalizeError> {
) -> Result<ExpressionStatement, ReducerError> {
Ok(ExpressionStatement {
expression,
span: expression_statement.span.clone(),
})
}
fn reduce_block(
&mut self,
block: &Block,
statements: Vec<Statement>,
_in_circuit: bool,
) -> Result<Block, CanonicalizeError> {
fn reduce_block(&mut self, block: &Block, statements: Vec<Statement>) -> Result<Block, ReducerError> {
Ok(Block {
statements,
span: block.span.clone(),
@ -444,7 +398,7 @@ pub trait ReconstructingReducer {
imports: Vec<ImportStatement>,
circuits: IndexMap<Identifier, Circuit>,
functions: IndexMap<Identifier, Function>,
) -> Result<Program, CanonicalizeError> {
) -> Result<Program, ReducerError> {
Ok(Program {
name: program.name.clone(),
expected_input,
@ -459,8 +413,7 @@ pub trait ReconstructingReducer {
variable: &FunctionInputVariable,
identifier: Identifier,
type_: Type,
_in_circuit: bool,
) -> Result<FunctionInputVariable, CanonicalizeError> {
) -> Result<FunctionInputVariable, ReducerError> {
Ok(FunctionInputVariable {
identifier,
const_: variable.const_,
@ -474,8 +427,7 @@ pub trait ReconstructingReducer {
&mut self,
_input: &FunctionInput,
new: FunctionInput,
_in_circuit: bool,
) -> Result<FunctionInput, CanonicalizeError> {
) -> Result<FunctionInput, ReducerError> {
Ok(new)
}
@ -483,7 +435,7 @@ pub trait ReconstructingReducer {
&mut self,
_package_or_packages: &PackageOrPackages,
new: PackageOrPackages,
) -> Result<PackageOrPackages, CanonicalizeError> {
) -> Result<PackageOrPackages, ReducerError> {
Ok(new)
}
@ -491,7 +443,7 @@ pub trait ReconstructingReducer {
&mut self,
import: &ImportStatement,
package_or_packages: PackageOrPackages,
) -> Result<ImportStatement, CanonicalizeError> {
) -> Result<ImportStatement, ReducerError> {
Ok(ImportStatement {
package_or_packages,
span: import.span.clone(),
@ -502,7 +454,7 @@ pub trait ReconstructingReducer {
&mut self,
_circuit_member: &CircuitMember,
new: CircuitMember,
) -> Result<CircuitMember, CanonicalizeError> {
) -> Result<CircuitMember, ReducerError> {
Ok(new)
}
@ -511,15 +463,11 @@ pub trait ReconstructingReducer {
_circuit: &Circuit,
circuit_name: Identifier,
members: Vec<CircuitMember>,
) -> Result<Circuit, CanonicalizeError> {
) -> Result<Circuit, ReducerError> {
Ok(Circuit { circuit_name, members })
}
fn reduce_annotation(
&mut self,
annotation: &Annotation,
name: Identifier,
) -> Result<Annotation, CanonicalizeError> {
fn reduce_annotation(&mut self, annotation: &Annotation, name: Identifier) -> Result<Annotation, ReducerError> {
Ok(Annotation {
span: annotation.span.clone(),
name,
@ -536,8 +484,7 @@ pub trait ReconstructingReducer {
input: Vec<FunctionInput>,
output: Option<Type>,
block: Block,
_in_circuit: bool,
) -> Result<Function, CanonicalizeError> {
) -> Result<Function, ReducerError> {
Ok(Function {
identifier,
annotations,

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{Expression, FormattedString, Node, Span};
use crate::{Expression, FormatString, Node, Span};
use serde::{Deserialize, Serialize};
use std::fmt;
@ -22,9 +22,9 @@ use std::fmt;
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub enum ConsoleFunction {
Assert(Expression),
Debug(FormattedString),
Error(FormattedString),
Log(FormattedString),
Debug(FormatString),
Error(FormatString),
Log(FormatString),
}
impl fmt::Display for ConsoleFunction {

View File

@ -21,19 +21,19 @@ use std::fmt;
use tendril::StrTendril;
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub enum FormattedStringPart {
pub enum FormatStringPart {
Const(#[serde(with = "crate::common::tendril_json")] StrTendril),
Container,
}
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct FormattedString {
pub parts: Vec<FormattedStringPart>,
pub struct FormatString {
pub parts: Vec<FormatStringPart>,
pub parameters: Vec<Expression>,
pub span: Span,
}
impl fmt::Display for FormattedString {
impl fmt::Display for FormatString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -41,8 +41,8 @@ impl fmt::Display for FormattedString {
self.parts
.iter()
.map(|x| match x {
FormattedStringPart::Const(x) => x,
FormattedStringPart::Container => "{}",
FormatStringPart::Const(x) => x,
FormatStringPart::Container => "{}",
})
.collect::<Vec<_>>()
.join("")
@ -50,7 +50,7 @@ impl fmt::Display for FormattedString {
}
}
impl Node for FormattedString {
impl Node for FormatString {
fn span(&self) -> &Span {
&self.span
}

View File

@ -1,6 +1,6 @@
[package]
name = "leo-compiler"
version = "1.3.0"
version = "1.4.0"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Compiler of the Leo programming language"
homepage = "https://aleo.org"
@ -19,35 +19,38 @@ edition = "2018"
[dependencies.leo-ast]
path = "../ast"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-imports]
path = "../imports"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-input]
path = "../input"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-package]
path = "../package"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-state]
path = "../state"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-asg]
path = "../asg"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-parser]
path = "../parser"
version = "1.3.0"
version = "1.4.0"
[dependencies.leo-asg-passes]
path = "../asg-passes"
version = "1.3.0"
version = "1.4.0"
[dependencies.tendril]
version = "0.4"
[dependencies.snarkvm-curves]
version = "0.2.2"

View File

@ -219,6 +219,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
// Use the parser to construct the abstract syntax tree (ast).
let mut ast = parse_ast(self.main_file_path.to_str().unwrap_or_default(), program_string)?;
// Preform compiler optimization via canonicalizing AST if its enabled.
if self.options.canonicalization_enabled {
ast.canonicalize()?;

View File

@ -17,8 +17,8 @@
//! Evaluates a formatted string in a compiled Leo program.
use crate::{errors::ConsoleError, program::ConstrainedProgram, GroupType};
use leo_asg::FormattedString;
use leo_ast::FormattedStringPart;
use leo_asg::FormatString;
use leo_ast::FormatStringPart;
use snarkvm_fields::PrimeField;
use snarkvm_r1cs::ConstraintSystem;
@ -26,13 +26,13 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
pub fn format<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
formatted: &FormattedString<'a>,
formatted: &FormatString<'a>,
) -> Result<String, ConsoleError> {
// Check that containers and parameters match
let container_count = formatted
.parts
.iter()
.filter(|x| matches!(x, FormattedStringPart::Container))
.filter(|x| matches!(x, FormatStringPart::Container))
.count();
if container_count != formatted.parameters.len() {
return Err(ConsoleError::length(
@ -51,8 +51,8 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
let mut parameters = executed_containers.iter();
for part in formatted.parts.iter() {
match part {
FormattedStringPart::Const(c) => out.push(&**c),
FormattedStringPart::Container => out.push(&**parameters.next().unwrap()),
FormatStringPart::Const(c) => out.push(&**c),
FormatStringPart::Container => out.push(&**parameters.next().unwrap()),
}
}

View File

@ -16,7 +16,7 @@
use crate::errors::FunctionError;
use leo_asg::{AsgConvertError, FormattedError};
use leo_ast::{CanonicalizeError, LeoError};
use leo_ast::{LeoError, ReducerError};
use leo_input::InputParserError;
use leo_parser::SyntaxError;
use leo_state::LocalDataVerificationError;
@ -56,7 +56,7 @@ pub enum CompilerError {
AsgConvertError(#[from] AsgConvertError),
#[error("{}", _0)]
CanonicalizeError(#[from] CanonicalizeError),
ReducerError(#[from] ReducerError),
}
impl LeoError for CompilerError {}

View File

@ -35,13 +35,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
let registers = input.get_registers();
// Iterate over main function input variables and allocate new values
if function.has_input {
// let input_var = function.scope.
let asg_input = function
.scope
.resolve_input()
.expect("no input variable in scope when function is qualified");
let asg_input = function.scope.resolve_input();
if let Some(asg_input) = asg_input {
let value =
self.allocate_input_keyword(cs, &function.name.borrow().span, &asg_input.container_circuit, input)?;

View File

@ -56,8 +56,11 @@ pub use prelude::*;
pub mod value;
pub use value::*;
pub mod stage;
pub use stage::*;
pub mod phase;
pub use phase::*;
pub mod phases;
pub use phases::*;
pub mod option;
pub use option::*;

View File

@ -16,6 +16,6 @@
use leo_asg::Program;
pub trait ASGStage {
pub trait ASGPhase {
fn apply(asg: &mut Program);
}

View File

@ -0,0 +1,23 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
//! Compiles a Leo program from a file path.
pub mod reducing_director;
pub use reducing_director::*;
pub mod phase;
pub use phase::*;

View File

@ -0,0 +1,65 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
//! Compiles a Leo program from a file path.
use crate::{CombineAstAsgDirector, CombinerOptions};
use leo_asg::Program as AsgProgram;
use leo_ast::{Ast, Program as AstProgram, ReconstructingReducer, ReducerError};
macro_rules! phase {
($phase_name:ident, $function:item) => {
pub struct $phase_name {
in_circuit: bool,
}
pub struct Options;
impl CombinerOptions for Options {
$function
}
impl ReconstructingReducer for $phase_name {
fn in_circuit(&self) -> bool {
self.in_circuit
}
fn swap_in_circuit(&mut self) {
self.in_circuit = !self.in_circuit;
}
}
impl Default for $phase_name {
fn default() -> Self {
Self { in_circuit: false }
}
}
impl $phase_name {
pub fn phase_ast(&self, ast: &AstProgram, asg: &AsgProgram) -> Result<Ast, ReducerError> {
Ok(Ast::new(CombineAstAsgDirector::new(Self::default(), Options{})
.reduce_program(ast, asg)?))
}
}
};
}
phase!(
TypeInferencePhase,
fn type_inference_enabled(&self) -> bool {
true
}
);

View File

@ -0,0 +1,775 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
//! Compiles a Leo program from a file path.
use indexmap::IndexMap;
use leo_asg::{
ArrayAccessExpression as AsgArrayAccessExpression,
ArrayInitExpression as AsgArrayInitExpression,
ArrayInlineExpression as AsgArrayInlineExpression,
ArrayRangeAccessExpression as AsgArrayRangeAccessExpression,
AssignAccess as AsgAssignAccess,
AssignStatement as AsgAssignStatement,
BinaryExpression as AsgBinaryExpression,
BlockStatement as AsgBlockStatement,
CallExpression as AsgCallExpression,
CastExpression as AsgCastExpression,
Circuit as AsgCircuit,
CircuitAccessExpression as AsgCircuitAccessExpression,
CircuitInitExpression as AsgCircuitInitExpression,
CircuitMember as AsgCircuitMember,
ConditionalStatement as AsgConditionalStatement,
ConsoleFunction as AsgConsoleFunction,
ConsoleStatement as AsgConsoleStatement,
ConstValue,
Constant as AsgConstant,
DefinitionStatement as AsgDefinitionStatement,
Expression as AsgExpression,
ExpressionStatement as AsgExpressionStatement,
Function as AsgFunction,
GroupValue as AsgGroupValue,
IterationStatement as AsgIterationStatement,
ReturnStatement as AsgReturnStatement,
Statement as AsgStatement,
TernaryExpression as AsgTernaryExpression,
TupleAccessExpression as AsgTupleAccessExpression,
TupleInitExpression as AsgTupleInitExpression,
Type as AsgType,
UnaryExpression as AsgUnaryExpression,
VariableRef as AsgVariableRef,
};
use leo_ast::{
ArrayAccessExpression as AstArrayAccessExpression,
ArrayDimensions,
ArrayInitExpression as AstArrayInitExpression,
ArrayInlineExpression as AstArrayInlineExpression,
ArrayRangeAccessExpression as AstArrayRangeAccessExpression,
AssignStatement as AstAssignStatement,
Assignee,
AssigneeAccess as AstAssignAccess,
BinaryExpression as AstBinaryExpression,
Block as AstBlockStatement,
CallExpression as AstCallExpression,
CastExpression as AstCastExpression,
Circuit as AstCircuit,
CircuitImpliedVariableDefinition,
CircuitInitExpression as AstCircuitInitExpression,
CircuitMember as AstCircuitMember,
CircuitMemberAccessExpression,
CircuitStaticFunctionAccessExpression,
CombinerError,
ConditionalStatement as AstConditionalStatement,
ConsoleFunction as AstConsoleFunction,
ConsoleStatement as AstConsoleStatement,
DefinitionStatement as AstDefinitionStatement,
Expression as AstExpression,
ExpressionStatement as AstExpressionStatement,
FormatString,
Function as AstFunction,
GroupTuple,
GroupValue as AstGroupValue,
IterationStatement as AstIterationStatement,
PositiveNumber,
ReconstructingReducer,
ReducerError,
ReturnStatement as AstReturnStatement,
Span,
SpreadOrExpression,
Statement as AstStatement,
TernaryExpression as AstTernaryExpression,
TupleAccessExpression as AstTupleAccessExpression,
TupleInitExpression as AstTupleInitExpression,
Type as AstType,
UnaryExpression as AstUnaryExpression,
ValueExpression,
};
use tendril::StrTendril;
pub trait CombinerOptions {
fn type_inference_enabled(&self) -> bool {
false
}
}
pub struct CombineAstAsgDirector<R: ReconstructingReducer, O: CombinerOptions> {
ast_reducer: R,
options: O,
}
impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
pub fn new(ast_reducer: R, options: O) -> Self {
Self { ast_reducer, options }
}
pub fn reduce_type(&mut self, ast: &AstType, asg: &AsgType, span: &Span) -> Result<AstType, ReducerError> {
let new = match (ast, asg) {
(AstType::Array(ast_type, ast_dimensions), AsgType::Array(asg_type, asg_dimensions)) => {
if self.options.type_inference_enabled() {
AstType::Array(
Box::new(self.reduce_type(ast_type, asg_type, span)?),
ArrayDimensions(vec![PositiveNumber {
value: StrTendril::from(format!("{}", asg_dimensions)),
}]),
)
} else {
AstType::Array(
Box::new(self.reduce_type(ast_type, asg_type, span)?),
ast_dimensions.clone(),
)
}
}
(AstType::Tuple(ast_types), AsgType::Tuple(asg_types)) => {
let mut reduced_types = vec![];
for (ast_type, asg_type) in ast_types.iter().zip(asg_types) {
reduced_types.push(self.reduce_type(ast_type, asg_type, span)?);
}
AstType::Tuple(reduced_types)
}
_ => ast.clone(),
};
self.ast_reducer.reduce_type(ast, new, span)
}
pub fn reduce_expression(
&mut self,
ast: &AstExpression,
asg: &AsgExpression,
) -> Result<AstExpression, ReducerError> {
let new = match (ast, asg) {
(AstExpression::Value(value), AsgExpression::Constant(const_)) => {
AstExpression::Value(self.reduce_value(&value, &const_)?)
}
(AstExpression::Binary(ast), AsgExpression::Binary(asg)) => {
AstExpression::Binary(self.reduce_binary(&ast, &asg)?)
}
(AstExpression::Unary(ast), AsgExpression::Unary(asg)) => {
AstExpression::Unary(self.reduce_unary(&ast, &asg)?)
}
(AstExpression::Ternary(ast), AsgExpression::Ternary(asg)) => {
AstExpression::Ternary(self.reduce_ternary(&ast, &asg)?)
}
(AstExpression::Cast(ast), AsgExpression::Cast(asg)) => AstExpression::Cast(self.reduce_cast(&ast, &asg)?),
(AstExpression::ArrayInline(ast), AsgExpression::ArrayInline(asg)) => {
AstExpression::ArrayInline(self.reduce_array_inline(&ast, &asg)?)
}
(AstExpression::ArrayInit(ast), AsgExpression::ArrayInit(asg)) => {
AstExpression::ArrayInit(self.reduce_array_init(&ast, &asg)?)
}
(AstExpression::ArrayAccess(ast), AsgExpression::ArrayAccess(asg)) => {
AstExpression::ArrayAccess(self.reduce_array_access(&ast, &asg)?)
}
(AstExpression::ArrayRangeAccess(ast), AsgExpression::ArrayRangeAccess(asg)) => {
AstExpression::ArrayRangeAccess(self.reduce_array_range_access(&ast, &asg)?)
}
(AstExpression::TupleInit(ast), AsgExpression::TupleInit(asg)) => {
AstExpression::TupleInit(self.reduce_tuple_init(&ast, &asg)?)
}
(AstExpression::TupleAccess(ast), AsgExpression::TupleAccess(asg)) => {
AstExpression::TupleAccess(self.reduce_tuple_access(&ast, &asg)?)
}
(AstExpression::CircuitInit(ast), AsgExpression::CircuitInit(asg)) => {
AstExpression::CircuitInit(self.reduce_circuit_init(&ast, &asg)?)
}
(AstExpression::CircuitMemberAccess(ast), AsgExpression::CircuitAccess(asg)) => {
AstExpression::CircuitMemberAccess(self.reduce_circuit_member_access(&ast, &asg)?)
}
(AstExpression::CircuitStaticFunctionAccess(ast), AsgExpression::CircuitAccess(asg)) => {
AstExpression::CircuitStaticFunctionAccess(self.reduce_circuit_static_fn_access(&ast, &asg)?)
}
(AstExpression::Call(ast), AsgExpression::Call(asg)) => AstExpression::Call(self.reduce_call(&ast, &asg)?),
_ => ast.clone(),
};
self.ast_reducer.reduce_expression(ast, new)
}
pub fn reduce_array_access(
&mut self,
ast: &AstArrayAccessExpression,
asg: &AsgArrayAccessExpression,
) -> Result<AstArrayAccessExpression, ReducerError> {
let array = self.reduce_expression(&ast.array, asg.array.get())?;
let index = self.reduce_expression(&ast.index, asg.index.get())?;
self.ast_reducer.reduce_array_access(ast, array, index)
}
pub fn reduce_array_init(
&mut self,
ast: &AstArrayInitExpression,
asg: &AsgArrayInitExpression,
) -> Result<AstArrayInitExpression, ReducerError> {
let element = self.reduce_expression(&ast.element, asg.element.get())?;
self.ast_reducer.reduce_array_init(ast, element)
}
pub fn reduce_array_inline(
&mut self,
ast: &AstArrayInlineExpression,
asg: &AsgArrayInlineExpression,
) -> Result<AstArrayInlineExpression, ReducerError> {
let mut elements = vec![];
for (ast_element, asg_element) in ast.elements.iter().zip(asg.elements.iter()) {
let reduced_element = match ast_element {
SpreadOrExpression::Expression(ast_expression) => {
SpreadOrExpression::Expression(self.reduce_expression(ast_expression, asg_element.0.get())?)
}
SpreadOrExpression::Spread(ast_expression) => {
SpreadOrExpression::Spread(self.reduce_expression(ast_expression, asg_element.0.get())?)
}
};
elements.push(reduced_element);
}
self.ast_reducer.reduce_array_inline(ast, elements)
}
pub fn reduce_array_range_access(
&mut self,
ast: &AstArrayRangeAccessExpression,
asg: &AsgArrayRangeAccessExpression,
) -> Result<AstArrayRangeAccessExpression, ReducerError> {
let array = self.reduce_expression(&ast.array, asg.array.get())?;
let left = match (ast.left.as_ref(), asg.left.get()) {
(Some(ast_left), Some(asg_left)) => Some(self.reduce_expression(ast_left, asg_left)?),
_ => None,
};
let right = match (ast.right.as_ref(), asg.right.get()) {
(Some(ast_right), Some(asg_right)) => Some(self.reduce_expression(ast_right, asg_right)?),
_ => None,
};
self.ast_reducer.reduce_array_range_access(ast, array, left, right)
}
pub fn reduce_binary(
&mut self,
ast: &AstBinaryExpression,
asg: &AsgBinaryExpression,
) -> Result<AstBinaryExpression, ReducerError> {
let left = self.reduce_expression(&ast.left, asg.left.get())?;
let right = self.reduce_expression(&ast.right, asg.right.get())?;
self.ast_reducer.reduce_binary(ast, left, right, ast.op.clone())
}
pub fn reduce_call(
&mut self,
ast: &AstCallExpression,
asg: &AsgCallExpression,
) -> Result<AstCallExpression, ReducerError> {
// TODO FIGURE IT OUT
// let function = self.reduce_expression(&ast.function, asg.function.get())?;
// let target = asg.target.get().map(|exp| self.reduce_expression())
// Is this needed?
let mut arguments = vec![];
for (ast_arg, asg_arg) in ast.arguments.iter().zip(asg.arguments.iter()) {
arguments.push(self.reduce_expression(ast_arg, asg_arg.get())?);
}
self.ast_reducer.reduce_call(ast, *ast.function.clone(), arguments)
}
pub fn reduce_cast(
&mut self,
ast: &AstCastExpression,
asg: &AsgCastExpression,
) -> Result<AstCastExpression, ReducerError> {
let inner = self.reduce_expression(&ast.inner, &asg.inner.get())?;
let target_type = self.reduce_type(&ast.target_type, &asg.target_type, &ast.span)?;
self.ast_reducer.reduce_cast(ast, inner, target_type)
}
pub fn reduce_circuit_member_access(
&mut self,
ast: &CircuitMemberAccessExpression,
_asg: &AsgCircuitAccessExpression,
) -> Result<CircuitMemberAccessExpression, ReducerError> {
// let circuit = self.reduce_expression(&circuit_member_access.circuit)?;
// let name = self.reduce_identifier(&circuit_member_access.name)?;
// let target = input.target.get().map(|e| self.reduce_expression(e));
self.ast_reducer
.reduce_circuit_member_access(ast, *ast.circuit.clone(), ast.name.clone())
}
pub fn reduce_circuit_static_fn_access(
&mut self,
ast: &CircuitStaticFunctionAccessExpression,
_asg: &AsgCircuitAccessExpression,
) -> Result<CircuitStaticFunctionAccessExpression, ReducerError> {
// let circuit = self.reduce_expression(&circuit_member_access.circuit)?;
// let name = self.reduce_identifier(&circuit_member_access.name)?;
// let target = input.target.get().map(|e| self.reduce_expression(e));
self.ast_reducer
.reduce_circuit_static_fn_access(ast, *ast.circuit.clone(), ast.name.clone())
}
pub fn reduce_circuit_implied_variable_definition(
&mut self,
ast: &CircuitImpliedVariableDefinition,
asg: &AsgExpression,
) -> Result<CircuitImpliedVariableDefinition, ReducerError> {
let expression = ast
.expression
.as_ref()
.map(|ast_expr| self.reduce_expression(ast_expr, asg))
.transpose()?;
self.ast_reducer
.reduce_circuit_implied_variable_definition(ast, ast.identifier.clone(), expression)
}
pub fn reduce_circuit_init(
&mut self,
ast: &AstCircuitInitExpression,
asg: &AsgCircuitInitExpression,
) -> Result<AstCircuitInitExpression, ReducerError> {
let mut members = vec![];
for (ast_member, asg_member) in ast.members.iter().zip(asg.values.iter()) {
members.push(self.reduce_circuit_implied_variable_definition(ast_member, asg_member.1.get())?);
}
self.ast_reducer.reduce_circuit_init(ast, ast.name.clone(), members)
}
pub fn reduce_ternary(
&mut self,
ast: &AstTernaryExpression,
asg: &AsgTernaryExpression,
) -> Result<AstTernaryExpression, ReducerError> {
let condition = self.reduce_expression(&ast.condition, asg.condition.get())?;
let if_true = self.reduce_expression(&ast.if_true, asg.if_true.get())?;
let if_false = self.reduce_expression(&ast.if_false, asg.if_false.get())?;
self.ast_reducer.reduce_ternary(ast, condition, if_true, if_false)
}
pub fn reduce_tuple_access(
&mut self,
ast: &AstTupleAccessExpression,
asg: &AsgTupleAccessExpression,
) -> Result<AstTupleAccessExpression, ReducerError> {
let tuple = self.reduce_expression(&ast.tuple, asg.tuple_ref.get())?;
self.ast_reducer.reduce_tuple_access(ast, tuple)
}
pub fn reduce_tuple_init(
&mut self,
ast: &AstTupleInitExpression,
asg: &AsgTupleInitExpression,
) -> Result<AstTupleInitExpression, ReducerError> {
let mut elements = vec![];
for (ast_element, asg_element) in ast.elements.iter().zip(asg.elements.iter()) {
let element = self.reduce_expression(ast_element, asg_element.get())?;
elements.push(element);
}
self.ast_reducer.reduce_tuple_init(ast, elements)
}
pub fn reduce_unary(
&mut self,
ast: &AstUnaryExpression,
asg: &AsgUnaryExpression,
) -> Result<AstUnaryExpression, ReducerError> {
let inner = self.reduce_expression(&ast.inner, asg.inner.get())?;
self.ast_reducer.reduce_unary(ast, inner, ast.op.clone())
}
pub fn reduce_value(&mut self, ast: &ValueExpression, asg: &AsgConstant) -> Result<ValueExpression, ReducerError> {
let mut new = ast.clone();
if self.options.type_inference_enabled() {
if let ValueExpression::Implicit(tendril, span) = ast {
match &asg.value {
ConstValue::Int(int) => {
new = ValueExpression::Integer(int.get_int_type(), tendril.clone(), span.clone());
}
ConstValue::Group(group) => {
let group_value = match group {
AsgGroupValue::Single(_) => AstGroupValue::Single(tendril.clone(), span.clone()),
AsgGroupValue::Tuple(x, y) => AstGroupValue::Tuple(GroupTuple {
x: x.into(),
y: y.into(),
span: span.clone(),
}),
};
new = ValueExpression::Group(Box::new(group_value));
}
ConstValue::Field(_) => {
new = ValueExpression::Field(tendril.clone(), span.clone());
}
ConstValue::Address(_) => {
new = ValueExpression::Address(tendril.clone(), span.clone());
}
ConstValue::Boolean(_) => {
new = ValueExpression::Boolean(tendril.clone(), span.clone());
}
_ => unimplemented!(), // impossible?
}
}
}
self.ast_reducer.reduce_value(ast, new)
}
pub fn reduce_variable_ref(
&mut self,
ast: &ValueExpression,
_asg: &AsgVariableRef,
) -> Result<ValueExpression, ReducerError> {
// TODO FIGURE IT OUT
let new = match ast {
// ValueExpression::Group(group_value) => {
// ValueExpression::Group(Box::new(self.reduce_group_value(&group_value)?))
// }
_ => ast.clone(),
};
Ok(new)
// self.ast_reducer.reduce_value(value, new)
}
pub fn reduce_statement(
&mut self,
ast_statement: &AstStatement,
asg_statement: &AsgStatement,
) -> Result<AstStatement, ReducerError> {
let new = match (ast_statement, asg_statement) {
(AstStatement::Assign(ast), AsgStatement::Assign(asg)) => {
AstStatement::Assign(self.reduce_assign(ast, asg)?)
}
(AstStatement::Block(ast), AsgStatement::Block(asg)) => AstStatement::Block(self.reduce_block(ast, asg)?),
(AstStatement::Conditional(ast), AsgStatement::Conditional(asg)) => {
AstStatement::Conditional(self.reduce_conditional(ast, asg)?)
}
(AstStatement::Console(ast), AsgStatement::Console(asg)) => {
AstStatement::Console(self.reduce_console(ast, asg)?)
}
(AstStatement::Definition(ast), AsgStatement::Definition(asg)) => {
AstStatement::Definition(self.reduce_definition(ast, asg)?)
}
(AstStatement::Expression(ast), AsgStatement::Expression(asg)) => {
AstStatement::Expression(self.reduce_expression_statement(ast, asg)?)
}
(AstStatement::Iteration(ast), AsgStatement::Iteration(asg)) => {
AstStatement::Iteration(self.reduce_iteration(ast, asg)?)
}
(AstStatement::Return(ast), AsgStatement::Return(asg)) => {
AstStatement::Return(self.reduce_return(ast, asg)?)
}
_ => ast_statement.clone(),
};
self.ast_reducer.reduce_statement(ast_statement, new)
}
pub fn reduce_assign_access(
&mut self,
ast: &AstAssignAccess,
asg: &AsgAssignAccess,
) -> Result<AstAssignAccess, ReducerError> {
let new = match (ast, asg) {
(AstAssignAccess::ArrayRange(ast_left, ast_right), AsgAssignAccess::ArrayRange(asg_left, asg_right)) => {
let left = match (ast_left.as_ref(), asg_left.get()) {
(Some(ast_left), Some(asg_left)) => Some(self.reduce_expression(ast_left, asg_left)?),
_ => None,
};
let right = match (ast_right.as_ref(), asg_right.get()) {
(Some(ast_right), Some(asg_right)) => Some(self.reduce_expression(ast_right, asg_right)?),
_ => None,
};
AstAssignAccess::ArrayRange(left, right)
}
(AstAssignAccess::ArrayIndex(ast_index), AsgAssignAccess::ArrayIndex(asg_index)) => {
let index = self.reduce_expression(&ast_index, asg_index.get())?;
AstAssignAccess::ArrayIndex(index)
}
_ => ast.clone(),
};
self.ast_reducer.reduce_assignee_access(ast, new)
}
pub fn reduce_assignee(&mut self, ast: &Assignee, asg: &[AsgAssignAccess]) -> Result<Assignee, ReducerError> {
let mut accesses = vec![];
for (ast_access, asg_access) in ast.accesses.iter().zip(asg) {
accesses.push(self.reduce_assign_access(ast_access, asg_access)?);
}
self.ast_reducer.reduce_assignee(ast, ast.identifier.clone(), accesses)
}
pub fn reduce_assign(
&mut self,
ast: &AstAssignStatement,
asg: &AsgAssignStatement,
) -> Result<AstAssignStatement, ReducerError> {
let assignee = self.reduce_assignee(&ast.assignee, &asg.target_accesses)?;
let value = self.reduce_expression(&ast.value, asg.value.get())?;
self.ast_reducer.reduce_assign(ast, assignee, value)
}
pub fn reduce_block(
&mut self,
ast: &AstBlockStatement,
asg: &AsgBlockStatement,
) -> Result<AstBlockStatement, ReducerError> {
let mut statements = vec![];
for (ast_statement, asg_statement) in ast.statements.iter().zip(asg.statements.iter()) {
statements.push(self.reduce_statement(ast_statement, asg_statement.get())?);
}
self.ast_reducer.reduce_block(ast, statements)
}
pub fn reduce_conditional(
&mut self,
ast: &AstConditionalStatement,
asg: &AsgConditionalStatement,
) -> Result<AstConditionalStatement, ReducerError> {
let condition = self.reduce_expression(&ast.condition, asg.condition.get())?;
let block;
if let AsgStatement::Block(asg_block) = asg.result.get() {
block = self.reduce_block(&ast.block, asg_block)?;
} else {
return Err(ReducerError::from(CombinerError::asg_statement_not_block(
&asg.span.as_ref().unwrap(),
)));
}
let next = match (ast.next.as_ref(), asg.next.get()) {
(Some(ast_next), Some(asg_next)) => Some(self.reduce_statement(ast_next, asg_next)?),
_ => None,
};
self.ast_reducer.reduce_conditional(ast, condition, block, next)
}
pub fn reduce_console(
&mut self,
ast: &AstConsoleStatement,
asg: &AsgConsoleStatement,
) -> Result<AstConsoleStatement, ReducerError> {
let function = match (&ast.function, &asg.function) {
(AstConsoleFunction::Assert(ast_expression), AsgConsoleFunction::Assert(asg_expression)) => {
AstConsoleFunction::Assert(self.reduce_expression(&ast_expression, asg_expression.get())?)
}
(AstConsoleFunction::Debug(ast_format), AsgConsoleFunction::Debug(asg_format))
| (AstConsoleFunction::Error(ast_format), AsgConsoleFunction::Error(asg_format))
| (AstConsoleFunction::Log(ast_format), AsgConsoleFunction::Log(asg_format)) => {
let mut parameters = vec![];
for (ast_parameter, asg_parameter) in ast_format.parameters.iter().zip(asg_format.parameters.iter()) {
parameters.push(self.reduce_expression(&ast_parameter, asg_parameter.get())?);
}
let formatted = FormatString {
parts: ast_format.parts.clone(),
parameters,
span: ast_format.span.clone(),
};
match &ast.function {
AstConsoleFunction::Debug(_) => AstConsoleFunction::Debug(formatted),
AstConsoleFunction::Error(_) => AstConsoleFunction::Error(formatted),
AstConsoleFunction::Log(_) => AstConsoleFunction::Log(formatted),
_ => return Err(ReducerError::impossible_console_assert_call(&ast_format.span)),
}
}
_ => ast.function.clone(),
};
self.ast_reducer.reduce_console(ast, function)
}
pub fn reduce_definition(
&mut self,
ast: &AstDefinitionStatement,
asg: &AsgDefinitionStatement,
) -> Result<AstDefinitionStatement, ReducerError> {
let type_;
if asg.variables.len() > 1 {
let mut types = vec![];
for variable in asg.variables.iter() {
types.push(variable.borrow().type_.clone());
}
let asg_type = AsgType::Tuple(types);
type_ = match &ast.type_ {
Some(ast_type) => Some(self.reduce_type(&ast_type, &asg_type, &ast.span)?),
None if self.options.type_inference_enabled() => Some((&asg_type).into()),
_ => None,
};
} else {
type_ = match &ast.type_ {
Some(ast_type) => {
Some(self.reduce_type(&ast_type, &asg.variables.first().unwrap().borrow().type_, &ast.span)?)
}
None if self.options.type_inference_enabled() => {
Some((&asg.variables.first().unwrap().borrow().type_).into())
}
_ => None,
};
}
let value = self.reduce_expression(&ast.value, asg.value.get())?;
self.ast_reducer
.reduce_definition(ast, ast.variable_names.clone(), type_, value)
}
pub fn reduce_expression_statement(
&mut self,
ast: &AstExpressionStatement,
asg: &AsgExpressionStatement,
) -> Result<AstExpressionStatement, ReducerError> {
let inner_expression = self.reduce_expression(&ast.expression, asg.expression.get())?;
self.ast_reducer.reduce_expression_statement(ast, inner_expression)
}
pub fn reduce_iteration(
&mut self,
ast: &AstIterationStatement,
asg: &AsgIterationStatement,
) -> Result<AstIterationStatement, ReducerError> {
let start = self.reduce_expression(&ast.start, asg.start.get())?;
let stop = self.reduce_expression(&ast.stop, asg.stop.get())?;
let block;
if let AsgStatement::Block(asg_block) = asg.body.get() {
block = self.reduce_block(&ast.block, asg_block)?;
} else {
return Err(ReducerError::from(CombinerError::asg_statement_not_block(
&asg.span.as_ref().unwrap(),
)));
}
self.ast_reducer
.reduce_iteration(ast, ast.variable.clone(), start, stop, block)
}
pub fn reduce_return(
&mut self,
ast: &AstReturnStatement,
asg: &AsgReturnStatement,
) -> Result<AstReturnStatement, ReducerError> {
let expression = self.reduce_expression(&ast.expression, asg.expression.get())?;
self.ast_reducer.reduce_return(ast, expression)
}
pub fn reduce_program(
&mut self,
ast: &leo_ast::Program,
asg: &leo_asg::Program,
) -> Result<leo_ast::Program, leo_ast::ReducerError> {
self.ast_reducer.swap_in_circuit();
let mut circuits = IndexMap::new();
for ((ast_ident, ast_circuit), (_asg_ident, asg_circuit)) in ast.circuits.iter().zip(&asg.circuits) {
circuits.insert(ast_ident.clone(), self.reduce_circuit(ast_circuit, asg_circuit)?);
}
self.ast_reducer.swap_in_circuit();
let mut functions = IndexMap::new();
for ((ast_ident, ast_function), (_asg_ident, asg_function)) in ast.functions.iter().zip(&asg.functions) {
functions.insert(ast_ident.clone(), self.reduce_function(ast_function, asg_function)?);
}
self.ast_reducer.reduce_program(
ast,
ast.expected_input.clone(),
ast.imports.clone(),
circuits,
functions,
)
}
pub fn reduce_function(&mut self, ast: &AstFunction, asg: &AsgFunction) -> Result<AstFunction, ReducerError> {
let output = ast
.output
.as_ref()
.map(|type_| self.reduce_type(type_, &asg.output, &ast.span))
.transpose()?;
let mut statements = vec![];
if let Some(AsgStatement::Block(asg_block)) = asg.body.get() {
for (ast_statement, asg_statement) in ast.block.statements.iter().zip(asg_block.statements.iter()) {
statements.push(self.reduce_statement(ast_statement, asg_statement.get())?);
}
}
let block = AstBlockStatement {
statements,
span: ast.block.span.clone(),
};
self.ast_reducer.reduce_function(
ast,
ast.identifier.clone(),
ast.annotations.clone(),
ast.input.clone(),
output,
block,
)
}
pub fn reduce_circuit_member(
&mut self,
ast: &AstCircuitMember,
asg: &AsgCircuitMember,
) -> Result<AstCircuitMember, ReducerError> {
let new = match (ast, asg) {
(AstCircuitMember::CircuitVariable(identifier, ast_type), AsgCircuitMember::Variable(asg_type)) => {
AstCircuitMember::CircuitVariable(
identifier.clone(),
self.reduce_type(ast_type, asg_type, &identifier.span)?,
)
}
(AstCircuitMember::CircuitFunction(ast_function), AsgCircuitMember::Function(asg_function)) => {
AstCircuitMember::CircuitFunction(self.reduce_function(ast_function, asg_function)?)
}
_ => ast.clone(),
};
self.ast_reducer.reduce_circuit_member(ast, new)
}
pub fn reduce_circuit(&mut self, ast: &AstCircuit, asg: &AsgCircuit) -> Result<AstCircuit, ReducerError> {
let mut members = vec![];
for (ast_member, asg_member) in ast.members.iter().zip(asg.members.borrow().iter()) {
members.push(self.reduce_circuit_member(ast_member, asg_member.1)?);
}
self.ast_reducer.reduce_circuit(ast, ast.circuit_name.clone(), members)
}
}

View File

@ -1,6 +1,6 @@
function main() {
const address_1 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8);
const address_2 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j9);
const address_1 = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
const address_2 = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j9;
console.assert(address_1 == address_2);
}

Some files were not shown because too many files have changed in this diff Show More