mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-01 10:17:30 +03:00
merge master, next is parser
This commit is contained in:
commit
406692c2aa
@ -1,5 +1,2 @@
|
||||
[build]
|
||||
[target.'cfg(not(target_arch = "wasm32"))']
|
||||
rustflags = ["-C", "target-cpu=native"]
|
||||
|
||||
[net]
|
||||
git-fetch-with-cli = true
|
||||
|
@ -53,13 +53,46 @@ jobs:
|
||||
- run:
|
||||
name: Build and run tests
|
||||
no_output_timeout: 30m
|
||||
command: cargo install --path . --root .
|
||||
command: cargo test --all
|
||||
- persist_to_workspace:
|
||||
root: ~/
|
||||
paths: project/
|
||||
- clear_environment:
|
||||
cache_key: leo-stable-cache
|
||||
|
||||
rust-nightly:
|
||||
docker:
|
||||
- image: howardwu/snarkos-ci:2021-01-31
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- setup_environment:
|
||||
cache_key: leo-nightly-cache
|
||||
- run:
|
||||
name: Build and test
|
||||
no_output_timeout: 30m
|
||||
command: cargo test --all
|
||||
- clear_environment:
|
||||
cache_key: leo-nightly-cache
|
||||
|
||||
leo-executable:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- setup_environment:
|
||||
cache_key: leo-executable-cache
|
||||
- run:
|
||||
name: Build and install Leo
|
||||
no_output_timeout: 30m
|
||||
command: cargo install --path . --root .
|
||||
- persist_to_workspace:
|
||||
root: ~/
|
||||
paths: project/
|
||||
- clear_environment:
|
||||
cache_key: leo-executable-cache
|
||||
|
||||
leo-new:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
@ -138,26 +171,60 @@ jobs:
|
||||
export LEO=/home/circleci/project/project/bin/leo
|
||||
./project/.circleci/leo-login-logout.sh
|
||||
|
||||
leo-clone:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /home/circleci/project/
|
||||
- run:
|
||||
name: leo clone
|
||||
command: |
|
||||
export LEO=/home/circleci/project/project/bin/leo
|
||||
./project/.circleci/leo-clone.sh
|
||||
|
||||
leo-publish:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /home/circleci/project/
|
||||
- run:
|
||||
name: leo publish
|
||||
command: |
|
||||
export LEO=/home/circleci/project/project/bin/leo
|
||||
./project/.circleci/leo-publish.sh
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
main-workflow:
|
||||
jobs:
|
||||
- rust-stable
|
||||
- rust-nightly
|
||||
- leo-executable
|
||||
- leo-new:
|
||||
requires:
|
||||
- rust-stable
|
||||
- leo-executable
|
||||
- leo-init:
|
||||
requires:
|
||||
- rust-stable
|
||||
- leo-executable
|
||||
- leo-clean:
|
||||
requires:
|
||||
- rust-stable
|
||||
- leo-executable
|
||||
- leo-setup:
|
||||
requires:
|
||||
- rust-stable
|
||||
- leo-executable
|
||||
- leo-add-remove:
|
||||
requires:
|
||||
- rust-stable
|
||||
- leo-executable
|
||||
- leo-login-logout:
|
||||
requires:
|
||||
- rust-stable
|
||||
- leo-executable
|
||||
- leo-clone:
|
||||
requires:
|
||||
- leo-executable
|
||||
- leo-publish:
|
||||
requires:
|
||||
- leo-executable
|
||||
|
18
.circleci/leo-clone.sh
Executable file
18
.circleci/leo-clone.sh
Executable file
@ -0,0 +1,18 @@
|
||||
# leo clone
|
||||
|
||||
# Clone the test-app package.
|
||||
export PACKAGE="$ALEO_PM_USERNAME/test-app"
|
||||
$LEO clone $PACKAGE
|
||||
|
||||
# Assert that the 'test-app' folder is not empty
|
||||
|
||||
cd test-app || exit 1
|
||||
if [ "$(ls -A $DIR)" ]; then
|
||||
echo "$DIR is not empty"
|
||||
else
|
||||
echo "$DIR is empty"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ls -la
|
||||
$LEO run
|
56
.circleci/leo-publish.sh
Executable file
56
.circleci/leo-publish.sh
Executable file
@ -0,0 +1,56 @@
|
||||
# leo login, publish and logout
|
||||
|
||||
# Login
|
||||
$LEO login -u "$ALEO_PM_USERNAME" -p "$ALEO_PM_PASSWORD"
|
||||
|
||||
# Clone the test-app package.
|
||||
export PACKAGE="$ALEO_PM_USERNAME/test-app"
|
||||
$LEO clone $PACKAGE
|
||||
cd test-app || exit 1
|
||||
|
||||
# Fetch the current Leo package version number.
|
||||
#
|
||||
# 1. Print out the Leo.toml file.
|
||||
# 2. Search for a line with the word "version".
|
||||
# 3. Isolate that into a single line.
|
||||
# 4. Split the line from the '=' sign and keep the right-hand side.
|
||||
# 5. Remove the quotes around the version number.
|
||||
# 6. Trim any excess whitespace.
|
||||
export CURRENT=$(cat Leo.toml \
|
||||
| grep version \
|
||||
| head -1 \
|
||||
| awk -F= '{ print $2 }' \
|
||||
| sed 's/[",]//g' \
|
||||
| xargs)
|
||||
|
||||
# Increment the current Leo package version number by 1.
|
||||
#
|
||||
# 1. Print out the Leo.toml file.
|
||||
# 2. Search for a line with the word "version".
|
||||
# 3. Isolate that into a single line.
|
||||
# 4. Split the line from the '=' sign and keep the right-hand side.
|
||||
# 5. Remove the quotes around the version number.
|
||||
# 6. Trim any excess whitespace.
|
||||
# 7. Increment the version number by 1 (on the semver patch).
|
||||
#
|
||||
# https://stackoverflow.com/questions/8653126/how-to-increment-version-number-in-a-shell-script
|
||||
export UPDATED=$(cat Leo.toml \
|
||||
| grep version \
|
||||
| head -1 \
|
||||
| awk -F= '{ print $2 }' \
|
||||
| sed 's/[",]//g' \
|
||||
| xargs \
|
||||
| awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{if(length($NF+1)>length($NF))$(NF-1)++; $NF=sprintf("%0*d", length($NF), ($NF+1)%(10^length($NF))); print}')
|
||||
|
||||
# Write the updated Leo package version number to the Leo.toml file.
|
||||
export TOML=$(cat Leo.toml | sed "s/$CURRENT/$UPDATED/g")
|
||||
echo "$TOML" > Leo.toml
|
||||
|
||||
# Run the package to confirm the manifest remains well-formed.
|
||||
$LEO run
|
||||
|
||||
# Publish the package to Aleo.pm
|
||||
$LEO publish
|
||||
|
||||
# Logout
|
||||
$LEO logout
|
57
.github/workflows/ci.yml
vendored
57
.github/workflows/ci.yml
vendored
@ -71,63 +71,6 @@ jobs:
|
||||
command: clippy
|
||||
args: --all-features --examples --all --benches
|
||||
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
# env:
|
||||
# RUSTFLAGS: -Dwarnings
|
||||
strategy:
|
||||
matrix:
|
||||
rust:
|
||||
- stable
|
||||
- nightly
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust (${{ matrix.rust }})
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# - name: Check examples
|
||||
# uses: actions-rs/cargo@v1
|
||||
# env:
|
||||
# CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||
# with:
|
||||
# command: check
|
||||
# args: --examples --all
|
||||
#
|
||||
# - name: Check examples with all features on stable
|
||||
# uses: actions-rs/cargo@v1
|
||||
# with:
|
||||
# command: check
|
||||
# args: --examples --all-features --all
|
||||
# if: matrix.rust == 'stable'
|
||||
#
|
||||
# - name: Check benchmarks on nightly
|
||||
# uses: actions-rs/cargo@v1
|
||||
# with:
|
||||
# command: check
|
||||
# args: --all-features --examples --all --benches
|
||||
# if: matrix.rust == 'nightly'
|
||||
|
||||
- name: Test
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --all --features ci_skip --no-fail-fast
|
||||
|
||||
test-package:
|
||||
name: Test Package
|
||||
runs-on: ubuntu-latest
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 29 KiB |
@ -1 +1 @@
|
||||
v1.2.2
|
||||
v1.2.3
|
||||
|
70
.travis.yml
70
.travis.yml
@ -1,70 +0,0 @@
|
||||
language: rust
|
||||
|
||||
before_install:
|
||||
- set -e
|
||||
- export SCCACHE_CACHE_SIZE=200M
|
||||
- export SCCACHE_DIR="$TRAVIS_HOME/.cache/sccache"
|
||||
- mkdir "$TRAVIS_HOME/.bin"
|
||||
- wget https://github.com/mozilla/sccache/releases/download/0.2.13/sccache-0.2.13-x86_64-unknown-linux-musl.tar.gz
|
||||
- tar -C "$TRAVIS_HOME/.bin" -xvf sccache-0.2.13-x86_64-unknown-linux-musl.tar.gz
|
||||
- mv $TRAVIS_HOME/.bin/sccache-0.2.13-x86_64-unknown-linux-musl/sccache $TRAVIS_HOME/.bin/sccache
|
||||
- export PATH="$PATH:$TRAVIS_HOME/.bin"
|
||||
- export RUSTC_WRAPPER="sccache"
|
||||
- |
|
||||
declare -r SSH_FILE="$(mktemp -u $HOME/.ssh/XXXXX)"
|
||||
openssl aes-256-cbc -K $encrypted_beefc4a47cdc_key -iv $encrypted_beefc4a47cdc_iv -in .travis/travis-snarkvm.enc -out $SSH_FILE -d
|
||||
chmod 600 "$SSH_FILE" \
|
||||
&& printf "%s\n" \
|
||||
"Host github.com" \
|
||||
" IdentityFile $SSH_FILE" \
|
||||
" LogLevel ERROR" >> ~/.ssh/config
|
||||
- git clone --progress --verbose git@github.com:AleoHQ/snarkOS.git
|
||||
- mv snarkOS ..
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $TRAVIS_HOME/.cache/sccache
|
||||
- $TRAVIS_HOME/.cargo
|
||||
|
||||
# See https://levans.fr/rust_travis_cache.html
|
||||
before_cache:
|
||||
- rm -rf "$TRAVIS_HOME/.cargo/registry"
|
||||
|
||||
after_script:
|
||||
- (sccache -s||true)
|
||||
- set +e
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- rust: stable
|
||||
env: TEST_COVERAGE=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcurl4-openssl-dev
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
- cmake
|
||||
- gcc
|
||||
- binutils-dev
|
||||
- libiberty-dev
|
||||
script:
|
||||
- cargo test --all
|
||||
after_success:
|
||||
- wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz
|
||||
- tar xzf master.tar.gz && cd kcov-master
|
||||
- mkdir build && cd build && cmake .. && make && sudo make install
|
||||
- cd ../.. && rm -rf kcov-master
|
||||
- for file in target/debug/deps/*-*; do if [[ "$file" != *\.* ]]; then mkdir -p "target/cov/$(basename $file)"; kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; fi done
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
- echo "Uploaded code coverage"
|
||||
- rust: nightly-2020-03-18
|
||||
install:
|
||||
- rustup component add rustfmt
|
||||
script:
|
||||
- cargo fmt -- --check
|
||||
- cargo test --all
|
||||
|
||||
script:
|
||||
- echo "leo"
|
Binary file not shown.
386
Cargo.lock
generated
386
Cargo.lock
generated
@ -1,5 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.14.1"
|
||||
@ -50,9 +52,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.38"
|
||||
version = "1.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
|
||||
checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
@ -365,9 +367,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc80946b3480f421c2f17ed1cb841753a371c7c5104f51d507e13f532c856aa"
|
||||
checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45"
|
||||
dependencies = [
|
||||
"encode_unicode",
|
||||
"lazy_static",
|
||||
@ -508,9 +510,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.5"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9d58633299b24b515ac72a3f869f8b91306a3cec616a602843a383acd6f9e97"
|
||||
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
@ -530,9 +532,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "curl"
|
||||
version = "0.4.34"
|
||||
version = "0.4.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e268162af1a5fe89917ae25ba3b0a77c8da752bdc58e7dbb4f15b91fbd33756e"
|
||||
checksum = "5a872858e9cb9e3b96c80dd78774ad9e32e44d3b05dc31e142b858d14aebc82c"
|
||||
dependencies = [
|
||||
"curl-sys",
|
||||
"libc",
|
||||
@ -545,9 +547,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "curl-sys"
|
||||
version = "0.4.40+curl-7.75.0"
|
||||
version = "0.4.41+curl-7.75.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffafc1c35958318bd7fdd0582995ce4c72f4f461a8e70499ccee83a619fd562"
|
||||
checksum = "0ec466abd277c7cab2905948f3e94d10bc4963f1f5d47921c1cc4ffd2028fe65"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -566,7 +568,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -669,7 +671,7 @@ checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -956,9 +958,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
@ -1052,9 +1054,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.6.1"
|
||||
version = "1.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
|
||||
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
@ -1192,12 +1194,12 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "leo-asg"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"indexmap",
|
||||
"leo-ast",
|
||||
"leo-grammar",
|
||||
"leo-parser",
|
||||
"num-bigint",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -1206,12 +1208,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-ast"
|
||||
version = "1.2.2"
|
||||
name = "leo-asg-passes"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"leo-asg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-ast"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"criterion",
|
||||
"indexmap",
|
||||
"leo-grammar",
|
||||
"leo-input",
|
||||
"pest",
|
||||
"serde",
|
||||
@ -1221,18 +1230,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leo-compiler"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"hex",
|
||||
"indexmap",
|
||||
"leo-asg",
|
||||
"leo-asg-passes",
|
||||
"leo-ast",
|
||||
"leo-gadgets",
|
||||
"leo-grammar",
|
||||
"leo-imports",
|
||||
"leo-input",
|
||||
"leo-package",
|
||||
"leo-parser",
|
||||
"leo-state",
|
||||
"num-bigint",
|
||||
"pest",
|
||||
@ -1244,60 +1253,29 @@ dependencies = [
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-dpc",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-fields",
|
||||
"snarkvm-gadgets",
|
||||
"snarkvm-models",
|
||||
"snarkvm-objects",
|
||||
"snarkvm-r1cs",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-gadgets"
|
||||
version = "1.2.2"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"rand_xorshift",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-models",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-grammar"
|
||||
version = "1.2.2"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"from-pest",
|
||||
"lazy_static",
|
||||
"pest",
|
||||
"pest-ast",
|
||||
"pest_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-imports"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"leo-asg",
|
||||
"leo-ast",
|
||||
"leo-grammar",
|
||||
"leo-parser",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-input"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"from-pest",
|
||||
"pest",
|
||||
@ -1309,7 +1287,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leo-lang"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1320,13 +1298,12 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"leo-ast",
|
||||
"leo-compiler",
|
||||
"leo-gadgets",
|
||||
"leo-imports",
|
||||
"leo-input",
|
||||
"leo-package",
|
||||
"leo-state",
|
||||
"leo-synthesizer",
|
||||
"notify",
|
||||
"num-bigint",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"reqwest",
|
||||
@ -1336,9 +1313,8 @@ dependencies = [
|
||||
"serde_json",
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-gadgets",
|
||||
"snarkvm-models",
|
||||
"snarkvm-r1cs",
|
||||
"snarkvm-utilities",
|
||||
"structopt",
|
||||
"thiserror",
|
||||
@ -1350,11 +1326,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leo-linter"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
|
||||
[[package]]
|
||||
name = "leo-package"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"serde",
|
||||
@ -1365,9 +1341,23 @@ dependencies = [
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-parser"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
"leo-ast",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-state"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"leo-ast",
|
||||
@ -1378,19 +1368,29 @@ dependencies = [
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-dpc",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-models",
|
||||
"snarkvm-objects",
|
||||
"snarkvm-storage",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-synthesizer"
|
||||
version = "1.2.3"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-fields",
|
||||
"snarkvm-gadgets",
|
||||
"snarkvm-r1cs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.86"
|
||||
version = "0.2.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
|
||||
checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -1536,9 +1536,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.9"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a"
|
||||
checksum = "2182a122f3b7f3f5329cb1972cee089ba2459a0a80a56935e6e674f096f8d839"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
@ -1655,9 +1655,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.3.1"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e9a41747ae4633fce5adffb4d2e81ffc5e89593cb19917f8fb2cc5ff76507bf"
|
||||
checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
@ -1707,9 +1707,9 @@ checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.7.0"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a"
|
||||
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
@ -1731,15 +1731,15 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.32"
|
||||
version = "0.10.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70"
|
||||
checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"foreign-types",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
@ -1751,9 +1751,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.60"
|
||||
version = "0.9.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6"
|
||||
checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
@ -1841,7 +1841,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1872,7 +1872,7 @@ checksum = "758669ae3558c6f74bd2a18b41f7ac0b5a195aea6639d6a9b5e5d1ad5ba24c0b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1945,7 +1945,7 @@ dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
@ -2113,14 +2113,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.3"
|
||||
version = "1.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
|
||||
checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2135,9 +2134,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.22"
|
||||
version = "0.6.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
|
||||
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
@ -2150,9 +2149,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0460542b551950620a3648c6aa23318ac6b3cd779114bd873209e6e8b5eb1c34"
|
||||
checksum = "bf12057f289428dbf5c591c74bf10392e4a8003f993405a902f20117019022d4"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@ -2281,9 +2280,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.1.0"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6af1b6204f89cf0069736daf8b852573e3bc34898eee600e95d3dd855c12e81"
|
||||
checksum = "d493c5f39e02dfb062cd8f33301f90f9b13b650e8c1b1d0fd75c19dd64bff69d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
@ -2294,9 +2293,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31531d257baab426203cf81c5ce1b0b55159dda7ed602ac81b582ccd62265741"
|
||||
checksum = "dee48cdde5ed250b0d3252818f646e174ab414036edb884dde62d80a3ac6082d"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@ -2304,9 +2303,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "self_update"
|
||||
version = "0.25.0"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5abe13436707b8fd0044592de0b8d9565ab700fbb06611d6e4d89384687da195"
|
||||
checksum = "9031099ba3962ce8faaff991066bcbe6ec1f7ccb0be12a4b56733028ae090054"
|
||||
dependencies = [
|
||||
"hyper",
|
||||
"indicatif",
|
||||
@ -2355,9 +2354,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.123"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
|
||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@ -2374,13 +2373,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.123"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
|
||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2469,9 +2468,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-algorithms"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "739c2aaf5dbf6322d3a40bbb9739a87d458f32460da1b8affeae45214ec88e8c"
|
||||
checksum = "472ed062cdd1f54076312dd34e5fb56bd585c80c12209045f4b5bbbd368e9000"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"derivative",
|
||||
@ -2482,48 +2481,52 @@ dependencies = [
|
||||
"rayon",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-models",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-fields",
|
||||
"snarkvm-profiler",
|
||||
"snarkvm-r1cs",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-curves"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c39148bec803c5e41b0696326a60817d9b84c4c2c1df6ea5be56f857b078988"
|
||||
checksum = "cdfdfa3aa137f64a7f49df03393e5d0269f133ca8c8c79e569cb3bb13181aeb2"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"rustc_version 0.3.3",
|
||||
"serde",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-models",
|
||||
"snarkvm-fields",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-derives"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24c5c4170d43a65e23bce115d6d2940c7fc66e1562a7822dd460db56f1fb07b1"
|
||||
checksum = "6a2ba967601ff2534adbc6a71a691be4285e61c83d23d54a59824f8fa80f6038"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-dpc"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3feb5d2cec547779e0acec01cd58f5d5fe6aac60cc4804e5e3cf9c807bb1880"
|
||||
checksum = "ff4cb55898089843ba44b9f96448dcb2badcc1ce12daa8d7365d4e41513e37bc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base58",
|
||||
"bech32",
|
||||
"blake2",
|
||||
"derivative",
|
||||
"hex",
|
||||
@ -2531,75 +2534,57 @@ dependencies = [
|
||||
"rand",
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-fields",
|
||||
"snarkvm-gadgets",
|
||||
"snarkvm-models",
|
||||
"snarkvm-objects",
|
||||
"snarkvm-parameters",
|
||||
"snarkvm-profiler",
|
||||
"snarkvm-r1cs",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-errors"
|
||||
version = "0.0.5"
|
||||
name = "snarkvm-fields"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cfe9f6fac097aed079fa68a63c8989783b2cf21705de75bc91672dec60c9684"
|
||||
checksum = "ca9ea954196e76fe8968fb99eced7ccf08f901ab22747c4c489bda6674a7cb39"
|
||||
dependencies = [
|
||||
"base58",
|
||||
"bech32",
|
||||
"bincode",
|
||||
"curl",
|
||||
"hex",
|
||||
"derivative",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"serde",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-gadgets"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978bcc75bce7a1274f51b2adc4d69c30d866930aa37c656b4b8c1be5d631891c"
|
||||
checksum = "fdda42a0a6484d9f008801a8a4d494a69a4db3f7b317057a8cc3c6e4b3ef6884"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"digest 0.9.0",
|
||||
"itertools 0.10.0",
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-models",
|
||||
"snarkvm-utilities",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-models"
|
||||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c8da5920c6f4062c0d348e93ff0f72d17681c34f3c13ee4e99196495d896ed9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"cfg-if 1.0.0",
|
||||
"derivative",
|
||||
"fxhash",
|
||||
"indexmap",
|
||||
"itertools 0.10.0",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"serde",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-fields",
|
||||
"snarkvm-r1cs",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-objects"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4641e23002d38caeb51fa3244320355cab07eaf22d17dc44b481c763b63b5f4d"
|
||||
checksum = "e20d13db49cedc147df06c4a6f2dd727ea25640bdf50b876f40005331767a68f"
|
||||
dependencies = [
|
||||
"base58",
|
||||
"bech32",
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"chrono",
|
||||
"derivative",
|
||||
"hex",
|
||||
"once_cell",
|
||||
"rand",
|
||||
@ -2607,36 +2592,50 @@ dependencies = [
|
||||
"sha2",
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-models",
|
||||
"snarkvm-parameters",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-parameters"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cb0f27fbccad7dee0ad4c2e5aeb0832c393fec76b4ad5d834c2e6cc0297e9a9"
|
||||
checksum = "d35fa1819d803e45b4e99fe822e6981f177716f5384eef27245b5f6ed59a8305"
|
||||
dependencies = [
|
||||
"curl",
|
||||
"hex",
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-models",
|
||||
"snarkvm-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-profiler"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb5e9b964cb9653588607d8793bc7d6d0dfa78763a02d61aa3daa6c7d665e2b"
|
||||
checksum = "7834d57af37a31f2f280f08b61d07a04a9a4b7720819b06ca325da32a5a925f5"
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-r1cs"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0838118f276e7bb673cbf3741f4966c56861aaff399a46d343fc98c12851d9eb"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fxhash",
|
||||
"indexmap",
|
||||
"itertools 0.10.0",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-fields",
|
||||
"snarkvm-utilities",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-storage"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ef134de5e33fe0577f3936e9dcf9bfac1973a0d820390e19558672808bad6b9"
|
||||
checksum = "a42d92a817502878f315cc264704fa2a3d563755f16186316d8177ea685769af"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -2646,8 +2645,7 @@ dependencies = [
|
||||
"rocksdb",
|
||||
"serde",
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-errors",
|
||||
"snarkvm-models",
|
||||
"snarkvm-dpc",
|
||||
"snarkvm-objects",
|
||||
"snarkvm-parameters",
|
||||
"snarkvm-utilities",
|
||||
@ -2656,14 +2654,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-utilities"
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "872c2ee1675c5039caf8cb4c5ef37b0ad844ffe7e0d81b68fb39f713da199561"
|
||||
checksum = "5598f7f71c8aaf4fc267b5b420b2440a4d86c9243cecd57ff0af5c366217e5cc"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"rand",
|
||||
"snarkvm-derives",
|
||||
"snarkvm-errors",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2704,7 +2702,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2726,9 +2724,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.60"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
|
||||
checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
@ -2743,7 +2741,7 @@ checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
"unicode-xid 0.2.1",
|
||||
]
|
||||
|
||||
@ -2806,7 +2804,7 @@ checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2830,9 +2828,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2ada8616fad06a2d0c455adc530de4ef57605a8120cc65da9653e0e9623ca74"
|
||||
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -2855,15 +2853,15 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a"
|
||||
checksum = "8d56477f6ed99e10225f38f9f75f872f29b8b8bd8c0b946f63345bb144e9eeda"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio 0.7.9",
|
||||
"mio 0.7.10",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
]
|
||||
@ -2880,9 +2878,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.3"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebb7cb2f00c5ae8df755b252306272cd1790d39728363936e01827e11f0b017b"
|
||||
checksum = "ec31e5cc6b46e653cf57762f36f71d5e6386391d88a72fd6db4508f8f676fb29"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
@ -2921,13 +2919,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.13"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8a9bd1db7706f2373a190b0d067146caa39350c486f3d455b0e33b431f94c07"
|
||||
checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2972,9 +2970,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.2.16"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ab8966ac3ca27126141f7999361cc97dd6fb4b71da04c02044fa9045d98bb96"
|
||||
checksum = "705096c6f83bf68ea5d357a6aa01829ddbdac531b357b45abeca842938085baa"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"chrono",
|
||||
@ -3006,9 +3004,9 @@ checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
@ -3105,9 +3103,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.1"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi 0.3.9",
|
||||
@ -3159,7 +3157,7 @@ dependencies = [
|
||||
"log",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -3193,7 +3191,7 @@ checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
"syn 1.0.64",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
52
Cargo.toml
52
Cargo.toml
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leo-lang"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "The Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
@ -29,65 +29,62 @@ members = [
|
||||
"asg",
|
||||
"ast",
|
||||
"compiler",
|
||||
"gadgets",
|
||||
"grammar",
|
||||
"imports",
|
||||
"input",
|
||||
"linter",
|
||||
"package",
|
||||
"parser",
|
||||
"state",
|
||||
"synthesizer",
|
||||
"asg-passes",
|
||||
]
|
||||
|
||||
[dependencies.leo-ast]
|
||||
path = "./ast"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.leo-compiler]
|
||||
path = "./compiler"
|
||||
version = "1.2.2"
|
||||
|
||||
[dependencies.leo-gadgets]
|
||||
path = "./gadgets"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.leo-imports]
|
||||
path = "./imports"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.leo-input]
|
||||
path = "./input"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.leo-package]
|
||||
path = "./package"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.leo-state]
|
||||
path = "./state"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.leo-synthesizer]
|
||||
path = "./synthesizer"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.snarkvm-algorithms]
|
||||
version = "0.0.5"
|
||||
default-features = false
|
||||
version = "0.2.1"
|
||||
#default-features = false
|
||||
|
||||
[dependencies.snarkvm-curves]
|
||||
version = "0.0.5"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-errors]
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-gadgets]
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-models]
|
||||
version = "0.0.5"
|
||||
[dependencies.snarkvm-r1cs]
|
||||
version = "0.2.1"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-utilities]
|
||||
version = "0.0.5"
|
||||
version = "0.2.1"
|
||||
|
||||
[dependencies.anyhow]
|
||||
version = "1.0"
|
||||
@ -116,9 +113,6 @@ version = "1.4.0"
|
||||
[dependencies.notify]
|
||||
version = "4.0.15"
|
||||
|
||||
[dependencies.num-bigint]
|
||||
version = "0.3"
|
||||
|
||||
[dependencies.rand]
|
||||
version = "0.8"
|
||||
|
||||
@ -126,11 +120,11 @@ version = "0.8"
|
||||
version = "0.6.2"
|
||||
|
||||
[dependencies.reqwest]
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
features = [ "blocking", "json", "multipart" ]
|
||||
|
||||
[dependencies.self_update]
|
||||
version = "0.25.0"
|
||||
version = "0.26.0"
|
||||
features = [ "archive-zip" ]
|
||||
|
||||
[dependencies.serde]
|
||||
|
@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<img width="1412" src=".resources/banner.png">
|
||||
<img width="1412" src="https://cdn.aleo.org/leo/banner.png">
|
||||
</p>
|
||||
|
||||
<h1 align="center">The Leo Programming Language</h1>
|
||||
|
25
asg-passes/Cargo.toml
Normal file
25
asg-passes/Cargo.toml
Normal file
@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "leo-asg-passes"
|
||||
version = "1.2.3"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "The Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
repository = "https://github.com/AleoHQ/leo"
|
||||
keywords = [
|
||||
"aleo",
|
||||
"cryptography",
|
||||
"leo",
|
||||
"programming-language",
|
||||
"zero-knowledge"
|
||||
]
|
||||
categories = [ "cryptography::cryptocurrencies", "web-programming" ]
|
||||
include = [ "Cargo.toml", "leo", "README.md", "LICENSE.md" ]
|
||||
license = "GPL-3.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies.leo-asg]
|
||||
path = "../asg"
|
||||
version = "1.2.3"
|
54
asg-passes/src/constant_folding/mod.rs
Normal file
54
asg-passes/src/constant_folding/mod.rs
Normal file
@ -0,0 +1,54 @@
|
||||
// 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 std::cell::Cell;
|
||||
|
||||
use leo_asg::*;
|
||||
|
||||
pub struct ConstantFolding<'a, 'b> {
|
||||
program: &'b Program<'a>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> ExpressionVisitor<'a> for ConstantFolding<'a, 'b> {
|
||||
fn visit_expression(&mut self, input: &Cell<&Expression<'a>>) -> VisitResult {
|
||||
let expr = input.get();
|
||||
if let Some(const_value) = expr.const_value() {
|
||||
let folded_expr = Expression::Constant(Constant {
|
||||
parent: Cell::new(expr.get_parent()),
|
||||
span: expr.span().cloned(),
|
||||
value: const_value,
|
||||
});
|
||||
let folded_expr = self.program.context.alloc_expression(folded_expr);
|
||||
input.set(folded_expr);
|
||||
VisitResult::SkipChildren
|
||||
} else {
|
||||
VisitResult::VisitChildren
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> StatementVisitor<'a> for ConstantFolding<'a, 'b> {}
|
||||
|
||||
impl<'a, 'b> ProgramVisitor<'a> for ConstantFolding<'a, 'b> {}
|
||||
|
||||
impl<'a, 'b> AsgPass<'a> for ConstantFolding<'a, 'b> {
|
||||
fn do_pass(asg: Program<'a>) -> Result<Program<'a>, FormattedError> {
|
||||
let pass = ConstantFolding { program: &asg };
|
||||
let mut director = VisitorDirector::new(pass);
|
||||
director.visit_program(&asg).ok();
|
||||
Ok(asg)
|
||||
}
|
||||
}
|
73
asg-passes/src/dead_code_elimination/mod.rs
Normal file
73
asg-passes/src/dead_code_elimination/mod.rs
Normal file
@ -0,0 +1,73 @@
|
||||
// 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 std::cell::Cell;
|
||||
|
||||
use leo_asg::*;
|
||||
|
||||
pub struct DeadCodeElimination {}
|
||||
|
||||
impl<'a> ReconstructingReducerExpression<'a> for DeadCodeElimination {}
|
||||
|
||||
impl<'a> ReconstructingReducerProgram<'a> for DeadCodeElimination {}
|
||||
|
||||
impl<'a> ReconstructingReducerStatement<'a> for DeadCodeElimination {
|
||||
///
|
||||
/// Removes dead code inside a false conditional statement block.
|
||||
///
|
||||
fn reduce_statement_alloc(
|
||||
&mut self,
|
||||
context: AsgContext<'a>,
|
||||
_input: &'a Statement<'a>,
|
||||
value: Statement<'a>,
|
||||
) -> &'a Statement<'a> {
|
||||
match &value {
|
||||
Statement::Conditional(conditional) => match conditional.condition.get().const_value() {
|
||||
Some(ConstValue::Boolean(true)) => conditional.result.get(),
|
||||
Some(ConstValue::Boolean(false)) => {
|
||||
if let Some(if_false) = conditional.next.get() {
|
||||
if_false
|
||||
} else {
|
||||
context.alloc_statement(Statement::Empty(conditional.span.clone()))
|
||||
}
|
||||
}
|
||||
_ => context.alloc_statement(value),
|
||||
},
|
||||
_ => context.alloc_statement(value),
|
||||
}
|
||||
}
|
||||
|
||||
fn reduce_block(&mut self, input: BlockStatement<'a>, mut statements: Vec<&'a Statement<'a>>) -> Statement<'a> {
|
||||
let first_return = statements.iter().position(|x| matches!(x, Statement::Return(_)));
|
||||
if let Some(first_return) = first_return {
|
||||
statements.truncate(first_return + 1);
|
||||
}
|
||||
Statement::Block(BlockStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
statements: statements.into_iter().map(Cell::new).collect(),
|
||||
scope: input.scope,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AsgPass<'a> for DeadCodeElimination {
|
||||
fn do_pass(asg: Program<'a>) -> Result<Program<'a>, FormattedError> {
|
||||
let pass = DeadCodeElimination {};
|
||||
let mut director = ReconstructingDirector::new(asg.context, pass);
|
||||
Ok(director.reduce_program(asg))
|
||||
}
|
||||
}
|
@ -14,9 +14,8 @@
|
||||
// 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/>.
|
||||
|
||||
#[macro_use]
|
||||
pub mod eq;
|
||||
pub use self::eq::*;
|
||||
pub mod constant_folding;
|
||||
pub use constant_folding::*;
|
||||
|
||||
pub mod cmp;
|
||||
pub use self::cmp::*;
|
||||
pub mod dead_code_elimination;
|
||||
pub use dead_code_elimination::*;
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leo-asg"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "ASG of the Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
@ -30,15 +30,15 @@ version = "1.6"
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.leo-ast]
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
path = "../ast"
|
||||
|
||||
[dependencies.leo-grammar]
|
||||
version = "1.2.2"
|
||||
path = "../grammar"
|
||||
[dependencies.leo-parser]
|
||||
version = "1.2.3"
|
||||
path = "../parser"
|
||||
|
||||
[dependencies.num-bigint]
|
||||
version = "0.3"
|
||||
version = "0.4"
|
||||
|
||||
[dependencies.typed-arena]
|
||||
version = "2.0"
|
||||
|
@ -91,6 +91,16 @@ pub enum GroupValue {
|
||||
Tuple(GroupCoordinate, GroupCoordinate),
|
||||
}
|
||||
|
||||
impl From<leo_ast::GroupValue> for GroupValue {
|
||||
fn from(other: leo_ast::GroupValue) -> Self {
|
||||
use leo_ast::GroupValue::*;
|
||||
match other {
|
||||
Single(value, _) => GroupValue::Single(value),
|
||||
Tuple(value) => GroupValue::Tuple(GroupCoordinate::from(&value.x), GroupCoordinate::from(&value.y)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ConstValue {
|
||||
Int(ConstInt),
|
||||
@ -188,8 +198,30 @@ impl ConstInt {
|
||||
|
||||
const_int_map!(value_negate, x, x.checked_neg()?);
|
||||
|
||||
const_int_map!(value_bit_negate, x, !x);
|
||||
|
||||
const_int_op!(to_usize, Option<usize>, x, (*x).try_into().ok());
|
||||
|
||||
const_int_op!(to_u128, u128, x, *x as u128);
|
||||
|
||||
const_int_op!(to_u64, u64, x, *x as u64);
|
||||
|
||||
const_int_op!(to_u32, u32, x, *x as u32);
|
||||
|
||||
const_int_op!(to_u16, u16, x, *x as u16);
|
||||
|
||||
const_int_op!(to_u8, u8, x, *x as u8);
|
||||
|
||||
const_int_op!(to_i128, i128, x, *x as i128);
|
||||
|
||||
const_int_op!(to_i64, i64, x, *x as i64);
|
||||
|
||||
const_int_op!(to_i32, i32, x, *x as i32);
|
||||
|
||||
const_int_op!(to_i16, i16, x, *x as i16);
|
||||
|
||||
const_int_op!(to_i8, i8, x, *x as i8);
|
||||
|
||||
const_int_op!(to_string, String, x, (*x).to_string());
|
||||
|
||||
const_int_bimap!(value_add, x, y, x.checked_add(*y)?);
|
||||
@ -226,6 +258,21 @@ impl ConstInt {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast_to(&self, target: &IntegerType) -> ConstInt {
|
||||
match target {
|
||||
IntegerType::I8 => ConstInt::I8(self.to_i8()),
|
||||
IntegerType::I16 => ConstInt::I16(self.to_i16()),
|
||||
IntegerType::I32 => ConstInt::I32(self.to_i32()),
|
||||
IntegerType::I64 => ConstInt::I64(self.to_i64()),
|
||||
IntegerType::I128 => ConstInt::I128(self.to_i128()),
|
||||
IntegerType::U8 => ConstInt::U8(self.to_u8()),
|
||||
IntegerType::U16 => ConstInt::U16(self.to_u16()),
|
||||
IntegerType::U32 => ConstInt::U32(self.to_u32()),
|
||||
IntegerType::U64 => ConstInt::U64(self.to_u64()),
|
||||
IntegerType::U128 => ConstInt::U128(self.to_u128()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_type<'a>(&self) -> Type<'a> {
|
||||
Type::Integer(self.get_int_type())
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use std::{cell::Cell, unimplemented};
|
||||
|
||||
use typed_arena::Arena;
|
||||
|
||||
use crate::ArenaNode;
|
||||
use crate::{ArenaNode, Circuit, Expression, Function, Scope, Statement, Variable};
|
||||
|
||||
pub struct AsgContextInner<'a> {
|
||||
pub arena: &'a Arena<ArenaNode<'a>>,
|
||||
@ -41,6 +41,54 @@ impl<'a> AsgContextInner<'a> {
|
||||
self.next_id.replace(next_id + 1);
|
||||
next_id
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub fn alloc_expression(&'a self, expr: Expression<'a>) -> &'a Expression<'a> {
|
||||
match self.arena.alloc(ArenaNode::Expression(expr)) {
|
||||
ArenaNode::Expression(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub fn alloc_statement(&'a self, statement: Statement<'a>) -> &'a Statement<'a> {
|
||||
match self.arena.alloc(ArenaNode::Statement(statement)) {
|
||||
ArenaNode::Statement(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub fn alloc_variable(&'a self, variable: Variable<'a>) -> &'a Variable<'a> {
|
||||
match self.arena.alloc(ArenaNode::Variable(variable)) {
|
||||
ArenaNode::Variable(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub fn alloc_scope(&'a self, scope: Scope<'a>) -> &'a Scope<'a> {
|
||||
match self.arena.alloc(ArenaNode::Scope(scope)) {
|
||||
ArenaNode::Scope(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub fn alloc_circuit(&'a self, circuit: Circuit<'a>) -> &'a Circuit<'a> {
|
||||
match self.arena.alloc(ArenaNode::Circuit(circuit)) {
|
||||
ArenaNode::Circuit(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub fn alloc_function(&'a self, function: Function<'a>) -> &'a Function<'a> {
|
||||
match self.arena.alloc(ArenaNode::Function(function)) {
|
||||
ArenaNode::Function(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type AsgContext<'a> = &'a AsgContextInner<'a>;
|
||||
|
@ -17,14 +17,11 @@
|
||||
//! Errors encountered when attempting to convert to an asg from an ast.
|
||||
|
||||
use crate::Span;
|
||||
use leo_ast::{AstError, Error as FormattedError};
|
||||
use leo_grammar::ParserError;
|
||||
use leo_ast::{FormattedError, LeoError};
|
||||
use leo_parser::SyntaxError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AsgConvertError {
|
||||
#[error("{}", _0)]
|
||||
AstError(#[from] AstError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] FormattedError),
|
||||
|
||||
@ -35,12 +32,32 @@ pub enum AsgConvertError {
|
||||
InternalError(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ParserError(#[from] ParserError),
|
||||
SyntaxError(#[from] SyntaxError),
|
||||
}
|
||||
|
||||
impl LeoError for AsgConvertError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
AsgConvertError::Error(error) => error.get_path(),
|
||||
AsgConvertError::SyntaxError(error) => error.get_path(),
|
||||
AsgConvertError::ImportError(error) => error.get_path(),
|
||||
AsgConvertError::InternalError(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
AsgConvertError::Error(error) => error.set_path(path, contents),
|
||||
AsgConvertError::SyntaxError(error) => error.set_path(path, contents),
|
||||
AsgConvertError::ImportError(error) => error.set_path(path, contents),
|
||||
AsgConvertError::InternalError(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsgConvertError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
AsgConvertError::Error(FormattedError::new_from_span(message, span.clone()))
|
||||
AsgConvertError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
|
||||
pub fn unresolved_circuit(name: &str, span: &Span) -> Self {
|
||||
@ -227,6 +244,10 @@ impl AsgConvertError {
|
||||
Self::new_from_span(format!("failed to parse int value '{}'", value), span)
|
||||
}
|
||||
|
||||
pub fn unsigned_negation(span: &Span) -> Self {
|
||||
Self::new_from_span("cannot negate unsigned integer".to_string(), span)
|
||||
}
|
||||
|
||||
pub fn immutable_assignment(name: &str, span: &Span) -> Self {
|
||||
Self::new_from_span(format!("illegal assignment to immutable variable '{}'", name), span)
|
||||
}
|
||||
@ -256,6 +277,14 @@ impl AsgConvertError {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn call_test_function(span: &Span) -> Self {
|
||||
Self::new_from_span("cannot call test function".to_string(), span)
|
||||
}
|
||||
|
||||
pub fn circuit_test_function(span: &Span) -> Self {
|
||||
Self::new_from_span("cannot have test function as member of circuit".to_string(), span)
|
||||
}
|
||||
|
||||
pub fn parse_index_error() -> Self {
|
||||
AsgConvertError::InternalError("failed to parse index".to_string())
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayInitExpression> for ArrayInitExpression<'a> {
|
||||
element: Cell::new(
|
||||
output
|
||||
.map(Expression::ArrayInit)
|
||||
.map(|expr| &*scope.alloc_expression(expr))
|
||||
.map(|expr| &*scope.context.alloc_expression(expr))
|
||||
.unwrap_or_else(|| element.take().unwrap()),
|
||||
),
|
||||
len: dimension,
|
||||
|
@ -114,7 +114,28 @@ impl<'a> FromAst<'a, leo_ast::ArrayInlineExpression> for ArrayInlineExpression<'
|
||||
}
|
||||
};
|
||||
|
||||
// If we still don't know the type iterate through processing to get a type.
|
||||
// Once we encouter the type break the loop so we process as little as possible.
|
||||
if expected_item.is_none() {
|
||||
for expr in value.elements.iter() {
|
||||
expected_item = match expr {
|
||||
SpreadOrExpression::Expression(e) => {
|
||||
match <&Expression<'a>>::from_ast(scope, e, expected_item.clone()) {
|
||||
Ok(expr) => expr.get_type().map(Type::partial),
|
||||
Err(_) => continue,
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if expected_item.is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut len = 0;
|
||||
|
||||
let output = ArrayInlineExpression {
|
||||
parent: Cell::new(None),
|
||||
span: Some(value.span.clone()),
|
||||
|
@ -109,7 +109,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
return Err(AsgConvertError::unexpected_type(
|
||||
"circuit",
|
||||
type_.map(|x| x.to_string()).as_deref(),
|
||||
&span,
|
||||
span,
|
||||
));
|
||||
}
|
||||
};
|
||||
@ -117,26 +117,26 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
let member = circuit.members.borrow();
|
||||
let member = member
|
||||
.get(&name.name)
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, &span))?;
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, span))?;
|
||||
match member {
|
||||
CircuitMember::Function(body) => {
|
||||
if body.qualifier == FunctionQualifier::Static {
|
||||
return Err(AsgConvertError::circuit_static_call_invalid(
|
||||
&circuit_name,
|
||||
&name.name,
|
||||
&span,
|
||||
span,
|
||||
));
|
||||
} else if body.qualifier == FunctionQualifier::MutSelfRef && !target.is_mut_ref() {
|
||||
return Err(AsgConvertError::circuit_member_mut_call_invalid(
|
||||
&circuit_name,
|
||||
&name.name,
|
||||
&span,
|
||||
span,
|
||||
));
|
||||
}
|
||||
(Some(target), *body)
|
||||
}
|
||||
CircuitMember::Variable(_) => {
|
||||
return Err(AsgConvertError::circuit_variable_call(&circuit_name, &name.name, &span));
|
||||
return Err(AsgConvertError::circuit_variable_call(&circuit_name, &name.name, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,27 +150,27 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
.resolve_circuit(&circuit_name.name)
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit(&circuit_name.name, &circuit_name.span))?
|
||||
} else {
|
||||
return Err(AsgConvertError::unexpected_type("circuit", None, &span));
|
||||
return Err(AsgConvertError::unexpected_type("circuit", None, span));
|
||||
};
|
||||
let circuit_name = circuit.name.borrow().name.clone();
|
||||
|
||||
let member = circuit.members.borrow();
|
||||
let member = member
|
||||
.get(&name.name)
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, &span))?;
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, span))?;
|
||||
match member {
|
||||
CircuitMember::Function(body) => {
|
||||
if body.qualifier != FunctionQualifier::Static {
|
||||
return Err(AsgConvertError::circuit_member_call_invalid(
|
||||
&circuit_name,
|
||||
&name.name,
|
||||
&span,
|
||||
span,
|
||||
));
|
||||
}
|
||||
(None, *body)
|
||||
}
|
||||
CircuitMember::Variable(_) => {
|
||||
return Err(AsgConvertError::circuit_variable_call(&circuit_name, &name.name, &span));
|
||||
return Err(AsgConvertError::circuit_variable_call(&circuit_name, &name.name, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,12 +206,15 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
let argument = argument.get().borrow();
|
||||
let converted = <&Expression<'a>>::from_ast(scope, expr, Some(argument.type_.clone().partial()))?;
|
||||
if argument.const_ && !converted.is_consty() {
|
||||
return Err(AsgConvertError::unexpected_nonconst(&expr.span()));
|
||||
return Err(AsgConvertError::unexpected_nonconst(expr.span()));
|
||||
}
|
||||
Ok(Cell::new(converted))
|
||||
})
|
||||
.collect::<Result<Vec<_>, AsgConvertError>>()?;
|
||||
|
||||
if function.is_test() {
|
||||
return Err(AsgConvertError::call_test_function(&value.span));
|
||||
}
|
||||
Ok(CallExpression {
|
||||
parent: Cell::new(None),
|
||||
span: Some(value.span.clone()),
|
||||
|
109
asg/src/expression/cast.rs
Normal file
109
asg/src/expression/cast.rs
Normal file
@ -0,0 +1,109 @@
|
||||
// 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::{AsgConvertError, ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Span, Type};
|
||||
pub use leo_ast::UnaryOperation;
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CastExpression<'a> {
|
||||
pub parent: Cell<Option<&'a Expression<'a>>>,
|
||||
pub span: Option<Span>,
|
||||
pub inner: Cell<&'a Expression<'a>>,
|
||||
pub target_type: Type<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Node for CastExpression<'a> {
|
||||
fn span(&self) -> Option<&Span> {
|
||||
self.span.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExpressionNode<'a> for CastExpression<'a> {
|
||||
fn set_parent(&self, parent: &'a Expression<'a>) {
|
||||
self.parent.replace(Some(parent));
|
||||
}
|
||||
|
||||
fn get_parent(&self) -> Option<&'a Expression<'a>> {
|
||||
self.parent.get()
|
||||
}
|
||||
|
||||
fn enforce_parents(&self, expr: &'a Expression<'a>) {
|
||||
self.inner.get().set_parent(expr);
|
||||
}
|
||||
|
||||
fn get_type(&self) -> Option<Type<'a>> {
|
||||
Some(self.target_type.clone())
|
||||
}
|
||||
|
||||
fn is_mut_ref(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn const_value(&self) -> Option<ConstValue> {
|
||||
let value = self.inner.get().const_value()?;
|
||||
match value {
|
||||
ConstValue::Int(int) => match &self.target_type {
|
||||
Type::Integer(target) => Some(ConstValue::Int(int.cast_to(target))),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_consty(&self) -> bool {
|
||||
self.inner.get().is_consty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromAst<'a, leo_ast::CastExpression> for CastExpression<'a> {
|
||||
fn from_ast(
|
||||
scope: &'a Scope<'a>,
|
||||
value: &leo_ast::CastExpression,
|
||||
expected_type: Option<PartialType<'a>>,
|
||||
) -> Result<CastExpression<'a>, AsgConvertError> {
|
||||
let target_type = scope.resolve_ast_type(&value.target_type)?;
|
||||
if let Some(expected_type) = &expected_type {
|
||||
if !expected_type.matches(&target_type) {
|
||||
return Err(AsgConvertError::unexpected_type(
|
||||
&expected_type.to_string(),
|
||||
Some(&target_type.to_string()),
|
||||
&value.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let inner = <&Expression<'a>>::from_ast(scope, &*value.inner, None)?;
|
||||
|
||||
Ok(CastExpression {
|
||||
parent: Cell::new(None),
|
||||
span: Some(value.span.clone()),
|
||||
inner: Cell::new(inner),
|
||||
target_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<leo_ast::CastExpression> for &CastExpression<'a> {
|
||||
fn into(self) -> leo_ast::CastExpression {
|
||||
leo_ast::CastExpression {
|
||||
target_type: (&self.target_type).into(),
|
||||
inner: Box::new(self.inner.get().into()),
|
||||
span: self.span.clone().unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
@ -99,10 +99,10 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
));
|
||||
}
|
||||
}
|
||||
let members: IndexMap<&String, (&Identifier, &leo_ast::Expression)> = value
|
||||
let members: IndexMap<&String, (&Identifier, Option<&leo_ast::Expression>)> = value
|
||||
.members
|
||||
.iter()
|
||||
.map(|x| (&x.identifier.name, (&x.identifier, &x.expression)))
|
||||
.map(|x| (&x.identifier.name, (&x.identifier, x.expression.as_ref())))
|
||||
.collect();
|
||||
|
||||
let mut values: Vec<(Identifier, Cell<&'a Expression<'a>>)> = vec![];
|
||||
@ -125,7 +125,15 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
continue;
|
||||
};
|
||||
if let Some((identifier, receiver)) = members.get(&name) {
|
||||
let received = <&Expression<'a>>::from_ast(scope, *receiver, Some(type_.partial()))?;
|
||||
let received = if let Some(receiver) = *receiver {
|
||||
<&Expression<'a>>::from_ast(scope, receiver, Some(type_.partial()))?
|
||||
} else {
|
||||
<&Expression<'a>>::from_ast(
|
||||
scope,
|
||||
&leo_ast::Expression::Identifier((*identifier).clone()),
|
||||
Some(type_.partial()),
|
||||
)?
|
||||
};
|
||||
values.push(((*identifier).clone(), Cell::new(received)));
|
||||
} else {
|
||||
return Err(AsgConvertError::missing_circuit_member(
|
||||
@ -165,7 +173,7 @@ impl<'a> Into<leo_ast::CircuitInitExpression> for &CircuitInitExpression<'a> {
|
||||
.iter()
|
||||
.map(|(name, value)| leo_ast::CircuitImpliedVariableDefinition {
|
||||
identifier: name.clone(),
|
||||
expression: value.get().into(),
|
||||
expression: Some(value.get().into()),
|
||||
})
|
||||
.collect(),
|
||||
span: self.span.clone().unwrap_or_default(),
|
||||
|
@ -62,6 +62,9 @@ pub use unary::*;
|
||||
mod variable_ref;
|
||||
pub use variable_ref::*;
|
||||
|
||||
mod cast;
|
||||
pub use cast::*;
|
||||
|
||||
use crate::{AsgConvertError, ConstValue, FromAst, Node, PartialType, Scope, Span, Type};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -71,6 +74,7 @@ pub enum Expression<'a> {
|
||||
Binary(BinaryExpression<'a>),
|
||||
Unary(UnaryExpression<'a>),
|
||||
Ternary(TernaryExpression<'a>),
|
||||
Cast(CastExpression<'a>),
|
||||
|
||||
ArrayInline(ArrayInlineExpression<'a>),
|
||||
ArrayInit(ArrayInitExpression<'a>),
|
||||
@ -86,6 +90,12 @@ pub enum Expression<'a> {
|
||||
Call(CallExpression<'a>),
|
||||
}
|
||||
|
||||
impl<'a> Expression<'a> {
|
||||
pub fn ptr_eq(&self, other: &Expression<'a>) -> bool {
|
||||
std::ptr::eq(self as *const Expression<'a>, other as *const Expression<'a>)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Node for Expression<'a> {
|
||||
fn span(&self) -> Option<&Span> {
|
||||
use Expression::*;
|
||||
@ -95,6 +105,7 @@ impl<'a> Node for Expression<'a> {
|
||||
Binary(x) => x.span(),
|
||||
Unary(x) => x.span(),
|
||||
Ternary(x) => x.span(),
|
||||
Cast(x) => x.span(),
|
||||
ArrayInline(x) => x.span(),
|
||||
ArrayInit(x) => x.span(),
|
||||
ArrayAccess(x) => x.span(),
|
||||
@ -128,6 +139,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Binary(x) => x.set_parent(parent),
|
||||
Unary(x) => x.set_parent(parent),
|
||||
Ternary(x) => x.set_parent(parent),
|
||||
Cast(x) => x.set_parent(parent),
|
||||
ArrayInline(x) => x.set_parent(parent),
|
||||
ArrayInit(x) => x.set_parent(parent),
|
||||
ArrayAccess(x) => x.set_parent(parent),
|
||||
@ -148,6 +160,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Binary(x) => x.get_parent(),
|
||||
Unary(x) => x.get_parent(),
|
||||
Ternary(x) => x.get_parent(),
|
||||
Cast(x) => x.get_parent(),
|
||||
ArrayInline(x) => x.get_parent(),
|
||||
ArrayInit(x) => x.get_parent(),
|
||||
ArrayAccess(x) => x.get_parent(),
|
||||
@ -168,6 +181,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Binary(x) => x.enforce_parents(expr),
|
||||
Unary(x) => x.enforce_parents(expr),
|
||||
Ternary(x) => x.enforce_parents(expr),
|
||||
Cast(x) => x.enforce_parents(expr),
|
||||
ArrayInline(x) => x.enforce_parents(expr),
|
||||
ArrayInit(x) => x.enforce_parents(expr),
|
||||
ArrayAccess(x) => x.enforce_parents(expr),
|
||||
@ -188,6 +202,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Binary(x) => x.get_type(),
|
||||
Unary(x) => x.get_type(),
|
||||
Ternary(x) => x.get_type(),
|
||||
Cast(x) => x.get_type(),
|
||||
ArrayInline(x) => x.get_type(),
|
||||
ArrayInit(x) => x.get_type(),
|
||||
ArrayAccess(x) => x.get_type(),
|
||||
@ -208,6 +223,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Binary(x) => x.is_mut_ref(),
|
||||
Unary(x) => x.is_mut_ref(),
|
||||
Ternary(x) => x.is_mut_ref(),
|
||||
Cast(x) => x.is_mut_ref(),
|
||||
ArrayInline(x) => x.is_mut_ref(),
|
||||
ArrayInit(x) => x.is_mut_ref(),
|
||||
ArrayAccess(x) => x.is_mut_ref(),
|
||||
@ -228,6 +244,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Binary(x) => x.const_value(),
|
||||
Unary(x) => x.const_value(),
|
||||
Ternary(x) => x.const_value(),
|
||||
Cast(x) => x.const_value(),
|
||||
ArrayInline(x) => x.const_value(),
|
||||
ArrayInit(x) => x.const_value(),
|
||||
ArrayAccess(x) => x.const_value(),
|
||||
@ -248,6 +265,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Binary(x) => x.is_consty(),
|
||||
Unary(x) => x.is_consty(),
|
||||
Ternary(x) => x.is_consty(),
|
||||
Cast(x) => x.is_consty(),
|
||||
ArrayInline(x) => x.is_consty(),
|
||||
ArrayInit(x) => x.is_consty(),
|
||||
ArrayAccess(x) => x.is_consty(),
|
||||
@ -270,54 +288,58 @@ impl<'a> FromAst<'a, leo_ast::Expression> for &'a Expression<'a> {
|
||||
use leo_ast::Expression::*;
|
||||
let expression = match value {
|
||||
Identifier(identifier) => Self::from_ast(scope, identifier, expected_type)?,
|
||||
Value(value) => {
|
||||
scope.alloc_expression(Constant::from_ast(scope, value, expected_type).map(Expression::Constant)?)
|
||||
}
|
||||
Value(value) => scope
|
||||
.context
|
||||
.alloc_expression(Constant::from_ast(scope, value, expected_type).map(Expression::Constant)?),
|
||||
Binary(binary) => scope
|
||||
.context
|
||||
.alloc_expression(BinaryExpression::from_ast(scope, binary, expected_type).map(Expression::Binary)?),
|
||||
Unary(unary) => {
|
||||
scope.alloc_expression(UnaryExpression::from_ast(scope, unary, expected_type).map(Expression::Unary)?)
|
||||
}
|
||||
Ternary(conditional) => scope.alloc_expression(
|
||||
Unary(unary) => scope
|
||||
.context
|
||||
.alloc_expression(UnaryExpression::from_ast(scope, unary, expected_type).map(Expression::Unary)?),
|
||||
Ternary(conditional) => scope.context.alloc_expression(
|
||||
TernaryExpression::from_ast(scope, conditional, expected_type).map(Expression::Ternary)?,
|
||||
),
|
||||
Cast(cast) => scope
|
||||
.context
|
||||
.alloc_expression(CastExpression::from_ast(scope, cast, expected_type).map(Expression::Cast)?),
|
||||
|
||||
ArrayInline(array_inline) => scope.alloc_expression(
|
||||
ArrayInline(array_inline) => scope.context.alloc_expression(
|
||||
ArrayInlineExpression::from_ast(scope, array_inline, expected_type).map(Expression::ArrayInline)?,
|
||||
),
|
||||
ArrayInit(array_init) => scope.alloc_expression(
|
||||
ArrayInit(array_init) => scope.context.alloc_expression(
|
||||
ArrayInitExpression::from_ast(scope, array_init, expected_type).map(Expression::ArrayInit)?,
|
||||
),
|
||||
ArrayAccess(array_access) => scope.alloc_expression(
|
||||
ArrayAccess(array_access) => scope.context.alloc_expression(
|
||||
ArrayAccessExpression::from_ast(scope, array_access, expected_type).map(Expression::ArrayAccess)?,
|
||||
),
|
||||
ArrayRangeAccess(array_range_access) => scope.alloc_expression(
|
||||
ArrayRangeAccess(array_range_access) => scope.context.alloc_expression(
|
||||
ArrayRangeAccessExpression::from_ast(scope, array_range_access, expected_type)
|
||||
.map(Expression::ArrayRangeAccess)?,
|
||||
),
|
||||
|
||||
TupleInit(tuple_init) => scope.alloc_expression(
|
||||
TupleInit(tuple_init) => scope.context.alloc_expression(
|
||||
TupleInitExpression::from_ast(scope, tuple_init, expected_type).map(Expression::TupleInit)?,
|
||||
),
|
||||
TupleAccess(tuple_access) => scope.alloc_expression(
|
||||
TupleAccess(tuple_access) => scope.context.alloc_expression(
|
||||
TupleAccessExpression::from_ast(scope, tuple_access, expected_type).map(Expression::TupleAccess)?,
|
||||
),
|
||||
|
||||
CircuitInit(circuit_init) => scope.alloc_expression(
|
||||
CircuitInit(circuit_init) => scope.context.alloc_expression(
|
||||
CircuitInitExpression::from_ast(scope, circuit_init, expected_type).map(Expression::CircuitInit)?,
|
||||
),
|
||||
CircuitMemberAccess(circuit_member) => scope.alloc_expression(
|
||||
CircuitMemberAccess(circuit_member) => scope.context.alloc_expression(
|
||||
CircuitAccessExpression::from_ast(scope, circuit_member, expected_type)
|
||||
.map(Expression::CircuitAccess)?,
|
||||
),
|
||||
CircuitStaticFunctionAccess(circuit_member) => scope.alloc_expression(
|
||||
CircuitStaticFunctionAccess(circuit_member) => scope.context.alloc_expression(
|
||||
CircuitAccessExpression::from_ast(scope, circuit_member, expected_type)
|
||||
.map(Expression::CircuitAccess)?,
|
||||
),
|
||||
|
||||
Call(call) => {
|
||||
scope.alloc_expression(CallExpression::from_ast(scope, call, expected_type).map(Expression::Call)?)
|
||||
}
|
||||
Call(call) => scope
|
||||
.context
|
||||
.alloc_expression(CallExpression::from_ast(scope, call, expected_type).map(Expression::Call)?),
|
||||
};
|
||||
expression.enforce_parents(&expression);
|
||||
Ok(expression)
|
||||
@ -333,6 +355,7 @@ impl<'a> Into<leo_ast::Expression> for &Expression<'a> {
|
||||
Binary(x) => leo_ast::Expression::Binary(x.into()),
|
||||
Unary(x) => leo_ast::Expression::Unary(x.into()),
|
||||
Ternary(x) => leo_ast::Expression::Ternary(x.into()),
|
||||
Cast(x) => leo_ast::Expression::Cast(x.into()),
|
||||
ArrayInline(x) => leo_ast::Expression::ArrayInline(x.into()),
|
||||
ArrayInit(x) => leo_ast::Expression::ArrayInit(x.into()),
|
||||
ArrayAccess(x) => leo_ast::Expression::ArrayAccess(x.into()),
|
||||
|
@ -69,6 +69,10 @@ impl<'a> ExpressionNode<'a> for UnaryExpression<'a> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
UnaryOperation::BitNot => match inner {
|
||||
ConstValue::Int(value) => Some(ConstValue::Int(value.value_bit_negate()?)),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
None
|
||||
@ -110,16 +114,37 @@ impl<'a> FromAst<'a, leo_ast::UnaryExpression> for UnaryExpression<'a> {
|
||||
));
|
||||
}
|
||||
},
|
||||
UnaryOperation::BitNot => match expected_type.map(|x| x.full()).flatten() {
|
||||
Some(type_ @ Type::Integer(_)) => Some(type_),
|
||||
None => None,
|
||||
Some(type_) => {
|
||||
return Err(AsgConvertError::unexpected_type(
|
||||
&type_.to_string(),
|
||||
Some("integer"),
|
||||
&value.span,
|
||||
));
|
||||
}
|
||||
},
|
||||
};
|
||||
let expr = <&Expression<'a>>::from_ast(scope, &*value.inner, expected_type.map(Into::into))?;
|
||||
|
||||
if matches!(value.op, UnaryOperation::Negate) {
|
||||
let is_expr_unsigned = expr
|
||||
.get_type()
|
||||
.map(|x| match x {
|
||||
Type::Integer(x) => !x.is_signed(),
|
||||
_ => false,
|
||||
})
|
||||
.unwrap_or(false);
|
||||
if is_expr_unsigned {
|
||||
return Err(AsgConvertError::unsigned_negation(&value.span));
|
||||
}
|
||||
}
|
||||
Ok(UnaryExpression {
|
||||
parent: Cell::new(None),
|
||||
span: Some(value.span.clone()),
|
||||
operation: value.op.clone(),
|
||||
inner: Cell::new(<&Expression<'a>>::from_ast(
|
||||
scope,
|
||||
&*value.inner,
|
||||
expected_type.map(Into::into),
|
||||
)?),
|
||||
inner: Cell::new(expr),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -80,10 +80,14 @@ impl<'a> ExpressionNode<'a> for VariableRef<'a> {
|
||||
|
||||
value.get().const_value()
|
||||
} else {
|
||||
for defined_variable in variables.iter() {
|
||||
for (i, defined_variable) in variables.iter().enumerate() {
|
||||
let defined_variable = defined_variable.borrow();
|
||||
if defined_variable.id == variable.id {
|
||||
return value.get().const_value();
|
||||
match value.get().const_value() {
|
||||
Some(ConstValue::Tuple(values)) => return values.get(i).cloned(),
|
||||
None => return None,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
panic!("no corresponding tuple variable found during const destructuring (corrupt asg?)");
|
||||
@ -152,7 +156,7 @@ impl<'a> FromAst<'a, leo_ast::Identifier> for &'a Expression<'a> {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
if value.name.starts_with("aleo1") {
|
||||
return Ok(scope.alloc_expression(Expression::Constant(Constant {
|
||||
return Ok(scope.context.alloc_expression(Expression::Constant(Constant {
|
||||
parent: Cell::new(None),
|
||||
span: Some(value.span.clone()),
|
||||
value: ConstValue::Address(value.name.clone()),
|
||||
@ -168,7 +172,7 @@ impl<'a> FromAst<'a, leo_ast::Identifier> for &'a Expression<'a> {
|
||||
span: Some(value.span.clone()),
|
||||
variable,
|
||||
};
|
||||
let expression = scope.alloc_expression(Expression::VariableRef(variable_ref));
|
||||
let expression = scope.context.alloc_expression(Expression::VariableRef(variable_ref));
|
||||
|
||||
if let Some(expected_type) = expected_type {
|
||||
let type_ = expression
|
||||
|
@ -38,7 +38,7 @@ pub const STATE_LEAF_PSEUDO_CIRCUIT: &str = "$InputStateLeaf";
|
||||
|
||||
impl<'a> Input<'a> {
|
||||
fn make_header(scope: &'a Scope<'a>, name: &str) -> &'a Circuit<'a> {
|
||||
scope.alloc_circuit(Circuit {
|
||||
scope.context.alloc_circuit(Circuit {
|
||||
id: scope.context.get_id(),
|
||||
name: RefCell::new(Identifier::new(name.to_string())),
|
||||
members: RefCell::new(IndexMap::new()),
|
||||
@ -67,7 +67,7 @@ impl<'a> Input<'a> {
|
||||
CircuitMember::Variable(Type::Circuit(state_leaf)),
|
||||
);
|
||||
|
||||
let container_circuit = input_scope.alloc_circuit(Circuit {
|
||||
let container_circuit = input_scope.context.alloc_circuit(Circuit {
|
||||
id: scope.context.get_id(),
|
||||
name: RefCell::new(Identifier::new(CONTAINER_PSEUDO_CIRCUIT.to_string())),
|
||||
members: RefCell::new(container_members),
|
||||
@ -82,7 +82,7 @@ impl<'a> Input<'a> {
|
||||
state,
|
||||
state_leaf,
|
||||
container_circuit,
|
||||
container: input_scope.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
container: input_scope.context.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
id: scope.context.get_id(),
|
||||
name: Identifier::new("input".to_string()),
|
||||
type_: Type::Circuit(container_circuit),
|
||||
|
@ -22,6 +22,9 @@
|
||||
//! A new [`Asg`] type can be created from an [`Ast`].
|
||||
//! Converting to an [`Asg`] provides greater type safety by canonicalizing and checking program types.
|
||||
|
||||
#![allow(clippy::from_over_into)]
|
||||
#![allow(clippy::result_unit_err)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
@ -76,8 +79,6 @@ pub use context::*;
|
||||
|
||||
pub use leo_ast::{Ast, Identifier, Span};
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
/// The abstract semantic graph (ASG) for a Leo program.
|
||||
///
|
||||
/// The [`Asg`] type represents a Leo program as a series of recursive data types.
|
||||
@ -92,20 +93,24 @@ pub struct Asg<'a> {
|
||||
|
||||
impl<'a> Asg<'a> {
|
||||
/// Creates a new ASG from a given AST and import resolver.
|
||||
pub fn new<T: ImportResolver<'a>>(
|
||||
pub fn new<T: ImportResolver<'a>, Y: AsRef<leo_ast::Program>>(
|
||||
context: AsgContext<'a>,
|
||||
ast: &Ast,
|
||||
ast: Y,
|
||||
resolver: &mut T,
|
||||
) -> Result<Self, AsgConvertError> {
|
||||
Ok(Self {
|
||||
context,
|
||||
asg: InternalProgram::new(context, &ast.as_repr(), resolver)?,
|
||||
asg: Program::new(context, ast.as_ref(), resolver)?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the internal program ASG representation.
|
||||
pub fn as_repr(&self) -> Program<'a> {
|
||||
self.asg.clone()
|
||||
pub fn as_repr(&self) -> &Program<'a> {
|
||||
&self.asg
|
||||
}
|
||||
|
||||
pub fn into_repr(self) -> Program<'a> {
|
||||
self.asg
|
||||
}
|
||||
|
||||
// /// Serializes the ast into a JSON string.
|
||||
@ -127,10 +132,9 @@ pub fn load_asg<'a, T: ImportResolver<'a>>(
|
||||
resolver: &mut T,
|
||||
) -> Result<Program<'a>, AsgConvertError> {
|
||||
// Parses the Leo file and constructs a grammar ast.
|
||||
let ast = leo_grammar::Grammar::new(&Path::new("input.leo"), content)
|
||||
.map_err(|e| AsgConvertError::InternalError(format!("ast: {:?}", e)))?;
|
||||
let ast = leo_parser::parse_ast("input.leo", content)?;
|
||||
|
||||
InternalProgram::new(context, leo_ast::Ast::new("load_ast", &ast)?.as_repr(), resolver)
|
||||
Program::new(context, ast.as_repr(), resolver)
|
||||
}
|
||||
|
||||
pub fn new_alloc_context<'a>() -> Arena<ArenaNode<'a>> {
|
||||
|
@ -15,8 +15,8 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Program;
|
||||
pub use leo_ast::Error as FormattedError;
|
||||
pub use leo_ast::FormattedError;
|
||||
|
||||
pub trait AsgPass {
|
||||
fn do_pass(asg: &Program) -> Result<(), FormattedError>;
|
||||
pub trait AsgPass<'a> {
|
||||
fn do_pass(asg: Program<'a>) -> Result<Program<'a>, FormattedError>;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ impl<'a> Circuit<'a> {
|
||||
pub(super) fn init(scope: &'a Scope<'a>, value: &leo_ast::Circuit) -> Result<&'a Circuit<'a>, AsgConvertError> {
|
||||
let new_scope = scope.make_subscope();
|
||||
|
||||
let circuit = scope.alloc_circuit(Circuit {
|
||||
let circuit = scope.context.alloc_circuit(Circuit {
|
||||
id: scope.context.get_id(),
|
||||
name: RefCell::new(value.circuit_name.clone()),
|
||||
members: RefCell::new(IndexMap::new()),
|
||||
@ -68,32 +68,50 @@ impl<'a> Circuit<'a> {
|
||||
|
||||
let mut members = circuit.members.borrow_mut();
|
||||
for member in value.members.iter() {
|
||||
match member {
|
||||
leo_ast::CircuitMember::CircuitVariable(name, type_) => {
|
||||
if members.contains_key(&name.name) {
|
||||
return Err(AsgConvertError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&name.name,
|
||||
&name.span,
|
||||
));
|
||||
}
|
||||
members.insert(
|
||||
name.name.clone(),
|
||||
CircuitMember::Variable(new_scope.resolve_ast_type(type_)?),
|
||||
);
|
||||
if let leo_ast::CircuitMember::CircuitVariable(name, type_) = member {
|
||||
if members.contains_key(&name.name) {
|
||||
return Err(AsgConvertError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&name.name,
|
||||
&name.span,
|
||||
));
|
||||
}
|
||||
leo_ast::CircuitMember::CircuitFunction(function) => {
|
||||
if members.contains_key(&function.identifier.name) {
|
||||
return Err(AsgConvertError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&function.identifier.name,
|
||||
&function.identifier.span,
|
||||
));
|
||||
}
|
||||
let asg_function = Function::init(new_scope, function)?;
|
||||
asg_function.circuit.replace(Some(circuit));
|
||||
members.insert(function.identifier.name.clone(), CircuitMember::Function(asg_function));
|
||||
members.insert(
|
||||
name.name.clone(),
|
||||
CircuitMember::Variable(new_scope.resolve_ast_type(type_)?),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(circuit)
|
||||
}
|
||||
|
||||
pub(super) fn init_member(
|
||||
scope: &'a Scope<'a>,
|
||||
value: &leo_ast::Circuit,
|
||||
) -> Result<&'a Circuit<'a>, AsgConvertError> {
|
||||
let new_scope = scope.make_subscope();
|
||||
let circuits = scope.circuits.borrow();
|
||||
|
||||
let circuit = circuits.get(&value.circuit_name.name).unwrap();
|
||||
new_scope.circuit_self.replace(Some(circuit));
|
||||
|
||||
let mut members = circuit.members.borrow_mut();
|
||||
for member in value.members.iter() {
|
||||
if let leo_ast::CircuitMember::CircuitFunction(function) = member {
|
||||
if members.contains_key(&function.identifier.name) {
|
||||
return Err(AsgConvertError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&function.identifier.name,
|
||||
&function.identifier.span,
|
||||
));
|
||||
}
|
||||
let asg_function = Function::init(new_scope, function)?;
|
||||
asg_function.circuit.replace(Some(circuit));
|
||||
if asg_function.is_test() {
|
||||
return Err(AsgConvertError::circuit_test_function(&function.identifier.span));
|
||||
}
|
||||
members.insert(function.identifier.name.clone(), CircuitMember::Function(asg_function));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ use crate::{
|
||||
Variable,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
pub use leo_ast::Annotation;
|
||||
use leo_ast::FunctionInput;
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
@ -36,6 +37,7 @@ use std::cell::{Cell, RefCell};
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum FunctionQualifier {
|
||||
SelfRef,
|
||||
ConstSelfRef,
|
||||
MutSelfRef,
|
||||
Static,
|
||||
}
|
||||
@ -52,6 +54,7 @@ pub struct Function<'a> {
|
||||
pub body: Cell<Option<&'a Statement<'a>>>,
|
||||
pub scope: &'a Scope<'a>,
|
||||
pub qualifier: FunctionQualifier,
|
||||
pub annotations: Vec<Annotation>,
|
||||
}
|
||||
|
||||
impl<'a> PartialEq for Function<'a> {
|
||||
@ -87,6 +90,9 @@ impl<'a> Function<'a> {
|
||||
FunctionInput::SelfKeyword(_) => {
|
||||
qualifier = FunctionQualifier::SelfRef;
|
||||
}
|
||||
FunctionInput::ConstSelfKeyword(_) => {
|
||||
qualifier = FunctionQualifier::ConstSelfRef;
|
||||
}
|
||||
FunctionInput::MutSelfKeyword(_) => {
|
||||
qualifier = FunctionQualifier::MutSelfRef;
|
||||
}
|
||||
@ -97,7 +103,7 @@ impl<'a> Function<'a> {
|
||||
mutable,
|
||||
..
|
||||
}) => {
|
||||
let variable = scope.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
let variable = scope.context.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
id: scope.context.get_id(),
|
||||
name: identifier.clone(),
|
||||
type_: scope.resolve_ast_type(&type_)?,
|
||||
@ -115,7 +121,7 @@ impl<'a> Function<'a> {
|
||||
if qualifier != FunctionQualifier::Static && scope.circuit_self.get().is_none() {
|
||||
return Err(AsgConvertError::invalid_self_in_global(&value.span));
|
||||
}
|
||||
let function = scope.alloc_function(Function {
|
||||
let function = scope.context.alloc_function(Function {
|
||||
id: scope.context.get_id(),
|
||||
name: RefCell::new(value.identifier.clone()),
|
||||
output,
|
||||
@ -126,6 +132,7 @@ impl<'a> Function<'a> {
|
||||
qualifier,
|
||||
scope: new_scope,
|
||||
span: Some(value.span.clone()),
|
||||
annotations: value.annotations.clone(),
|
||||
});
|
||||
function.scope.function.replace(Some(function));
|
||||
|
||||
@ -135,7 +142,7 @@ impl<'a> Function<'a> {
|
||||
pub(super) fn fill_from_ast(self: &'a Function<'a>, value: &leo_ast::Function) -> Result<(), AsgConvertError> {
|
||||
if self.qualifier != FunctionQualifier::Static {
|
||||
let circuit = self.circuit.get();
|
||||
let self_variable = self.scope.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
let self_variable = self.scope.context.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
id: self.scope.context.get_id(),
|
||||
name: Identifier::new("self".to_string()),
|
||||
type_: Type::Circuit(circuit.as_ref().unwrap()),
|
||||
@ -173,10 +180,14 @@ impl<'a> Function<'a> {
|
||||
}
|
||||
|
||||
self.body
|
||||
.replace(Some(self.scope.alloc_statement(Statement::Block(main_block))));
|
||||
.replace(Some(self.scope.context.alloc_statement(Statement::Block(main_block))));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_test(&self) -> bool {
|
||||
self.annotations.iter().any(|x| x.name.name == "test")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<leo_ast::Function> for &Function<'a> {
|
||||
@ -213,6 +224,7 @@ impl<'a> Into<leo_ast::Function> for &Function<'a> {
|
||||
block: body,
|
||||
output: Some((&output).into()),
|
||||
span,
|
||||
annotations: self.annotations.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,70 +37,70 @@ pub struct GlobalConst<'a> {
|
||||
pub value: Cell<&'a Expression<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Node for GlobalConst<'a> {
|
||||
fn span(&self) -> Option<&Span> {
|
||||
self.span.as_ref()
|
||||
}
|
||||
}
|
||||
// impl<'a> Node for GlobalConst<'a> {
|
||||
// fn span(&self) -> Option<&Span> {
|
||||
// self.span.as_ref()
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<'a> GlobalConst<'a> {
|
||||
pub(super) fn init(
|
||||
scope: &'a Scope<'a>,
|
||||
global_const: &leo_ast::GlobalConst,
|
||||
) -> Result<&'a GlobalConst<'a>, AsgConvertError> {
|
||||
let type_ = global_const
|
||||
.type_
|
||||
.as_ref()
|
||||
.map(|x| scope.resolve_ast_type(&x))
|
||||
.transpose()?;
|
||||
// impl<'a> GlobalConst<'a> {
|
||||
// pub(super) fn init(
|
||||
// scope: &'a Scope<'a>,
|
||||
// global_const: &leo_ast::GlobalConst,
|
||||
// ) -> Result<&'a GlobalConst<'a>, AsgConvertError> {
|
||||
// let type_ = global_const
|
||||
// .type_
|
||||
// .as_ref()
|
||||
// .map(|x| scope.resolve_ast_type(&x))
|
||||
// .transpose()?;
|
||||
|
||||
let value = <&Expression<'a>>::from_ast(scope, &global_const.value, type_.clone().map(Into::into))?;
|
||||
// let value = <&Expression<'a>>::from_ast(scope, &global_const.value, type_.clone().map(Into::into))?;
|
||||
|
||||
let type_ = type_.or_else(|| value.get_type());
|
||||
// let type_ = type_.or_else(|| value.get_type());
|
||||
|
||||
let variable = scope.alloc_variable(RefCell::new(InnerVariable {
|
||||
id: scope.context.get_id(),
|
||||
name: global_const.variable_name.identifier.clone(),
|
||||
type_: type_.ok_or_else(|| {
|
||||
AsgConvertError::unresolved_type(&global_const.variable_name.identifier.name, &global_const.span)
|
||||
})?,
|
||||
mutable: global_const.variable_name.mutable,
|
||||
const_: false,
|
||||
declaration: crate::VariableDeclaration::Definition,
|
||||
references: vec![],
|
||||
assignments: vec![],
|
||||
}));
|
||||
// let variable = scope.alloc_variable(RefCell::new(InnerVariable {
|
||||
// id: scope.context.get_id(),
|
||||
// name: global_const.variable_name.identifier.clone(),
|
||||
// type_: type_.ok_or_else(|| {
|
||||
// AsgConvertError::unresolved_type(&global_const.variable_name.identifier.name, &global_const.span)
|
||||
// })?,
|
||||
// mutable: global_const.variable_name.mutable,
|
||||
// const_: false,
|
||||
// declaration: crate::VariableDeclaration::Definition,
|
||||
// references: vec![],
|
||||
// assignments: vec![],
|
||||
// }));
|
||||
|
||||
let global_const = scope.alloc_global_const(GlobalConst {
|
||||
parent: Cell::new(None),
|
||||
span: Some(global_const.span.clone()),
|
||||
variable,
|
||||
value: Cell::new(value),
|
||||
});
|
||||
// let global_const = scope.alloc_global_const(GlobalConst {
|
||||
// parent: Cell::new(None),
|
||||
// span: Some(global_const.span.clone()),
|
||||
// variable,
|
||||
// value: Cell::new(value),
|
||||
// });
|
||||
|
||||
Ok(global_const)
|
||||
}
|
||||
}
|
||||
// Ok(global_const)
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<'a> Into<leo_ast::GlobalConst> for &GlobalConst<'a> {
|
||||
fn into(self) -> leo_ast::GlobalConst {
|
||||
let mut type_ = None::<leo_ast::Type>;
|
||||
let variable = self.variable.borrow();
|
||||
let variable_name = leo_ast::VariableName {
|
||||
mutable: variable.mutable,
|
||||
identifier: variable.name.clone(),
|
||||
span: variable.name.span.clone(),
|
||||
};
|
||||
if type_.is_none() {
|
||||
type_ = Some((&variable.type_.clone()).into());
|
||||
}
|
||||
// impl<'a> Into<leo_ast::GlobalConst> for &GlobalConst<'a> {
|
||||
// fn into(self) -> leo_ast::GlobalConst {
|
||||
// let mut type_ = None::<leo_ast::Type>;
|
||||
// let variable = self.variable.borrow();
|
||||
// let variable_name = leo_ast::VariableName {
|
||||
// mutable: variable.mutable,
|
||||
// identifier: variable.name.clone(),
|
||||
// span: variable.name.span.clone(),
|
||||
// };
|
||||
// if type_.is_none() {
|
||||
// type_ = Some((&variable.type_.clone()).into());
|
||||
// }
|
||||
|
||||
leo_ast::GlobalConst {
|
||||
declaration_type: leo_ast::Declare::Let,
|
||||
variable_name,
|
||||
type_,
|
||||
value: self.value.get().into(),
|
||||
span: self.span.clone().unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// leo_ast::GlobalConst {
|
||||
// declaration_type: leo_ast::Declare::Let,
|
||||
// variable_name,
|
||||
// type_,
|
||||
// value: self.value.get().into(),
|
||||
// span: self.span.clone().unwrap_or_default(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
@ -35,7 +35,7 @@ use std::cell::{Cell, RefCell};
|
||||
|
||||
/// Stores the Leo program abstract semantic graph (ASG).
|
||||
#[derive(Clone)]
|
||||
pub struct InternalProgram<'a> {
|
||||
pub struct Program<'a> {
|
||||
pub context: AsgContext<'a>,
|
||||
|
||||
/// The unique id of the program.
|
||||
@ -48,9 +48,6 @@ pub struct InternalProgram<'a> {
|
||||
/// these should generally not be accessed directly, but through scoped imports
|
||||
pub imported_modules: IndexMap<String, Program<'a>>,
|
||||
|
||||
/// Maps test name => test code block.
|
||||
pub test_functions: IndexMap<String, (&'a Function<'a>, Option<Identifier>)>, // identifier = test input file
|
||||
|
||||
/// Maps function name => function code block.
|
||||
pub functions: IndexMap<String, &'a Function<'a>>,
|
||||
|
||||
@ -65,8 +62,6 @@ pub struct InternalProgram<'a> {
|
||||
pub scope: &'a Scope<'a>,
|
||||
}
|
||||
|
||||
pub type Program<'a> = InternalProgram<'a>;
|
||||
|
||||
/// Enumerates what names are imported from a package.
|
||||
#[derive(Clone)]
|
||||
enum ImportSymbol {
|
||||
@ -133,7 +128,7 @@ fn resolve_import_package_access(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> InternalProgram<'a> {
|
||||
impl<'a> Program<'a> {
|
||||
/// Returns a new Leo program ASG from the given Leo program AST and its imports.
|
||||
///
|
||||
/// Stages:
|
||||
@ -238,7 +233,7 @@ impl<'a> InternalProgram<'a> {
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
|
||||
let scope = import_scope.alloc_scope(Scope {
|
||||
let scope = import_scope.context.alloc_scope(Scope {
|
||||
context,
|
||||
input: Cell::new(Some(Input::new(import_scope))), // we use import_scope to avoid recursive scope ref here
|
||||
id: context.get_id(),
|
||||
@ -259,12 +254,12 @@ impl<'a> InternalProgram<'a> {
|
||||
scope.circuits.borrow_mut().insert(name.name.clone(), asg_circuit);
|
||||
}
|
||||
|
||||
let mut proto_test_functions = IndexMap::new();
|
||||
for (name, test_function) in program.tests.iter() {
|
||||
assert_eq!(name.name, test_function.function.identifier.name);
|
||||
let function = Function::init(scope, &test_function.function)?;
|
||||
// Second pass for circuit members.
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = Circuit::init_member(scope, circuit)?;
|
||||
|
||||
proto_test_functions.insert(name.name.clone(), function);
|
||||
scope.circuits.borrow_mut().insert(name.name.clone(), asg_circuit);
|
||||
}
|
||||
|
||||
for (name, function) in program.functions.iter() {
|
||||
@ -276,28 +271,20 @@ impl<'a> InternalProgram<'a> {
|
||||
|
||||
for (name, global_const) in program.global_consts.iter() {
|
||||
assert_eq!(name.name, global_const.variable_name.identifier.name);
|
||||
let gc = GlobalConst::init(scope, global_const)?;
|
||||
scope.global_consts.borrow_mut().insert(name.name.clone(), gc);
|
||||
// TODO re-enable
|
||||
// let gc = GlobalConst::init(scope, global_const)?;
|
||||
// scope.global_consts.borrow_mut().insert(name.name.clone(), gc);
|
||||
}
|
||||
|
||||
// Load concrete definitions.
|
||||
// TODO RE-ENABLE
|
||||
let mut global_consts = IndexMap::new();
|
||||
for (name, global_const) in program.global_consts.iter() {
|
||||
assert_eq!(name.name, global_const.variable_name.identifier.name);
|
||||
let asg_global_const = *scope.global_consts.borrow().get(&name.name).unwrap();
|
||||
// for (name, global_const) in program.global_consts.iter() {
|
||||
// assert_eq!(name.name, global_const.variable_name.identifier.name);
|
||||
// let asg_global_const = *scope.global_consts.borrow().get(&name.name).unwrap();
|
||||
|
||||
global_consts.insert(name.name.clone(), asg_global_const);
|
||||
}
|
||||
|
||||
let mut test_functions = IndexMap::new();
|
||||
for (name, test_function) in program.tests.iter() {
|
||||
assert_eq!(name.name, test_function.function.identifier.name);
|
||||
let function = proto_test_functions.get(&name.name).unwrap();
|
||||
|
||||
function.fill_from_ast(&test_function.function)?;
|
||||
|
||||
test_functions.insert(name.name.clone(), (*function, test_function.input_file.clone()));
|
||||
}
|
||||
// global_consts.insert(name.name.clone(), asg_global_const);
|
||||
// }
|
||||
|
||||
let mut functions = IndexMap::new();
|
||||
for (name, function) in program.functions.iter() {
|
||||
@ -319,11 +306,10 @@ impl<'a> InternalProgram<'a> {
|
||||
circuits.insert(name.name.clone(), asg_circuit);
|
||||
}
|
||||
|
||||
Ok(InternalProgram {
|
||||
Ok(Program {
|
||||
context,
|
||||
id: context.get_id(),
|
||||
name: program.name.clone(),
|
||||
test_functions,
|
||||
functions,
|
||||
global_consts,
|
||||
circuits,
|
||||
@ -377,7 +363,6 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
let mut all_circuits: IndexMap<String, &'a Circuit<'a>> = IndexMap::new();
|
||||
let mut all_functions: IndexMap<String, &'a Function<'a>> = IndexMap::new();
|
||||
let mut all_global_consts: IndexMap<String, &'a GlobalConst<'a>> = IndexMap::new();
|
||||
let mut all_test_functions: IndexMap<String, (&'a Function<'a>, Option<Identifier>)> = IndexMap::new();
|
||||
let mut identifiers = InternalIdentifierGenerator { next: 0 };
|
||||
for (_, program) in all_programs.into_iter() {
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
@ -394,16 +379,12 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
function.name.borrow_mut().name = identifier.clone();
|
||||
all_functions.insert(identifier, *function);
|
||||
}
|
||||
for (name, global_const) in program.global_consts.iter() {
|
||||
let identifier = format!("{}{}", identifiers.next().unwrap(), name);
|
||||
global_const.variable.borrow_mut().name.name = identifier.clone();
|
||||
all_global_consts.insert(identifier, *global_const);
|
||||
}
|
||||
for (name, function) in program.test_functions.iter() {
|
||||
let identifier = format!("{}{}", identifiers.next().unwrap(), name);
|
||||
function.0.name.borrow_mut().name = identifier.clone();
|
||||
all_test_functions.insert(identifier, function.clone());
|
||||
}
|
||||
// TODO RE-ENABLE
|
||||
// for (name, global_const) in program.global_consts.iter() {
|
||||
// let identifier = format!("{}{}", identifiers.next().unwrap(), name);
|
||||
// global_const.variable.borrow_mut().name.name = identifier.clone();
|
||||
// all_global_consts.insert(identifier, *global_const);
|
||||
// }
|
||||
}
|
||||
|
||||
leo_ast::Program {
|
||||
@ -420,15 +401,6 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
})
|
||||
.collect(),
|
||||
expected_input: vec![],
|
||||
tests: all_test_functions
|
||||
.into_iter()
|
||||
.map(|(_, (function, ident))| {
|
||||
(function.name.borrow().clone(), leo_ast::TestFunction {
|
||||
function: function.into(),
|
||||
input_file: ident,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
functions: all_functions
|
||||
.into_iter()
|
||||
.map(|(_, function)| (function.name.borrow().clone(), function.into()))
|
||||
@ -437,14 +409,16 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
.into_iter()
|
||||
.map(|(_, circuit)| (circuit.name.borrow().clone(), circuit.into()))
|
||||
.collect(),
|
||||
global_consts: all_global_consts
|
||||
.into_iter()
|
||||
.map(|(_, global_const)| (global_const.variable.borrow().name.clone(), global_const.into()))
|
||||
.collect(),
|
||||
global_consts: IndexMap::new(),
|
||||
// TODO re-enable
|
||||
// all_global_consts
|
||||
// .into_iter()
|
||||
// .map(|(_, global_const)| (global_const.variable.borrow().name.clone(), global_const.into()))
|
||||
// .collect(),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<leo_ast::Program> for &InternalProgram<'a> {
|
||||
impl<'a> Into<leo_ast::Program> for &Program<'a> {
|
||||
fn into(self) -> leo_ast::Program {
|
||||
leo_ast::Program {
|
||||
name: self.name.clone(),
|
||||
@ -460,21 +434,13 @@ impl<'a> Into<leo_ast::Program> for &InternalProgram<'a> {
|
||||
.iter()
|
||||
.map(|(_, function)| (function.name.borrow().clone(), (*function).into()))
|
||||
.collect(),
|
||||
tests: self
|
||||
.test_functions
|
||||
.iter()
|
||||
.map(|(_, function)| {
|
||||
(function.0.name.borrow().clone(), leo_ast::TestFunction {
|
||||
function: function.0.into(),
|
||||
input_file: function.1.clone(),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
global_consts: self
|
||||
.global_consts
|
||||
.iter()
|
||||
.map(|(_, global_const)| (global_const.variable.borrow().name.clone(), (*global_const).into()))
|
||||
.collect(),
|
||||
global_consts: IndexMap::new(),
|
||||
// TODO re-enable
|
||||
// self
|
||||
// .global_consts
|
||||
// .iter()
|
||||
// .map(|(_, global_const)| (global_const.variable.borrow().name.clone(), (*global_const).into()))
|
||||
// .collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,12 @@ pub use monoidal_director::*;
|
||||
mod monoidal_reducer;
|
||||
pub use monoidal_reducer::*;
|
||||
|
||||
mod reconstructing_reducer;
|
||||
pub use reconstructing_reducer::*;
|
||||
|
||||
mod reconstructing_director;
|
||||
pub use reconstructing_director::*;
|
||||
|
||||
mod visitor;
|
||||
pub use visitor::*;
|
||||
|
||||
|
@ -47,6 +47,7 @@ impl<'a, T: Monoid, R: MonoidalReducerExpression<'a, T>> MonoidalDirector<'a, T,
|
||||
Expression::CircuitAccess(e) => self.reduce_circuit_access(e),
|
||||
Expression::CircuitInit(e) => self.reduce_circuit_init(e),
|
||||
Expression::Ternary(e) => self.reduce_ternary_expression(e),
|
||||
Expression::Cast(e) => self.reduce_cast_expression(e),
|
||||
Expression::Constant(e) => self.reduce_constant(e),
|
||||
Expression::TupleAccess(e) => self.reduce_tuple_access(e),
|
||||
Expression::TupleInit(e) => self.reduce_tuple_init(e),
|
||||
@ -131,6 +132,12 @@ impl<'a, T: Monoid, R: MonoidalReducerExpression<'a, T>> MonoidalDirector<'a, T,
|
||||
.reduce_ternary_expression(input, condition, if_true, if_false)
|
||||
}
|
||||
|
||||
pub fn reduce_cast_expression(&mut self, input: &CastExpression<'a>) -> T {
|
||||
let inner = self.reduce_expression(input.inner.get());
|
||||
|
||||
self.reducer.reduce_cast_expression(input, inner)
|
||||
}
|
||||
|
||||
pub fn reduce_constant(&mut self, input: &Constant<'a>) -> T {
|
||||
self.reducer.reduce_constant(input)
|
||||
}
|
||||
@ -169,6 +176,7 @@ impl<'a, T: Monoid, R: MonoidalReducerStatement<'a, T>> MonoidalDirector<'a, T,
|
||||
Statement::Expression(s) => self.reduce_expression_statement(s),
|
||||
Statement::Iteration(s) => self.reduce_iteration(s),
|
||||
Statement::Return(s) => self.reduce_return(s),
|
||||
Statement::Empty(_) => T::default(),
|
||||
};
|
||||
|
||||
self.reducer.reduce_statement(input, value)
|
||||
@ -265,15 +273,14 @@ impl<'a, T: Monoid, R: MonoidalReducerStatement<'a, T>> MonoidalDirector<'a, T,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl<'a, T: Monoid, R: MonoidalReducerProgram<'a, T>> MonoidalDirector<'a, T, R> {
|
||||
fn reduce_function(&mut self, input: &'a Function<'a>) -> T {
|
||||
pub fn reduce_function(&mut self, input: &'a Function<'a>) -> T {
|
||||
let body = input.body.get().map(|s| self.reduce_statement(s)).unwrap_or_default();
|
||||
|
||||
self.reducer.reduce_function(input, body)
|
||||
}
|
||||
|
||||
fn reduce_circuit_member(&mut self, input: &CircuitMember<'a>) -> T {
|
||||
pub fn reduce_circuit_member(&mut self, input: &CircuitMember<'a>) -> T {
|
||||
let function = match input {
|
||||
CircuitMember::Function(f) => Some(self.reduce_function(f)),
|
||||
_ => None,
|
||||
@ -282,7 +289,7 @@ impl<'a, T: Monoid, R: MonoidalReducerProgram<'a, T>> MonoidalDirector<'a, T, R>
|
||||
self.reducer.reduce_circuit_member(input, function)
|
||||
}
|
||||
|
||||
fn reduce_circuit(&mut self, input: &'a Circuit<'a>) -> T {
|
||||
pub fn reduce_circuit(&mut self, input: &'a Circuit<'a>) -> T {
|
||||
let members = input
|
||||
.members
|
||||
.borrow()
|
||||
@ -293,21 +300,16 @@ impl<'a, T: Monoid, R: MonoidalReducerProgram<'a, T>> MonoidalDirector<'a, T, R>
|
||||
self.reducer.reduce_circuit(input, members)
|
||||
}
|
||||
|
||||
fn reduce_program(&mut self, input: &Program<'a>) -> T {
|
||||
pub fn reduce_program(&mut self, input: &Program<'a>) -> T {
|
||||
let imported_modules = input
|
||||
.imported_modules
|
||||
.iter()
|
||||
.map(|(_, import)| self.reduce_program(import))
|
||||
.collect();
|
||||
let test_functions = input
|
||||
.test_functions
|
||||
.iter()
|
||||
.map(|(_, (f, _))| self.reduce_function(f))
|
||||
.collect();
|
||||
let functions = input.functions.iter().map(|(_, f)| self.reduce_function(f)).collect();
|
||||
let circuits = input.circuits.iter().map(|(_, c)| self.reduce_circuit(c)).collect();
|
||||
|
||||
self.reducer
|
||||
.reduce_program(&input, imported_modules, test_functions, functions, circuits)
|
||||
.reduce_program(&input, imported_modules, functions, circuits)
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,10 @@ pub trait MonoidalReducerExpression<'a, T: Monoid> {
|
||||
condition.append(if_true).append(if_false)
|
||||
}
|
||||
|
||||
fn reduce_cast_expression(&mut self, input: &CastExpression<'a>, inner: T) -> T {
|
||||
inner
|
||||
}
|
||||
|
||||
fn reduce_constant(&mut self, input: &Constant<'a>) -> T {
|
||||
T::default()
|
||||
}
|
||||
@ -153,17 +157,9 @@ pub trait MonoidalReducerProgram<'a, T: Monoid>: MonoidalReducerStatement<'a, T>
|
||||
T::default().append_all(members.into_iter())
|
||||
}
|
||||
|
||||
fn reduce_program(
|
||||
&mut self,
|
||||
input: &InternalProgram,
|
||||
imported_modules: Vec<T>,
|
||||
test_functions: Vec<T>,
|
||||
functions: Vec<T>,
|
||||
circuits: Vec<T>,
|
||||
) -> T {
|
||||
fn reduce_program(&mut self, input: &Program, imported_modules: Vec<T>, functions: Vec<T>, circuits: Vec<T>) -> T {
|
||||
T::default()
|
||||
.append_all(imported_modules.into_iter())
|
||||
.append_all(test_functions.into_iter())
|
||||
.append_all(functions.into_iter())
|
||||
.append_all(circuits.into_iter())
|
||||
}
|
||||
|
345
asg/src/reducer/reconstructing_director.rs
Normal file
345
asg/src/reducer/reconstructing_director.rs
Normal file
@ -0,0 +1,345 @@
|
||||
// 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 super::*;
|
||||
use crate::{expression::*, program::*, statement::*, AsgContext};
|
||||
|
||||
/*
|
||||
reconstructing director tries to maintain a normalized ASG but may require renormalization under the following circumstances:
|
||||
* breaking strict reducer model (i.e. live mutations)
|
||||
* dropping or duplicating branches
|
||||
*/
|
||||
pub struct ReconstructingDirector<'a, R: ReconstructingReducerExpression<'a>> {
|
||||
context: AsgContext<'a>,
|
||||
reducer: R,
|
||||
}
|
||||
|
||||
impl<'a, R: ReconstructingReducerExpression<'a>> ReconstructingDirector<'a, R> {
|
||||
pub fn new(context: AsgContext<'a>, reducer: R) -> Self {
|
||||
Self { context, reducer }
|
||||
}
|
||||
|
||||
pub fn reducer(self) -> R {
|
||||
self.reducer
|
||||
}
|
||||
|
||||
pub fn reduce_expression(&mut self, input: &'a Expression<'a>) -> &'a Expression<'a> {
|
||||
let value = match input.clone() {
|
||||
Expression::ArrayAccess(e) => self.reduce_array_access(e),
|
||||
Expression::ArrayInit(e) => self.reduce_array_init(e),
|
||||
Expression::ArrayInline(e) => self.reduce_array_inline(e),
|
||||
Expression::ArrayRangeAccess(e) => self.reduce_array_range_access(e),
|
||||
Expression::Binary(e) => self.reduce_binary(e),
|
||||
Expression::Call(e) => self.reduce_call(e),
|
||||
Expression::CircuitAccess(e) => self.reduce_circuit_access(e),
|
||||
Expression::CircuitInit(e) => self.reduce_circuit_init(e),
|
||||
Expression::Ternary(e) => self.reduce_ternary_expression(e),
|
||||
Expression::Cast(e) => self.reduce_cast_expression(e),
|
||||
Expression::Constant(e) => self.reduce_constant(e),
|
||||
Expression::TupleAccess(e) => self.reduce_tuple_access(e),
|
||||
Expression::TupleInit(e) => self.reduce_tuple_init(e),
|
||||
Expression::Unary(e) => self.reduce_unary(e),
|
||||
Expression::VariableRef(e) => {
|
||||
{
|
||||
let mut variable = e.variable.borrow_mut();
|
||||
let index = variable.references.iter().position(|x| (*x).ptr_eq(input));
|
||||
if let Some(index) = index {
|
||||
variable.references.remove(index);
|
||||
}
|
||||
}
|
||||
self.reduce_variable_ref(e)
|
||||
}
|
||||
};
|
||||
|
||||
let allocated = self
|
||||
.context
|
||||
.alloc_expression(self.reducer.reduce_expression(input, value));
|
||||
if let Expression::VariableRef(reference) = allocated {
|
||||
let mut variable = reference.variable.borrow_mut();
|
||||
variable.references.push(allocated);
|
||||
}
|
||||
allocated
|
||||
}
|
||||
|
||||
pub fn reduce_array_access(&mut self, input: ArrayAccessExpression<'a>) -> Expression<'a> {
|
||||
let array = self.reduce_expression(input.array.get());
|
||||
let index = self.reduce_expression(input.index.get());
|
||||
|
||||
self.reducer.reduce_array_access(input, array, index)
|
||||
}
|
||||
|
||||
pub fn reduce_array_init(&mut self, input: ArrayInitExpression<'a>) -> Expression<'a> {
|
||||
let element = self.reduce_expression(input.element.get());
|
||||
|
||||
self.reducer.reduce_array_init(input, element)
|
||||
}
|
||||
|
||||
pub fn reduce_array_inline(&mut self, input: ArrayInlineExpression<'a>) -> Expression<'a> {
|
||||
let elements = input
|
||||
.elements
|
||||
.iter()
|
||||
.map(|(x, spread)| (self.reduce_expression(x.get()), *spread))
|
||||
.collect();
|
||||
|
||||
self.reducer.reduce_array_inline(input, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_array_range_access(&mut self, input: ArrayRangeAccessExpression<'a>) -> Expression<'a> {
|
||||
let array = self.reduce_expression(input.array.get());
|
||||
let left = input.left.get().map(|e| self.reduce_expression(e));
|
||||
let right = input.right.get().map(|e| self.reduce_expression(e));
|
||||
|
||||
self.reducer.reduce_array_range_access(input, array, left, right)
|
||||
}
|
||||
|
||||
pub fn reduce_binary(&mut self, input: BinaryExpression<'a>) -> Expression<'a> {
|
||||
let left = self.reduce_expression(input.left.get());
|
||||
let right = self.reduce_expression(input.right.get());
|
||||
|
||||
self.reducer.reduce_binary(input, left, right)
|
||||
}
|
||||
|
||||
pub fn reduce_call(&mut self, input: CallExpression<'a>) -> Expression<'a> {
|
||||
let target = input.target.get().map(|e| self.reduce_expression(e));
|
||||
let arguments = input
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|e| self.reduce_expression(e.get()))
|
||||
.collect();
|
||||
|
||||
self.reducer.reduce_call(input, target, arguments)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_access(&mut self, input: CircuitAccessExpression<'a>) -> Expression<'a> {
|
||||
let target = input.target.get().map(|e| self.reduce_expression(e));
|
||||
|
||||
self.reducer.reduce_circuit_access(input, target)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_init(&mut self, input: CircuitInitExpression<'a>) -> Expression<'a> {
|
||||
let values = input
|
||||
.values
|
||||
.iter()
|
||||
.map(|(ident, e)| (ident.clone(), self.reduce_expression(e.get())))
|
||||
.collect();
|
||||
|
||||
self.reducer.reduce_circuit_init(input, values)
|
||||
}
|
||||
|
||||
pub fn reduce_ternary_expression(&mut self, input: TernaryExpression<'a>) -> Expression<'a> {
|
||||
let condition = self.reduce_expression(input.condition.get());
|
||||
let if_true = self.reduce_expression(input.if_true.get());
|
||||
let if_false = self.reduce_expression(input.if_false.get());
|
||||
|
||||
self.reducer
|
||||
.reduce_ternary_expression(input, condition, if_true, if_false)
|
||||
}
|
||||
|
||||
pub fn reduce_cast_expression(&mut self, input: CastExpression<'a>) -> Expression<'a> {
|
||||
let inner = self.reduce_expression(input.inner.get());
|
||||
|
||||
self.reducer.reduce_cast_expression(input, inner)
|
||||
}
|
||||
|
||||
pub fn reduce_constant(&mut self, input: Constant<'a>) -> Expression<'a> {
|
||||
self.reducer.reduce_constant(input)
|
||||
}
|
||||
|
||||
pub fn reduce_tuple_access(&mut self, input: TupleAccessExpression<'a>) -> Expression<'a> {
|
||||
let tuple_ref = self.reduce_expression(input.tuple_ref.get());
|
||||
|
||||
self.reducer.reduce_tuple_access(input, tuple_ref)
|
||||
}
|
||||
|
||||
pub fn reduce_tuple_init(&mut self, input: TupleInitExpression<'a>) -> Expression<'a> {
|
||||
let values = input.elements.iter().map(|e| self.reduce_expression(e.get())).collect();
|
||||
|
||||
self.reducer.reduce_tuple_init(input, values)
|
||||
}
|
||||
|
||||
pub fn reduce_unary(&mut self, input: UnaryExpression<'a>) -> Expression<'a> {
|
||||
let inner = self.reduce_expression(input.inner.get());
|
||||
|
||||
self.reducer.reduce_unary(input, inner)
|
||||
}
|
||||
|
||||
pub fn reduce_variable_ref(&mut self, input: VariableRef<'a>) -> Expression<'a> {
|
||||
self.reducer.reduce_variable_ref(input)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: ReconstructingReducerStatement<'a>> ReconstructingDirector<'a, R> {
|
||||
pub fn reduce_statement(&mut self, input: &'a Statement<'a>) -> &'a Statement<'a> {
|
||||
let value = match input.clone() {
|
||||
Statement::Assign(s) => self.reduce_assign(s),
|
||||
Statement::Block(s) => self.reduce_block(s),
|
||||
Statement::Conditional(s) => self.reduce_conditional_statement(s),
|
||||
Statement::Console(s) => self.reduce_console(s),
|
||||
Statement::Definition(s) => self.reduce_definition(s),
|
||||
Statement::Expression(s) => self.reduce_expression_statement(s),
|
||||
Statement::Iteration(s) => self.reduce_iteration(s),
|
||||
Statement::Return(s) => self.reduce_return(s),
|
||||
x @ Statement::Empty(_) => x,
|
||||
};
|
||||
|
||||
self.reducer.reduce_statement_alloc(self.context, input, value)
|
||||
}
|
||||
|
||||
pub fn reduce_assign_access(&mut self, input: AssignAccess<'a>) -> AssignAccess<'a> {
|
||||
match &input {
|
||||
AssignAccess::ArrayRange(left, right) => {
|
||||
let left = left.get().map(|e| self.reduce_expression(e));
|
||||
let right = right.get().map(|e| self.reduce_expression(e));
|
||||
self.reducer.reduce_assign_access_range(input, left, right)
|
||||
}
|
||||
AssignAccess::ArrayIndex(index) => {
|
||||
let index = self.reduce_expression(index.get());
|
||||
self.reducer.reduce_assign_access_index(input, index)
|
||||
}
|
||||
_ => self.reducer.reduce_assign_access(input),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reduce_assign(&mut self, input: AssignStatement<'a>) -> Statement<'a> {
|
||||
let accesses = input
|
||||
.target_accesses
|
||||
.iter()
|
||||
.map(|x| self.reduce_assign_access(x.clone()))
|
||||
.collect();
|
||||
let value = self.reduce_expression(input.value.get());
|
||||
|
||||
self.reducer.reduce_assign(input, accesses, value)
|
||||
}
|
||||
|
||||
pub fn reduce_block(&mut self, input: BlockStatement<'a>) -> Statement<'a> {
|
||||
let statements = input
|
||||
.statements
|
||||
.iter()
|
||||
.map(|x| self.reduce_statement(x.get()))
|
||||
.collect();
|
||||
|
||||
self.reducer.reduce_block(input, statements)
|
||||
}
|
||||
|
||||
pub fn reduce_conditional_statement(&mut self, input: ConditionalStatement<'a>) -> Statement<'a> {
|
||||
let condition = self.reduce_expression(input.condition.get());
|
||||
let if_true = self.reduce_statement(input.result.get());
|
||||
let if_false = input.next.get().map(|s| self.reduce_statement(s));
|
||||
|
||||
self.reducer
|
||||
.reduce_conditional_statement(input, condition, if_true, if_false)
|
||||
}
|
||||
|
||||
pub fn reduce_formatted_string(&mut self, input: FormattedString<'a>) -> FormattedString<'a> {
|
||||
let parameters = input
|
||||
.parameters
|
||||
.iter()
|
||||
.map(|e| self.reduce_expression(e.get()))
|
||||
.collect();
|
||||
|
||||
self.reducer.reduce_formatted_string(input, parameters)
|
||||
}
|
||||
|
||||
pub fn reduce_console(&mut self, input: ConsoleStatement<'a>) -> Statement<'a> {
|
||||
match &input.function {
|
||||
ConsoleFunction::Assert(argument) => {
|
||||
let argument = self.reduce_expression(argument.get());
|
||||
self.reducer.reduce_console_assert(input, argument)
|
||||
}
|
||||
ConsoleFunction::Debug(f) | ConsoleFunction::Error(f) | ConsoleFunction::Log(f) => {
|
||||
let formatted = self.reduce_formatted_string(f.clone());
|
||||
self.reducer.reduce_console_log(input, formatted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reduce_definition(&mut self, input: DefinitionStatement<'a>) -> Statement<'a> {
|
||||
let value = self.reduce_expression(input.value.get());
|
||||
|
||||
self.reducer.reduce_definition(input, value)
|
||||
}
|
||||
|
||||
pub fn reduce_expression_statement(&mut self, input: ExpressionStatement<'a>) -> Statement<'a> {
|
||||
let value = self.reduce_expression(input.expression.get());
|
||||
|
||||
self.reducer.reduce_expression_statement(input, value)
|
||||
}
|
||||
|
||||
pub fn reduce_iteration(&mut self, input: IterationStatement<'a>) -> Statement<'a> {
|
||||
let start = self.reduce_expression(input.start.get());
|
||||
let stop = self.reduce_expression(input.stop.get());
|
||||
let body = self.reduce_statement(input.body.get());
|
||||
|
||||
self.reducer.reduce_iteration(input, start, stop, body)
|
||||
}
|
||||
|
||||
pub fn reduce_return(&mut self, input: ReturnStatement<'a>) -> Statement<'a> {
|
||||
let value = self.reduce_expression(input.expression.get());
|
||||
|
||||
self.reducer.reduce_return(input, value)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl<'a, R: ReconstructingReducerProgram<'a>> ReconstructingDirector<'a, R> {
|
||||
fn reduce_function(&mut self, input: &'a Function<'a>) -> &'a Function<'a> {
|
||||
let body = input.body.get().map(|s| self.reduce_statement(s));
|
||||
|
||||
self.reducer.reduce_function(input, body)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_member(&mut self, input: CircuitMember<'a>) -> CircuitMember<'a> {
|
||||
match input {
|
||||
CircuitMember::Function(function) => {
|
||||
let function = self.reduce_function(function);
|
||||
self.reducer.reduce_circuit_member_function(input, function)
|
||||
}
|
||||
CircuitMember::Variable(_) => self.reducer.reduce_circuit_member_variable(input),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reduce_circuit(&mut self, input: &'a Circuit<'a>) -> &'a Circuit<'a> {
|
||||
let members = input
|
||||
.members
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|(_, member)| self.reduce_circuit_member(member.clone()))
|
||||
.collect();
|
||||
|
||||
self.reducer.reduce_circuit(input, members)
|
||||
}
|
||||
|
||||
pub fn reduce_program(&mut self, input: Program<'a>) -> Program<'a> {
|
||||
let imported_modules = input
|
||||
.imported_modules
|
||||
.iter()
|
||||
.map(|(module, import)| (module.clone(), self.reduce_program(import.clone())))
|
||||
.collect();
|
||||
let functions = input
|
||||
.functions
|
||||
.iter()
|
||||
.map(|(name, f)| (name.clone(), self.reduce_function(f)))
|
||||
.collect();
|
||||
let circuits = input
|
||||
.circuits
|
||||
.iter()
|
||||
.map(|(name, c)| (name.clone(), self.reduce_circuit(c)))
|
||||
.collect();
|
||||
|
||||
self.reducer
|
||||
.reduce_program(input, imported_modules, functions, circuits)
|
||||
}
|
||||
}
|
405
asg/src/reducer/reconstructing_reducer.rs
Normal file
405
asg/src/reducer/reconstructing_reducer.rs
Normal file
@ -0,0 +1,405 @@
|
||||
// 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 std::cell::Cell;
|
||||
|
||||
use leo_ast::Identifier;
|
||||
|
||||
use crate::{expression::*, program::*, statement::*, AsgContext};
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub trait ReconstructingReducerExpression<'a> {
|
||||
fn reduce_expression(&mut self, input: &'a Expression<'a>, value: Expression<'a>) -> Expression<'a> {
|
||||
value
|
||||
}
|
||||
|
||||
fn reduce_array_access(
|
||||
&mut self,
|
||||
input: ArrayAccessExpression<'a>,
|
||||
array: &'a Expression<'a>,
|
||||
index: &'a Expression<'a>,
|
||||
) -> Expression<'a> {
|
||||
Expression::ArrayAccess(ArrayAccessExpression {
|
||||
parent: input.parent,
|
||||
array: Cell::new(array),
|
||||
index: Cell::new(index),
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_array_init(&mut self, input: ArrayInitExpression<'a>, element: &'a Expression<'a>) -> Expression<'a> {
|
||||
Expression::ArrayInit(ArrayInitExpression {
|
||||
parent: input.parent,
|
||||
element: Cell::new(element),
|
||||
len: input.len,
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_array_inline(
|
||||
&mut self,
|
||||
input: ArrayInlineExpression<'a>,
|
||||
elements: Vec<(&'a Expression<'a>, bool)>,
|
||||
) -> Expression<'a> {
|
||||
Expression::ArrayInline(ArrayInlineExpression {
|
||||
parent: input.parent,
|
||||
elements: elements.into_iter().map(|x| (Cell::new(x.0), x.1)).collect(),
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_array_range_access(
|
||||
&mut self,
|
||||
input: ArrayRangeAccessExpression<'a>,
|
||||
array: &'a Expression<'a>,
|
||||
left: Option<&'a Expression<'a>>,
|
||||
right: Option<&'a Expression<'a>>,
|
||||
) -> Expression<'a> {
|
||||
Expression::ArrayRangeAccess(ArrayRangeAccessExpression {
|
||||
parent: input.parent,
|
||||
array: Cell::new(array),
|
||||
left: Cell::new(left),
|
||||
right: Cell::new(right),
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_binary(
|
||||
&mut self,
|
||||
input: BinaryExpression<'a>,
|
||||
left: &'a Expression<'a>,
|
||||
right: &'a Expression<'a>,
|
||||
) -> Expression<'a> {
|
||||
Expression::Binary(BinaryExpression {
|
||||
parent: input.parent,
|
||||
left: Cell::new(left),
|
||||
right: Cell::new(right),
|
||||
span: input.span,
|
||||
operation: input.operation,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_call(
|
||||
&mut self,
|
||||
input: CallExpression<'a>,
|
||||
target: Option<&'a Expression<'a>>,
|
||||
arguments: Vec<&'a Expression<'a>>,
|
||||
) -> Expression<'a> {
|
||||
Expression::Call(CallExpression {
|
||||
parent: input.parent,
|
||||
function: input.function,
|
||||
target: Cell::new(target),
|
||||
arguments: arguments.into_iter().map(Cell::new).collect(),
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_circuit_access(
|
||||
&mut self,
|
||||
input: CircuitAccessExpression<'a>,
|
||||
target: Option<&'a Expression<'a>>,
|
||||
) -> Expression<'a> {
|
||||
Expression::CircuitAccess(CircuitAccessExpression {
|
||||
parent: input.parent,
|
||||
circuit: input.circuit,
|
||||
target: Cell::new(target),
|
||||
member: input.member,
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_circuit_init(
|
||||
&mut self,
|
||||
input: CircuitInitExpression<'a>,
|
||||
values: Vec<(Identifier, &'a Expression<'a>)>,
|
||||
) -> Expression<'a> {
|
||||
Expression::CircuitInit(CircuitInitExpression {
|
||||
parent: input.parent,
|
||||
circuit: input.circuit,
|
||||
values: values.into_iter().map(|x| (x.0, Cell::new(x.1))).collect(),
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_ternary_expression(
|
||||
&mut self,
|
||||
input: TernaryExpression<'a>,
|
||||
condition: &'a Expression<'a>,
|
||||
if_true: &'a Expression<'a>,
|
||||
if_false: &'a Expression<'a>,
|
||||
) -> Expression<'a> {
|
||||
Expression::Ternary(TernaryExpression {
|
||||
parent: input.parent,
|
||||
condition: Cell::new(condition),
|
||||
if_true: Cell::new(if_true),
|
||||
if_false: Cell::new(if_false),
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_cast_expression(&mut self, input: CastExpression<'a>, inner: &'a Expression<'a>) -> Expression<'a> {
|
||||
Expression::Cast(CastExpression {
|
||||
parent: input.parent,
|
||||
inner: Cell::new(inner),
|
||||
target_type: input.target_type,
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_constant(&mut self, input: Constant<'a>) -> Expression<'a> {
|
||||
Expression::Constant(input)
|
||||
}
|
||||
|
||||
fn reduce_tuple_access(
|
||||
&mut self,
|
||||
input: TupleAccessExpression<'a>,
|
||||
tuple_ref: &'a Expression<'a>,
|
||||
) -> Expression<'a> {
|
||||
Expression::TupleAccess(TupleAccessExpression {
|
||||
parent: input.parent,
|
||||
tuple_ref: Cell::new(tuple_ref),
|
||||
index: input.index,
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_tuple_init(&mut self, input: TupleInitExpression<'a>, values: Vec<&'a Expression<'a>>) -> Expression<'a> {
|
||||
Expression::TupleInit(TupleInitExpression {
|
||||
parent: input.parent,
|
||||
elements: values.into_iter().map(Cell::new).collect(),
|
||||
span: input.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_unary(&mut self, input: UnaryExpression<'a>, inner: &'a Expression<'a>) -> Expression<'a> {
|
||||
Expression::Unary(UnaryExpression {
|
||||
parent: input.parent,
|
||||
inner: Cell::new(inner),
|
||||
span: input.span,
|
||||
operation: input.operation,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_variable_ref(&mut self, input: VariableRef<'a>) -> Expression<'a> {
|
||||
Expression::VariableRef(input)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub trait ReconstructingReducerStatement<'a>: ReconstructingReducerExpression<'a> {
|
||||
fn reduce_statement_alloc(
|
||||
&mut self,
|
||||
context: AsgContext<'a>,
|
||||
input: &'a Statement<'a>,
|
||||
value: Statement<'a>,
|
||||
) -> &'a Statement<'a> {
|
||||
context.alloc_statement(value)
|
||||
}
|
||||
|
||||
fn reduce_statement(&mut self, input: &'a Statement<'a>, value: Statement<'a>) -> Statement<'a> {
|
||||
value
|
||||
}
|
||||
|
||||
fn reduce_assign_access_range(
|
||||
&mut self,
|
||||
input: AssignAccess<'a>,
|
||||
left: Option<&'a Expression<'a>>,
|
||||
right: Option<&'a Expression<'a>>,
|
||||
) -> AssignAccess<'a> {
|
||||
AssignAccess::ArrayRange(Cell::new(left), Cell::new(right))
|
||||
}
|
||||
|
||||
fn reduce_assign_access_index(&mut self, input: AssignAccess<'a>, index: &'a Expression<'a>) -> AssignAccess<'a> {
|
||||
AssignAccess::ArrayIndex(Cell::new(index))
|
||||
}
|
||||
|
||||
fn reduce_assign_access(&mut self, input: AssignAccess<'a>) -> AssignAccess<'a> {
|
||||
input
|
||||
}
|
||||
|
||||
fn reduce_assign(
|
||||
&mut self,
|
||||
input: AssignStatement<'a>,
|
||||
accesses: Vec<AssignAccess<'a>>,
|
||||
value: &'a Expression<'a>,
|
||||
) -> Statement<'a> {
|
||||
Statement::Assign(AssignStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
operation: input.operation,
|
||||
target_accesses: accesses,
|
||||
target_variable: input.target_variable,
|
||||
value: Cell::new(value),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_block(&mut self, input: BlockStatement<'a>, statements: Vec<&'a Statement<'a>>) -> Statement<'a> {
|
||||
Statement::Block(BlockStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
statements: statements.into_iter().map(Cell::new).collect(),
|
||||
scope: input.scope,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_conditional_statement(
|
||||
&mut self,
|
||||
input: ConditionalStatement<'a>,
|
||||
condition: &'a Expression<'a>,
|
||||
if_true: &'a Statement<'a>,
|
||||
if_false: Option<&'a Statement<'a>>,
|
||||
) -> Statement<'a> {
|
||||
Statement::Conditional(ConditionalStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
condition: Cell::new(condition),
|
||||
result: Cell::new(if_true),
|
||||
next: Cell::new(if_false),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_formatted_string(
|
||||
&mut self,
|
||||
input: FormattedString<'a>,
|
||||
parameters: Vec<&'a Expression<'a>>,
|
||||
) -> FormattedString<'a> {
|
||||
FormattedString {
|
||||
span: input.span,
|
||||
parts: input.parts,
|
||||
parameters: parameters.into_iter().map(Cell::new).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn reduce_console_assert(&mut self, input: ConsoleStatement<'a>, argument: &'a Expression<'a>) -> Statement<'a> {
|
||||
assert!(matches!(input.function, ConsoleFunction::Assert(_)));
|
||||
Statement::Console(ConsoleStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
function: ConsoleFunction::Assert(Cell::new(argument)),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_console_log(&mut self, input: ConsoleStatement<'a>, argument: FormattedString<'a>) -> Statement<'a> {
|
||||
assert!(!matches!(input.function, ConsoleFunction::Assert(_)));
|
||||
Statement::Console(ConsoleStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
function: match input.function {
|
||||
ConsoleFunction::Assert(_) => unimplemented!(),
|
||||
ConsoleFunction::Debug(_) => ConsoleFunction::Debug(argument),
|
||||
ConsoleFunction::Error(_) => ConsoleFunction::Error(argument),
|
||||
ConsoleFunction::Log(_) => ConsoleFunction::Log(argument),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_definition(&mut self, input: DefinitionStatement<'a>, value: &'a Expression<'a>) -> Statement<'a> {
|
||||
Statement::Definition(DefinitionStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
variables: input.variables,
|
||||
value: Cell::new(value),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_expression_statement(
|
||||
&mut self,
|
||||
input: ExpressionStatement<'a>,
|
||||
expression: &'a Expression<'a>,
|
||||
) -> Statement<'a> {
|
||||
Statement::Expression(ExpressionStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
expression: Cell::new(expression),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_iteration(
|
||||
&mut self,
|
||||
input: IterationStatement<'a>,
|
||||
start: &'a Expression<'a>,
|
||||
stop: &'a Expression<'a>,
|
||||
body: &'a Statement<'a>,
|
||||
) -> Statement<'a> {
|
||||
Statement::Iteration(IterationStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
variable: input.variable,
|
||||
start: Cell::new(start),
|
||||
stop: Cell::new(stop),
|
||||
body: Cell::new(body),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_return(&mut self, input: ReturnStatement<'a>, value: &'a Expression<'a>) -> Statement<'a> {
|
||||
Statement::Return(ReturnStatement {
|
||||
parent: input.parent,
|
||||
span: input.span,
|
||||
expression: Cell::new(value),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub trait ReconstructingReducerProgram<'a>: ReconstructingReducerStatement<'a> {
|
||||
// todo @protryon: this is kind of hacky
|
||||
fn reduce_function(&mut self, input: &'a Function<'a>, body: Option<&'a Statement<'a>>) -> &'a Function<'a> {
|
||||
input.body.set(body);
|
||||
input
|
||||
}
|
||||
|
||||
fn reduce_circuit_member_variable(&mut self, input: CircuitMember<'a>) -> CircuitMember<'a> {
|
||||
input
|
||||
}
|
||||
|
||||
fn reduce_circuit_member_function(
|
||||
&mut self,
|
||||
input: CircuitMember<'a>,
|
||||
function: &'a Function<'a>,
|
||||
) -> CircuitMember<'a> {
|
||||
CircuitMember::Function(function)
|
||||
}
|
||||
|
||||
// todo @protryon: this is kind of hacky
|
||||
fn reduce_circuit(&mut self, input: &'a Circuit<'a>, members: Vec<CircuitMember<'a>>) -> &'a Circuit<'a> {
|
||||
let mut input_members = input.members.borrow_mut();
|
||||
for ((name, input_member), member) in input_members.iter_mut().zip(members) {
|
||||
*input_member = member;
|
||||
}
|
||||
input
|
||||
}
|
||||
|
||||
fn reduce_program(
|
||||
&mut self,
|
||||
input: Program<'a>,
|
||||
imported_modules: Vec<(String, Program<'a>)>,
|
||||
functions: Vec<(String, &'a Function<'a>)>,
|
||||
circuits: Vec<(String, &'a Circuit<'a>)>,
|
||||
) -> Program<'a> {
|
||||
// TODO
|
||||
use indexmap::IndexMap;
|
||||
Program {
|
||||
context: input.context,
|
||||
id: input.id,
|
||||
name: input.name,
|
||||
imported_modules: imported_modules.into_iter().collect(),
|
||||
functions: functions.into_iter().collect(),
|
||||
circuits: circuits.into_iter().collect(),
|
||||
scope: input.scope,
|
||||
global_consts: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
@ -72,6 +72,10 @@ pub trait ExpressionVisitor<'a> {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_cast_expression(&mut self, input: &CastExpression<'a>) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, input: &Constant<'a>) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ impl<'a, R: ExpressionVisitor<'a>> VisitorDirector<'a, R> {
|
||||
Expression::CircuitAccess(e) => self.visit_circuit_access(e),
|
||||
Expression::CircuitInit(e) => self.visit_circuit_init(e),
|
||||
Expression::Ternary(e) => self.visit_ternary_expression(e),
|
||||
Expression::Cast(e) => self.visit_cast_expression(e),
|
||||
Expression::Constant(e) => self.visit_constant(e),
|
||||
Expression::TupleAccess(e) => self.visit_tuple_access(e),
|
||||
Expression::TupleInit(e) => self.visit_tuple_init(e),
|
||||
@ -71,10 +72,7 @@ impl<'a, R: ExpressionVisitor<'a>> VisitorDirector<'a, R> {
|
||||
}
|
||||
|
||||
fn visit_opt_expression(&mut self, input: &Cell<Option<&'a Expression<'a>>>) -> ConcreteVisitResult {
|
||||
let interior = match input.get() {
|
||||
Some(expr) => Some(Cell::new(expr)),
|
||||
None => None,
|
||||
};
|
||||
let interior = input.get().map(Cell::new);
|
||||
if let Some(interior) = interior.as_ref() {
|
||||
let result = self.visit_expression(interior);
|
||||
input.replace(Some(interior.get()));
|
||||
@ -187,6 +185,16 @@ impl<'a, R: ExpressionVisitor<'a>> VisitorDirector<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_cast_expression(&mut self, input: &CastExpression<'a>) -> ConcreteVisitResult {
|
||||
match self.visitor.visit_cast_expression(input) {
|
||||
VisitResult::VisitChildren => {
|
||||
self.visit_expression(&input.inner)?;
|
||||
Ok(())
|
||||
}
|
||||
x => x.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_constant(&mut self, input: &Constant<'a>) -> ConcreteVisitResult {
|
||||
self.visitor.visit_constant(input).into()
|
||||
}
|
||||
@ -240,16 +248,14 @@ impl<'a, R: StatementVisitor<'a>> VisitorDirector<'a, R> {
|
||||
Statement::Expression(s) => self.visit_expression_statement(s),
|
||||
Statement::Iteration(s) => self.visit_iteration(s),
|
||||
Statement::Return(s) => self.visit_return(s),
|
||||
Statement::Empty(_) => Ok(()),
|
||||
},
|
||||
x => x.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_opt_statement(&mut self, input: &Cell<Option<&'a Statement<'a>>>) -> ConcreteVisitResult {
|
||||
let interior = match input.get() {
|
||||
Some(expr) => Some(Cell::new(expr)),
|
||||
None => None,
|
||||
};
|
||||
let interior = input.get().map(Cell::new);
|
||||
if let Some(interior) = interior.as_ref() {
|
||||
let result = self.visit_statement(interior);
|
||||
input.replace(Some(interior.get()));
|
||||
@ -383,9 +389,8 @@ impl<'a, R: StatementVisitor<'a>> VisitorDirector<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl<'a, R: ProgramVisitor<'a>> VisitorDirector<'a, R> {
|
||||
fn visit_function(&mut self, input: &'a Function<'a>) -> ConcreteVisitResult {
|
||||
pub fn visit_function(&mut self, input: &'a Function<'a>) -> ConcreteVisitResult {
|
||||
match self.visitor.visit_function(input) {
|
||||
VisitResult::VisitChildren => {
|
||||
self.visit_opt_statement(&input.body)?;
|
||||
@ -395,7 +400,7 @@ impl<'a, R: ProgramVisitor<'a>> VisitorDirector<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_circuit_member(&mut self, input: &CircuitMember<'a>) -> ConcreteVisitResult {
|
||||
pub fn visit_circuit_member(&mut self, input: &CircuitMember<'a>) -> ConcreteVisitResult {
|
||||
match self.visitor.visit_circuit_member(input) {
|
||||
VisitResult::VisitChildren => {
|
||||
if let CircuitMember::Function(f) = input {
|
||||
@ -407,7 +412,7 @@ impl<'a, R: ProgramVisitor<'a>> VisitorDirector<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_circuit(&mut self, input: &'a Circuit<'a>) -> ConcreteVisitResult {
|
||||
pub fn visit_circuit(&mut self, input: &'a Circuit<'a>) -> ConcreteVisitResult {
|
||||
match self.visitor.visit_circuit(input) {
|
||||
VisitResult::VisitChildren => {
|
||||
for (_, member) in input.members.borrow().iter() {
|
||||
@ -419,15 +424,12 @@ impl<'a, R: ProgramVisitor<'a>> VisitorDirector<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_program(&mut self, input: &Program<'a>) -> ConcreteVisitResult {
|
||||
pub fn visit_program(&mut self, input: &Program<'a>) -> ConcreteVisitResult {
|
||||
match self.visitor.visit_program(input) {
|
||||
VisitResult::VisitChildren => {
|
||||
for (_, import) in input.imported_modules.iter() {
|
||||
self.visit_program(import)?;
|
||||
}
|
||||
for (_, (function, _)) in input.test_functions.iter() {
|
||||
self.visit_function(function)?;
|
||||
}
|
||||
for (_, function) in input.functions.iter() {
|
||||
self.visit_function(function)?;
|
||||
}
|
||||
|
@ -14,19 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
ArenaNode,
|
||||
AsgContext,
|
||||
AsgConvertError,
|
||||
Circuit,
|
||||
Expression,
|
||||
Function,
|
||||
GlobalConst,
|
||||
Input,
|
||||
Statement,
|
||||
Type,
|
||||
Variable,
|
||||
};
|
||||
use crate::{AsgContext, AsgConvertError, Circuit, Function, Input, Type, Variable};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use std::cell::{Cell, RefCell};
|
||||
@ -55,7 +43,8 @@ pub struct Scope<'a> {
|
||||
pub functions: RefCell<IndexMap<String, &'a Function<'a>>>,
|
||||
|
||||
/// Maps global constant name => global const code block.
|
||||
pub global_consts: RefCell<IndexMap<String, &'a GlobalConst<'a>>>,
|
||||
/// TODO fixs
|
||||
pub global_consts: RefCell<IndexMap<String, String>>,
|
||||
|
||||
/// Maps circuit name => circuit.
|
||||
pub circuits: RefCell<IndexMap<String, &'a Circuit<'a>>>,
|
||||
@ -66,55 +55,6 @@ pub struct Scope<'a> {
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
impl<'a> Scope<'a> {
|
||||
pub fn alloc_expression(&'a self, expr: Expression<'a>) -> &'a mut Expression<'a> {
|
||||
match self.context.arena.alloc(ArenaNode::Expression(expr)) {
|
||||
ArenaNode::Expression(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_statement(&'a self, statement: Statement<'a>) -> &'a mut Statement<'a> {
|
||||
match self.context.arena.alloc(ArenaNode::Statement(statement)) {
|
||||
ArenaNode::Statement(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_variable(&'a self, variable: Variable<'a>) -> &'a mut Variable<'a> {
|
||||
match self.context.arena.alloc(ArenaNode::Variable(variable)) {
|
||||
ArenaNode::Variable(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_scope(&'a self, scope: Scope<'a>) -> &'a mut Scope<'a> {
|
||||
match self.context.arena.alloc(ArenaNode::Scope(scope)) {
|
||||
ArenaNode::Scope(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_circuit(&'a self, circuit: Circuit<'a>) -> &'a mut Circuit<'a> {
|
||||
match self.context.arena.alloc(ArenaNode::Circuit(circuit)) {
|
||||
ArenaNode::Circuit(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_function(&'a self, function: Function<'a>) -> &'a mut Function<'a> {
|
||||
match self.context.arena.alloc(ArenaNode::Function(function)) {
|
||||
ArenaNode::Function(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_global_const(&'a self, global_const: GlobalConst<'a>) -> &'a mut GlobalConst<'a> {
|
||||
match self.context.arena.alloc(ArenaNode::GlobalConst(global_const)) {
|
||||
ArenaNode::GlobalConst(e) => e,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the variable corresponding to the name.
|
||||
///
|
||||
@ -124,9 +64,12 @@ impl<'a> Scope<'a> {
|
||||
pub fn resolve_variable(&self, name: &str) -> Option<&'a Variable<'a>> {
|
||||
if let Some(resolved) = self.variables.borrow().get(name) {
|
||||
Some(*resolved)
|
||||
} else if let Some(resolved) = self.global_consts.borrow().get(name) {
|
||||
Some(resolved.variable)
|
||||
} else if let Some(scope) = self.parent_scope.get() {
|
||||
}
|
||||
// TODO re-enable
|
||||
// else if let Some(resolved) = self.global_consts.borrow().get(name) {
|
||||
// Some(resolved.variable)
|
||||
// }
|
||||
else if let Some(scope) = self.parent_scope.get() {
|
||||
scope.resolve_variable(name)
|
||||
} else {
|
||||
None
|
||||
@ -219,7 +162,7 @@ impl<'a> Scope<'a> {
|
||||
/// Returns a new scope given a parent scope.
|
||||
///
|
||||
pub fn make_subscope(self: &'a Scope<'a>) -> &'a Scope<'a> {
|
||||
self.alloc_scope(Scope::<'a> {
|
||||
self.context.alloc_scope(Scope::<'a> {
|
||||
context: self.context,
|
||||
id: self.context.get_id(),
|
||||
parent_scope: Cell::new(Some(self)),
|
||||
|
@ -72,10 +72,10 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
let variable = if name == "input" {
|
||||
if let Some(function) = scope.resolve_current_function() {
|
||||
if !function.has_input {
|
||||
return Err(AsgConvertError::unresolved_reference(name, span));
|
||||
return Err(AsgConvertError::unresolved_reference(name, &span));
|
||||
}
|
||||
} else {
|
||||
return Err(AsgConvertError::unresolved_reference(name, span));
|
||||
return Err(AsgConvertError::unresolved_reference(name, &span));
|
||||
}
|
||||
if let Some(input) = scope.resolve_input() {
|
||||
input.container
|
||||
@ -87,7 +87,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
} else {
|
||||
scope
|
||||
.resolve_variable(&name)
|
||||
.ok_or_else(|| AsgConvertError::unresolved_reference(name, span))?
|
||||
.ok_or_else(|| AsgConvertError::unresolved_reference(name, &span))?
|
||||
};
|
||||
|
||||
if !variable.borrow().mutable {
|
||||
@ -217,7 +217,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
}
|
||||
let value = <&Expression<'a>>::from_ast(scope, &statement.value, target_type)?;
|
||||
|
||||
let statement = scope.alloc_statement(Statement::Assign(AssignStatement {
|
||||
let statement = scope.context.alloc_statement(Statement::Assign(AssignStatement {
|
||||
parent: Cell::new(None),
|
||||
span: Some(statement.span.clone()),
|
||||
operation: statement.operation.clone(),
|
||||
|
@ -40,7 +40,7 @@ impl<'a> FromAst<'a, leo_ast::ConditionalStatement> for ConditionalStatement<'a>
|
||||
_expected_type: Option<PartialType<'a>>,
|
||||
) -> Result<Self, AsgConvertError> {
|
||||
let condition = <&Expression<'a>>::from_ast(scope, &statement.condition, Some(Type::Boolean.into()))?;
|
||||
let result = scope.alloc_statement(Statement::Block(BlockStatement::from_ast(
|
||||
let result = scope.context.alloc_statement(Statement::Block(BlockStatement::from_ast(
|
||||
scope,
|
||||
&statement.block,
|
||||
None,
|
||||
|
@ -15,15 +15,14 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{AsgConvertError, Expression, FromAst, Node, PartialType, Scope, Span, Statement, Type};
|
||||
use leo_ast::ConsoleFunction as AstConsoleFunction;
|
||||
use leo_ast::{ConsoleFunction as AstConsoleFunction, FormattedStringPart};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// TODO (protryon): Refactor to not require/depend on span
|
||||
#[derive(Clone)]
|
||||
pub struct FormattedString<'a> {
|
||||
pub string: String,
|
||||
pub containers: Vec<Span>,
|
||||
pub parts: Vec<FormattedStringPart>,
|
||||
pub parameters: Vec<Cell<&'a Expression<'a>>>,
|
||||
pub span: Span,
|
||||
}
|
||||
@ -55,10 +54,15 @@ impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> {
|
||||
value: &leo_ast::FormattedString,
|
||||
_expected_type: Option<PartialType<'a>>,
|
||||
) -> Result<Self, AsgConvertError> {
|
||||
if value.parameters.len() != value.containers.len() {
|
||||
let expected_param_len = value
|
||||
.parts
|
||||
.iter()
|
||||
.filter(|x| matches!(x, FormattedStringPart::Container))
|
||||
.count();
|
||||
if value.parameters.len() != expected_param_len {
|
||||
// + 1 for formatting string as to not confuse user
|
||||
return Err(AsgConvertError::unexpected_call_argument_count(
|
||||
value.containers.len() + 1,
|
||||
expected_param_len + 1,
|
||||
value.parameters.len() + 1,
|
||||
&value.span,
|
||||
));
|
||||
@ -68,8 +72,7 @@ impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> {
|
||||
parameters.push(Cell::new(<&Expression<'a>>::from_ast(scope, parameter, None)?));
|
||||
}
|
||||
Ok(FormattedString {
|
||||
string: value.string.clone(),
|
||||
containers: value.containers.iter().map(|x| x.span.clone()).collect(),
|
||||
parts: value.parts.clone(),
|
||||
parameters,
|
||||
span: value.span.clone(),
|
||||
})
|
||||
@ -79,12 +82,7 @@ impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> {
|
||||
impl<'a> Into<leo_ast::FormattedString> for &FormattedString<'a> {
|
||||
fn into(self) -> leo_ast::FormattedString {
|
||||
leo_ast::FormattedString {
|
||||
string: self.string.clone(),
|
||||
containers: self
|
||||
.containers
|
||||
.iter()
|
||||
.map(|span| leo_ast::FormattedContainer { span: span.clone() })
|
||||
.collect(),
|
||||
parts: self.parts.clone(),
|
||||
parameters: self.parameters.iter().map(|e| e.get().into()).collect(),
|
||||
span: self.span.clone(),
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ use crate::{
|
||||
Type,
|
||||
Variable,
|
||||
};
|
||||
use leo_ast::{AstError, DeprecatedError};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
@ -90,12 +89,7 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
}
|
||||
|
||||
for (variable, type_) in statement.variable_names.iter().zip(output_types.into_iter()) {
|
||||
if statement.declaration_type == leo_ast::Declare::Const {
|
||||
return Err(AsgConvertError::AstError(AstError::DeprecatedError(
|
||||
DeprecatedError::const_statement(&statement.span),
|
||||
)));
|
||||
}
|
||||
variables.push(&*scope.alloc_variable(RefCell::new(InnerVariable {
|
||||
variables.push(&*scope.context.alloc_variable(RefCell::new(InnerVariable {
|
||||
id: scope.context.get_id(),
|
||||
name: variable.identifier.clone(),
|
||||
type_:
|
||||
@ -115,12 +109,14 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
.insert(variable.borrow().name.name.clone(), *variable);
|
||||
}
|
||||
|
||||
let statement = scope.alloc_statement(Statement::Definition(DefinitionStatement {
|
||||
parent: Cell::new(None),
|
||||
span: Some(statement.span.clone()),
|
||||
variables: variables.clone(),
|
||||
value: Cell::new(value),
|
||||
}));
|
||||
let statement = scope
|
||||
.context
|
||||
.alloc_statement(Statement::Definition(DefinitionStatement {
|
||||
parent: Cell::new(None),
|
||||
span: Some(statement.span.clone()),
|
||||
variables: variables.clone(),
|
||||
value: Cell::new(value),
|
||||
}));
|
||||
|
||||
for variable in variables {
|
||||
variable.borrow_mut().assignments.push(statement);
|
||||
|
@ -57,7 +57,20 @@ impl<'a> FromAst<'a, leo_ast::IterationStatement> for &'a Statement<'a> {
|
||||
let expected_index_type = Some(PartialType::Integer(None, Some(IntegerType::U32)));
|
||||
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 variable = scope.alloc_variable(RefCell::new(InnerVariable {
|
||||
|
||||
// Return an error if start or stop is not constant.
|
||||
if !start.is_consty() {
|
||||
return Err(AsgConvertError::unexpected_nonconst(
|
||||
&start.span().cloned().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
if !stop.is_consty() {
|
||||
return Err(AsgConvertError::unexpected_nonconst(
|
||||
&stop.span().cloned().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
|
||||
let variable = scope.context.alloc_variable(RefCell::new(InnerVariable {
|
||||
id: scope.context.get_id(),
|
||||
name: statement.variable.clone(),
|
||||
type_: start
|
||||
@ -74,17 +87,21 @@ impl<'a> FromAst<'a, leo_ast::IterationStatement> for &'a Statement<'a> {
|
||||
.borrow_mut()
|
||||
.insert(statement.variable.name.clone(), variable);
|
||||
|
||||
let statement = scope.alloc_statement(Statement::Iteration(IterationStatement {
|
||||
let statement = scope.context.alloc_statement(Statement::Iteration(IterationStatement {
|
||||
parent: Cell::new(None),
|
||||
span: Some(statement.span.clone()),
|
||||
variable,
|
||||
stop: Cell::new(stop),
|
||||
start: Cell::new(start),
|
||||
body: Cell::new(scope.alloc_statement(Statement::Block(crate::BlockStatement::from_ast(
|
||||
scope,
|
||||
&statement.block,
|
||||
None,
|
||||
)?))),
|
||||
body: Cell::new(
|
||||
scope
|
||||
.context
|
||||
.alloc_statement(Statement::Block(crate::BlockStatement::from_ast(
|
||||
scope,
|
||||
&statement.block,
|
||||
None,
|
||||
)?)),
|
||||
),
|
||||
}));
|
||||
variable.borrow_mut().assignments.push(statement);
|
||||
Ok(statement)
|
||||
|
@ -54,6 +54,7 @@ pub enum Statement<'a> {
|
||||
Console(ConsoleStatement<'a>),
|
||||
Expression(ExpressionStatement<'a>),
|
||||
Block(BlockStatement<'a>),
|
||||
Empty(Option<Span>),
|
||||
}
|
||||
|
||||
impl<'a> Node for Statement<'a> {
|
||||
@ -68,6 +69,7 @@ impl<'a> Node for Statement<'a> {
|
||||
Console(s) => s.span(),
|
||||
Expression(s) => s.span(),
|
||||
Block(s) => s.span(),
|
||||
Empty(s) => s.as_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,24 +82,32 @@ impl<'a> FromAst<'a, leo_ast::Statement> for &'a Statement<'a> {
|
||||
) -> Result<&'a Statement<'a>, AsgConvertError> {
|
||||
use leo_ast::Statement::*;
|
||||
Ok(match value {
|
||||
Return(statement) => {
|
||||
scope.alloc_statement(Statement::Return(ReturnStatement::from_ast(scope, statement, None)?))
|
||||
}
|
||||
Return(statement) => scope
|
||||
.context
|
||||
.alloc_statement(Statement::Return(ReturnStatement::from_ast(scope, statement, None)?)),
|
||||
Definition(statement) => Self::from_ast(scope, statement, None)?,
|
||||
Assign(statement) => Self::from_ast(scope, statement, None)?,
|
||||
Conditional(statement) => scope.alloc_statement(Statement::Conditional(ConditionalStatement::from_ast(
|
||||
scope, statement, None,
|
||||
)?)),
|
||||
Conditional(statement) => {
|
||||
scope
|
||||
.context
|
||||
.alloc_statement(Statement::Conditional(ConditionalStatement::from_ast(
|
||||
scope, statement, None,
|
||||
)?))
|
||||
}
|
||||
Iteration(statement) => Self::from_ast(scope, statement, None)?,
|
||||
Console(statement) => {
|
||||
scope.alloc_statement(Statement::Console(ConsoleStatement::from_ast(scope, statement, None)?))
|
||||
}
|
||||
Expression(statement) => scope.alloc_statement(Statement::Expression(ExpressionStatement::from_ast(
|
||||
scope, statement, None,
|
||||
)?)),
|
||||
Block(statement) => {
|
||||
scope.alloc_statement(Statement::Block(BlockStatement::from_ast(scope, statement, None)?))
|
||||
Console(statement) => scope
|
||||
.context
|
||||
.alloc_statement(Statement::Console(ConsoleStatement::from_ast(scope, statement, None)?)),
|
||||
Expression(statement) => {
|
||||
scope
|
||||
.context
|
||||
.alloc_statement(Statement::Expression(ExpressionStatement::from_ast(
|
||||
scope, statement, None,
|
||||
)?))
|
||||
}
|
||||
Block(statement) => scope
|
||||
.context
|
||||
.alloc_statement(Statement::Block(BlockStatement::from_ast(scope, statement, None)?)),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -114,6 +124,7 @@ impl<'a> Into<leo_ast::Statement> for &Statement<'a> {
|
||||
Console(statement) => leo_ast::Statement::Console(statement.into()),
|
||||
Expression(statement) => leo_ast::Statement::Expression(statement.into()),
|
||||
Block(statement) => leo_ast::Statement::Block(statement.into()),
|
||||
Empty(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +123,10 @@ impl<'a> Type<'a> {
|
||||
pub fn is_unit(&self) -> bool {
|
||||
matches!(self, Type::Tuple(t) if t.is_empty())
|
||||
}
|
||||
|
||||
pub fn can_cast_to(&self, to: &Type<'a>) -> bool {
|
||||
matches!(self, Type::Integer(_)) && matches!(to, Type::Integer(_))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for Type<'a> {
|
||||
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let public_key_string: address = zleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
|
||||
const public_key_string: address = zleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let arr: [u8; (2, 2)] = [[1u8; 2]; 1]; // incorrect dimensions
|
||||
const arr: [u8; (2, 2)] = [[1u8; 2]; 1]; // incorrect dimensions
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
function main() {
|
||||
let arr: [u8; (2, 2)] = [[1u8, 1u8],
|
||||
const arr: [u8; (2, 2)] = [[1u8, 1u8],
|
||||
[1u8]]; // incorrect dimensions
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let arr: [u8; (2, 2)] = [1u8; (2, 1)]; // incorrect dimensions
|
||||
const arr: [u8; (2, 2)] = [1u8; (2, 1)]; // incorrect dimensions
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Multidimensional array syntax in leo
|
||||
function main() {
|
||||
let a: [u32; (3, 2)] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering)
|
||||
const a: [u32; (3, 2)] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Multidimensional array syntax in leo
|
||||
function main() {
|
||||
let a: [u32; (3, 2)] = [0; (2, 3)]; // initializer (incorrectly reversed ordering)
|
||||
const a: [u32; (3, 2)] = [0; (2, 3)]; // initializer (incorrectly reversed ordering)
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a: [u8; -2] = [0u32; 2];
|
||||
const a: [u8; -2] = [0u32; 2];
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let b: [[u8; 2]; 3] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering)
|
||||
const b: [[u8; 2]; 3] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering)
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let b: [[[u8; 2]; 3]; 4] = [[[0; 4]; 3]; 2]; // initializer (incorrectly reversed ordering)
|
||||
const b: [[[u8; 2]; 3]; 4] = [[[0; 4]; 3]; 2]; // initializer (incorrectly reversed ordering)
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let b: [[u8; 2]; 3] = [0; (2, 3)]; // initializer (incorrectly reversed ordering)
|
||||
const b: [[u8; 2]; 3] = [0; (2, 3)]; // initializer (incorrectly reversed ordering)
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let b: [[[u8; 2]; 3]; 4] = [0; (2, 3, 4)]; // initializer (incorrectly reversed ordering)
|
||||
const b: [[[u8; 2]; 3]; 4] = [0; (2, 3, 4)]; // initializer (incorrectly reversed ordering)
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let b: [u8; (2, 3)] = [[0; 2]; 3]; // initializer (incorrectly reversed ordering)
|
||||
const b: [u8; (2, 3)] = [[0; 2]; 3]; // initializer (incorrectly reversed ordering)
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
function main() {
|
||||
let a = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline
|
||||
const a = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline
|
||||
|
||||
let b: [u8; (2, 3)] = [[0; 3]; 2]; // initializer
|
||||
const b: [u8; (2, 3)] = [[0; 3]; 2]; // initializer
|
||||
|
||||
console.assert(a == b);
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let b: [u8; (4, 3, 2)] = [[[0; 4]; 3]; 2]; // initializer (incorrectly reversed ordering)
|
||||
const b: [u8; (4, 3, 2)] = [[[0; 4]; 3]; 2]; // initializer (incorrectly reversed ordering)
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let b: [u8; (2, 3)] = [0; (3, 2)]; // initializer (incorrectly reversed ordering)
|
||||
const b: [u8; (2, 3)] = [0; (3, 2)]; // initializer (incorrectly reversed ordering)
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
function main() {
|
||||
let a = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline
|
||||
const a = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline
|
||||
|
||||
let b: [u8; (2, 3)] = [0; (2, 3)]; // initializer
|
||||
const b: [u8; (2, 3)] = [0; (2, 3)]; // initializer
|
||||
|
||||
console.assert(a == b);
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let b: [u8; (4, 3, 2)] = [0; (2, 3, 4)]; // initializer (incorrectly reversed order)
|
||||
const b: [u8; (4, 3, 2)] = [0; (2, 3, 4)]; // initializer (incorrectly reversed order)
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a = true && 1u32;
|
||||
const a = true && 1u32;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a = true || 1u32;
|
||||
const a = true || 1u32;
|
||||
}
|
@ -3,5 +3,5 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let a = Foo { y: 0u32 };
|
||||
const a = Foo { y: 0u32 };
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a = Foo { };
|
||||
const a = Foo { };
|
||||
}
|
@ -5,6 +5,6 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let a = Foo { };
|
||||
let err = a.echoed(1u32);
|
||||
const a = Foo { };
|
||||
const err = a.echoed(1u32);
|
||||
}
|
@ -5,6 +5,6 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let a = Foo { };
|
||||
let err = a.echo(1u32); // echo is a static function and must be accessed using `::`
|
||||
const a = Foo { };
|
||||
const err = a.echo(1u32); // echo is a static function and must be accessed using `::`
|
||||
}
|
@ -5,5 +5,5 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let err = Foo.echo(1u32); // Invalid, echo is a static function and must be accessed using `::`
|
||||
const err = Foo.echo(1u32); // Invalid, echo is a static function and must be accessed using `::`
|
||||
}
|
@ -5,5 +5,5 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let err = Foo::echoed(1u32);
|
||||
const err = Foo::echoed(1u32);
|
||||
}
|
@ -3,7 +3,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let a = Foo { x: 1u32 };
|
||||
const a = Foo { x: 1u32 };
|
||||
|
||||
let err = a.y;
|
||||
const err = a.y;
|
||||
}
|
@ -60,7 +60,7 @@ fn test_mut_member_function_fail() {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let a = Foo { };
|
||||
const a = Foo { };
|
||||
|
||||
console.assert(a.echo(1u32) == 1u32);
|
||||
}"#;
|
||||
|
@ -5,7 +5,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let mut f = Foo { a: 0u8 };
|
||||
let f = Foo { a: 0u8 };
|
||||
|
||||
f.bar = 1u8;
|
||||
}
|
@ -9,7 +9,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let mut f = Foo { a: 0u8 };
|
||||
let f = Foo { a: 0u8 };
|
||||
|
||||
f.set_a(1u8);
|
||||
}
|
@ -9,7 +9,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let mut f = Foo { a: 0u8 };
|
||||
let f = Foo { a: 0u8 };
|
||||
|
||||
f.set_a(1u8);
|
||||
}
|
@ -7,7 +7,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let mut f = Foo { a: 0u8 };
|
||||
let f = Foo { a: 0u8 };
|
||||
|
||||
f.set_a(1u8);
|
||||
}
|
@ -3,7 +3,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let mut f = Foo { a: 0u8 };
|
||||
let f = Foo { a: 0u8 };
|
||||
|
||||
f.bar = 1u8;
|
||||
}
|
@ -3,7 +3,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let f = Foo { a: 0u8 };
|
||||
const f = Foo { a: 0u8 };
|
||||
|
||||
f.a = 1u8;
|
||||
}
|
@ -7,6 +7,6 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() -> u32 {
|
||||
let foo = Foo { f: 1u32 };
|
||||
let err = foo.bar();
|
||||
const foo = Foo { f: 1u32 };
|
||||
const err = foo.bar();
|
||||
}
|
@ -5,6 +5,6 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let foo = Foo { };
|
||||
let err = foo.bar();
|
||||
const foo = Foo { };
|
||||
const err = foo.bar();
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
function foo(a: [u8; 1]) {}
|
||||
|
||||
function main() {
|
||||
let a: [u16; 1] = [1; 1];
|
||||
const a: [u16; 1] = [1; 1];
|
||||
foo(a);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
function main () -> u16 {
|
||||
if false {
|
||||
let a = 1u16;
|
||||
let b = a + 1u16;
|
||||
const a = 1u16;
|
||||
const b = a + 1u16;
|
||||
return b
|
||||
} else if false {
|
||||
return 0u16
|
||||
|
@ -3,5 +3,5 @@ function array_3x2_tuple() -> [[u8; 2]; 3] {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let b = array_3x2_tuple();
|
||||
const b = array_3x2_tuple();
|
||||
}
|
@ -3,5 +3,5 @@ function array_3x2_nested() -> [u8; (3, 2)] {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let a = array_3x2_nested();
|
||||
const a = array_3x2_nested();
|
||||
}
|
@ -3,6 +3,6 @@ function foo() -> field {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let myGlobal = 42field;
|
||||
let err = foo();
|
||||
const myGlobal = 42field;
|
||||
const err = foo();
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let element = (+, +)group;
|
||||
const element = (+, +)group;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let element = (_, _)group;
|
||||
const element = (_, _)group;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let element = (-, -)group;
|
||||
const element = (-, -)group;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a: i128 = 170141183460469231731687303715884105728;
|
||||
const a: i128 = 170141183460469231731687303715884105728;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a: i128 = -170141183460469231731687303715884105729;
|
||||
const a: i128 = -170141183460469231731687303715884105729;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
function main() {
|
||||
let a: i128 = -170141183460469231731687303715884105728;
|
||||
let b = -a;
|
||||
const a: i128 = -170141183460469231731687303715884105728;
|
||||
const b = -a;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a: i16 = 32768;
|
||||
const a: i16 = 32768;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a: i16 = -32769;
|
||||
const a: i16 = -32769;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
function main() {
|
||||
let a = -32768i16;
|
||||
let b = -a;
|
||||
const a = -32768i16;
|
||||
const b = -a;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() {
|
||||
let a: i32 = 2147483648;
|
||||
const a: i32 = 2147483648;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user