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 export LEO=/home/circleci/project/project/bin/leo
./project/.circleci/leo-add-remove.sh ./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: leo-login-logout:
docker: docker:
- image: cimg/rust:1.51.0 - image: cimg/rust:1.51.0
@ -219,6 +232,9 @@ workflows:
- leo-add-remove: - leo-add-remove:
requires: requires:
- leo-executable - leo-executable
- leo-check-constraints:
requires:
- leo-executable
- leo-login-logout: - leo-login-logout:
requires: requires:
- leo-executable - 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 login & logout
$LEO new my-app && cd my-app || exit 1
$LEO login -u "$ALEO_PM_USERNAME" -p "$ALEO_PM_PASSWORD" $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 add howard/silly-sudoku
$LEO remove silly-sudoku $LEO remove silly-sudoku
$LEO logout $LEO logout

View File

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

View File

@ -1,6 +1,6 @@
[package] [package]
name = "leo-lang" name = "leo-lang"
version = "1.3.0" version = "1.4.0"
authors = [ "The Aleo Team <hello@aleo.org>" ] authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "The Leo programming language" description = "The Leo programming language"
homepage = "https://aleo.org" homepage = "https://aleo.org"
@ -37,36 +37,37 @@ members = [
"package", "package",
"parser", "parser",
"state", "state",
"synthesizer" "synthesizer",
"test-framework"
] ]
[dependencies.leo-ast] [dependencies.leo-ast]
path = "./ast" path = "./ast"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-compiler] [dependencies.leo-compiler]
path = "./compiler" path = "./compiler"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-imports] [dependencies.leo-imports]
path = "./imports" path = "./imports"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-input] [dependencies.leo-input]
path = "./input" path = "./input"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-package] [dependencies.leo-package]
path = "./package" path = "./package"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-state] [dependencies.leo-state]
path = "./state" path = "./state"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-synthesizer] [dependencies.leo-synthesizer]
path = "./synthesizer" path = "./synthesizer"
version = "1.3.0" version = "1.4.0"
[dependencies.snarkvm-algorithms] [dependencies.snarkvm-algorithms]
version = "0.2.2" version = "0.2.2"
@ -111,7 +112,7 @@ version = "0.3.1"
version = "1.4.0" version = "1.4.0"
[dependencies.notify] [dependencies.notify]
version = "4.0.15" version = "4.0.16"
[dependencies.rand] [dependencies.rand]
version = "0.8" version = "0.8"
@ -120,7 +121,7 @@ version = "0.8"
version = "0.6.2" version = "0.6.2"
[dependencies.reqwest] [dependencies.reqwest]
version = "0.11.2" version = "0.11.3"
features = [ "blocking", "json", "multipart" ] features = [ "blocking", "json", "multipart" ]
[dependencies.self_update] [dependencies.self_update]
@ -150,9 +151,18 @@ features = [ "fmt" ]
[dependencies.zip] [dependencies.zip]
version = "0.5" version = "0.5"
[target."cfg(windows)".dependencies.ansi_term]
version = "0.12.1"
[dev-dependencies.rusty-hook] [dev-dependencies.rusty-hook]
version = "0.11.2" version = "0.11.2"
[dev-dependencies.assert_cmd]
version = "1.0.3"
[dev-dependencies.test_dir]
version = "0.1.0"
[features] [features]
default = [ ] default = [ ]
ci_skip = [ "leo-compiler/ci_skip" ] 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 Use the Leo CLI to create a new project
```bash ```bash
# create a new `hello_world` Leo project # create a new `hello-world` Leo project
leo new hello_world leo new hello-world
cd hello_world cd hello-world
# build & setup & prove & verify # build & setup & prove & verify
leo run 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) * [Hello World - Next Steps](https://developer.aleo.org/developer/getting_started/hello_world)
* [Leo Language Documentation](https://developer.aleo.org/developer/language/layout) * [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) * [Leo CLI Documentation](https://developer.aleo.org/developer/cli/new)
* [Homepage](https://developer.aleo.org/developer/getting_started/overview) * [Homepage](https://developer.aleo.org/developer/getting_started/overview)

View File

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

View File

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

View File

@ -71,7 +71,7 @@ impl<'a> ExpressionNode<'a> for CallExpression<'a> {
} }
fn is_mut_ref(&self) -> bool { fn is_mut_ref(&self) -> bool {
false true
} }
fn const_value(&self) -> Option<ConstValue> { 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>>, expected_type: Option<PartialType<'a>>,
) -> Result<&'a Expression<'a>, AsgConvertError> { ) -> Result<&'a Expression<'a>, AsgConvertError> {
let variable = if value.name.as_ref() == "input" { 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() { if let Some(input) = scope.resolve_input() {
input.container input.container
} else { } else {

View File

@ -29,7 +29,7 @@ pub fn resolve_core_module<'a>(context: AsgContext<'a>, module: &str) -> Result<
r#" r#"
circuit Blake2s { circuit Blake2s {
function hash(seed: [u8; 32], message: [u8; 32]) -> [u8; 32] { 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 id: u32,
pub name: RefCell<Identifier>, pub name: RefCell<Identifier>,
pub output: Type<'a>, pub output: Type<'a>,
pub has_input: bool,
pub arguments: IndexMap<String, Cell<&'a Variable<'a>>>, pub arguments: IndexMap<String, Cell<&'a Variable<'a>>>,
pub circuit: Cell<Option<&'a Circuit<'a>>>, pub circuit: Cell<Option<&'a Circuit<'a>>>,
pub span: Option<Span>, pub span: Option<Span>,
@ -77,16 +76,12 @@ impl<'a> Function<'a> {
.transpose()? .transpose()?
.unwrap_or_else(|| Type::Tuple(vec![])); .unwrap_or_else(|| Type::Tuple(vec![]));
let mut qualifier = FunctionQualifier::Static; let mut qualifier = FunctionQualifier::Static;
let mut has_input = false;
let new_scope = scope.make_subscope(); let new_scope = scope.make_subscope();
let mut arguments = IndexMap::new(); let mut arguments = IndexMap::new();
{ {
for input in value.input.iter() { for input in value.input.iter() {
match input { match input {
FunctionInput::InputKeyword(_) => {
has_input = true;
}
FunctionInput::SelfKeyword(_) => { FunctionInput::SelfKeyword(_) => {
qualifier = FunctionQualifier::SelfRef; qualifier = FunctionQualifier::SelfRef;
} }
@ -125,7 +120,6 @@ impl<'a> Function<'a> {
id: scope.context.get_id(), id: scope.context.get_id(),
name: RefCell::new(value.identifier.clone()), name: RefCell::new(value.identifier.clone()),
output, output,
has_input,
arguments, arguments,
circuit: Cell::new(None), circuit: Cell::new(None),
body: 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) .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 let parameters = input
.parameters .parameters
.iter() .iter()

View File

@ -118,7 +118,7 @@ pub trait MonoidalReducerStatement<'a, T: Monoid>: MonoidalReducerExpression<'a,
condition.append(if_true).append_option(if_false) 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()) 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) .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 let parameters = input
.parameters .parameters
.iter() .iter()

View File

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

View File

@ -120,7 +120,7 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
Default::default() Default::default()
} }
fn visit_formatted_string(&mut self, input: &FormattedString<'a>) -> VisitResult { fn visit_formatted_string(&mut self, input: &FormatString<'a>) -> VisitResult {
Default::default() 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) { match self.visitor.visit_formatted_string(input) {
VisitResult::VisitChildren => { VisitResult::VisitChildren => {
for parameter in input.parameters.iter() { 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 (name, span) = (&statement.assignee.identifier.name, &statement.assignee.identifier.span);
let variable = if name.as_ref() == "input" { 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() { if let Some(input) = scope.resolve_input() {
input.container input.container
} else { } else {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
circuit Foo { circuit Foo {
function echo(x: u32) -> u32 { 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#" let program_string = r#"
circuit Foo { circuit Foo {
function echo(mut self, x: u32) -> u32 { function echo(mut self, x: u32) -> u32 {
return x return x;
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,11 +2,11 @@ circuit Foo {
x: u32, x: u32,
function add_x(self, y: u32) -> u32 { function add_x(self, y: u32) -> u32 {
return self.x + y return self.x + y;
} }
function call_add_x(self, y: u32) -> u32 { 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 { circuit Foo {
function echo(x: u32) -> u32 { function echo(x: u32) -> u32 {
return x return x;
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
import core.unstable.blake2s.Blake2s; import core.unstable.blake2s.Blake2s;
function main(seed: [u8; 32], message: [u8; 32]) -> [u8; 32] { 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; a += 1;
} }
return a return a;
} }
function main() { function main() {
@ -63,7 +63,7 @@ fn test_imports() {
} }
function foo() -> u32 { function foo() -> u32 {
return 1u32 return 1u32;
} }
"#; "#;
imports imports

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,5 +4,5 @@ circuit Point {
} }
function foo() -> u32 { 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.registers.value_balance == 0u64);
console.assert(input.state.leaf_index == 0u32); 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]); console.assert(input.state.root == [0u8; 32]);
const expected: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8; const expected: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;

View File

@ -1,3 +1,3 @@
function main(input) { function main() {
console.assert(input.state.root == [0u8; 32]); 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]; const t = a[i];
a[i] = a[j]; a[i] = a[j];
a[j] = t; a[j] = t;
return a return a;
} }
function main() { function main() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,9 +23,6 @@ pub use const_self_keyword::*;
pub mod identifier; pub mod identifier;
pub use identifier::*; pub use identifier::*;
pub mod input_keyword;
pub use input_keyword::*;
pub mod mut_self_keyword; pub mod mut_self_keyword;
pub use 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 // 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/>. // 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)] #[derive(Debug, Error)]
pub enum CanonicalizeError { pub enum CanonicalizeError {
@ -22,6 +22,8 @@ pub enum CanonicalizeError {
Error(#[from] FormattedError), Error(#[from] FormattedError),
} }
impl LeoError for CanonicalizeError {}
impl CanonicalizeError { impl CanonicalizeError {
fn new_from_span(message: String, span: &Span) -> Self { fn new_from_span(message: String, span: &Span) -> Self {
CanonicalizeError::Error(FormattedError::new_from_span(message, span)) 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 // 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/>. // 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}; #[derive(Debug, Error)]
use std::fmt; pub enum CombinerError {
#[error("{}", _0)]
/// The `input` keyword can view program register, record, and state values. Error(#[from] FormattedError),
/// 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,
} }
impl fmt::Display for InputKeyword { impl LeoError for CombinerError {}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "input")
}
}
impl Node for InputKeyword { impl CombinerError {
fn span(&self) -> &Span { fn new_from_span(message: String, span: &Span) -> Self {
&self.identifier.span CombinerError::Error(FormattedError::new_from_span(message, span))
} }
fn set_span(&mut self, span: Span) { pub fn asg_statement_not_block(span: &Span) -> Self {
self.identifier.span = span; 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 { impl fmt::Display for FormattedError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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!( write!(
f, f,
"{indent }--> {path}: {line_start}:{start}\n\ "{indent }--> {path}:{line_start}:{start}\n\
{indent } |\n", {indent } |\n",
indent = INDENT, indent = INDENT,
path = &*self.path, path = &*self.path,
@ -99,7 +99,7 @@ impl fmt::Display for FormattedError {
write!( write!(
f, f,
"{indent } | {underline}\n\ "{indent } |{underline}\n\
{indent } |\n\ {indent } |\n\
{indent } = {message}", {indent } = {message}",
indent = INDENT, indent = INDENT,
@ -121,8 +121,8 @@ fn test_error() {
path: std::sync::Arc::new("file.leo".to_string()), path: std::sync::Arc::new("file.leo".to_string()),
line_start: 2, line_start: 2,
line_stop: 2, line_stop: 2,
col_start: 8, col_start: 9,
col_stop: 9, col_stop: 10,
content: "let a = x;".into(), content: "let a = x;".into(),
message: "undefined value `x`".to_string(), message: "undefined value `x`".to_string(),
}; };
@ -130,7 +130,7 @@ fn test_error() {
assert_eq!( assert_eq!(
err.to_string(), err.to_string(),
vec![ vec![
" --> file.leo: 2:8", " --> file.leo:2:9",
" |", " |",
" 2 | let a = x;", " 2 | let a = x;",
" | ^", " | ^",

View File

@ -14,7 +14,16 @@
// You should have received a copy of the GNU General Public License // 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/>. // 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 mod error;
pub use error::*; pub use error::*;
pub mod reducer;
pub use reducer::*;
pub trait LeoError {} 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 // 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/>. // 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 serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
@ -22,7 +22,6 @@ use std::fmt;
/// Enumerates the possible inputs to a function. /// Enumerates the possible inputs to a function.
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub enum FunctionInput { pub enum FunctionInput {
InputKeyword(InputKeyword),
SelfKeyword(SelfKeyword), SelfKeyword(SelfKeyword),
ConstSelfKeyword(ConstSelfKeyword), ConstSelfKeyword(ConstSelfKeyword),
MutSelfKeyword(MutSelfKeyword), MutSelfKeyword(MutSelfKeyword),
@ -36,7 +35,6 @@ impl FunctionInput {
/// ///
pub fn is_self(&self) -> bool { pub fn is_self(&self) -> bool {
match self { match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => true, FunctionInput::SelfKeyword(_) => true,
FunctionInput::ConstSelfKeyword(_) => true, FunctionInput::ConstSelfKeyword(_) => true,
FunctionInput::MutSelfKeyword(_) => true, FunctionInput::MutSelfKeyword(_) => true,
@ -50,7 +48,6 @@ impl FunctionInput {
/// ///
pub fn is_const_self(&self) -> bool { pub fn is_const_self(&self) -> bool {
match self { match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => false, FunctionInput::SelfKeyword(_) => false,
FunctionInput::ConstSelfKeyword(_) => true, FunctionInput::ConstSelfKeyword(_) => true,
FunctionInput::MutSelfKeyword(_) => false, FunctionInput::MutSelfKeyword(_) => false,
@ -64,7 +61,6 @@ impl FunctionInput {
/// ///
pub fn is_mut_self(&self) -> bool { pub fn is_mut_self(&self) -> bool {
match self { match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => false, FunctionInput::SelfKeyword(_) => false,
FunctionInput::ConstSelfKeyword(_) => false, FunctionInput::ConstSelfKeyword(_) => false,
FunctionInput::MutSelfKeyword(_) => true, FunctionInput::MutSelfKeyword(_) => true,
@ -74,7 +70,6 @@ impl FunctionInput {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
FunctionInput::InputKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::SelfKeyword(keyword) => write!(f, "{}", keyword), FunctionInput::SelfKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::ConstSelfKeyword(keyword) => write!(f, "{}", keyword), FunctionInput::ConstSelfKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::MutSelfKeyword(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. /// Returns true if `self == other`. Does not compare spans.
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
match (self, other) { match (self, other) {
(FunctionInput::InputKeyword(_), FunctionInput::InputKeyword(_)) => true,
(FunctionInput::SelfKeyword(_), FunctionInput::SelfKeyword(_)) => true, (FunctionInput::SelfKeyword(_), FunctionInput::SelfKeyword(_)) => true,
(FunctionInput::ConstSelfKeyword(_), FunctionInput::ConstSelfKeyword(_)) => true, (FunctionInput::ConstSelfKeyword(_), FunctionInput::ConstSelfKeyword(_)) => true,
(FunctionInput::MutSelfKeyword(_), FunctionInput::MutSelfKeyword(_)) => true, (FunctionInput::MutSelfKeyword(_), FunctionInput::MutSelfKeyword(_)) => true,
@ -115,7 +109,6 @@ impl Node for FunctionInput {
fn span(&self) -> &Span { fn span(&self) -> &Span {
use FunctionInput::*; use FunctionInput::*;
match self { match self {
InputKeyword(keyword) => &keyword.identifier.span,
SelfKeyword(keyword) => &keyword.identifier.span, SelfKeyword(keyword) => &keyword.identifier.span,
ConstSelfKeyword(keyword) => &keyword.identifier.span, ConstSelfKeyword(keyword) => &keyword.identifier.span,
MutSelfKeyword(keyword) => &keyword.identifier.span, MutSelfKeyword(keyword) => &keyword.identifier.span,
@ -126,7 +119,6 @@ impl Node for FunctionInput {
fn set_span(&mut self, span: Span) { fn set_span(&mut self, span: Span) {
use FunctionInput::*; use FunctionInput::*;
match self { match self {
InputKeyword(keyword) => keyword.identifier.span = span,
SelfKeyword(keyword) => keyword.identifier.span = span, SelfKeyword(keyword) => keyword.identifier.span = span,
ConstSelfKeyword(keyword) => keyword.identifier.span = span, ConstSelfKeyword(keyword) => keyword.identifier.span = span,
MutSelfKeyword(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. /// 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. /// 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 { pub struct Ast {
ast: Program, ast: Program,
} }
@ -83,7 +83,7 @@ impl Ast {
} }
/// Mutates the program ast by preforming canonicalization on it. /// 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())?; self.ast = ReconstructingDirector::new(Canonicalizer::default()).reduce_program(self.as_repr())?;
Ok(()) Ok(())
} }

View File

@ -25,11 +25,78 @@ use crate::*;
pub struct Canonicalizer { pub struct Canonicalizer {
// If we are in a circuit keep track of the circuit name. // If we are in a circuit keep track of the circuit name.
circuit_name: Option<Identifier>, circuit_name: Option<Identifier>,
in_circuit: bool,
}
impl Default for Canonicalizer {
fn default() -> Self {
Self {
circuit_name: None,
in_circuit: false,
}
}
} }
impl Canonicalizer { impl Canonicalizer {
pub fn default() -> Self { pub fn canonicalize_accesses(
Self { circuit_name: None } &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 { fn is_self_type(&mut self, type_option: Option<&Type>) -> bool {
@ -324,7 +391,7 @@ impl Canonicalizer {
.map(|parameter| self.canonicalize_expression(parameter)) .map(|parameter| self.canonicalize_expression(parameter))
.collect(); .collect();
let formatted = FormattedString { let formatted = FormatString {
parts: format.parts.clone(), parts: format.parts.clone(),
parameters, parameters,
span: format.span.clone(), span: format.span.clone(),
@ -380,17 +447,21 @@ impl Canonicalizer {
} }
impl ReconstructingReducer for Canonicalizer { impl ReconstructingReducer for Canonicalizer {
fn reduce_type( fn in_circuit(&self) -> bool {
&mut self, self.in_circuit
_type_: &Type, }
new: Type,
in_circuit: bool, fn swap_in_circuit(&mut self) {
span: &Span, self.in_circuit = !self.in_circuit;
) -> Result<Type, CanonicalizeError> { }
fn reduce_type(&mut self, _type_: &Type, new: Type, span: &Span) -> Result<Type, ReducerError> {
match new { match new {
Type::Array(type_, mut dimensions) => { Type::Array(type_, mut dimensions) => {
if dimensions.is_zero() { 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()])); let mut next = Type::Array(type_, ArrayDimensions(vec![dimensions.remove_last().unwrap()]));
@ -407,7 +478,9 @@ impl ReconstructingReducer for Canonicalizer {
Ok(array) 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()), _ => Ok(new.clone()),
} }
} }
@ -416,10 +489,11 @@ impl ReconstructingReducer for Canonicalizer {
&mut self, &mut self,
array_init: &ArrayInitExpression, array_init: &ArrayInitExpression,
element: Expression, element: Expression,
_in_circuit: bool, ) -> Result<ArrayInitExpression, ReducerError> {
) -> Result<ArrayInitExpression, CanonicalizeError> {
if array_init.dimensions.is_zero() { 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); let element = Box::new(element);
@ -466,58 +540,39 @@ impl ReconstructingReducer for Canonicalizer {
assign: &AssignStatement, assign: &AssignStatement,
assignee: Assignee, assignee: Assignee,
value: Expression, value: Expression,
_in_circuit: bool, ) -> Result<AssignStatement, ReducerError> {
) -> Result<AssignStatement, CanonicalizeError> {
match value { 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 => { Expression::Value(value_expr) if assign.operation != AssignOperation::Assign => {
let mut left = Box::new(Expression::Identifier(assignee.identifier.clone())); let left = self.canonicalize_accesses(
Expression::Identifier(assignee.identifier.clone()),
for access in assignee.accesses.iter().rev() { &assignee.accesses,
match self.canonicalize_assignee_access(&access) { &assign.span,
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 right = Box::new(Expression::Value(value_expr)); let right = Box::new(Expression::Value(value_expr));
let op = self.compound_operation_converstion(&assign.operation)?;
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 new_value = Expression::Binary(BinaryExpression { let new_value = Expression::Binary(BinaryExpression {
left, left,
@ -545,8 +600,7 @@ impl ReconstructingReducer for Canonicalizer {
input: Vec<FunctionInput>, input: Vec<FunctionInput>,
output: Option<Type>, output: Option<Type>,
block: Block, block: Block,
_in_circuit: bool, ) -> Result<Function, ReducerError> {
) -> Result<Function, CanonicalizeError> {
let new_output = match output { let new_output = match output {
None => Some(Type::Tuple(vec![])), None => Some(Type::Tuple(vec![])),
_ => output, _ => output,
@ -567,7 +621,7 @@ impl ReconstructingReducer for Canonicalizer {
_circuit: &Circuit, _circuit: &Circuit,
circuit_name: Identifier, circuit_name: Identifier,
members: Vec<CircuitMember>, members: Vec<CircuitMember>,
) -> Result<Circuit, CanonicalizeError> { ) -> Result<Circuit, ReducerError> {
self.circuit_name = Some(circuit_name.clone()); self.circuit_name = Some(circuit_name.clone());
let circ = Circuit { let circ = Circuit {
circuit_name, circuit_name,

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // 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/>. // 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 serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
@ -22,9 +22,9 @@ use std::fmt;
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub enum ConsoleFunction { pub enum ConsoleFunction {
Assert(Expression), Assert(Expression),
Debug(FormattedString), Debug(FormatString),
Error(FormattedString), Error(FormatString),
Log(FormattedString), Log(FormatString),
} }
impl fmt::Display for ConsoleFunction { impl fmt::Display for ConsoleFunction {

View File

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

View File

@ -1,6 +1,6 @@
[package] [package]
name = "leo-compiler" name = "leo-compiler"
version = "1.3.0" version = "1.4.0"
authors = [ "The Aleo Team <hello@aleo.org>" ] authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Compiler of the Leo programming language" description = "Compiler of the Leo programming language"
homepage = "https://aleo.org" homepage = "https://aleo.org"
@ -19,35 +19,38 @@ edition = "2018"
[dependencies.leo-ast] [dependencies.leo-ast]
path = "../ast" path = "../ast"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-imports] [dependencies.leo-imports]
path = "../imports" path = "../imports"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-input] [dependencies.leo-input]
path = "../input" path = "../input"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-package] [dependencies.leo-package]
path = "../package" path = "../package"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-state] [dependencies.leo-state]
path = "../state" path = "../state"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-asg] [dependencies.leo-asg]
path = "../asg" path = "../asg"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-parser] [dependencies.leo-parser]
path = "../parser" path = "../parser"
version = "1.3.0" version = "1.4.0"
[dependencies.leo-asg-passes] [dependencies.leo-asg-passes]
path = "../asg-passes" path = "../asg-passes"
version = "1.3.0" version = "1.4.0"
[dependencies.tendril]
version = "0.4"
[dependencies.snarkvm-curves] [dependencies.snarkvm-curves]
version = "0.2.2" 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). // 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)?; 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. // Preform compiler optimization via canonicalizing AST if its enabled.
if self.options.canonicalization_enabled { if self.options.canonicalization_enabled {
ast.canonicalize()?; ast.canonicalize()?;

View File

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

View File

@ -16,7 +16,7 @@
use crate::errors::FunctionError; use crate::errors::FunctionError;
use leo_asg::{AsgConvertError, FormattedError}; use leo_asg::{AsgConvertError, FormattedError};
use leo_ast::{CanonicalizeError, LeoError}; use leo_ast::{LeoError, ReducerError};
use leo_input::InputParserError; use leo_input::InputParserError;
use leo_parser::SyntaxError; use leo_parser::SyntaxError;
use leo_state::LocalDataVerificationError; use leo_state::LocalDataVerificationError;
@ -56,7 +56,7 @@ pub enum CompilerError {
AsgConvertError(#[from] AsgConvertError), AsgConvertError(#[from] AsgConvertError),
#[error("{}", _0)] #[error("{}", _0)]
CanonicalizeError(#[from] CanonicalizeError), ReducerError(#[from] ReducerError),
} }
impl LeoError for CompilerError {} 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(); let registers = input.get_registers();
// Iterate over main function input variables and allocate new values // Iterate over main function input variables and allocate new values
if function.has_input { let asg_input = function.scope.resolve_input();
// let input_var = function.scope.
let asg_input = function
.scope
.resolve_input()
.expect("no input variable in scope when function is qualified");
if let Some(asg_input) = asg_input {
let value = let value =
self.allocate_input_keyword(cs, &function.name.borrow().span, &asg_input.container_circuit, input)?; 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 mod value;
pub use value::*; pub use value::*;
pub mod stage; pub mod phase;
pub use stage::*; pub use phase::*;
pub mod phases;
pub use phases::*;
pub mod option; pub mod option;
pub use option::*; pub use option::*;

View File

@ -16,6 +16,6 @@
use leo_asg::Program; use leo_asg::Program;
pub trait ASGStage { pub trait ASGPhase {
fn apply(asg: &mut Program); 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() { function main() {
const address_1 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); const address_1 = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
const address_2 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j9); const address_2 = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j9;
console.assert(address_1 == address_2); console.assert(address_1 == address_2);
} }

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