mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-23 23:23:50 +03:00
Merge branch 'master' into feature/opti-cli-flag
This commit is contained in:
commit
1e1697b7fe
@ -1,2 +1,2 @@
|
||||
[target.'cfg(not(target_arch = "wasm32"))']
|
||||
[target.'cfg(any(not(target_arch = "wasm32"), feature = "noconfig"))']
|
||||
rustflags = ["-C", "target-cpu=native"]
|
||||
|
@ -44,7 +44,7 @@ jobs:
|
||||
|
||||
rust-stable:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
@ -62,7 +62,7 @@ jobs:
|
||||
|
||||
rust-nightly:
|
||||
docker:
|
||||
- image: howardwu/snarkos-ci:2021-01-31
|
||||
- image: howardwu/snarkos-ci:2021-03-25
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
@ -77,7 +77,7 @@ jobs:
|
||||
|
||||
leo-executable:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
@ -86,7 +86,7 @@ jobs:
|
||||
- run:
|
||||
name: Build and install Leo
|
||||
no_output_timeout: 30m
|
||||
command: cargo install --path . --root .
|
||||
command: cargo install --path . --root . --locked
|
||||
- persist_to_workspace:
|
||||
root: ~/
|
||||
paths: project/
|
||||
@ -95,7 +95,7 @@ jobs:
|
||||
|
||||
leo-new:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@ -108,7 +108,7 @@ jobs:
|
||||
|
||||
leo-init:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@ -121,7 +121,7 @@ jobs:
|
||||
|
||||
leo-clean:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@ -134,7 +134,7 @@ jobs:
|
||||
|
||||
leo-setup:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@ -147,7 +147,7 @@ jobs:
|
||||
|
||||
leo-add-remove:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@ -160,7 +160,7 @@ jobs:
|
||||
|
||||
leo-login-logout:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@ -173,7 +173,7 @@ jobs:
|
||||
|
||||
leo-clone:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@ -186,7 +186,7 @@ jobs:
|
||||
|
||||
leo-publish:
|
||||
docker:
|
||||
- image: cimg/rust:1.50.0
|
||||
- image: cimg/rust:1.51.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- attach_workspace:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# leo add (w/o login) & remove
|
||||
|
||||
$LEO new my-app && cd my-app
|
||||
$LEO new my-app && cd my-app || exit 1
|
||||
$LEO add howard/silly-sudoku
|
||||
$LEO remove silly-sudoku
|
||||
$LEO clean
|
||||
|
@ -1,4 +1,5 @@
|
||||
mkdir hello-world && cd hello-world || exit 1
|
||||
$LEO init
|
||||
ls -la
|
||||
mkdir hello-world
|
||||
cd hello-world
|
||||
$LEO init || exit 1
|
||||
ls -la hello-world
|
||||
$LEO run
|
||||
|
23
.github/workflows/release.yml
vendored
23
.github/workflows/release.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
- name: Build Leo
|
||||
run: |
|
||||
cargo build --all --release && strip target/release/leo
|
||||
cargo build --all --release --features noconfig && strip target/release/leo
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||
|
||||
@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
- name: Build Leo
|
||||
run: |
|
||||
cargo build --all --release && strip target/release/leo
|
||||
cargo build --all --release --features noconfig && strip target/release/leo
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||
|
||||
@ -95,7 +95,6 @@ jobs:
|
||||
windows:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
@ -111,12 +110,15 @@ jobs:
|
||||
- name: Install LLVM and Clang
|
||||
uses: KyleMayes/install-llvm-action@v1
|
||||
with:
|
||||
version: "10.0"
|
||||
directory: ~ / .clang
|
||||
version: "11"
|
||||
directory: ${{ runner.temp }}/llvm
|
||||
|
||||
- name: Set LIBCLANG_PATH
|
||||
run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Build Leo
|
||||
run: |
|
||||
cargo build --all --release
|
||||
cargo build --all --release --features noconfig
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||
|
||||
@ -125,18 +127,13 @@ jobs:
|
||||
|
||||
- name: Zip
|
||||
run: |
|
||||
mkdir tempdir
|
||||
mv target/release/leo tempdir
|
||||
cd tempdir
|
||||
Compress-Archive leo-${{ steps.get_version.outputs.version }}-x86_64-pc-windows-gnu leo
|
||||
cd ..
|
||||
mv leo-${{ steps.get_version.outputs.version }}-x86_64-pc-windows-gnu .
|
||||
Compress-Archive target/release/leo.exe leo-${{ steps.get_version.outputs.version }}-x86_64-pc-windows-msvc.zip
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: |
|
||||
leo-${{ steps.get_version.outputs.version }}-x86_64-pc-windows-gnu.zip
|
||||
leo-${{ steps.get_version.outputs.version }}-x86_64-pc-windows-msvc.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
@ -1 +1 @@
|
||||
v1.2.3
|
||||
v1.3.0
|
216
Cargo.lock
generated
216
Cargo.lock
generated
@ -2,6 +2,25 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "abnf"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd8863e7db43447ad50376e19b0549343b72ad45cbd394b3fc8fe3ede961facc"
|
||||
dependencies = [
|
||||
"abnf-core",
|
||||
"nom 6.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "abnf-core"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b514944cb7199c4201f54406bc58676a3e4f37d40bf8e3dbe30652ca82e3ddb4"
|
||||
dependencies = [
|
||||
"nom 6.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.14.1"
|
||||
@ -52,9 +71,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.39"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767"
|
||||
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
@ -157,6 +176,18 @@ version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "0.19.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.9.1"
|
||||
@ -290,7 +321,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||
dependencies = [
|
||||
"nom",
|
||||
"nom 5.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -787,6 +818,22 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
|
||||
|
||||
[[package]]
|
||||
name = "futf"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
|
||||
dependencies = [
|
||||
"mac",
|
||||
"new_debug_unreachable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.13"
|
||||
@ -1192,9 +1239,17 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "leo-abnf"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"abnf",
|
||||
"anyhow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-asg"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"indexmap",
|
||||
@ -1203,20 +1258,21 @@ dependencies = [
|
||||
"num-bigint",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendril",
|
||||
"thiserror",
|
||||
"typed-arena",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-asg-passes"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"leo-asg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-ast"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"criterion",
|
||||
@ -1225,12 +1281,13 @@ dependencies = [
|
||||
"pest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendril",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-compiler"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"hex",
|
||||
@ -1257,13 +1314,14 @@ dependencies = [
|
||||
"snarkvm-gadgets",
|
||||
"snarkvm-r1cs",
|
||||
"snarkvm-utilities",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-imports"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"leo-asg",
|
||||
@ -1275,7 +1333,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leo-input"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"from-pest",
|
||||
"pest",
|
||||
@ -1287,7 +1345,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leo-lang"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1326,11 +1384,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leo-linter"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[[package]]
|
||||
name = "leo-package"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"serde",
|
||||
@ -1343,7 +1401,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leo-parser"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"indexmap",
|
||||
@ -1351,13 +1409,14 @@ dependencies = [
|
||||
"leo-ast",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendril",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-state"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"leo-ast",
|
||||
@ -1375,7 +1434,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leo-synthesizer"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"serde",
|
||||
@ -1386,6 +1445,19 @@ dependencies = [
|
||||
"snarkvm-r1cs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21f866863575d0e1d654fbeeabdc927292fdf862873dc3c96c6f753357e13374"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.89"
|
||||
@ -1444,6 +1516,12 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
@ -1610,6 +1688,12 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "nias"
|
||||
version = "0.5.0"
|
||||
@ -1626,6 +1710,19 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "6.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"funty",
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "4.0.15"
|
||||
@ -2011,6 +2108,12 @@ dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.3"
|
||||
@ -2468,9 +2571,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-algorithms"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "472ed062cdd1f54076312dd34e5fb56bd585c80c12209045f4b5bbbd368e9000"
|
||||
checksum = "bdf8ca73d429824090b96f751846e37e539f24c527f1f1ce0254984ade6d17b2"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"derivative",
|
||||
@ -2491,9 +2594,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-curves"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdfdfa3aa137f64a7f49df03393e5d0269f133ca8c8c79e569cb3bb13181aeb2"
|
||||
checksum = "64610b135b8b1152439d5dfa4f745515933366082f08651961344aa0bb5abfca"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"rand",
|
||||
@ -2507,9 +2610,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-derives"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a2ba967601ff2534adbc6a71a691be4285e61c83d23d54a59824f8fa80f6038"
|
||||
checksum = "46c9829b6e2023b4c7c4d6c55e88fe755dd997171a6c9c063b75c28161d04326"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
@ -2520,9 +2623,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-dpc"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff4cb55898089843ba44b9f96448dcb2badcc1ce12daa8d7365d4e41513e37bc"
|
||||
checksum = "491ae936e24e17c358d112ff8638b260500b5a982ecefc804861e28b5279f552"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base58",
|
||||
@ -2546,9 +2649,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-fields"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca9ea954196e76fe8968fb99eced7ccf08f901ab22747c4c489bda6674a7cb39"
|
||||
checksum = "8c49c69d02df11be58e07f626c9d6f5804c6dd4ccf42e425f2be8d79fe6e5bb7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"derivative",
|
||||
@ -2561,9 +2664,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-gadgets"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdda42a0a6484d9f008801a8a4d494a69a4db3f7b317057a8cc3c6e4b3ef6884"
|
||||
checksum = "bd6f9ac2a166d926e1755a06fdae21ce40ce6164c75c89120401b8d78f3b7ba4"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"digest 0.9.0",
|
||||
@ -2578,9 +2681,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-objects"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e20d13db49cedc147df06c4a6f2dd727ea25640bdf50b876f40005331767a68f"
|
||||
checksum = "9bd9779ec6ab9211f34a6ba25566feb575a396f4c41cc0e002ec2d48d7560a2a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -2599,9 +2702,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-parameters"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d35fa1819d803e45b4e99fe822e6981f177716f5384eef27245b5f6ed59a8305"
|
||||
checksum = "98378f612206fc7dd44a26f4e345bd1f3ba51bd325acad1e5cc3785d14750ec5"
|
||||
dependencies = [
|
||||
"curl",
|
||||
"hex",
|
||||
@ -2612,15 +2715,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-profiler"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7834d57af37a31f2f280f08b61d07a04a9a4b7720819b06ca325da32a5a925f5"
|
||||
checksum = "b2460ac01c25f79f5ea306e4de82a1d4105e811f868206b4fd31c0c9b62a3d7b"
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-r1cs"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0838118f276e7bb673cbf3741f4966c56861aaff399a46d343fc98c12851d9eb"
|
||||
checksum = "a3a0d54b15802976aff7522765dd29d5733f338612449629cc57c5a4a4d51f05"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fxhash",
|
||||
@ -2633,9 +2736,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-storage"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a42d92a817502878f315cc264704fa2a3d563755f16186316d8177ea685769af"
|
||||
checksum = "1d76881939f008d7bba4c8cc4118d29567b5c71908ad66bef9880f8aa7c52881"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -2654,9 +2757,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-utilities"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5598f7f71c8aaf4fc267b5b420b2440a4d86c9243cecd57ff0af5c366217e5cc"
|
||||
checksum = "c763843fa67a3aa4ce68173c8cd96b4f04aaa135a5792bc051c36eec0fe1cd73"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"rand",
|
||||
@ -2675,6 +2778,12 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
@ -2745,6 +2854,12 @@ dependencies = [
|
||||
"unicode-xid 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
@ -2759,6 +2874,17 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendril"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33"
|
||||
dependencies = [
|
||||
"futf",
|
||||
"mac",
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
@ -3077,6 +3203,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.11"
|
||||
@ -3283,6 +3415,12 @@ dependencies = [
|
||||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.5.10"
|
||||
|
33
Cargo.toml
33
Cargo.toml
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leo-lang"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "The Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
@ -27,64 +27,64 @@ path = "leo/main.rs"
|
||||
[workspace]
|
||||
members = [
|
||||
"asg",
|
||||
"asg-passes",
|
||||
"ast",
|
||||
"compiler",
|
||||
"grammar",
|
||||
"imports",
|
||||
"input",
|
||||
"linter",
|
||||
"package",
|
||||
"parser",
|
||||
"state",
|
||||
"synthesizer",
|
||||
"asg-passes",
|
||||
"synthesizer"
|
||||
]
|
||||
|
||||
[dependencies.leo-ast]
|
||||
path = "./ast"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-compiler]
|
||||
path = "./compiler"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-imports]
|
||||
path = "./imports"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-input]
|
||||
path = "./input"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-package]
|
||||
path = "./package"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-state]
|
||||
path = "./state"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-synthesizer]
|
||||
path = "./synthesizer"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.snarkvm-algorithms]
|
||||
version = "0.2.1"
|
||||
#default-features = false
|
||||
version = "0.2.2"
|
||||
|
||||
[dependencies.snarkvm-curves]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-gadgets]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-r1cs]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-utilities]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
|
||||
[dependencies.anyhow]
|
||||
version = "1.0"
|
||||
@ -156,6 +156,7 @@ version = "0.11.2"
|
||||
[features]
|
||||
default = [ ]
|
||||
ci_skip = [ "leo-compiler/ci_skip" ]
|
||||
noconfig = [ ]
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leo-asg-passes"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "The Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
@ -13,7 +13,7 @@ keywords = [
|
||||
"zero-knowledge"
|
||||
]
|
||||
categories = [ "cryptography::cryptocurrencies", "web-programming" ]
|
||||
include = [ "Cargo.toml", "leo", "README.md", "LICENSE.md" ]
|
||||
include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ]
|
||||
license = "GPL-3.0"
|
||||
edition = "2018"
|
||||
|
||||
@ -22,4 +22,4 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies.leo-asg]
|
||||
path = "../asg"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leo-asg"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "ASG of the Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
@ -30,11 +30,11 @@ version = "1.6"
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.leo-ast]
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
path = "../ast"
|
||||
|
||||
[dependencies.leo-parser]
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
path = "../parser"
|
||||
|
||||
[dependencies.num-bigint]
|
||||
@ -43,5 +43,8 @@ version = "0.4"
|
||||
[dependencies.typed-arena]
|
||||
version = "2.0"
|
||||
|
||||
[dependencies.tendril]
|
||||
version = "0.4"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3"
|
||||
|
@ -18,6 +18,7 @@ use crate::{AsgConvertError, IntegerType, Span, Type};
|
||||
|
||||
use num_bigint::BigInt;
|
||||
use std::{convert::TryInto, fmt};
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// Constant integer values in a program.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@ -38,7 +39,7 @@ pub enum ConstInt {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum GroupCoordinate {
|
||||
/// Explicit field element number string.
|
||||
Number(String),
|
||||
Number(StrTendril),
|
||||
|
||||
/// Attempt to recover with a sign high bit.
|
||||
SignHigh,
|
||||
@ -87,7 +88,7 @@ impl Into<leo_ast::GroupCoordinate> for &GroupCoordinate {
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum GroupValue {
|
||||
Single(String),
|
||||
Single(StrTendril),
|
||||
Tuple(GroupCoordinate, GroupCoordinate),
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ pub enum ConstValue {
|
||||
Int(ConstInt),
|
||||
Group(GroupValue),
|
||||
Field(BigInt),
|
||||
Address(String),
|
||||
Address(StrTendril),
|
||||
Boolean(bool),
|
||||
|
||||
// compounds
|
||||
|
@ -35,25 +35,7 @@ pub enum AsgConvertError {
|
||||
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 LeoError for AsgConvertError {}
|
||||
|
||||
impl AsgConvertError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
@ -190,6 +172,13 @@ impl AsgConvertError {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn duplicate_function_definition(name: &str, span: &Span) -> Self {
|
||||
Self::new_from_span(
|
||||
format!("a function named \"{}\" already exists in this scope", name),
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn index_into_non_tuple(name: &str, span: &Span) -> Self {
|
||||
Self::new_from_span(format!("failed to index into non-tuple '{}'", name), span)
|
||||
}
|
||||
@ -198,6 +187,14 @@ impl AsgConvertError {
|
||||
Self::new_from_span(format!("tuple index out of bounds: '{}'", index), span)
|
||||
}
|
||||
|
||||
pub fn array_index_out_of_bounds(index: usize, span: &Span) -> Self {
|
||||
Self::new_from_span(format!("array index out of bounds: '{}'", index), span)
|
||||
}
|
||||
|
||||
pub fn unknown_array_size(span: &Span) -> Self {
|
||||
Self::new_from_span("array size cannot be inferred, add explicit types".to_string(), span)
|
||||
}
|
||||
|
||||
pub fn unexpected_call_argument_count(expected: usize, got: usize, span: &Span) -> Self {
|
||||
Self::new_from_span(
|
||||
format!("function call expected {} arguments, got {}", expected, got),
|
||||
|
@ -89,8 +89,8 @@ impl<'a> FromAst<'a, leo_ast::ArrayAccessExpression> for ArrayAccessExpression<'
|
||||
&*value.array,
|
||||
Some(PartialType::Array(expected_type.map(Box::new), None)),
|
||||
)?;
|
||||
match array.get_type() {
|
||||
Some(Type::Array(..)) => (),
|
||||
let array_len = match array.get_type() {
|
||||
Some(Type::Array(_, len)) => len,
|
||||
type_ => {
|
||||
return Err(AsgConvertError::unexpected_type(
|
||||
"array",
|
||||
@ -98,7 +98,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayAccessExpression> for ArrayAccessExpression<'
|
||||
&value.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let index = <&Expression<'a>>::from_ast(
|
||||
scope,
|
||||
@ -106,10 +106,17 @@ impl<'a> FromAst<'a, leo_ast::ArrayAccessExpression> for ArrayAccessExpression<'
|
||||
Some(PartialType::Integer(None, Some(IntegerType::U32))),
|
||||
)?;
|
||||
|
||||
if !index.is_consty() {
|
||||
return Err(AsgConvertError::unexpected_nonconst(
|
||||
&index.span().cloned().unwrap_or_default(),
|
||||
));
|
||||
if let Some(index) = index
|
||||
.const_value()
|
||||
.map(|x| x.int().map(|x| x.to_usize()).flatten())
|
||||
.flatten()
|
||||
{
|
||||
if index >= array_len {
|
||||
return Err(AsgConvertError::array_index_out_of_bounds(
|
||||
index,
|
||||
&array.span().cloned().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ArrayAccessExpression {
|
||||
|
@ -152,7 +152,7 @@ impl<'a> Into<leo_ast::ArrayInitExpression> for &ArrayInitExpression<'a> {
|
||||
leo_ast::ArrayInitExpression {
|
||||
element: Box::new(self.element.get().into()),
|
||||
dimensions: leo_ast::ArrayDimensions(vec![leo_ast::PositiveNumber {
|
||||
value: self.len.to_string(),
|
||||
value: self.len.to_string().into(),
|
||||
}]),
|
||||
span: self.span.clone().unwrap_or_default(),
|
||||
}
|
||||
|
@ -26,6 +26,9 @@ pub struct ArrayRangeAccessExpression<'a> {
|
||||
pub array: Cell<&'a Expression<'a>>,
|
||||
pub left: Cell<Option<&'a Expression<'a>>>,
|
||||
pub right: Cell<Option<&'a Expression<'a>>>,
|
||||
// this is either const(right) - const(left) OR the length inferred by type checking
|
||||
// special attention must be made to update this if semantic-altering changes are made to left or right.
|
||||
pub length: usize,
|
||||
}
|
||||
|
||||
impl<'a> Node for ArrayRangeAccessExpression<'a> {
|
||||
@ -55,25 +58,12 @@ impl<'a> ExpressionNode<'a> for ArrayRangeAccessExpression<'a> {
|
||||
}
|
||||
|
||||
fn get_type(&self) -> Option<Type<'a>> {
|
||||
let (element, array_len) = match self.array.get().get_type() {
|
||||
Some(Type::Array(element, len)) => (element, len),
|
||||
let element = match self.array.get().get_type() {
|
||||
Some(Type::Array(element, _)) => element,
|
||||
_ => return None,
|
||||
};
|
||||
let const_left = match self.left.get().map(|x| x.const_value()) {
|
||||
Some(Some(ConstValue::Int(x))) => x.to_usize()?,
|
||||
None => 0,
|
||||
_ => return None,
|
||||
};
|
||||
let const_right = match self.right.get().map(|x| x.const_value()) {
|
||||
Some(Some(ConstValue::Int(x))) => x.to_usize()?,
|
||||
None => array_len,
|
||||
_ => return None,
|
||||
};
|
||||
if const_left > const_right || const_right > array_len {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Type::Array(element, const_right - const_left))
|
||||
Some(Type::Array(element, self.length))
|
||||
}
|
||||
|
||||
fn is_mut_ref(&self) -> bool {
|
||||
@ -113,9 +103,9 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
value: &leo_ast::ArrayRangeAccessExpression,
|
||||
expected_type: Option<PartialType<'a>>,
|
||||
) -> Result<ArrayRangeAccessExpression<'a>, AsgConvertError> {
|
||||
let expected_array = match expected_type {
|
||||
Some(PartialType::Array(element, _len)) => Some(PartialType::Array(element, None)),
|
||||
None => None,
|
||||
let (expected_array, expected_len) = match expected_type.clone() {
|
||||
Some(PartialType::Array(element, len)) => (Some(PartialType::Array(element, None)), len),
|
||||
None => (None, None),
|
||||
Some(x) => {
|
||||
return Err(AsgConvertError::unexpected_type(
|
||||
&x.to_string(),
|
||||
@ -126,8 +116,8 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
};
|
||||
let array = <&Expression<'a>>::from_ast(scope, &*value.array, expected_array)?;
|
||||
let array_type = array.get_type();
|
||||
match array_type {
|
||||
Some(Type::Array(_, _)) => (),
|
||||
let (parent_element, parent_size) = match array_type {
|
||||
Some(Type::Array(inner, size)) => (inner, size),
|
||||
type_ => {
|
||||
return Err(AsgConvertError::unexpected_type(
|
||||
"array",
|
||||
@ -135,7 +125,8 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
&value.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let left = value
|
||||
.left
|
||||
.as_deref()
|
||||
@ -151,26 +142,72 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
if let Some(left) = left.as_ref() {
|
||||
if !left.is_consty() {
|
||||
return Err(AsgConvertError::unexpected_nonconst(
|
||||
&left.span().cloned().unwrap_or_default(),
|
||||
));
|
||||
let const_left = match left.map(|x| x.const_value()) {
|
||||
Some(Some(ConstValue::Int(x))) => x.to_usize(),
|
||||
None => Some(0),
|
||||
_ => None,
|
||||
};
|
||||
let const_right = match right.map(|x| x.const_value()) {
|
||||
Some(Some(ConstValue::Int(value))) => {
|
||||
let value = value.to_usize();
|
||||
if let Some(value) = value {
|
||||
if value > parent_size {
|
||||
return Err(AsgConvertError::array_index_out_of_bounds(
|
||||
value,
|
||||
&right.unwrap().span().cloned().unwrap_or_default(),
|
||||
));
|
||||
} else if let Some(left) = const_left {
|
||||
if left > value {
|
||||
return Err(AsgConvertError::array_index_out_of_bounds(
|
||||
value,
|
||||
&right.unwrap().span().cloned().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
value
|
||||
}
|
||||
}
|
||||
if let Some(right) = right.as_ref() {
|
||||
if !right.is_consty() {
|
||||
return Err(AsgConvertError::unexpected_nonconst(
|
||||
&right.span().cloned().unwrap_or_default(),
|
||||
));
|
||||
None => Some(parent_size),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let mut length = if let (Some(left), Some(right)) = (const_left, const_right) {
|
||||
Some(right - left)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(expected_len) = expected_len {
|
||||
if let Some(length) = length {
|
||||
if length != expected_len {
|
||||
let concrete_type = Type::Array(parent_element, length);
|
||||
return Err(AsgConvertError::unexpected_type(
|
||||
&expected_type.as_ref().unwrap().to_string(),
|
||||
Some(&concrete_type.to_string()),
|
||||
&value.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(value) = const_left {
|
||||
if value + expected_len > parent_size {
|
||||
return Err(AsgConvertError::array_index_out_of_bounds(
|
||||
value,
|
||||
&left.unwrap().span().cloned().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
}
|
||||
length = Some(expected_len);
|
||||
}
|
||||
if length.is_none() {
|
||||
return Err(AsgConvertError::unknown_array_size(&value.span));
|
||||
}
|
||||
|
||||
Ok(ArrayRangeAccessExpression {
|
||||
parent: Cell::new(None),
|
||||
span: Some(value.span.clone()),
|
||||
array: Cell::new(array),
|
||||
left: Cell::new(left),
|
||||
right: Cell::new(right),
|
||||
length: length.unwrap(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
let circuit_name = circuit.name.borrow().name.clone();
|
||||
let member = circuit.members.borrow();
|
||||
let member = member
|
||||
.get(&name.name)
|
||||
.get(name.name.as_ref())
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, span))?;
|
||||
match member {
|
||||
CircuitMember::Function(body) => {
|
||||
@ -156,7 +156,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
|
||||
let member = circuit.members.borrow();
|
||||
let member = member
|
||||
.get(&name.name)
|
||||
.get(name.name.as_ref())
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, span))?;
|
||||
match member {
|
||||
CircuitMember::Function(body) => {
|
||||
|
@ -67,7 +67,7 @@ impl<'a> ExpressionNode<'a> for CircuitAccessExpression<'a> {
|
||||
None // function target only for static
|
||||
} else {
|
||||
let members = self.circuit.get().members.borrow();
|
||||
let member = members.get(&self.member.name)?;
|
||||
let member = members.get(self.member.name.as_ref())?;
|
||||
match member {
|
||||
CircuitMember::Variable(type_) => Some(type_.clone()),
|
||||
CircuitMember::Function(_) => None,
|
||||
@ -112,7 +112,7 @@ impl<'a> FromAst<'a, leo_ast::CircuitMemberAccessExpression> for CircuitAccessEx
|
||||
|
||||
// scoping refcell reference
|
||||
let found_member = {
|
||||
if let Some(member) = circuit.members.borrow().get(&value.name.name) {
|
||||
if let Some(member) = circuit.members.borrow().get(value.name.name.as_ref()) {
|
||||
if let Some(expected_type) = &expected_type {
|
||||
if let CircuitMember::Variable(type_) = &member {
|
||||
let type_: Type = type_.clone();
|
||||
@ -136,10 +136,10 @@ impl<'a> FromAst<'a, leo_ast::CircuitMemberAccessExpression> for CircuitAccessEx
|
||||
} else if circuit.is_input_pseudo_circuit() {
|
||||
// add new member to implicit input
|
||||
if let Some(expected_type) = expected_type.map(PartialType::full).flatten() {
|
||||
circuit
|
||||
.members
|
||||
.borrow_mut()
|
||||
.insert(value.name.name.clone(), CircuitMember::Variable(expected_type.clone()));
|
||||
circuit.members.borrow_mut().insert(
|
||||
value.name.name.to_string(),
|
||||
CircuitMember::Variable(expected_type.clone()),
|
||||
);
|
||||
} else {
|
||||
return Err(AsgConvertError::input_ref_needs_type(
|
||||
&circuit.name.borrow().name,
|
||||
@ -192,7 +192,7 @@ impl<'a> FromAst<'a, leo_ast::CircuitStaticFunctionAccessExpression> for Circuit
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(CircuitMember::Function(_)) = circuit.members.borrow().get(&value.name.name) {
|
||||
if let Some(CircuitMember::Function(_)) = circuit.members.borrow().get(value.name.name.as_ref()) {
|
||||
// okay
|
||||
} else {
|
||||
return Err(AsgConvertError::unresolved_circuit_member(
|
||||
|
@ -67,7 +67,7 @@ impl<'a> ExpressionNode<'a> for CircuitInitExpression<'a> {
|
||||
}
|
||||
|
||||
fn is_mut_ref(&self) -> bool {
|
||||
false
|
||||
true
|
||||
}
|
||||
|
||||
fn const_value(&self) -> Option<ConstValue> {
|
||||
@ -99,10 +99,10 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
));
|
||||
}
|
||||
}
|
||||
let members: IndexMap<&String, (&Identifier, Option<&leo_ast::Expression>)> = value
|
||||
let members: IndexMap<&str, (&Identifier, Option<&leo_ast::Expression>)> = value
|
||||
.members
|
||||
.iter()
|
||||
.map(|x| (&x.identifier.name, (&x.identifier, x.expression.as_ref())))
|
||||
.map(|x| (x.identifier.name.as_ref(), (&x.identifier, x.expression.as_ref())))
|
||||
.collect();
|
||||
|
||||
let mut values: Vec<(Identifier, Cell<&'a Expression<'a>>)> = vec![];
|
||||
@ -124,7 +124,7 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
if let Some((identifier, receiver)) = members.get(&name) {
|
||||
if let Some((identifier, receiver)) = members.get(&**name) {
|
||||
let received = if let Some(receiver) = *receiver {
|
||||
<&Expression<'a>>::from_ast(scope, receiver, Some(type_.partial()))?
|
||||
} else {
|
||||
|
@ -174,12 +174,12 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
Some(PartialType::Type(Type::Group)) => Constant {
|
||||
parent: Cell::new(None),
|
||||
span: Some(span.clone()),
|
||||
value: ConstValue::Group(GroupValue::Single(value.to_string())),
|
||||
value: ConstValue::Group(GroupValue::Single(value.clone())),
|
||||
},
|
||||
Some(PartialType::Type(Type::Address)) => Constant {
|
||||
parent: Cell::new(None),
|
||||
span: Some(span.clone()),
|
||||
value: ConstValue::Address(value.to_string()),
|
||||
value: ConstValue::Address(value.clone()),
|
||||
},
|
||||
Some(x) => return Err(AsgConvertError::unexpected_type(&x.to_string(), Some("unknown"), span)),
|
||||
},
|
||||
@ -213,10 +213,10 @@ impl<'a> Into<leo_ast::ValueExpression> for &Constant<'a> {
|
||||
leo_ast::ValueExpression::Address(value.clone(), self.span.clone().unwrap_or_default())
|
||||
}
|
||||
ConstValue::Boolean(value) => {
|
||||
leo_ast::ValueExpression::Boolean(value.to_string(), self.span.clone().unwrap_or_default())
|
||||
leo_ast::ValueExpression::Boolean(value.to_string().into(), self.span.clone().unwrap_or_default())
|
||||
}
|
||||
ConstValue::Field(value) => {
|
||||
leo_ast::ValueExpression::Field(value.to_string(), self.span.clone().unwrap_or_default())
|
||||
leo_ast::ValueExpression::Field(value.to_string().into(), self.span.clone().unwrap_or_default())
|
||||
}
|
||||
ConstValue::Group(value) => leo_ast::ValueExpression::Group(Box::new(match value {
|
||||
GroupValue::Single(single) => {
|
||||
@ -230,7 +230,7 @@ impl<'a> Into<leo_ast::ValueExpression> for &Constant<'a> {
|
||||
})),
|
||||
ConstValue::Int(int) => leo_ast::ValueExpression::Integer(
|
||||
int.get_int_type(),
|
||||
int.raw_value(),
|
||||
int.raw_value().into(),
|
||||
self.span.clone().unwrap_or_default(),
|
||||
),
|
||||
ConstValue::Tuple(_) => unimplemented!(),
|
||||
|
@ -109,7 +109,7 @@ impl<'a> Into<leo_ast::TupleAccessExpression> for &TupleAccessExpression<'a> {
|
||||
leo_ast::TupleAccessExpression {
|
||||
tuple: Box::new(self.tuple_ref.get().into()),
|
||||
index: leo_ast::PositiveNumber {
|
||||
value: self.index.to_string(),
|
||||
value: self.index.to_string().into(),
|
||||
},
|
||||
span: self.span.clone().unwrap_or_default(),
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ impl<'a> FromAst<'a, leo_ast::Identifier> for &'a Expression<'a> {
|
||||
value: &leo_ast::Identifier,
|
||||
expected_type: Option<PartialType<'a>>,
|
||||
) -> Result<&'a Expression<'a>, AsgConvertError> {
|
||||
let variable = if value.name == "input" {
|
||||
let variable = if value.name.as_ref() == "input" {
|
||||
if let Some(function) = scope.resolve_current_function() {
|
||||
if !function.has_input {
|
||||
return Err(AsgConvertError::unresolved_reference(&value.name, &value.span));
|
||||
|
@ -40,7 +40,7 @@ impl<'a> Input<'a> {
|
||||
fn make_header(scope: &'a Scope<'a>, name: &str) -> &'a Circuit<'a> {
|
||||
scope.context.alloc_circuit(Circuit {
|
||||
id: scope.context.get_id(),
|
||||
name: RefCell::new(Identifier::new(name.to_string())),
|
||||
name: RefCell::new(Identifier::new(name.into())),
|
||||
members: RefCell::new(IndexMap::new()),
|
||||
core_mapping: RefCell::new(None),
|
||||
scope,
|
||||
@ -69,7 +69,7 @@ impl<'a> Input<'a> {
|
||||
|
||||
let container_circuit = input_scope.context.alloc_circuit(Circuit {
|
||||
id: scope.context.get_id(),
|
||||
name: RefCell::new(Identifier::new(CONTAINER_PSEUDO_CIRCUIT.to_string())),
|
||||
name: RefCell::new(Identifier::new(CONTAINER_PSEUDO_CIRCUIT.into())),
|
||||
members: RefCell::new(container_members),
|
||||
core_mapping: RefCell::new(None),
|
||||
scope: input_scope,
|
||||
@ -84,7 +84,7 @@ impl<'a> Input<'a> {
|
||||
container_circuit,
|
||||
container: input_scope.context.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
id: scope.context.get_id(),
|
||||
name: Identifier::new("input".to_string()),
|
||||
name: Identifier::new("input".into()),
|
||||
type_: Type::Circuit(container_circuit),
|
||||
mutable: false,
|
||||
const_: false,
|
||||
|
@ -69,7 +69,7 @@ impl<'a> Circuit<'a> {
|
||||
let mut members = circuit.members.borrow_mut();
|
||||
for member in value.members.iter() {
|
||||
if let leo_ast::CircuitMember::CircuitVariable(name, type_) = member {
|
||||
if members.contains_key(&name.name) {
|
||||
if members.contains_key(name.name.as_ref()) {
|
||||
return Err(AsgConvertError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&name.name,
|
||||
@ -77,7 +77,7 @@ impl<'a> Circuit<'a> {
|
||||
));
|
||||
}
|
||||
members.insert(
|
||||
name.name.clone(),
|
||||
name.name.to_string(),
|
||||
CircuitMember::Variable(new_scope.resolve_ast_type(type_)?),
|
||||
);
|
||||
}
|
||||
@ -93,13 +93,13 @@ impl<'a> Circuit<'a> {
|
||||
let new_scope = scope.make_subscope();
|
||||
let circuits = scope.circuits.borrow();
|
||||
|
||||
let circuit = circuits.get(&value.circuit_name.name).unwrap();
|
||||
let circuit = circuits.get(value.circuit_name.name.as_ref()).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) {
|
||||
if members.contains_key(function.identifier.name.as_ref()) {
|
||||
return Err(AsgConvertError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&function.identifier.name,
|
||||
@ -111,7 +111,10 @@ impl<'a> Circuit<'a> {
|
||||
if asg_function.is_test() {
|
||||
return Err(AsgConvertError::circuit_test_function(&function.identifier.span));
|
||||
}
|
||||
members.insert(function.identifier.name.clone(), CircuitMember::Function(asg_function));
|
||||
members.insert(
|
||||
function.identifier.name.to_string(),
|
||||
CircuitMember::Function(asg_function),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +129,7 @@ impl<'a> Circuit<'a> {
|
||||
let asg_function = match *self
|
||||
.members
|
||||
.borrow()
|
||||
.get(&function.identifier.name)
|
||||
.get(function.identifier.name.as_ref())
|
||||
.expect("missing header for defined circuit function")
|
||||
{
|
||||
CircuitMember::Function(f) => f,
|
||||
@ -148,7 +151,7 @@ impl<'a> Into<leo_ast::Circuit> for &Circuit<'a> {
|
||||
.iter()
|
||||
.map(|(name, member)| match &member {
|
||||
CircuitMember::Variable(type_) => {
|
||||
leo_ast::CircuitMember::CircuitVariable(Identifier::new(name.clone()), type_.into())
|
||||
leo_ast::CircuitMember::CircuitVariable(Identifier::new((&**name).into()), type_.into())
|
||||
}
|
||||
CircuitMember::Function(func) => leo_ast::CircuitMember::CircuitFunction((*func).into()),
|
||||
})
|
||||
|
@ -113,7 +113,7 @@ impl<'a> Function<'a> {
|
||||
references: vec![],
|
||||
assignments: vec![],
|
||||
}));
|
||||
arguments.insert(identifier.name.clone(), Cell::new(&*variable));
|
||||
arguments.insert(identifier.name.to_string(), Cell::new(&*variable));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,7 +144,7 @@ impl<'a> Function<'a> {
|
||||
let circuit = self.circuit.get();
|
||||
let self_variable = self.scope.context.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
id: self.scope.context.get_id(),
|
||||
name: Identifier::new("self".to_string()),
|
||||
name: Identifier::new("self".into()),
|
||||
type_: Type::Circuit(circuit.as_ref().unwrap()),
|
||||
mutable: self.qualifier == FunctionQualifier::MutSelfRef,
|
||||
const_: false,
|
||||
@ -186,7 +186,7 @@ impl<'a> Function<'a> {
|
||||
}
|
||||
|
||||
pub fn is_test(&self) -> bool {
|
||||
self.annotations.iter().any(|x| x.name.name == "test")
|
||||
self.annotations.iter().any(|x| x.name.name.as_ref() == "test")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,11 +75,11 @@ fn resolve_import_package(
|
||||
) {
|
||||
match package_or_packages {
|
||||
PackageOrPackages::Package(package) => {
|
||||
package_segments.push(package.name.name.clone());
|
||||
package_segments.push(package.name.name.to_string());
|
||||
resolve_import_package_access(output, package_segments, &package.access);
|
||||
}
|
||||
PackageOrPackages::Packages(packages) => {
|
||||
package_segments.push(packages.name.name.clone());
|
||||
package_segments.push(packages.name.name.to_string());
|
||||
for access in packages.accesses.clone() {
|
||||
resolve_import_package_access(output, package_segments.clone(), &access);
|
||||
}
|
||||
@ -106,14 +106,14 @@ fn resolve_import_package_access(
|
||||
PackageAccess::Symbol(symbol) => {
|
||||
let span = symbol.symbol.span.clone();
|
||||
let symbol = if let Some(alias) = symbol.alias.as_ref() {
|
||||
ImportSymbol::Alias(symbol.symbol.name.clone(), alias.name.clone())
|
||||
ImportSymbol::Alias(symbol.symbol.name.to_string(), alias.name.to_string())
|
||||
} else {
|
||||
ImportSymbol::Direct(symbol.symbol.name.clone())
|
||||
ImportSymbol::Direct(symbol.symbol.name.to_string())
|
||||
};
|
||||
output.push((package_segments, symbol, span));
|
||||
}
|
||||
PackageAccess::Multiple(packages) => {
|
||||
package_segments.push(packages.name.name.clone());
|
||||
package_segments.push(packages.name.name.to_string());
|
||||
for subaccess in packages.accesses.iter() {
|
||||
resolve_import_package_access(output, package_segments.clone(), &subaccess);
|
||||
}
|
||||
@ -240,7 +240,7 @@ impl<'a> Program<'a> {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = Circuit::init(scope, circuit)?;
|
||||
|
||||
scope.circuits.borrow_mut().insert(name.name.clone(), asg_circuit);
|
||||
scope.circuits.borrow_mut().insert(name.name.to_string(), asg_circuit);
|
||||
}
|
||||
|
||||
// Second pass for circuit members.
|
||||
@ -248,35 +248,41 @@ impl<'a> Program<'a> {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = Circuit::init_member(scope, circuit)?;
|
||||
|
||||
scope.circuits.borrow_mut().insert(name.name.clone(), asg_circuit);
|
||||
scope.circuits.borrow_mut().insert(name.name.to_string(), asg_circuit);
|
||||
}
|
||||
|
||||
for (name, function) in program.functions.iter() {
|
||||
assert_eq!(name.name, function.identifier.name);
|
||||
let function = Function::init(scope, function)?;
|
||||
|
||||
scope.functions.borrow_mut().insert(name.name.clone(), function);
|
||||
scope.functions.borrow_mut().insert(name.name.to_string(), function);
|
||||
}
|
||||
|
||||
// Load concrete definitions.
|
||||
let mut functions = IndexMap::new();
|
||||
for (name, function) in program.functions.iter() {
|
||||
assert_eq!(name.name, function.identifier.name);
|
||||
let asg_function = *scope.functions.borrow().get(&name.name).unwrap();
|
||||
let asg_function = *scope.functions.borrow().get(name.name.as_ref()).unwrap();
|
||||
|
||||
asg_function.fill_from_ast(function)?;
|
||||
|
||||
functions.insert(name.name.clone(), asg_function);
|
||||
let name = name.name.to_string();
|
||||
|
||||
if functions.contains_key(&name) {
|
||||
return Err(AsgConvertError::duplicate_function_definition(&name, &function.span));
|
||||
}
|
||||
|
||||
functions.insert(name, asg_function);
|
||||
}
|
||||
|
||||
let mut circuits = IndexMap::new();
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = *scope.circuits.borrow().get(&name.name).unwrap();
|
||||
let asg_circuit = *scope.circuits.borrow().get(name.name.as_ref()).unwrap();
|
||||
|
||||
asg_circuit.fill_from_ast(circuit)?;
|
||||
|
||||
circuits.insert(name.name.clone(), asg_circuit);
|
||||
circuits.insert(name.name.to_string(), asg_circuit);
|
||||
}
|
||||
|
||||
Ok(Program {
|
||||
@ -338,7 +344,7 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
for (_, program) in all_programs.into_iter() {
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
let identifier = format!("{}{}", identifiers.next().unwrap(), name);
|
||||
circuit.name.borrow_mut().name = identifier.clone();
|
||||
circuit.name.borrow_mut().name = identifier.clone().into();
|
||||
all_circuits.insert(identifier, *circuit);
|
||||
}
|
||||
for (name, function) in program.functions.iter() {
|
||||
@ -347,7 +353,7 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
} else {
|
||||
format!("{}{}", identifiers.next().unwrap(), name)
|
||||
};
|
||||
function.name.borrow_mut().name = identifier.clone();
|
||||
function.name.borrow_mut().name = identifier.clone().into();
|
||||
all_functions.insert(identifier, *function);
|
||||
}
|
||||
}
|
||||
@ -358,7 +364,7 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
.iter()
|
||||
.map(|(module, _)| leo_ast::ImportStatement {
|
||||
package_or_packages: leo_ast::PackageOrPackages::Package(leo_ast::Package {
|
||||
name: Identifier::new(module.clone()),
|
||||
name: Identifier::new(module.clone().into()),
|
||||
access: leo_ast::PackageAccess::Star(Span::default()),
|
||||
span: Default::default(),
|
||||
}),
|
||||
|
@ -74,6 +74,7 @@ pub trait ReconstructingReducerExpression<'a> {
|
||||
left: Cell::new(left),
|
||||
right: Cell::new(right),
|
||||
span: input.span,
|
||||
length: input.length,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ impl<'a> Scope<'a> {
|
||||
.map(|x| self.resolve_ast_type(x))
|
||||
.collect::<Result<Vec<_>, AsgConvertError>>()?,
|
||||
),
|
||||
Circuit(name) if name.name == "Self" => Type::Circuit(
|
||||
Circuit(name) if name.name.as_ref() == "Self" => Type::Circuit(
|
||||
self.resolve_circuit_self()
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit(&name.name, &name.span))?,
|
||||
),
|
||||
|
@ -69,7 +69,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
) -> Result<Self, AsgConvertError> {
|
||||
let (name, span) = (&statement.assignee.identifier.name, &statement.assignee.identifier.span);
|
||||
|
||||
let variable = if name == "input" {
|
||||
let variable = if name.as_ref() == "input" {
|
||||
if let Some(function) = scope.resolve_current_function() {
|
||||
if !function.has_input {
|
||||
return Err(AsgConvertError::unresolved_reference(name, &span));
|
||||
@ -188,7 +188,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
let circuit = circuit;
|
||||
|
||||
let members = circuit.members.borrow();
|
||||
let member = members.get(&name.name).ok_or_else(|| {
|
||||
let member = members.get(name.name.as_ref()).ok_or_else(|| {
|
||||
AsgConvertError::unresolved_circuit_member(
|
||||
&circuit.name.borrow().name,
|
||||
&name.name,
|
||||
@ -251,7 +251,7 @@ impl<'a> Into<leo_ast::AssignStatement> for &AssignStatement<'a> {
|
||||
AssignAccess::ArrayIndex(index) => AstAssigneeAccess::ArrayIndex(index.get().into()),
|
||||
AssignAccess::Tuple(index) => AstAssigneeAccess::Tuple(
|
||||
leo_ast::PositiveNumber {
|
||||
value: index.to_string(),
|
||||
value: index.to_string().into(),
|
||||
},
|
||||
self.span.clone().unwrap_or_default(),
|
||||
),
|
||||
|
@ -106,7 +106,7 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
scope
|
||||
.variables
|
||||
.borrow_mut()
|
||||
.insert(variable.borrow().name.name.clone(), *variable);
|
||||
.insert(variable.borrow().name.name.to_string(), *variable);
|
||||
}
|
||||
|
||||
let statement = scope
|
||||
|
@ -85,7 +85,7 @@ impl<'a> FromAst<'a, leo_ast::IterationStatement> for &'a Statement<'a> {
|
||||
scope
|
||||
.variables
|
||||
.borrow_mut()
|
||||
.insert(statement.variable.name.clone(), variable);
|
||||
.insert(statement.variable.name.to_string(), variable);
|
||||
|
||||
let statement = scope.context.alloc_statement(Statement::Iteration(IterationStatement {
|
||||
parent: Cell::new(None),
|
||||
|
@ -204,7 +204,9 @@ impl<'a> Into<leo_ast::Type> for &Type<'a> {
|
||||
Integer(int_type) => leo_ast::Type::IntegerType(int_type.clone()),
|
||||
Array(type_, len) => leo_ast::Type::Array(
|
||||
Box::new(type_.as_ref().into()),
|
||||
leo_ast::ArrayDimensions(vec![leo_ast::PositiveNumber { value: len.to_string() }]),
|
||||
leo_ast::ArrayDimensions(vec![leo_ast::PositiveNumber {
|
||||
value: len.to_string().into(),
|
||||
}]),
|
||||
),
|
||||
Tuple(subtypes) => leo_ast::Type::Tuple(subtypes.iter().map(Into::into).collect()),
|
||||
Circuit(circuit) => leo_ast::Type::Circuit(circuit.name.borrow().clone()),
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leo-ast"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "Core AST of the Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
@ -19,7 +19,7 @@ edition = "2018"
|
||||
|
||||
[dependencies.leo-input]
|
||||
path = "../input"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.6.2"
|
||||
@ -30,7 +30,7 @@ version = "2.0"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
features = ["derive", "rc"]
|
||||
features = [ "derive", "rc" ]
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1.0"
|
||||
@ -41,6 +41,9 @@ version = "1.0"
|
||||
[dependencies.thiserror]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.tendril]
|
||||
version = "0.4"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3"
|
||||
|
||||
|
@ -17,10 +17,12 @@
|
||||
use crate::{Identifier, Span};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Annotation {
|
||||
pub span: Span,
|
||||
pub name: Identifier,
|
||||
pub arguments: Vec<String>,
|
||||
#[serde(with = "crate::common::vec_tendril_json")]
|
||||
pub arguments: Vec<StrTendril>,
|
||||
}
|
||||
|
@ -26,18 +26,6 @@ use std::fmt;
|
||||
pub struct ArrayDimensions(pub Vec<PositiveNumber>);
|
||||
|
||||
impl ArrayDimensions {
|
||||
///
|
||||
/// Creates a new `PositiveNumber` from the given `usize` and `Span`.
|
||||
/// Appends the new `PositiveNumber` to the array dimensions.
|
||||
///
|
||||
pub fn push_usize(&mut self, number: usize) {
|
||||
let positive_number = PositiveNumber {
|
||||
value: number.to_string(),
|
||||
};
|
||||
|
||||
self.0.push(positive_number)
|
||||
}
|
||||
|
||||
///
|
||||
/// Appends a vector of array dimensions to the self array dimensions.
|
||||
///
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use crate::Span;
|
||||
use leo_input::common::Identifier as InputIdentifier;
|
||||
use tendril::StrTendril;
|
||||
|
||||
use crate::Node;
|
||||
use serde::{
|
||||
@ -41,7 +42,7 @@ use std::{
|
||||
/// to reflect the new struct instantiation.
|
||||
#[derive(Clone)]
|
||||
pub struct Identifier {
|
||||
pub name: String,
|
||||
pub name: StrTendril,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
@ -56,7 +57,7 @@ impl Node for Identifier {
|
||||
}
|
||||
|
||||
impl Identifier {
|
||||
pub fn new(name: String) -> Self {
|
||||
pub fn new(name: StrTendril) -> Self {
|
||||
Self {
|
||||
name,
|
||||
span: Span::default(),
|
||||
@ -65,24 +66,16 @@ impl Identifier {
|
||||
|
||||
pub fn new_with_span(name: &str, span: Span) -> Self {
|
||||
Self {
|
||||
name: name.to_owned(),
|
||||
name: name.into(),
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_self_type(&self) -> bool {
|
||||
self.name == "Self"
|
||||
}
|
||||
|
||||
pub fn is_self(&self) -> bool {
|
||||
self.is_self_type() || self.name == "self"
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<InputIdentifier<'ast>> for Identifier {
|
||||
fn from(identifier: InputIdentifier<'ast>) -> Self {
|
||||
Self {
|
||||
name: identifier.value,
|
||||
name: identifier.value.into(),
|
||||
span: Span::from(identifier.span),
|
||||
}
|
||||
}
|
||||
@ -123,7 +116,7 @@ impl Serialize for Identifier {
|
||||
|
||||
// Load the struct elements into a BTreeMap (to preserve serialized ordering of keys).
|
||||
let mut key: BTreeMap<String, String> = BTreeMap::new();
|
||||
key.insert("name".to_string(), self.name.clone());
|
||||
key.insert("name".to_string(), self.name.to_string());
|
||||
key.insert("span".to_string(), to_json_string(&self.span)?);
|
||||
|
||||
// Convert the serialized object into a string for use as a key.
|
||||
@ -164,7 +157,10 @@ impl<'de> Deserialize<'de> for Identifier {
|
||||
None => return Err(E::custom("missing 'span' in serialized Identifier struct")),
|
||||
};
|
||||
|
||||
Ok(Identifier { name, span })
|
||||
Ok(Identifier {
|
||||
name: name.into(),
|
||||
span,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,3 +40,7 @@ pub use span::*;
|
||||
|
||||
pub mod spread_or_expression;
|
||||
pub use spread_or_expression::*;
|
||||
|
||||
pub mod tendril_json;
|
||||
|
||||
pub mod vec_tendril_json;
|
||||
|
@ -18,11 +18,13 @@ use leo_input::values::PositiveNumber as InputPositiveNumber;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// A number string guaranteed to be positive by the pest grammar.
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct PositiveNumber {
|
||||
pub value: String,
|
||||
#[serde(with = "crate::common::tendril_json")]
|
||||
pub value: StrTendril,
|
||||
}
|
||||
|
||||
impl PositiveNumber {
|
||||
@ -30,14 +32,16 @@ impl PositiveNumber {
|
||||
/// Returns `true` if this number is zero.
|
||||
///
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.value.eq("0")
|
||||
self.value.as_ref().eq("0")
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new [`PositiveNumber`] from an [`InputPositiveNumber`] in a Leo input file.
|
||||
impl<'ast> From<InputPositiveNumber<'ast>> for PositiveNumber {
|
||||
fn from(array: InputPositiveNumber<'ast>) -> Self {
|
||||
Self { value: array.value }
|
||||
Self {
|
||||
value: array.value.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,10 @@
|
||||
// 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::{fmt, rc::Rc};
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
pub struct Span {
|
||||
@ -24,7 +25,9 @@ pub struct Span {
|
||||
pub line_stop: usize,
|
||||
pub col_start: usize,
|
||||
pub col_stop: usize,
|
||||
pub path: Rc<String>,
|
||||
pub path: Arc<String>,
|
||||
#[serde(with = "crate::common::tendril_json")]
|
||||
pub content: StrTendril,
|
||||
}
|
||||
|
||||
impl fmt::Display for Span {
|
||||
@ -51,7 +54,8 @@ impl<'ast> From<pest::Span<'ast>> for Span {
|
||||
line_stop: end.0,
|
||||
col_start: start.1,
|
||||
col_stop: end.1,
|
||||
path: Rc::new(String::new()),
|
||||
path: Arc::new(String::new()),
|
||||
content: span.as_str().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,22 +80,40 @@ impl std::ops::Add for Span {
|
||||
col_start: self.col_start.min(other.col_start),
|
||||
col_stop: self.col_stop.max(other.col_stop),
|
||||
path: self.path,
|
||||
}
|
||||
} else if self.line_start < other.line_stop {
|
||||
Span {
|
||||
line_start: self.line_start,
|
||||
line_stop: other.line_stop,
|
||||
col_start: self.col_start,
|
||||
col_stop: other.col_stop,
|
||||
path: self.path,
|
||||
content: self.content,
|
||||
}
|
||||
} else {
|
||||
Span {
|
||||
line_start: other.line_start,
|
||||
line_stop: self.line_stop,
|
||||
col_start: other.col_start,
|
||||
col_stop: self.col_stop,
|
||||
path: self.path,
|
||||
let mut new_content = vec![];
|
||||
let self_lines = self.content.lines().collect::<Vec<_>>();
|
||||
let other_lines = other.content.lines().collect::<Vec<_>>();
|
||||
for line in self.line_start.min(other.line_start)..self.line_stop.max(other.line_stop) + 1 {
|
||||
if line >= self.line_start && line <= self.line_stop {
|
||||
new_content.push(self_lines.get(line - self.line_start).copied().unwrap_or_default());
|
||||
} else if line >= other.line_start && line <= other.line_stop {
|
||||
new_content.push(other_lines.get(line - other.line_start).copied().unwrap_or_default());
|
||||
} else if new_content.last().map(|x| *x != "...").unwrap_or(true) {
|
||||
new_content.push("...");
|
||||
}
|
||||
}
|
||||
let new_content = new_content.join("\n").into();
|
||||
if self.line_start < other.line_stop {
|
||||
Span {
|
||||
line_start: self.line_start,
|
||||
line_stop: other.line_stop,
|
||||
col_start: self.col_start,
|
||||
col_stop: other.col_stop,
|
||||
path: self.path,
|
||||
content: new_content,
|
||||
}
|
||||
} else {
|
||||
Span {
|
||||
line_start: other.line_start,
|
||||
line_stop: self.line_stop,
|
||||
col_start: other.col_start,
|
||||
col_stop: self.col_stop,
|
||||
path: self.path,
|
||||
content: new_content,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
ast/src/common/tendril_json.rs
Normal file
26
ast/src/common/tendril_json.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// 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 serde::{Deserialize, Deserializer, Serializer};
|
||||
use tendril::StrTendril;
|
||||
|
||||
pub fn serialize<S: Serializer>(tendril: &StrTendril, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(&tendril[..])
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<StrTendril, D::Error> {
|
||||
Ok(String::deserialize(deserializer)?.into())
|
||||
}
|
34
ast/src/common/vec_tendril_json.rs
Normal file
34
ast/src/common/vec_tendril_json.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// 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 serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn serialize<S: Serializer>(tendril: &Vec<StrTendril>, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
tendril
|
||||
.iter()
|
||||
.map(|x| x.as_ref())
|
||||
.collect::<Vec<_>>()
|
||||
.serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<StrTendril>, D::Error> {
|
||||
Ok(Vec::<String>::deserialize(deserializer)?
|
||||
.into_iter()
|
||||
.map(|x| x.into())
|
||||
.collect())
|
||||
}
|
@ -16,12 +16,12 @@
|
||||
|
||||
use crate::{LeoError, Span};
|
||||
|
||||
use std::fmt;
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
pub const INDENT: &str = " ";
|
||||
|
||||
/// Formatted compiler error type
|
||||
/// --> file.leo 2:8
|
||||
/// --> file.leo: 2:8
|
||||
/// |
|
||||
/// 2 | let a = x;
|
||||
/// | ^
|
||||
@ -29,60 +29,30 @@ pub const INDENT: &str = " ";
|
||||
/// = undefined value `x`
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct FormattedError {
|
||||
/// File path where error occurred
|
||||
pub path: Option<String>,
|
||||
/// Line start number
|
||||
pub line_start: usize,
|
||||
/// Line end number
|
||||
pub line_stop: usize,
|
||||
/// Starting column
|
||||
pub start: usize,
|
||||
/// Ending column
|
||||
pub end: usize,
|
||||
/// Text of errored lines
|
||||
pub text: Option<Vec<String>>,
|
||||
/// Error explanation
|
||||
pub col_start: usize,
|
||||
pub col_stop: usize,
|
||||
pub path: Arc<String>,
|
||||
pub content: String,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl FormattedError {
|
||||
pub fn new_from_span(message: String, span: &Span) -> Self {
|
||||
Self {
|
||||
path: None,
|
||||
line_start: span.line_start,
|
||||
line_stop: span.line_stop,
|
||||
start: span.col_start,
|
||||
end: span.col_stop,
|
||||
text: None,
|
||||
col_start: span.col_start,
|
||||
col_stop: span.col_stop,
|
||||
path: span.path.clone(),
|
||||
content: span.content.to_string(),
|
||||
message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LeoError for FormattedError {
|
||||
fn set_path(&mut self, path: &str, content: &[String]) {
|
||||
self.path = Some(path.to_string());
|
||||
if self.line_stop - 1 > content.len() {
|
||||
self.text = Some(vec!["corrupt file".to_string()]);
|
||||
return;
|
||||
}
|
||||
assert!(self.line_stop >= self.line_start);
|
||||
// if self.line_stop == self.line_start {
|
||||
// self.text = Some(vec![content[self.line_start - 1][self.start - 1..self.end - 1].to_string()]);
|
||||
// } else {
|
||||
self.text = Some(
|
||||
content[self.line_start - 1..self.line_stop]
|
||||
.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect(),
|
||||
);
|
||||
// }
|
||||
}
|
||||
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
self.path.as_deref()
|
||||
}
|
||||
}
|
||||
impl LeoError for FormattedError {}
|
||||
|
||||
fn underline(mut start: usize, mut end: usize) -> String {
|
||||
if start > end {
|
||||
@ -105,29 +75,26 @@ fn underline(mut start: usize, mut end: usize) -> String {
|
||||
|
||||
impl fmt::Display for FormattedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let path = self.path.as_ref().map(|path| format!("{}:", path)).unwrap_or_default();
|
||||
let underline = underline(self.start - 1, self.end - 1);
|
||||
let underline = underline(self.col_start - 1, self.col_stop - 1);
|
||||
|
||||
write!(
|
||||
f,
|
||||
"{indent }--> {path} {line_start}:{start}\n\
|
||||
"{indent }--> {path}: {line_start}:{start}\n\
|
||||
{indent } |\n",
|
||||
indent = INDENT,
|
||||
path = path,
|
||||
path = &*self.path,
|
||||
line_start = self.line_start,
|
||||
start = self.start,
|
||||
start = self.col_start,
|
||||
)?;
|
||||
|
||||
if let Some(lines) = &self.text {
|
||||
for (line_no, line) in lines.iter().enumerate() {
|
||||
writeln!(
|
||||
f,
|
||||
"{line_no:width$} | {text}",
|
||||
width = INDENT.len(),
|
||||
line_no = self.line_start + line_no,
|
||||
text = line,
|
||||
)?;
|
||||
}
|
||||
for (line_no, line) in self.content.lines().enumerate() {
|
||||
writeln!(
|
||||
f,
|
||||
"{line_no:width$} | {text}",
|
||||
width = INDENT.len(),
|
||||
line_no = self.line_start + line_no,
|
||||
text = line,
|
||||
)?;
|
||||
}
|
||||
|
||||
write!(
|
||||
@ -151,12 +118,12 @@ impl std::error::Error for FormattedError {
|
||||
#[test]
|
||||
fn test_error() {
|
||||
let err = FormattedError {
|
||||
path: Some("file.leo".to_string()),
|
||||
path: std::sync::Arc::new("file.leo".to_string()),
|
||||
line_start: 2,
|
||||
line_stop: 2,
|
||||
start: 8,
|
||||
end: 9,
|
||||
text: Some(vec!["let a = x;".to_string()]),
|
||||
col_start: 8,
|
||||
col_stop: 9,
|
||||
content: "let a = x;".into(),
|
||||
message: "undefined value `x`".to_string(),
|
||||
};
|
||||
|
||||
|
@ -17,8 +17,4 @@
|
||||
pub mod error;
|
||||
pub use error::*;
|
||||
|
||||
pub trait LeoError {
|
||||
fn get_path(&self) -> Option<&str>;
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]);
|
||||
}
|
||||
pub trait LeoError {}
|
||||
|
@ -14,18 +14,24 @@
|
||||
// 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 tendril::StrTendril;
|
||||
|
||||
use super::*;
|
||||
use crate::GroupTuple;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ValueExpression {
|
||||
// todo: deserialize values here
|
||||
Address(String, Span),
|
||||
Boolean(String, Span),
|
||||
Field(String, Span),
|
||||
Address(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Boolean(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Field(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Group(Box<GroupValue>),
|
||||
Implicit(String, Span),
|
||||
Integer(IntegerType, String, Span),
|
||||
Implicit(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Integer(
|
||||
IntegerType,
|
||||
#[serde(with = "crate::common::tendril_json")] StrTendril,
|
||||
Span,
|
||||
),
|
||||
}
|
||||
|
||||
impl fmt::Display for ValueExpression {
|
||||
|
@ -25,10 +25,11 @@ use leo_input::values::{
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum GroupCoordinate {
|
||||
Number(String, Span),
|
||||
Number(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
SignHigh,
|
||||
SignLow,
|
||||
Inferred,
|
||||
@ -61,7 +62,7 @@ impl<'ast> From<InputNumberValue<'ast>> for GroupCoordinate {
|
||||
let value = number.to_string();
|
||||
let span = Span::from(number.span().clone());
|
||||
|
||||
GroupCoordinate::Number(value, span)
|
||||
GroupCoordinate::Number(value.into(), span)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,11 @@ use leo_input::values::{
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum GroupValue {
|
||||
Single(String, Span),
|
||||
Single(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Tuple(GroupTuple),
|
||||
}
|
||||
|
||||
@ -51,7 +52,7 @@ impl<'ast> From<InputGroupValue<'ast>> for GroupValue {
|
||||
let span = Span::from(ast_group.span);
|
||||
|
||||
match ast_group.value {
|
||||
InputGroupRepresentation::Single(number) => GroupValue::Single(number.to_string(), span),
|
||||
InputGroupRepresentation::Single(number) => GroupValue::Single(number.to_string().into(), span),
|
||||
InputGroupRepresentation::Tuple(tuple) => GroupValue::Tuple(GroupTuple::from(tuple)),
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ impl ImportSymbol {
|
||||
pub fn star(span: &Span) -> Self {
|
||||
Self {
|
||||
symbol: Identifier {
|
||||
name: "*".to_string(),
|
||||
name: "*".into(),
|
||||
span: span.clone(),
|
||||
},
|
||||
alias: None,
|
||||
@ -60,6 +60,6 @@ impl ImportSymbol {
|
||||
}
|
||||
|
||||
pub fn is_star(&self) -> bool {
|
||||
self.symbol.name.eq("*")
|
||||
self.symbol.name.as_ref().eq("*")
|
||||
}
|
||||
}
|
||||
|
@ -96,13 +96,13 @@ impl Input {
|
||||
|
||||
/// Returns the main function input value with the given `name`.
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
pub fn get(&self, name: &str) -> Option<Option<InputValue>> {
|
||||
self.program_input.get(name)
|
||||
}
|
||||
|
||||
/// Returns the constant input value with the given `name`.
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn get_constant(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
pub fn get_constant(&self, name: &str) -> Option<Option<InputValue>> {
|
||||
self.program_input.get_constant(name)
|
||||
}
|
||||
|
||||
|
@ -74,12 +74,12 @@ impl ProgramInput {
|
||||
|
||||
/// Returns the main function input value with the given `name`
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
pub fn get(&self, name: &str) -> Option<Option<InputValue>> {
|
||||
self.main.get(name)
|
||||
}
|
||||
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn get_constant(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
pub fn get_constant(&self, name: &str) -> Option<Option<InputValue>> {
|
||||
self.constants.get(name)
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ impl Canonicalizer {
|
||||
|
||||
Expression::CircuitInit(circuit_init) => {
|
||||
let mut name = circuit_init.name.clone();
|
||||
if name.name == *"Self" {
|
||||
if name.name.as_ref() == "Self" {
|
||||
name = self.circuit_name.as_ref().unwrap().clone();
|
||||
}
|
||||
|
||||
@ -470,7 +470,35 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
) -> Result<AssignStatement, CanonicalizeError> {
|
||||
match value {
|
||||
Expression::Value(value_expr) if assign.operation != AssignOperation::Assign => {
|
||||
let left = Box::new(Expression::Identifier(assignee.identifier.clone()));
|
||||
let mut left = Box::new(Expression::Identifier(assignee.identifier.clone()));
|
||||
|
||||
for access in assignee.accesses.iter().rev() {
|
||||
match self.canonicalize_assignee_access(&access) {
|
||||
AssigneeAccess::ArrayIndex(index) => {
|
||||
left = Box::new(Expression::ArrayAccess(ArrayAccessExpression {
|
||||
array: left,
|
||||
index: Box::new(index),
|
||||
span: assign.span.clone(),
|
||||
}));
|
||||
}
|
||||
AssigneeAccess::Tuple(positive_number, _) => {
|
||||
left = Box::new(Expression::TupleAccess(TupleAccessExpression {
|
||||
tuple: left,
|
||||
index: positive_number,
|
||||
span: assign.span.clone(),
|
||||
}));
|
||||
}
|
||||
AssigneeAccess::Member(identifier) => {
|
||||
left = Box::new(Expression::CircuitMemberAccess(CircuitMemberAccessExpression {
|
||||
circuit: left,
|
||||
name: identifier,
|
||||
span: assign.span.clone(),
|
||||
}));
|
||||
}
|
||||
_ => unimplemented!(), // No reason for someone to compute ArrayRanges.
|
||||
}
|
||||
}
|
||||
|
||||
let right = Box::new(Expression::Value(value_expr));
|
||||
|
||||
let op = match assign.operation {
|
||||
|
@ -18,10 +18,11 @@ use crate::{Expression, Node, Span};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
pub enum FormattedStringPart {
|
||||
Const(String),
|
||||
Const(#[serde(with = "crate::common::tendril_json")] StrTendril),
|
||||
Container,
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leo-compiler"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "Compiler of the Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
@ -19,58 +19,58 @@ edition = "2018"
|
||||
|
||||
[dependencies.leo-ast]
|
||||
path = "../ast"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-imports]
|
||||
path = "../imports"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-input]
|
||||
path = "../input"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-package]
|
||||
path = "../package"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-state]
|
||||
path = "../state"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-asg]
|
||||
path = "../asg"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-parser]
|
||||
path = "../parser"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.leo-asg-passes]
|
||||
path = "../asg-passes"
|
||||
version = "1.2.3"
|
||||
version = "1.3.0"
|
||||
|
||||
[dependencies.snarkvm-curves]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-fields]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-dpc]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-gadgets]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-r1cs]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-utilities]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
|
||||
[dependencies.bincode]
|
||||
version = "1.3"
|
||||
@ -111,9 +111,12 @@ version = "0.3"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.snarkvm-algorithms]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.tempfile]
|
||||
version = "3.0.4"
|
||||
|
||||
[features]
|
||||
default = [ ]
|
||||
ci_skip = [ "leo-ast/ci_skip" ]
|
||||
|
@ -24,10 +24,9 @@ use crate::{
|
||||
OutputBytes,
|
||||
OutputFile,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
pub use leo_asg::{new_context, AsgContext as Context, AsgContext};
|
||||
use leo_asg::{Asg, AsgPass, FormattedError, Program as AsgProgram};
|
||||
use leo_ast::{Input, LeoError, MainInput, Program as AstProgram};
|
||||
use leo_ast::{Input, MainInput, Program as AstProgram};
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
use leo_parser::parse_ast;
|
||||
@ -39,11 +38,9 @@ use snarkvm_r1cs::{ConstraintSynthesizer, ConstraintSystem, SynthesisError};
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fs,
|
||||
marker::PhantomData,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
thread_local! {
|
||||
@ -68,7 +65,6 @@ pub struct Compiler<'a, F: PrimeField, G: GroupType<F>> {
|
||||
program_input: Input,
|
||||
context: AsgContext<'a>,
|
||||
asg: Option<AsgProgram<'a>>,
|
||||
file_contents: RefCell<IndexMap<String, Rc<Vec<String>>>>,
|
||||
options: CompilerOptions,
|
||||
_engine: PhantomData<F>,
|
||||
_group: PhantomData<G>,
|
||||
@ -94,7 +90,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
asg: None,
|
||||
context,
|
||||
options: options.unwrap_or_default(),
|
||||
file_contents: RefCell::new(IndexMap::new()),
|
||||
_engine: PhantomData,
|
||||
_group: PhantomData,
|
||||
}
|
||||
@ -203,20 +198,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_content(&self, path: &str) -> Result<Rc<Vec<String>>, CompilerError> {
|
||||
let mut file_contents = self.file_contents.borrow_mut();
|
||||
if file_contents.contains_key(path) {
|
||||
// using this pattern because of mutable reference in branch below
|
||||
Ok(file_contents.get(path).unwrap().clone())
|
||||
} else {
|
||||
let content = fs::read_to_string(path).map_err(|e| CompilerError::FileReadError(PathBuf::from(path), e))?;
|
||||
|
||||
let content = Rc::new(content.lines().map(|x| x.to_string()).collect::<Vec<String>>());
|
||||
file_contents.insert(path.to_string(), content);
|
||||
Ok(file_contents.get(path).unwrap().clone())
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Parses and stores the main program file, constructs a syntax tree, and generates a program.
|
||||
///
|
||||
@ -227,31 +208,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
let content = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::FileReadError(self.main_file_path.clone(), e))?;
|
||||
|
||||
self.parse_program_from_string(&content).map_err(|mut error| {
|
||||
// Return a formatted error with file path and code text.
|
||||
|
||||
let path = match error.get_path().map(|x| x.to_string()) {
|
||||
// Get the file path if it exists
|
||||
Some(path) => path,
|
||||
|
||||
// If a file path does not exist, then insert the main file path.
|
||||
None => match self.main_file_path.clone().into_os_string().into_string() {
|
||||
Err(e) => return CompilerError::FileStringError(e),
|
||||
Ok(path) => path,
|
||||
},
|
||||
};
|
||||
|
||||
// Resolve the code text using the file path.
|
||||
let content = match self.resolve_content(&path) {
|
||||
Err(e) => return e,
|
||||
Ok(x) => x,
|
||||
};
|
||||
|
||||
// Update the formatted error.
|
||||
error.set_path(&path, &content[..]);
|
||||
|
||||
error
|
||||
})
|
||||
self.parse_program_from_string(&content)
|
||||
}
|
||||
|
||||
///
|
||||
@ -260,11 +217,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
///
|
||||
pub fn parse_program_from_string(&mut self, program_string: &str) -> Result<(), CompilerError> {
|
||||
// Use the parser to construct the abstract syntax tree (ast).
|
||||
let lines = program_string.lines().map(|x| x.to_string()).collect();
|
||||
self.file_contents.borrow_mut().insert(
|
||||
self.main_file_path.to_str().map(|x| x.to_string()).unwrap_or_default(),
|
||||
Rc::new(lines),
|
||||
);
|
||||
|
||||
let mut ast = parse_ast(self.main_file_path.to_str().unwrap_or_default(), program_string)?;
|
||||
// Preform compiler optimization via canonicalizing AST if its enabled.
|
||||
@ -316,28 +268,14 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
/// Synthesizes the circuit with program input to verify correctness.
|
||||
///
|
||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(&self, cs: &mut CS) -> Result<OutputBytes, CompilerError> {
|
||||
generate_constraints::<F, G, CS>(cs, &self.asg.as_ref().unwrap(), &self.program_input).map_err(|mut error| {
|
||||
if let Some(path) = error.get_path().map(|x| x.to_string()) {
|
||||
let content = match self.resolve_content(&path) {
|
||||
Err(e) => return e,
|
||||
Ok(x) => x,
|
||||
};
|
||||
error.set_path(&path, &content[..]);
|
||||
}
|
||||
error
|
||||
})
|
||||
generate_constraints::<F, G, CS>(cs, &self.asg.as_ref().unwrap(), &self.program_input)
|
||||
}
|
||||
|
||||
///
|
||||
/// Synthesizes the circuit for test functions with program input.
|
||||
///
|
||||
pub fn compile_test_constraints(self, input_pairs: InputPairs) -> Result<(u32, u32), CompilerError> {
|
||||
generate_test_constraints::<F, G>(
|
||||
&self.asg.as_ref().unwrap(),
|
||||
input_pairs,
|
||||
&self.main_file_path,
|
||||
&self.output_directory,
|
||||
)
|
||||
generate_test_constraints::<F, G>(&self.asg.as_ref().unwrap(), input_pairs, &self.output_directory)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{errors::CompilerError, ConstrainedProgram, GroupType, OutputBytes, OutputFile};
|
||||
use leo_asg::Program;
|
||||
use leo_ast::{Input, LeoError};
|
||||
use leo_ast::Input;
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
|
||||
@ -50,7 +50,6 @@ pub fn generate_constraints<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSy
|
||||
pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
program: &Program<'a>,
|
||||
input: InputPairs,
|
||||
main_file_path: &Path,
|
||||
output_directory: &Path,
|
||||
) -> Result<(u32, u32), CompilerError> {
|
||||
let mut resolved_program = ConstrainedProgram::<F, G>::new(program.clone());
|
||||
@ -78,7 +77,7 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
let input_file = function
|
||||
.annotations
|
||||
.iter()
|
||||
.find(|x| x.name.name == "test")
|
||||
.find(|x| x.name.name.as_ref() == "test")
|
||||
.unwrap()
|
||||
.arguments
|
||||
.get(0);
|
||||
@ -87,11 +86,11 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
Some(file_id) => {
|
||||
let file_name = file_id.clone();
|
||||
|
||||
output_file_name = file_name.clone();
|
||||
output_file_name = file_name.to_string();
|
||||
|
||||
match input.pairs.get(&file_name) {
|
||||
match input.pairs.get(file_name.as_ref()) {
|
||||
Some(pair) => pair.to_owned(),
|
||||
None => return Err(CompilerError::InvalidTestContext(file_name)),
|
||||
None => return Err(CompilerError::InvalidTestContext(file_name.to_string())),
|
||||
}
|
||||
}
|
||||
None => default.ok_or(CompilerError::NoTestInput)?,
|
||||
@ -135,8 +134,7 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
}
|
||||
(false, _) => {
|
||||
// Set file location of error
|
||||
let mut error = result.unwrap_err();
|
||||
error.set_path(main_file_path.to_str().unwrap_or_default(), &[]);
|
||||
let error = result.unwrap_err();
|
||||
|
||||
tracing::error!("{} failed due to error\n\n{}\n", full_test_name, error);
|
||||
|
||||
|
@ -14,16 +14,14 @@
|
||||
// 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::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError};
|
||||
use crate::errors::FunctionError;
|
||||
use leo_asg::{AsgConvertError, FormattedError};
|
||||
use leo_ast::{CanonicalizeError, LeoError};
|
||||
use leo_imports::ImportParserError;
|
||||
use leo_input::InputParserError;
|
||||
use leo_parser::SyntaxError;
|
||||
use leo_state::LocalDataVerificationError;
|
||||
|
||||
use bincode::Error as SerdeError;
|
||||
use std::{ffi::OsString, path::PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CompilerError {
|
||||
@ -33,12 +31,6 @@ pub enum CompilerError {
|
||||
#[error("{}", _0)]
|
||||
AsgPassError(FormattedError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ImportError(#[from] ImportError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ImportParserError(#[from] ImportParserError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
InputParserError(#[from] InputParserError),
|
||||
|
||||
@ -51,30 +43,15 @@ pub enum CompilerError {
|
||||
#[error("Cannot read from the provided file path '{:?}': {}", _0, _1)]
|
||||
FileReadError(PathBuf, std::io::Error),
|
||||
|
||||
#[error("Cannot parse file string `{:?}`", _0)]
|
||||
FileStringError(OsString),
|
||||
|
||||
#[error("{}", _0)]
|
||||
LocalDataVerificationError(#[from] LocalDataVerificationError),
|
||||
|
||||
#[error("`main` function not found")]
|
||||
NoMain,
|
||||
|
||||
#[error("`main` must be a function")]
|
||||
NoMainFunction,
|
||||
|
||||
#[error("Failed to find input files for the current test")]
|
||||
NoTestInput,
|
||||
|
||||
#[error("{}", _0)]
|
||||
OutputError(#[from] OutputFileError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
OutputStringError(#[from] OutputBytesError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SerdeError(#[from] SerdeError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
AsgConvertError(#[from] AsgConvertError),
|
||||
|
||||
@ -82,30 +59,4 @@ pub enum CompilerError {
|
||||
CanonicalizeError(#[from] CanonicalizeError),
|
||||
}
|
||||
|
||||
impl LeoError for CompilerError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
CompilerError::SyntaxError(error) => error.get_path(),
|
||||
CompilerError::ImportError(error) => error.get_path(),
|
||||
CompilerError::ImportParserError(error) => error.get_path(),
|
||||
CompilerError::InputParserError(error) => error.get_path(),
|
||||
CompilerError::FunctionError(error) => error.get_path(),
|
||||
CompilerError::OutputStringError(error) => error.get_path(),
|
||||
CompilerError::AsgConvertError(error) => error.get_path(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
CompilerError::SyntaxError(error) => error.set_path(path, contents),
|
||||
CompilerError::ImportError(error) => error.set_path(path, contents),
|
||||
CompilerError::ImportParserError(error) => error.set_path(path, contents),
|
||||
CompilerError::InputParserError(error) => error.set_path(path, contents),
|
||||
CompilerError::FunctionError(error) => error.set_path(path, contents),
|
||||
CompilerError::OutputStringError(error) => error.set_path(path, contents),
|
||||
CompilerError::AsgConvertError(error) => error.set_path(path, contents),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for CompilerError {}
|
||||
|
@ -26,21 +26,7 @@ pub enum ConsoleError {
|
||||
Expression(#[from] ExpressionError),
|
||||
}
|
||||
|
||||
impl LeoError for ConsoleError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ConsoleError::Error(error) => error.get_path(),
|
||||
ConsoleError::Expression(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ConsoleError::Error(error) => error.set_path(path, contents),
|
||||
ConsoleError::Expression(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for ConsoleError {}
|
||||
|
||||
impl ConsoleError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::errors::{AddressError, BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError};
|
||||
use leo_ast::{ArrayDimensions, FormattedError, Identifier, LeoError, PositiveNumber, Span};
|
||||
use leo_ast::{FormattedError, Identifier, LeoError, Span};
|
||||
use snarkvm_r1cs::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -45,33 +45,7 @@ pub enum ExpressionError {
|
||||
ValueError(#[from] ValueError),
|
||||
}
|
||||
|
||||
impl LeoError for ExpressionError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ExpressionError::AddressError(error) => error.get_path(),
|
||||
ExpressionError::BooleanError(error) => error.get_path(),
|
||||
ExpressionError::Error(error) => error.get_path(),
|
||||
ExpressionError::FieldError(error) => error.get_path(),
|
||||
ExpressionError::FunctionError(error) => error.get_path(),
|
||||
ExpressionError::GroupError(error) => error.get_path(),
|
||||
ExpressionError::IntegerError(error) => error.get_path(),
|
||||
ExpressionError::ValueError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ExpressionError::AddressError(error) => error.set_path(path, contents),
|
||||
ExpressionError::BooleanError(error) => error.set_path(path, contents),
|
||||
ExpressionError::Error(error) => error.set_path(path, contents),
|
||||
ExpressionError::FieldError(error) => error.set_path(path, contents),
|
||||
ExpressionError::FunctionError(error) => error.set_path(path, contents),
|
||||
ExpressionError::GroupError(error) => error.set_path(path, contents),
|
||||
ExpressionError::IntegerError(error) => error.set_path(path, contents),
|
||||
ExpressionError::ValueError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for ExpressionError {}
|
||||
|
||||
impl ExpressionError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
@ -93,6 +67,18 @@ impl ExpressionError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn array_length_out_of_bounds(span: &Span) -> Self {
|
||||
let message = "array length cannot be >= 2^32".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn array_index_out_of_legal_bounds(span: &Span) -> Self {
|
||||
let message = "array index cannot be >= 2^32".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn conditional_boolean(actual: String, span: &Span) -> Self {
|
||||
let message = format!("if, else conditional must resolve to a boolean, found `{}`", actual);
|
||||
|
||||
@ -111,26 +97,20 @@ impl ExpressionError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn index_out_of_bounds(index: usize, span: &Span) -> Self {
|
||||
pub fn tuple_index_out_of_bounds(index: usize, span: &Span) -> Self {
|
||||
let message = format!("cannot access index {} of tuple out of bounds", index);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_dimensions(expected: &ArrayDimensions, actual: &ArrayDimensions, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"expected array dimensions {}, found array dimensions {}",
|
||||
expected, actual
|
||||
);
|
||||
pub fn array_index_out_of_bounds(index: usize, span: &Span) -> Self {
|
||||
let message = format!("cannot access index {} of array out of bounds", index);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_first_dimension(expected: &PositiveNumber, actual: &PositiveNumber, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"expected array dimension {}, found array dimension {}",
|
||||
expected, actual
|
||||
);
|
||||
pub fn array_invalid_slice_length(span: &Span) -> Self {
|
||||
let message = "illegal length of slice".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
@ -147,48 +127,18 @@ impl ExpressionError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_spread(actual: String, span: &Span) -> Self {
|
||||
let message = format!("spread should contain an array, found `{}`", actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_member_access(member: String, span: &Span) -> Self {
|
||||
let message = format!("non-static member `{}` must be accessed using `.` syntax", member);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_static_access(member: String, span: &Span) -> Self {
|
||||
let message = format!("static member `{}` must be accessed using `::` syntax", member);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn function_no_return(function: String, span: &Span) -> Self {
|
||||
let message = format!("inline function call to `{}` did not return", function);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn self_keyword(span: &Span) -> Self {
|
||||
let message = "cannot call keyword `Self` outside of a circuit function".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn undefined_array(actual: String, span: &Span) -> Self {
|
||||
let message = format!("array `{}` must be declared before it is used in an expression", actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn undefined_tuple(actual: String, span: &Span) -> Self {
|
||||
let message = format!("tuple `{}` must be declared before it is used in an expression", actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn undefined_circuit(actual: String, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"circuit `{}` must be declared before it is used in an expression",
|
||||
@ -198,21 +148,6 @@ impl ExpressionError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn undefined_first_dimension(span: &Span) -> Self {
|
||||
let message = "the first dimension of the array must be a number".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn undefined_function(function: String, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"function `{}` must be declared before it is used in an inline expression",
|
||||
function
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn undefined_identifier(identifier: Identifier) -> Self {
|
||||
let message = format!("Cannot find value `{}` in this scope", identifier.name);
|
||||
|
||||
@ -224,22 +159,4 @@ impl ExpressionError {
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn undefined_static_access(circuit: String, member: String, span: &Span) -> Self {
|
||||
let message = format!("Circuit `{}` has no static member `{}`", circuit, member);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn unexpected_array(expected: String, span: &Span) -> Self {
|
||||
let message = format!("expected type `{}`, found array with elements", expected);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn unexpected_tuple(expected: String, actual: String, span: &Span) -> Self {
|
||||
let message = format!("expected type `{}`, found tuple with values `{}`", expected, actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
}
|
||||
|
@ -64,39 +64,7 @@ pub enum FunctionError {
|
||||
ImportASGError(#[from] AsgConvertError),
|
||||
}
|
||||
|
||||
impl LeoError for FunctionError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
FunctionError::AddressError(error) => error.get_path(),
|
||||
FunctionError::BooleanError(error) => error.get_path(),
|
||||
FunctionError::ExpressionError(error) => error.get_path(),
|
||||
FunctionError::Error(error) => error.get_path(),
|
||||
FunctionError::FieldError(error) => error.get_path(),
|
||||
FunctionError::GroupError(error) => error.get_path(),
|
||||
FunctionError::IntegerError(error) => error.get_path(),
|
||||
FunctionError::OutputStringError(error) => error.get_path(),
|
||||
FunctionError::StatementError(error) => error.get_path(),
|
||||
FunctionError::ValueError(error) => error.get_path(),
|
||||
FunctionError::ImportASGError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
FunctionError::AddressError(error) => error.set_path(path, contents),
|
||||
FunctionError::BooleanError(error) => error.set_path(path, contents),
|
||||
FunctionError::ExpressionError(error) => error.set_path(path, contents),
|
||||
FunctionError::Error(error) => error.set_path(path, contents),
|
||||
FunctionError::FieldError(error) => error.set_path(path, contents),
|
||||
FunctionError::GroupError(error) => error.set_path(path, contents),
|
||||
FunctionError::IntegerError(error) => error.set_path(path, contents),
|
||||
FunctionError::OutputStringError(error) => error.set_path(path, contents),
|
||||
FunctionError::StatementError(error) => error.set_path(path, contents),
|
||||
FunctionError::ValueError(error) => error.set_path(path, contents),
|
||||
FunctionError::ImportASGError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for FunctionError {}
|
||||
|
||||
impl FunctionError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
@ -160,18 +128,6 @@ impl FunctionError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn return_arguments_length(expected: usize, actual: usize, span: &Span) -> Self {
|
||||
let message = format!("function expected {} returns, found {} returns", expected, actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn return_argument_type(expected: String, actual: String, span: &Span) -> Self {
|
||||
let message = format!("Expected function return type `{}`, found `{}`", expected, actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn input_not_found(expected: String, span: &Span) -> Self {
|
||||
let message = format!("main function input {} not found", expected);
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_ast::{FormattedError, Identifier, ImportSymbol, LeoError, Span};
|
||||
use leo_ast::{FormattedError, LeoError};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ImportError {
|
||||
@ -22,38 +22,4 @@ pub enum ImportError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for ImportError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ImportError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ImportError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ImportError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
ImportError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
|
||||
pub fn unknown_package(identifier: Identifier) -> Self {
|
||||
let message = format!(
|
||||
"cannot find imported package `{}` in source files or import directory",
|
||||
identifier.name
|
||||
);
|
||||
|
||||
Self::new_from_span(message, &identifier.span)
|
||||
}
|
||||
|
||||
pub fn unknown_symbol(symbol: ImportSymbol, file: String) -> Self {
|
||||
let message = format!("cannot find imported symbol `{}` in imported file `{}`", symbol, file);
|
||||
let error = FormattedError::new_from_span(message, &symbol.span);
|
||||
|
||||
ImportError::Error(error)
|
||||
}
|
||||
}
|
||||
impl LeoError for ImportError {}
|
||||
|
@ -30,23 +30,7 @@ pub enum OutputBytesError {
|
||||
AsgConvertError(#[from] AsgConvertError),
|
||||
}
|
||||
|
||||
impl LeoError for OutputBytesError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
OutputBytesError::Error(error) => error.get_path(),
|
||||
OutputBytesError::ValueError(error) => error.get_path(),
|
||||
OutputBytesError::AsgConvertError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
OutputBytesError::Error(error) => error.set_path(path, contents),
|
||||
OutputBytesError::ValueError(error) => error.set_path(path, contents),
|
||||
OutputBytesError::AsgConvertError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for OutputBytesError {}
|
||||
|
||||
impl OutputBytesError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -21,9 +21,6 @@ pub enum OutputFileError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
|
@ -42,45 +42,21 @@ pub enum StatementError {
|
||||
ValueError(#[from] ValueError),
|
||||
}
|
||||
|
||||
impl LeoError for StatementError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
StatementError::AddressError(error) => error.get_path(),
|
||||
StatementError::BooleanError(error) => error.get_path(),
|
||||
StatementError::Error(error) => error.get_path(),
|
||||
StatementError::ExpressionError(error) => error.get_path(),
|
||||
StatementError::IntegerError(error) => error.get_path(),
|
||||
StatementError::MacroError(error) => error.get_path(),
|
||||
StatementError::ValueError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
StatementError::AddressError(error) => error.set_path(path, contents),
|
||||
StatementError::BooleanError(error) => error.set_path(path, contents),
|
||||
StatementError::Error(error) => error.set_path(path, contents),
|
||||
StatementError::ExpressionError(error) => error.set_path(path, contents),
|
||||
StatementError::IntegerError(error) => error.set_path(path, contents),
|
||||
StatementError::MacroError(error) => error.set_path(path, contents),
|
||||
StatementError::ValueError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for StatementError {}
|
||||
|
||||
impl StatementError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
StatementError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
|
||||
pub fn arguments_type(expected: &Type, actual: &Type, span: &Span) -> Self {
|
||||
let message = format!("expected return argument type `{}`, found type `{}`", expected, actual);
|
||||
pub fn array_assign_index(span: &Span) -> Self {
|
||||
let message = "Cannot assign single index to array of values".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn array_assign_index(span: &Span) -> Self {
|
||||
let message = "Cannot assign single index to array of values".to_string();
|
||||
pub fn array_assign_index_const(span: &Span) -> Self {
|
||||
let message = "Cannot assign to non-const array index".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
@ -121,24 +97,6 @@ impl StatementError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn immutable_assign(name: String, span: &Span) -> Self {
|
||||
let message = format!("Cannot assign to immutable variable `{}`", name);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn immutable_circuit_function(name: String, span: &Span) -> Self {
|
||||
let message = format!("Cannot mutate circuit function, `{}`", name);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn immutable_circuit_variable(name: String, span: &Span) -> Self {
|
||||
let message = format!("Circuit member variable `{}` is immutable", name);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn indicator_calculation(name: String, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"Constraint system failed to evaluate branch selection indicator `{}`",
|
||||
@ -157,15 +115,6 @@ impl StatementError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_number_of_returns(expected: usize, actual: usize, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"Function return statement expected {} return values, found {} values",
|
||||
expected, actual
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn multiple_definition(value: String, span: &Span) -> Self {
|
||||
let message = format!("cannot assign multiple variables to a single value: {}", value,);
|
||||
|
||||
@ -212,12 +161,6 @@ impl StatementError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn tuple_type(type_: String, span: &Span) -> Self {
|
||||
let message = format!("Expected tuple type, found type `{}`", type_);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn unassigned(span: &Span) -> Self {
|
||||
let message = "Expected assignment of return values for expression".to_string();
|
||||
|
||||
@ -241,4 +184,10 @@ impl StatementError {
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn loop_index_const(span: &Span) -> Self {
|
||||
let message = "iteration range must be const".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
use leo_ast::{FormattedError, LeoError, Span};
|
||||
use snarkvm_dpc::AccountError;
|
||||
use snarkvm_r1cs::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AddressError {
|
||||
@ -24,19 +23,7 @@ pub enum AddressError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for AddressError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
AddressError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
AddressError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for AddressError {}
|
||||
|
||||
impl AddressError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
@ -49,21 +36,6 @@ impl AddressError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn cannot_enforce(operation: String, error: SynthesisError, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"the address operation `{:?}` failed due to the synthesis error `{}`",
|
||||
operation, error,
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn cannot_evaluate(operation: String, span: &Span) -> Self {
|
||||
let message = format!("no implementation found for `{}`", operation);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_address(actual: String, span: &Span) -> Self {
|
||||
let message = format!("expected address input type, found `{}`", actual);
|
||||
|
||||
|
@ -23,19 +23,7 @@ pub enum BooleanError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for BooleanError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
BooleanError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
BooleanError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for BooleanError {}
|
||||
|
||||
impl BooleanError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -23,19 +23,7 @@ pub enum FieldError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for FieldError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
FieldError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
FieldError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for FieldError {}
|
||||
|
||||
impl FieldError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
@ -74,10 +62,4 @@ impl FieldError {
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn synthesis_error(error: SynthesisError, span: &Span) -> Self {
|
||||
let message = format!("compilation failed due to field synthesis error `{:?}`", error);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
}
|
||||
|
@ -23,19 +23,7 @@ pub enum GroupError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for GroupError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
GroupError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
GroupError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for GroupError {}
|
||||
|
||||
impl GroupError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -14,9 +14,9 @@
|
||||
// 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 leo_ast::{FormattedError, IntegerType, LeoError, Span, Type};
|
||||
use leo_ast::{FormattedError, LeoError, Span};
|
||||
|
||||
use snarkvm_gadgets::errors::SignedIntegerError;
|
||||
use snarkvm_gadgets::errors::{SignedIntegerError, UnsignedIntegerError};
|
||||
use snarkvm_r1cs::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -25,44 +25,23 @@ pub enum IntegerError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for IntegerError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
IntegerError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
IntegerError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for IntegerError {}
|
||||
|
||||
impl IntegerError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
IntegerError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
|
||||
pub fn cannot_enforce(operation: String, error: SynthesisError, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"the integer operation `{}` failed due to the synthesis error `{:?}`",
|
||||
operation, error,
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn signed(error: SignedIntegerError, span: &Span) -> Self {
|
||||
let message = format!("integer operation failed due to the signed integer error `{:?}`", error);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn signed_error(operation: String, error: SignedIntegerError, span: &Span) -> Self {
|
||||
pub fn unsigned(error: UnsignedIntegerError, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"the integer operation `{}` failed due to the signed integer error `{:?}`",
|
||||
operation, error
|
||||
"integer operation failed due to the unsigned integer error `{:?}`",
|
||||
error
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
@ -89,32 +68,12 @@ impl IntegerError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_index(span: &Span) -> Self {
|
||||
let message =
|
||||
"index must be a constant value unsigned integer. allocated indices produce a circuit of unknown size"
|
||||
.to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_integer(actual: String, span: &Span) -> Self {
|
||||
let message = format!("failed to parse `{}` as expected integer type", actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_integer_type(expected: &IntegerType, actual: &IntegerType, span: &Span) -> Self {
|
||||
let message = format!("expected integer type {} found integer type {}", expected, actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_type(actual: &Type, span: &Span) -> Self {
|
||||
let message = format!("expected type {}, found type IntegerType", actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn missing_integer(expected: String, span: &Span) -> Self {
|
||||
let message = format!("expected integer input `{}` not found", expected);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::errors::{AddressError, BooleanError, FieldError, GroupError, IntegerError};
|
||||
use leo_ast::{FormattedError, LeoError, Span};
|
||||
use leo_ast::{FormattedError, LeoError};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ValueError {
|
||||
@ -38,44 +38,4 @@ pub enum ValueError {
|
||||
IntegerError(#[from] IntegerError),
|
||||
}
|
||||
|
||||
impl LeoError for ValueError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ValueError::AddressError(error) => error.get_path(),
|
||||
ValueError::BooleanError(error) => error.get_path(),
|
||||
ValueError::Error(error) => error.get_path(),
|
||||
ValueError::FieldError(error) => error.get_path(),
|
||||
ValueError::GroupError(error) => error.get_path(),
|
||||
ValueError::IntegerError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ValueError::AddressError(error) => error.set_path(path, contents),
|
||||
ValueError::BooleanError(error) => error.set_path(path, contents),
|
||||
ValueError::Error(error) => error.set_path(path, contents),
|
||||
ValueError::FieldError(error) => error.set_path(path, contents),
|
||||
ValueError::GroupError(error) => error.set_path(path, contents),
|
||||
ValueError::IntegerError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ValueError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
ValueError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
|
||||
pub fn implicit(value: String, span: &Span) -> Self {
|
||||
let message = format!("explicit type needed for `{}`", value);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn implicit_group(span: &Span) -> Self {
|
||||
let message = "group coordinates should be in (x, y)group format".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
}
|
||||
impl LeoError for ValueError {}
|
||||
|
@ -16,10 +16,24 @@
|
||||
|
||||
//! Enforces array access in a compiled Leo program.
|
||||
|
||||
use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::{Expression, Span};
|
||||
use std::convert::TryInto;
|
||||
|
||||
use crate::{
|
||||
arithmetic::*,
|
||||
errors::ExpressionError,
|
||||
program::ConstrainedProgram,
|
||||
relational::*,
|
||||
value::{ConstrainedValue, Integer},
|
||||
GroupType,
|
||||
};
|
||||
use leo_asg::{ConstInt, Expression, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::utilities::{
|
||||
boolean::Boolean,
|
||||
eq::{EqGadget, EvaluateEqGadget},
|
||||
select::CondSelectGadget,
|
||||
};
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
|
||||
impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
@ -31,13 +45,65 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
index: &'a Expression<'a>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, ExpressionError> {
|
||||
let array = match self.enforce_expression(cs, array)? {
|
||||
let mut array = match self.enforce_expression(cs, array)? {
|
||||
ConstrainedValue::Array(array) => array,
|
||||
value => return Err(ExpressionError::undefined_array(value.to_string(), span)),
|
||||
};
|
||||
|
||||
let index_resolved = self.enforce_index(cs, index, span)?;
|
||||
Ok(array[index_resolved].to_owned())
|
||||
if let Some(resolved) = index_resolved.to_usize() {
|
||||
if resolved >= array.len() {
|
||||
return Err(ExpressionError::array_index_out_of_bounds(resolved, span));
|
||||
}
|
||||
Ok(array[resolved].to_owned())
|
||||
} else {
|
||||
if array.is_empty() {
|
||||
return Err(ExpressionError::array_index_out_of_bounds(0, span));
|
||||
}
|
||||
{
|
||||
let array_len: u32 = array
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| ExpressionError::array_length_out_of_bounds(span))?;
|
||||
let bounds_check = evaluate_lt::<F, G, CS>(
|
||||
cs,
|
||||
ConstrainedValue::Integer(index_resolved.clone()),
|
||||
ConstrainedValue::Integer(Integer::new(&ConstInt::U32(array_len))),
|
||||
span,
|
||||
)?;
|
||||
let bounds_check = match bounds_check {
|
||||
ConstrainedValue::Boolean(b) => b,
|
||||
_ => unimplemented!("illegal non-Integer returned from lt"),
|
||||
};
|
||||
let namespace_string = format!("evaluate array access bounds {}:{}", span.line_start, span.col_start);
|
||||
let mut unique_namespace = cs.ns(|| namespace_string);
|
||||
bounds_check
|
||||
.enforce_equal(&mut unique_namespace, &Boolean::Constant(true))
|
||||
.map_err(|e| ExpressionError::cannot_enforce("array bounds check".to_string(), e, span))?;
|
||||
}
|
||||
|
||||
let mut current_value = array.pop().unwrap();
|
||||
for (i, item) in array.into_iter().enumerate() {
|
||||
let namespace_string = format!("evaluate array access eq {} {}:{}", i, span.line_start, span.col_start);
|
||||
let eq_namespace = cs.ns(|| namespace_string);
|
||||
|
||||
let index_bounded = i
|
||||
.try_into()
|
||||
.map_err(|_| ExpressionError::array_index_out_of_legal_bounds(span))?;
|
||||
let const_index = ConstInt::U32(index_bounded).cast_to(&index_resolved.get_type());
|
||||
let index_comparison = index_resolved
|
||||
.evaluate_equal(eq_namespace, &Integer::new(&const_index))
|
||||
.map_err(|_| ExpressionError::cannot_evaluate("==".to_string(), span))?;
|
||||
|
||||
let unique_namespace =
|
||||
cs.ns(|| format!("select array access {} {}:{}", i, span.line_start, span.col_start));
|
||||
let value =
|
||||
ConstrainedValue::conditionally_select(unique_namespace, &index_comparison, &item, ¤t_value)
|
||||
.map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, span))?;
|
||||
current_value = value;
|
||||
}
|
||||
Ok(current_value)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@ -47,6 +113,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
array: &'a Expression<'a>,
|
||||
left: Option<&'a Expression<'a>>,
|
||||
right: Option<&'a Expression<'a>>,
|
||||
length: usize,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, ExpressionError> {
|
||||
let array = match self.enforce_expression(cs, array)? {
|
||||
@ -56,12 +123,103 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
|
||||
let from_resolved = match left {
|
||||
Some(from_index) => self.enforce_index(cs, from_index, span)?,
|
||||
None => 0usize, // Array slice starts at index 0
|
||||
None => Integer::new(&ConstInt::U32(0)), // Array slice starts at index 0
|
||||
};
|
||||
let to_resolved = match right {
|
||||
Some(to_index) => self.enforce_index(cs, to_index, span)?,
|
||||
None => array.len(), // Array slice ends at array length
|
||||
None => {
|
||||
let index_bounded: u32 = array
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| ExpressionError::array_length_out_of_bounds(span))?;
|
||||
Integer::new(&ConstInt::U32(index_bounded))
|
||||
} // Array slice ends at array length
|
||||
};
|
||||
Ok(ConstrainedValue::Array(array[from_resolved..to_resolved].to_owned()))
|
||||
let const_dimensions = match (from_resolved.to_usize(), to_resolved.to_usize()) {
|
||||
(Some(from), Some(to)) => Some((from, to)),
|
||||
(Some(from), None) => Some((from, from + length)),
|
||||
(None, Some(to)) => Some((to - length, to)),
|
||||
(None, None) => None,
|
||||
};
|
||||
Ok(if let Some((left, right)) = const_dimensions {
|
||||
if right - left != length {
|
||||
return Err(ExpressionError::array_invalid_slice_length(span));
|
||||
}
|
||||
if right > array.len() {
|
||||
return Err(ExpressionError::array_index_out_of_bounds(right, span));
|
||||
}
|
||||
ConstrainedValue::Array(array[left..right].to_owned())
|
||||
} else {
|
||||
{
|
||||
let calc_len = enforce_sub::<F, G, _>(
|
||||
cs,
|
||||
ConstrainedValue::Integer(to_resolved.clone()),
|
||||
ConstrainedValue::Integer(from_resolved.clone()),
|
||||
span,
|
||||
)?;
|
||||
let calc_len = match calc_len {
|
||||
ConstrainedValue::Integer(i) => i,
|
||||
_ => unimplemented!("illegal non-Integer returned from sub"),
|
||||
};
|
||||
let namespace_string = format!(
|
||||
"evaluate array range access length check {}:{}",
|
||||
span.line_start, span.col_start
|
||||
);
|
||||
let mut unique_namespace = cs.ns(|| namespace_string);
|
||||
calc_len
|
||||
.enforce_equal(&mut unique_namespace, &Integer::new(&ConstInt::U32(length as u32)))
|
||||
.map_err(|e| ExpressionError::cannot_enforce("array length check".to_string(), e, span))?;
|
||||
}
|
||||
{
|
||||
let bounds_check = evaluate_le::<F, G, _>(
|
||||
cs,
|
||||
ConstrainedValue::Integer(to_resolved),
|
||||
ConstrainedValue::Integer(Integer::new(&ConstInt::U32(array.len() as u32))),
|
||||
span,
|
||||
)?;
|
||||
let bounds_check = match bounds_check {
|
||||
ConstrainedValue::Boolean(b) => b,
|
||||
_ => unimplemented!("illegal non-Integer returned from le"),
|
||||
};
|
||||
let namespace_string = format!(
|
||||
"evaluate array range access bounds {}:{}",
|
||||
span.line_start, span.col_start
|
||||
);
|
||||
let mut unique_namespace = cs.ns(|| namespace_string);
|
||||
bounds_check
|
||||
.enforce_equal(&mut unique_namespace, &Boolean::Constant(true))
|
||||
.map_err(|e| ExpressionError::cannot_enforce("array bounds check".to_string(), e, span))?;
|
||||
}
|
||||
let mut windows = array.windows(length);
|
||||
let mut result = ConstrainedValue::Array(vec![]);
|
||||
|
||||
for i in 0..length {
|
||||
let window = if let Some(window) = windows.next() {
|
||||
window
|
||||
} else {
|
||||
break;
|
||||
};
|
||||
let array_value = ConstrainedValue::Array(window.to_vec());
|
||||
let mut unique_namespace =
|
||||
cs.ns(|| format!("array index eq-check {} {}:{}", i, span.line_start, span.col_start));
|
||||
|
||||
let equality = evaluate_eq::<F, G, _>(
|
||||
&mut unique_namespace,
|
||||
ConstrainedValue::Integer(from_resolved.clone()),
|
||||
ConstrainedValue::Integer(Integer::new(&ConstInt::U32(i as u32))),
|
||||
span,
|
||||
)?;
|
||||
let equality = match equality {
|
||||
ConstrainedValue::Boolean(b) => b,
|
||||
_ => unimplemented!("unexpected non-Boolean for evaluate_eq"),
|
||||
};
|
||||
|
||||
let unique_namespace =
|
||||
unique_namespace.ns(|| format!("array index {} {}:{}", i, span.line_start, span.col_start));
|
||||
result = ConstrainedValue::conditionally_select(unique_namespace, &equality, &array_value, &result)
|
||||
.map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, span))?;
|
||||
}
|
||||
result
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
//! Enforces an array index expression in a compiled Leo program.
|
||||
|
||||
use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType, Integer};
|
||||
use leo_asg::{Expression, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
@ -28,9 +28,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
index: &'a Expression<'a>,
|
||||
span: &Span,
|
||||
) -> Result<usize, ExpressionError> {
|
||||
) -> Result<Integer, ExpressionError> {
|
||||
match self.enforce_expression(cs, index)? {
|
||||
ConstrainedValue::Integer(number) => Ok(number.to_usize(span)?),
|
||||
ConstrainedValue::Integer(number) => Ok(number),
|
||||
value => Err(ExpressionError::invalid_index(value.to_string(), span)),
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,15 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
left: &'a Expression<'a>,
|
||||
right: &'a Expression<'a>,
|
||||
) -> Result<ConstrainedValuePair<'a, F, G>, ExpressionError> {
|
||||
let resolved_left = self.enforce_expression(cs, left)?;
|
||||
let resolved_right = self.enforce_expression(cs, right)?;
|
||||
let resolved_left = {
|
||||
let mut left_namespace = cs.ns(|| "left".to_string());
|
||||
self.enforce_expression(&mut left_namespace, left)?
|
||||
};
|
||||
|
||||
let resolved_right = {
|
||||
let mut right_namespace = cs.ns(|| "right".to_string());
|
||||
self.enforce_expression(&mut right_namespace, right)?
|
||||
};
|
||||
|
||||
Ok((resolved_left, resolved_right))
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// type checking is already done in asg
|
||||
for (name, inner) in expr.values.iter() {
|
||||
let target = members
|
||||
.get(&name.name)
|
||||
.get(name.name.as_ref())
|
||||
.expect("illegal name in asg circuit init expression");
|
||||
match target {
|
||||
CircuitMember::Variable(_type_) => {
|
||||
|
@ -41,7 +41,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, ExpressionError> {
|
||||
Ok(match value {
|
||||
ConstValue::Address(value) => ConstrainedValue::Address(Address::constant(value.clone(), span)?),
|
||||
ConstValue::Address(value) => ConstrainedValue::Address(Address::constant(value.to_string(), span)?),
|
||||
ConstValue::Boolean(value) => ConstrainedValue::Boolean(Boolean::Constant(*value)),
|
||||
ConstValue::Field(value) => ConstrainedValue::Field(FieldType::constant(value.to_string(), span)?),
|
||||
ConstValue::Group(value) => ConstrainedValue::Group(G::constant(value, span)?),
|
||||
@ -133,9 +133,13 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
Expression::ArrayAccess(ArrayAccessExpression { array, index, .. }) => {
|
||||
self.enforce_array_access(cs, array.get(), index.get(), span)
|
||||
}
|
||||
Expression::ArrayRangeAccess(ArrayRangeAccessExpression { array, left, right, .. }) => {
|
||||
self.enforce_array_range_access(cs, array.get(), left.get(), right.get(), span)
|
||||
}
|
||||
Expression::ArrayRangeAccess(ArrayRangeAccessExpression {
|
||||
array,
|
||||
left,
|
||||
right,
|
||||
length,
|
||||
..
|
||||
}) => self.enforce_array_range_access(cs, array.get(), left.get(), right.get(), *length, span),
|
||||
|
||||
// Tuples
|
||||
Expression::TupleInit(TupleInitExpression { elements, .. }) => self.enforce_tuple(cs, &elements[..]),
|
||||
|
@ -40,7 +40,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// Check for out of bounds access.
|
||||
if index > tuple.len() - 1 {
|
||||
// probably safe to be a panic here
|
||||
return Err(ExpressionError::index_out_of_bounds(index, span));
|
||||
return Err(ExpressionError::tuple_index_out_of_bounds(index, span));
|
||||
}
|
||||
|
||||
Ok(tuple[index].to_owned())
|
||||
|
@ -37,19 +37,19 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// Create an identifier for each input variable
|
||||
|
||||
let registers_name = Identifier {
|
||||
name: REGISTERS_VARIABLE_NAME.to_string(),
|
||||
name: REGISTERS_VARIABLE_NAME.into(),
|
||||
span: span.clone(),
|
||||
};
|
||||
let record_name = Identifier {
|
||||
name: RECORD_VARIABLE_NAME.to_string(),
|
||||
name: RECORD_VARIABLE_NAME.into(),
|
||||
span: span.clone(),
|
||||
};
|
||||
let state_name = Identifier {
|
||||
name: STATE_VARIABLE_NAME.to_string(),
|
||||
name: STATE_VARIABLE_NAME.into(),
|
||||
span: span.clone(),
|
||||
};
|
||||
let state_leaf_name = Identifier {
|
||||
name: STATE_LEAF_VARIABLE_NAME.to_string(),
|
||||
name: STATE_LEAF_VARIABLE_NAME.into(),
|
||||
span: span.clone(),
|
||||
};
|
||||
|
||||
@ -72,7 +72,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let mut members = Vec::with_capacity(sections.len());
|
||||
|
||||
for (name, values) in sections {
|
||||
let sub_circuit = match expected_type.members.borrow().get(&name.name) {
|
||||
let sub_circuit = match expected_type.members.borrow().get(name.name.as_ref()) {
|
||||
Some(CircuitMember::Variable(Type::Circuit(circuit))) => *circuit,
|
||||
_ => panic!("illegal input type definition from asg"),
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// Allocate each section definition as a circuit member value
|
||||
for (parameter, option) in section.into_iter() {
|
||||
let section_members = expected_type.members.borrow();
|
||||
let expected_type = match section_members.get(¶meter.variable.name) {
|
||||
let expected_type = match section_members.get(parameter.variable.name.as_ref()) {
|
||||
Some(CircuitMember::Variable(inner)) => inner,
|
||||
_ => continue, // present, but unused
|
||||
};
|
||||
|
@ -62,11 +62,15 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let input_variable = input_variable.get().borrow();
|
||||
let name = input_variable.name.name.clone();
|
||||
|
||||
let input_value = match (input_variable.const_, input.get(&name), input.get_constant(&name)) {
|
||||
let input_value = match (
|
||||
input_variable.const_,
|
||||
input.get(&name),
|
||||
input.get_constant(name.as_ref()),
|
||||
) {
|
||||
// If variable is in both [main] and [constants] sections - error.
|
||||
(_, Some(_), Some(_)) => {
|
||||
return Err(FunctionError::double_input_declaration(
|
||||
name.clone(),
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
@ -89,21 +93,21 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// Function argument is const, input is not.
|
||||
(true, Some(_), None) => {
|
||||
return Err(FunctionError::expected_const_input(
|
||||
name.clone(),
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
// Input is const, function argument is not.
|
||||
(false, None, Some(_)) => {
|
||||
return Err(FunctionError::expected_non_const_input(
|
||||
name.clone(),
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
// When not found - Error out.
|
||||
(_, _, _) => {
|
||||
return Err(FunctionError::input_not_found(
|
||||
name.clone(),
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
|
@ -51,15 +51,31 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let start_index = left
|
||||
.get()
|
||||
.map(|start| self.enforce_index(cs, start, span))
|
||||
.transpose()?
|
||||
.map(|x| {
|
||||
x.to_usize()
|
||||
.ok_or_else(|| StatementError::array_assign_index_const(span))
|
||||
})
|
||||
.transpose()?;
|
||||
let stop_index = right
|
||||
.get()
|
||||
.map(|stop| self.enforce_index(cs, stop, span))
|
||||
.transpose()?
|
||||
.map(|x| {
|
||||
x.to_usize()
|
||||
.ok_or_else(|| StatementError::array_assign_index_const(span))
|
||||
})
|
||||
.transpose()?;
|
||||
let stop_index = right.get().map(|stop| self.enforce_index(cs, stop, span)).transpose()?;
|
||||
|
||||
output.push(ResolvedAssigneeAccess::ArrayRange(start_index, stop_index));
|
||||
Ok(inner)
|
||||
}
|
||||
Expression::ArrayAccess(ArrayAccessExpression { array, index, .. }) => {
|
||||
let inner = self.prepare_mut_access(cs, array.get(), span, output)?;
|
||||
let index = self.enforce_index(cs, index.get(), span)?;
|
||||
let index = self
|
||||
.enforce_index(cs, index.get(), span)?
|
||||
.to_usize()
|
||||
.ok_or_else(|| StatementError::array_assign_index_const(span))?;
|
||||
|
||||
output.push(ResolvedAssigneeAccess::ArrayIndex(index));
|
||||
Ok(inner)
|
||||
|
@ -42,19 +42,6 @@ impl OutputFile {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exists_at(&self, path: &Path) -> bool {
|
||||
let path = self.setup_file_path(path);
|
||||
path.exists()
|
||||
}
|
||||
|
||||
/// Reads the output register variables from the given file path if it exists.
|
||||
pub fn read_from(&self, path: &Path) -> Result<String, OutputFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
let output = fs::read_to_string(&path).map_err(|_| OutputFileError::FileReadError(path.into_owned()))?;
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
/// Writes output to a file.
|
||||
pub fn write(&self, path: &Path, bytes: &[u8]) -> Result<(), OutputFileError> {
|
||||
// create output file
|
||||
@ -88,3 +75,26 @@ impl OutputFile {
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_output_file {
|
||||
use crate::{OutputFile, OUTPUTS_DIRECTORY_NAME};
|
||||
use std::{error::Error, fs};
|
||||
|
||||
#[test]
|
||||
fn test_all() -> Result<(), Box<dyn Error>> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let file = OutputFile::new("test");
|
||||
let path = dir.path();
|
||||
|
||||
assert!(file.write(path, Default::default()).is_err());
|
||||
assert!(!(file.remove(path)?));
|
||||
|
||||
fs::create_dir(dir.path().join(OUTPUTS_DIRECTORY_NAME))?;
|
||||
|
||||
assert!(file.write(path, Default::default()).is_ok());
|
||||
assert!(file.remove(path)?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> CoreCircuit<'a, F, G> for Blake2s {
|
||||
mut arguments: Vec<ConstrainedValue<'a, F, G>>,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, ExpressionError> {
|
||||
assert_eq!(arguments.len(), 2); // asg enforced
|
||||
assert!(function.name.borrow().name == "hash"); // asg enforced
|
||||
assert!(function.name.borrow().name.as_ref() == "hash"); // asg enforced
|
||||
assert!(target.is_none()); // asg enforced
|
||||
let input = unwrap_argument(arguments.remove(1));
|
||||
let seed = unwrap_argument(arguments.remove(0));
|
||||
|
@ -45,19 +45,35 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let start_index = start
|
||||
.get()
|
||||
.map(|start| self.enforce_index(cs, start, &span))
|
||||
.transpose()?
|
||||
.map(|x| {
|
||||
x.to_usize()
|
||||
.ok_or_else(|| StatementError::array_assign_index_const(&span))
|
||||
})
|
||||
.transpose()?;
|
||||
let stop_index = stop
|
||||
.get()
|
||||
.map(|stop| self.enforce_index(cs, stop, &span))
|
||||
.transpose()?
|
||||
.map(|x| {
|
||||
x.to_usize()
|
||||
.ok_or_else(|| StatementError::array_assign_index_const(&span))
|
||||
})
|
||||
.transpose()?;
|
||||
let stop_index = stop.get().map(|stop| self.enforce_index(cs, stop, &span)).transpose()?;
|
||||
Ok(ResolvedAssigneeAccess::ArrayRange(start_index, stop_index))
|
||||
}
|
||||
AssignAccess::ArrayIndex(index) => {
|
||||
let index = self.enforce_index(cs, index.get(), &span)?;
|
||||
let index = self
|
||||
.enforce_index(cs, index.get(), &span)?
|
||||
.to_usize()
|
||||
.ok_or_else(|| StatementError::array_assign_index_const(&span))?;
|
||||
|
||||
Ok(ResolvedAssigneeAccess::ArrayIndex(index))
|
||||
}
|
||||
AssignAccess::Tuple(index) => Ok(ResolvedAssigneeAccess::Tuple(*index, span.clone())),
|
||||
AssignAccess::Member(identifier) => Ok(ResolvedAssigneeAccess::Member(identifier.clone())),
|
||||
})
|
||||
.collect::<Result<Vec<_>, crate::errors::ExpressionError>>()?;
|
||||
.collect::<Result<Vec<_>, StatementError>>()?;
|
||||
|
||||
let variable = assignee.target_variable.get().borrow();
|
||||
|
||||
|
@ -17,11 +17,13 @@
|
||||
//! Enforces an iteration statement in a compiled Leo program.
|
||||
|
||||
use crate::{
|
||||
errors::StatementError,
|
||||
program::ConstrainedProgram,
|
||||
value::ConstrainedValue,
|
||||
GroupType,
|
||||
IndicatorAndConstrainedValue,
|
||||
Integer,
|
||||
IntegerTrait,
|
||||
StatementResult,
|
||||
};
|
||||
use leo_asg::IterationStatement;
|
||||
@ -42,8 +44,14 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
|
||||
let span = statement.span.clone().unwrap_or_default();
|
||||
|
||||
let from = self.enforce_index(cs, statement.start.get(), &span)?;
|
||||
let to = self.enforce_index(cs, statement.stop.get(), &span)?;
|
||||
let from = self
|
||||
.enforce_index(cs, statement.start.get(), &span)?
|
||||
.to_usize()
|
||||
.ok_or_else(|| StatementError::loop_index_const(&span))?;
|
||||
let to = self
|
||||
.enforce_index(cs, statement.stop.get(), &span)?
|
||||
.to_usize()
|
||||
.ok_or_else(|| StatementError::loop_index_const(&span))?;
|
||||
|
||||
for i in from..to {
|
||||
// Store index in current function scope.
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a statement in a compiled Leo program.
|
||||
|
||||
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Statement;
|
||||
use leo_asg::{Node, Statement};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::traits::utilities::boolean::Boolean;
|
||||
@ -42,6 +42,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
statement: &'a Statement<'a>,
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<'a, F, G>>> {
|
||||
let mut results = vec![];
|
||||
let span = statement.span().cloned().unwrap_or_default();
|
||||
let mut cs = cs.ns(|| format!("statement {}:{}", span.line_start, span.col_start));
|
||||
let cs = &mut cs;
|
||||
|
||||
match statement {
|
||||
Statement::Return(statement) => {
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{errors::AddressError, ConstrainedValue, GroupType};
|
||||
use crate::{errors::AddressError, ConstrainedValue, GroupType, IntegerTrait};
|
||||
use leo_ast::{InputValue, Span};
|
||||
|
||||
use snarkvm_dpc::{account::AccountAddress, base_dpc::instantiated::Components};
|
||||
@ -24,7 +24,7 @@ use snarkvm_gadgets::traits::utilities::{
|
||||
boolean::Boolean,
|
||||
eq::{ConditionalEqGadget, EqGadget, EvaluateEqGadget},
|
||||
select::CondSelectGadget,
|
||||
uint::{UInt, UInt8},
|
||||
uint::UInt8,
|
||||
};
|
||||
use snarkvm_r1cs::{Assignment, ConstraintSystem, SynthesisError};
|
||||
use snarkvm_utilities::ToBytes;
|
||||
|
@ -28,10 +28,10 @@ use snarkvm_gadgets::traits::utilities::{
|
||||
eq::{ConditionalEqGadget, EqGadget, EvaluateEqGadget},
|
||||
int::{Int128, Int16, Int32, Int64, Int8},
|
||||
select::CondSelectGadget,
|
||||
uint::*,
|
||||
uint::{Sub as UIntSub, *},
|
||||
};
|
||||
use snarkvm_r1cs::{ConstraintSystem, SynthesisError};
|
||||
use std::fmt;
|
||||
use std::{convert::TryInto, fmt};
|
||||
|
||||
/// An integer type enum wrapping the integer value.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
|
||||
@ -83,7 +83,7 @@ impl Integer {
|
||||
|
||||
pub fn get_bits(&self) -> Vec<Boolean> {
|
||||
let integer = self;
|
||||
match_integer!(integer => integer.get_bits())
|
||||
match_integer!(integer => integer.to_bits_le())
|
||||
}
|
||||
|
||||
// pub fn get_bits_typed(&self) -> (Vec<Boolean>, IntegerType) {
|
||||
@ -111,15 +111,9 @@ impl Integer {
|
||||
match_integer!(integer => integer.get_value())
|
||||
}
|
||||
|
||||
pub fn to_usize(&self, span: &Span) -> Result<usize, IntegerError> {
|
||||
pub fn to_usize(&self) -> Option<usize> {
|
||||
let unsigned_integer = self;
|
||||
let value_option: Option<String> = match_unsigned_integer!(unsigned_integer => unsigned_integer.get_value());
|
||||
|
||||
let value = value_option.ok_or_else(|| IntegerError::invalid_index(span))?;
|
||||
let value_usize = value
|
||||
.parse::<usize>()
|
||||
.map_err(|_| IntegerError::invalid_integer(value, span))?;
|
||||
Ok(value_usize)
|
||||
match_unsigned_integer!(unsigned_integer => unsigned_integer.value.map(|num| num.try_into().ok()).flatten())
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> IntegerType {
|
||||
@ -146,148 +140,17 @@ impl Integer {
|
||||
span: &Span,
|
||||
) -> Result<Self, IntegerError> {
|
||||
Ok(match integer_type {
|
||||
IntegerType::U8 => {
|
||||
let u8_option = option.map(|s| {
|
||||
s.parse::<u8>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
IntegerType::U8 => allocate_type!(u8, UInt8, Integer::U8, cs, name, option, span),
|
||||
IntegerType::U16 => allocate_type!(u16, UInt16, Integer::U16, cs, name, option, span),
|
||||
IntegerType::U32 => allocate_type!(u32, UInt32, Integer::U32, cs, name, option, span),
|
||||
IntegerType::U64 => allocate_type!(u64, UInt64, Integer::U64, cs, name, option, span),
|
||||
IntegerType::U128 => allocate_type!(u128, UInt128, Integer::U128, cs, name, option, span),
|
||||
|
||||
let u8_result = UInt8::alloc(
|
||||
cs.ns(|| format!("`{}: u8` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| u8_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: u8", name), span))?;
|
||||
|
||||
Integer::U8(u8_result)
|
||||
}
|
||||
IntegerType::U16 => {
|
||||
let u16_option = option.map(|s| {
|
||||
s.parse::<u16>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let u16_result = UInt16::alloc(
|
||||
cs.ns(|| format!("`{}: u16` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| u16_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: u16", name), span))?;
|
||||
|
||||
Integer::U16(u16_result)
|
||||
}
|
||||
IntegerType::U32 => {
|
||||
let u32_option = option.map(|s| {
|
||||
s.parse::<u32>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let u32_result = UInt32::alloc(
|
||||
cs.ns(|| format!("`{}: u32` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| u32_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: u32", name), span))?;
|
||||
|
||||
Integer::U32(u32_result)
|
||||
}
|
||||
IntegerType::U64 => {
|
||||
let u64_option = option.map(|s| {
|
||||
s.parse::<u64>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let u64_result = UInt64::alloc(
|
||||
cs.ns(|| format!("`{}: u64` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| u64_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: u64", name), span))?;
|
||||
|
||||
Integer::U64(u64_result)
|
||||
}
|
||||
IntegerType::U128 => {
|
||||
let u128_option = option.map(|s| {
|
||||
s.parse::<u128>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let u128_result = UInt128::alloc(
|
||||
cs.ns(|| format!("`{}: u128` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| u128_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: u128", name), span))?;
|
||||
|
||||
Integer::U128(u128_result)
|
||||
}
|
||||
|
||||
IntegerType::I8 => {
|
||||
let i8_option = option.map(|s| {
|
||||
s.parse::<i8>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let i8_result = Int8::alloc(
|
||||
cs.ns(|| format!("`{}: i8` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| i8_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: i8", name), span))?;
|
||||
|
||||
Integer::I8(i8_result)
|
||||
}
|
||||
IntegerType::I16 => {
|
||||
let i16_option = option.map(|s| {
|
||||
s.parse::<i16>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let i16_result = Int16::alloc(
|
||||
cs.ns(|| format!("`{}: i16` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| i16_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: i16", name), span))?;
|
||||
|
||||
Integer::I16(i16_result)
|
||||
}
|
||||
IntegerType::I32 => {
|
||||
let i32_option = option.map(|s| {
|
||||
s.parse::<i32>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let i32_result = Int32::alloc(
|
||||
cs.ns(|| format!("`{}: i32` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| i32_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: i32", name), span))?;
|
||||
|
||||
Integer::I32(i32_result)
|
||||
}
|
||||
IntegerType::I64 => {
|
||||
let i64_option = option.map(|s| {
|
||||
s.parse::<i64>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let i64_result = Int64::alloc(
|
||||
cs.ns(|| format!("`{}: i64` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| i64_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: i64", name), span))?;
|
||||
|
||||
Integer::I64(i64_result)
|
||||
}
|
||||
IntegerType::I128 => {
|
||||
let i128_option = option.map(|s| {
|
||||
s.parse::<i128>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, span))
|
||||
.unwrap()
|
||||
});
|
||||
let i128_result = Int128::alloc(
|
||||
cs.ns(|| format!("`{}: i128` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| i128_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: i128", name), span))?;
|
||||
|
||||
Integer::I128(i128_result)
|
||||
}
|
||||
IntegerType::I8 => allocate_type!(i8, Int8, Integer::I8, cs, name, option, span),
|
||||
IntegerType::I16 => allocate_type!(i16, Int16, Integer::I16, cs, name, option, span),
|
||||
IntegerType::I32 => allocate_type!(i32, Int32, Integer::I32, cs, name, option, span),
|
||||
IntegerType::I64 => allocate_type!(i64, Int64, Integer::I64, cs, name, option, span),
|
||||
IntegerType::I128 => allocate_type!(i128, Int128, Integer::I128, cs, name, option, span),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -14,35 +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 snarkvm_gadgets::traits::utilities::{
|
||||
boolean::Boolean,
|
||||
int::{Int128, Int16, Int32, Int64, Int8},
|
||||
uint::{UInt128, UInt16, UInt32, UInt64, UInt8},
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait IntegerTrait: Sized + Clone + Debug {
|
||||
fn get_value(&self) -> Option<String>;
|
||||
|
||||
fn get_bits(&self) -> Vec<Boolean>;
|
||||
}
|
||||
|
||||
macro_rules! integer_trait_impl {
|
||||
($($gadget: ident)*) => ($(
|
||||
impl IntegerTrait for $gadget {
|
||||
fn get_value(&self) -> Option<String> {
|
||||
self.value.map(|num| num.to_string())
|
||||
}
|
||||
|
||||
fn get_bits(&self) -> Vec<Boolean> {
|
||||
self.bits.clone()
|
||||
}
|
||||
}
|
||||
|
||||
)*)
|
||||
}
|
||||
|
||||
integer_trait_impl!(UInt8 UInt16 UInt32 UInt64 UInt128 Int8 Int16 Int32 Int64 Int128);
|
||||
pub use snarkvm_gadgets::traits::utilities::integer::Integer as IntegerTrait;
|
||||
|
||||
/// Useful macros to avoid duplicating `match` constructions.
|
||||
#[macro_export]
|
||||
@ -119,19 +91,19 @@ macro_rules! match_integers_span {
|
||||
(($a: ident, $b: ident), $span: ident => $expression:expr) => {
|
||||
match ($a, $b) {
|
||||
(Integer::U8($a), Integer::U8($b)) => {
|
||||
Some(Integer::U8($expression.map_err(|e| IntegerError::synthesis(e, $span))?))
|
||||
Some(Integer::U8($expression.map_err(|e| IntegerError::unsigned(e, $span))?))
|
||||
}
|
||||
(Integer::U16($a), Integer::U16($b)) => {
|
||||
Some(Integer::U16($expression.map_err(|e| IntegerError::unsigned(e, $span))?))
|
||||
}
|
||||
(Integer::U32($a), Integer::U32($b)) => {
|
||||
Some(Integer::U32($expression.map_err(|e| IntegerError::unsigned(e, $span))?))
|
||||
}
|
||||
(Integer::U64($a), Integer::U64($b)) => {
|
||||
Some(Integer::U64($expression.map_err(|e| IntegerError::unsigned(e, $span))?))
|
||||
}
|
||||
(Integer::U16($a), Integer::U16($b)) => Some(Integer::U16(
|
||||
$expression.map_err(|e| IntegerError::synthesis(e, $span))?,
|
||||
)),
|
||||
(Integer::U32($a), Integer::U32($b)) => Some(Integer::U32(
|
||||
$expression.map_err(|e| IntegerError::synthesis(e, $span))?,
|
||||
)),
|
||||
(Integer::U64($a), Integer::U64($b)) => Some(Integer::U64(
|
||||
$expression.map_err(|e| IntegerError::synthesis(e, $span))?,
|
||||
)),
|
||||
(Integer::U128($a), Integer::U128($b)) => Some(Integer::U128(
|
||||
$expression.map_err(|e| IntegerError::synthesis(e, $span))?,
|
||||
$expression.map_err(|e| IntegerError::unsigned(e, $span))?,
|
||||
)),
|
||||
|
||||
(Integer::I8($a), Integer::I8($b)) => {
|
||||
@ -153,3 +125,29 @@ macro_rules! match_integers_span {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! allocate_type {
|
||||
($rust_ty:ty, $gadget_ty:ty, $leo_ty:path, $cs:expr, $name:expr, $option:expr, $span:expr) => {{
|
||||
let option = $option.map(|s| {
|
||||
s.parse::<$rust_ty>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, $span))
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
let result = <$gadget_ty>::alloc(
|
||||
$cs.ns(|| {
|
||||
format!(
|
||||
"`{}: {}` {}:{}",
|
||||
$name,
|
||||
stringify!($rust_ty),
|
||||
$span.line_start,
|
||||
$span.col_start
|
||||
)
|
||||
}),
|
||||
|| option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| IntegerError::missing_integer(format!("{}: {}", $name, stringify!($rust_ty)), $span))?;
|
||||
|
||||
$leo_ty(result)
|
||||
}};
|
||||
}
|
||||
|
@ -539,3 +539,178 @@ fn test_variable_slice_fail() {
|
||||
|
||||
expect_asg_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_index() {
|
||||
let program_string = r#"
|
||||
function main(i: u32) {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert(2 == b[i]);
|
||||
console.assert(3 == b[2]);
|
||||
}
|
||||
"#;
|
||||
let input_string = r#"
|
||||
[main]
|
||||
i: u32 = 1;
|
||||
"#;
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_index_bounds_fail() {
|
||||
let program_string = r#"
|
||||
function main(i: u32) {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert(2 == b[i]);
|
||||
}
|
||||
"#;
|
||||
let input_string = r#"
|
||||
[main]
|
||||
i: u32 = 4;
|
||||
"#;
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_const_array_index_bounds_fail() {
|
||||
let program_string = r#"
|
||||
function main() {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
const i: u32 = 4;
|
||||
|
||||
console.assert(2 == b[i]);
|
||||
}
|
||||
"#;
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_asg_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_range_index() {
|
||||
let program_string = r#"
|
||||
function main(i: u32) {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert([1u8, 2] == b[0..i]);
|
||||
console.assert([3u8, 4] == b[i..4]);
|
||||
}
|
||||
"#;
|
||||
let input_string = r#"
|
||||
[main]
|
||||
i: u32 = 2;
|
||||
"#;
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_range_index_dyn() {
|
||||
let program_string = r#"
|
||||
function main(i: u32) {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert([1u8, 2] == b[..i]);
|
||||
console.assert([3u8, 4] == b[i..]);
|
||||
}
|
||||
"#;
|
||||
let input_string = r#"
|
||||
[main]
|
||||
i: u32 = 2;
|
||||
"#;
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_range_index_full_dyn() {
|
||||
let program_string = r#"
|
||||
function main(i: u32, y: u32) {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert([3u8, 4] == b[i..y]);
|
||||
}
|
||||
"#;
|
||||
let input_string = r#"
|
||||
[main]
|
||||
i: u32 = 2;
|
||||
y: u32 = 4;
|
||||
"#;
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_range_index_out_of_bounds_fail() {
|
||||
let program_string = r#"
|
||||
function main() {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert([1, 2] == b[3..5]);
|
||||
}
|
||||
"#;
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_asg_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_range_index_invalid_bounds_fail() {
|
||||
let program_string = r#"
|
||||
function main() {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert([1, 2] == b[2..1]);
|
||||
}
|
||||
"#;
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_asg_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_range_index_full_dyn_resized_fail() {
|
||||
let program_string = r#"
|
||||
function main(i: u32, y: u32) {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert([3u8, 4] == b[i..y]);
|
||||
}
|
||||
"#;
|
||||
let input_string = r#"
|
||||
[main]
|
||||
i: u32 = 1;
|
||||
y: u32 = 4;
|
||||
"#;
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_range_index_full_dyn_bounds_fail() {
|
||||
let program_string = r#"
|
||||
function main(i: u32, y: u32) {
|
||||
let b = [1u8, 2, 3, 4];
|
||||
|
||||
console.assert([3u8, 4] == b[i..y]);
|
||||
}
|
||||
"#;
|
||||
let input_string = r#"
|
||||
[main]
|
||||
i: u32 = 3;
|
||||
y: u32 = 5;
|
||||
"#;
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
@ -4,15 +4,15 @@
|
||||
"imports": [],
|
||||
"circuits": {},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main(a: [group; (2, 1)]) {\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main(a: [group; (2, 1)]) {\\\"}\"}",
|
||||
"input": [
|
||||
{
|
||||
"Variable": {
|
||||
"identifier": "{\"name\":\"a\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":15,\\\"col_stop\\\":16,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"identifier": "{\"name\":\"a\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":15,\\\"col_stop\\\":16,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main(a: [group; (2, 1)]) {\\\"}\"}",
|
||||
"const_": false,
|
||||
"mutable": false,
|
||||
"mutable": true,
|
||||
"type_": {
|
||||
"Array": [
|
||||
{
|
||||
@ -37,7 +37,8 @@
|
||||
"line_stop": 1,
|
||||
"col_start": 15,
|
||||
"col_stop": 16,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main(a: [group; (2, 1)]) {"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,14 +53,15 @@
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"b\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"b\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let b = [true; (6, 5, 4, 3, 2)];\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -83,7 +85,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 12,
|
||||
"col_stop": 16,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -98,7 +101,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -112,7 +116,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -126,7 +131,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -140,7 +146,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -154,7 +161,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -163,7 +171,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 3,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -172,14 +181,15 @@
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"c\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"c\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let c: [u32; (1, 2)] = [0u32; (1, 2)];\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -218,7 +228,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 27,
|
||||
"col_stop": 31,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -233,7 +244,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 26,
|
||||
"col_stop": 40,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -247,7 +259,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 26,
|
||||
"col_stop": 40,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -256,7 +269,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 40,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -265,14 +279,15 @@
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"d\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"d\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let d = [0i8; (1)];\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 4,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let d = [0i8; (1)];"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -289,7 +304,8 @@
|
||||
"line_stop": 4,
|
||||
"col_start": 12,
|
||||
"col_stop": 15,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let d = [0i8; (1)];"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -304,7 +320,8 @@
|
||||
"line_stop": 4,
|
||||
"col_start": 11,
|
||||
"col_stop": 21,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let d = [0i8; (1)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -313,26 +330,29 @@
|
||||
"line_stop": 4,
|
||||
"col_start": 3,
|
||||
"col_stop": 21,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let d = [0i8; (1)];"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 35,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main(a: [group; (2, 1)]) {\n...\n}"
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 1,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main(a: [group; (2, 1)]) {\n...\n}\n\n\n\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,206 +1,218 @@
|
||||
{
|
||||
"name": "",
|
||||
"expected_input": [],
|
||||
"imports": [],
|
||||
"circuits": {
|
||||
"{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}": {
|
||||
"circuit_name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"CircuitVariable": [
|
||||
"{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\"}\"}",
|
||||
{
|
||||
"IntegerType": "U32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"CircuitFunction": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 5,
|
||||
"col_start": 9,
|
||||
"col_stop": 12,
|
||||
"path": ""
|
||||
}
|
||||
"name": "",
|
||||
"expected_input": [],
|
||||
"imports": [],
|
||||
"circuits": {
|
||||
"{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}": {
|
||||
"circuit_name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"CircuitVariable": [
|
||||
"{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" x: u32\\\"}\"}",
|
||||
{
|
||||
"IntegerType": "U32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"CircuitFunction": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" function new() -> Self {\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}"
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let new: Self = Self {\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 5,
|
||||
"col_start": 9,
|
||||
"col_stop": 12,
|
||||
"path": "",
|
||||
"content": " let new: Self = Self {"
|
||||
}
|
||||
],
|
||||
"type_": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"value": {
|
||||
"CircuitInit": {
|
||||
"name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":6,\\\"line_stop\\\":6,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U32",
|
||||
"1",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 10,
|
||||
"col_stop": 14,
|
||||
"path": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}"
|
||||
},
|
||||
"value": {
|
||||
"CircuitInit": {
|
||||
"name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":6,\\\"line_stop\\\":6,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" x: 1u32\\\"}\"}",
|
||||
"expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U32",
|
||||
"1",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 10,
|
||||
"col_stop": 14,
|
||||
"path": "",
|
||||
"content": " x: 1u32"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 21,
|
||||
"col_stop": 6,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 5,
|
||||
"col_stop": 6,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Return": {
|
||||
"expression": {
|
||||
"Identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":9,\\\"line_stop\\\":9,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"span": {
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 5,
|
||||
"col_stop": 15,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 10,
|
||||
"col_start": 26,
|
||||
"col_stop": 4,
|
||||
"path": ""
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 10,
|
||||
"col_start": 3,
|
||||
"col_stop": 4,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Tuple": []
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":7,\\\"col_stop\\\":10,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 7,
|
||||
"col_stop": 10,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"value": {
|
||||
"Call": {
|
||||
"function": {
|
||||
"CircuitStaticFunctionAccess": {
|
||||
"circuit": {
|
||||
"Identifier": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":18,\\\"col_stop\\\":21,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"name": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":23,\\\"col_stop\\\":26,\\\"path\\\":\\\"\\\"}\"}",
|
||||
],
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 18,
|
||||
"col_stop": 26,
|
||||
"path": ""
|
||||
"line_start": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 21,
|
||||
"col_stop": 6,
|
||||
"path": "",
|
||||
"content": " let new: Self = Self {\n...\n };"
|
||||
}
|
||||
}
|
||||
},
|
||||
"arguments": [],
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 18,
|
||||
"col_stop": 28,
|
||||
"path": ""
|
||||
"line_start": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 5,
|
||||
"col_stop": 6,
|
||||
"path": "",
|
||||
"content": " let new: Self = Self {\n...\n };"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 28,
|
||||
"path": ""
|
||||
{
|
||||
"Return": {
|
||||
"expression": {
|
||||
"Identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":9,\\\"line_stop\\\":9,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" return new\\\"}\"}"
|
||||
},
|
||||
"span": {
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 5,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " return new"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 10,
|
||||
"col_start": 26,
|
||||
"col_stop": 4,
|
||||
"path": "",
|
||||
"content": " function new() -> Self {\n...\n }"
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 10,
|
||||
"col_start": 3,
|
||||
"col_stop": 4,
|
||||
"path": "",
|
||||
"content": " function new() -> Self {\n...\n }\n\n\n\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main() {\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main() {\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Tuple": []
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":7,\\\"col_stop\\\":10,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo: Foo = Foo::new();\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 7,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " let foo: Foo = Foo::new();"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo: Foo = Foo::new();\\\"}\"}"
|
||||
},
|
||||
"value": {
|
||||
"Call": {
|
||||
"function": {
|
||||
"CircuitStaticFunctionAccess": {
|
||||
"circuit": {
|
||||
"Identifier": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":18,\\\"col_stop\\\":21,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo: Foo = Foo::new();\\\"}\"}"
|
||||
},
|
||||
"name": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":23,\\\"col_stop\\\":26,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo: Foo = Foo::new();\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 18,
|
||||
"col_stop": 26,
|
||||
"path": "",
|
||||
"content": " let foo: Foo = Foo::new();"
|
||||
}
|
||||
}
|
||||
},
|
||||
"arguments": [],
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 18,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " let foo: Foo = Foo::new();"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " let foo: Foo = Foo::new();"
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 15,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
}
|
||||
},
|
||||
],
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 15,
|
||||
"col_start": 1,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n}"
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 15,
|
||||
"col_start": 1,
|
||||
"col_stop": 2,
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,128 +1,867 @@
|
||||
{
|
||||
"name": "",
|
||||
"expected_input": [],
|
||||
"imports": [],
|
||||
"circuits": {},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Tuple": []
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
"name": "",
|
||||
"expected_input": [],
|
||||
"imports": [],
|
||||
"circuits": {
|
||||
"{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}": {
|
||||
"circuit_name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"CircuitVariable": [
|
||||
"{\"name\":\"f\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" f: u8,\\\"}\"}",
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":11,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 7,
|
||||
"col_stop": 12,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": null,
|
||||
"value": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U32",
|
||||
"10",
|
||||
{
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 15,
|
||||
"col_stop": 20,
|
||||
"path": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 3,
|
||||
"col_stop": 20,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"operation": "Assign",
|
||||
"assignee": {
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"accesses": [],
|
||||
"IntegerType": "U8"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main() {\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main() {\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Tuple": []
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let x = 10u32;\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 4,
|
||||
"path": ""
|
||||
"line_start": 5,
|
||||
"line_stop": 5,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": "",
|
||||
"content": " let x = 10u32;"
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
}
|
||||
],
|
||||
"type_": null,
|
||||
"value": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U32",
|
||||
"10",
|
||||
{
|
||||
"line_start": 5,
|
||||
"line_stop": 5,
|
||||
"col_start": 11,
|
||||
"col_stop": 16,
|
||||
"path": "",
|
||||
"content": " let x = 10u32;"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 5,
|
||||
"col_start": 3,
|
||||
"col_stop": 16,
|
||||
"path": "",
|
||||
"content": " let x = 10u32;"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"operation": "Assign",
|
||||
"assignee": {
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":6,\\\"line_stop\\\":6,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" x += 20;\\\"}\"}",
|
||||
"accesses": [],
|
||||
"span": {
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 3,
|
||||
"col_stop": 4,
|
||||
"path": "",
|
||||
"content": " x += 20;"
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"Identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":6,\\\"line_stop\\\":6,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" x += 20;\\\"}\"}"
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"20",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 8,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " x += 20;"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Add",
|
||||
"span": {
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 3,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " x += 20;"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 3,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " x += 20;"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Console": {
|
||||
"function": {
|
||||
"Assert": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"Identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\"}\"}"
|
||||
"Identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":7,\\\"line_stop\\\":7,\\\"col_start\\\":18,\\\"col_stop\\\":19,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" console.assert(x == 30u32);\\\"}\"}"
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"20",
|
||||
"Integer": [
|
||||
"U32",
|
||||
"30",
|
||||
{
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 8,
|
||||
"col_stop": 10,
|
||||
"path": ""
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 23,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " console.assert(x == 30u32);"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Add",
|
||||
"op": "Eq",
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 10,
|
||||
"path": ""
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 18,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " console.assert(x == 30u32);"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 10,
|
||||
"path": ""
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 3,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " console.assert(x == 30u32);"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":9,\\\"line_stop\\\":9,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let y = [1u8, 2u8];\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": "",
|
||||
"content": " let y = [1u8, 2u8];"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": null,
|
||||
"value": {
|
||||
"ArrayInline": {
|
||||
"elements": [
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"1",
|
||||
{
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 12,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " let y = [1u8, 2u8];"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"2",
|
||||
{
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 17,
|
||||
"col_stop": 20,
|
||||
"path": "",
|
||||
"content": " let y = [1u8, 2u8];"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 11,
|
||||
"col_stop": 21,
|
||||
"path": "",
|
||||
"content": " let y = [1u8, 2u8];"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 3,
|
||||
"col_stop": 21,
|
||||
"path": "",
|
||||
"content": " let y = [1u8, 2u8];"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"operation": "Assign",
|
||||
"assignee": {
|
||||
"identifier": "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":10,\\\"line_stop\\\":10,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" y[0] += 3u8;\\\"}\"}",
|
||||
"accesses": [
|
||||
{
|
||||
"ArrayIndex": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"0",
|
||||
{
|
||||
"line_start": 10,
|
||||
"line_stop": 10,
|
||||
"col_start": 5,
|
||||
"col_stop": 6,
|
||||
"path": "",
|
||||
"content": " y[0] += 3u8;"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 10,
|
||||
"line_stop": 10,
|
||||
"col_start": 3,
|
||||
"col_stop": 7,
|
||||
"path": "",
|
||||
"content": " y[0] += 3u8;"
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"ArrayAccess": {
|
||||
"array": {
|
||||
"Identifier": "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":10,\\\"line_stop\\\":10,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" y[0] += 3u8;\\\"}\"}"
|
||||
},
|
||||
"index": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"0",
|
||||
{
|
||||
"line_start": 10,
|
||||
"line_stop": 10,
|
||||
"col_start": 5,
|
||||
"col_stop": 6,
|
||||
"path": "",
|
||||
"content": " y[0] += 3u8;"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 10,
|
||||
"line_stop": 10,
|
||||
"col_start": 3,
|
||||
"col_stop": 14,
|
||||
"path": "",
|
||||
"content": " y[0] += 3u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"3",
|
||||
{
|
||||
"line_start": 10,
|
||||
"line_stop": 10,
|
||||
"col_start": 11,
|
||||
"col_stop": 14,
|
||||
"path": "",
|
||||
"content": " y[0] += 3u8;"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Add",
|
||||
"span": {
|
||||
"line_start": 10,
|
||||
"line_stop": 10,
|
||||
"col_start": 3,
|
||||
"col_stop": 14,
|
||||
"path": "",
|
||||
"content": " y[0] += 3u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 10,
|
||||
"line_stop": 10,
|
||||
"col_start": 3,
|
||||
"col_stop": 14,
|
||||
"path": "",
|
||||
"content": " y[0] += 3u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Console": {
|
||||
"function": {
|
||||
"Assert": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"ArrayAccess": {
|
||||
"array": {
|
||||
"Identifier": "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":11,\\\"line_stop\\\":11,\\\"col_start\\\":18,\\\"col_stop\\\":19,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" console.assert(y[0] == 4u8);\\\"}\"}"
|
||||
},
|
||||
"index": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"0",
|
||||
{
|
||||
"line_start": 11,
|
||||
"line_stop": 11,
|
||||
"col_start": 20,
|
||||
"col_stop": 21,
|
||||
"path": "",
|
||||
"content": " console.assert(y[0] == 4u8);"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 11,
|
||||
"line_stop": 11,
|
||||
"col_start": 18,
|
||||
"col_stop": 22,
|
||||
"path": "",
|
||||
"content": " console.assert(y[0] == 4u8);"
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"4",
|
||||
{
|
||||
"line_start": 11,
|
||||
"line_stop": 11,
|
||||
"col_start": 26,
|
||||
"col_stop": 29,
|
||||
"path": "",
|
||||
"content": " console.assert(y[0] == 4u8);"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Eq",
|
||||
"span": {
|
||||
"line_start": 11,
|
||||
"line_stop": 11,
|
||||
"col_start": 18,
|
||||
"col_stop": 29,
|
||||
"path": "",
|
||||
"content": " console.assert(y[0] == 4u8);"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 11,
|
||||
"line_stop": 11,
|
||||
"col_start": 3,
|
||||
"col_stop": 29,
|
||||
"path": "",
|
||||
"content": " console.assert(y[0] == 4u8);"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"z\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let z = (1u8, 2u8);\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 13,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": "",
|
||||
"content": " let z = (1u8, 2u8);"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": null,
|
||||
"value": {
|
||||
"TupleInit": {
|
||||
"elements": [
|
||||
{
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"1",
|
||||
{
|
||||
"line_start": 13,
|
||||
"line_stop": 13,
|
||||
"col_start": 12,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " let z = (1u8, 2u8);"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"2",
|
||||
{
|
||||
"line_start": 13,
|
||||
"line_stop": 13,
|
||||
"col_start": 17,
|
||||
"col_stop": 20,
|
||||
"path": "",
|
||||
"content": " let z = (1u8, 2u8);"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 13,
|
||||
"col_start": 11,
|
||||
"col_stop": 21,
|
||||
"path": "",
|
||||
"content": " let z = (1u8, 2u8);"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 13,
|
||||
"col_start": 3,
|
||||
"col_stop": 21,
|
||||
"path": "",
|
||||
"content": " let z = (1u8, 2u8);"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"operation": "Assign",
|
||||
"assignee": {
|
||||
"identifier": "{\"name\":\"z\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" z.1 += 3u8;\\\"}\"}",
|
||||
"accesses": [
|
||||
{
|
||||
"Tuple": [
|
||||
{
|
||||
"value": "1"
|
||||
},
|
||||
{
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 6,
|
||||
"path": "",
|
||||
"content": " z.1 += 3u8;"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 6,
|
||||
"path": "",
|
||||
"content": " z.1 += 3u8;"
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"TupleAccess": {
|
||||
"tuple": {
|
||||
"Identifier": "{\"name\":\"z\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" z.1 += 3u8;\\\"}\"}"
|
||||
},
|
||||
"index": {
|
||||
"value": "1"
|
||||
},
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 13,
|
||||
"path": "",
|
||||
"content": " z.1 += 3u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"3",
|
||||
{
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 10,
|
||||
"col_stop": 13,
|
||||
"path": "",
|
||||
"content": " z.1 += 3u8;"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Add",
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 13,
|
||||
"path": "",
|
||||
"content": " z.1 += 3u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 13,
|
||||
"path": "",
|
||||
"content": " z.1 += 3u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Console": {
|
||||
"function": {
|
||||
"Assert": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"TupleAccess": {
|
||||
"tuple": {
|
||||
"Identifier": "{\"name\":\"z\",\"span\":\"{\\\"line_start\\\":15,\\\"line_stop\\\":15,\\\"col_start\\\":18,\\\"col_stop\\\":19,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" console.assert(z.1 == 5u8);\\\"}\"}"
|
||||
},
|
||||
"index": {
|
||||
"value": "1"
|
||||
},
|
||||
"span": {
|
||||
"line_start": 15,
|
||||
"line_stop": 15,
|
||||
"col_start": 18,
|
||||
"col_stop": 21,
|
||||
"path": "",
|
||||
"content": " console.assert(z.1 == 5u8);"
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"5",
|
||||
{
|
||||
"line_start": 15,
|
||||
"line_stop": 15,
|
||||
"col_start": 25,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " console.assert(z.1 == 5u8);"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Eq",
|
||||
"span": {
|
||||
"line_start": 15,
|
||||
"line_stop": 15,
|
||||
"col_start": 18,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " console.assert(z.1 == 5u8);"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 15,
|
||||
"line_stop": 15,
|
||||
"col_start": 3,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " console.assert(z.1 == 5u8);"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"foo\",\"span\":\"{\\\"line_start\\\":17,\\\"line_stop\\\":17,\\\"col_start\\\":7,\\\"col_stop\\\":10,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo = Foo { f: 6u8 };\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 17,
|
||||
"line_stop": 17,
|
||||
"col_start": 7,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " let foo = Foo { f: 6u8 };"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": null,
|
||||
"value": {
|
||||
"CircuitInit": {
|
||||
"name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":17,\\\"line_stop\\\":17,\\\"col_start\\\":13,\\\"col_stop\\\":16,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo = Foo { f: 6u8 };\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"identifier": "{\"name\":\"f\",\"span\":\"{\\\"line_start\\\":17,\\\"line_stop\\\":17,\\\"col_start\\\":19,\\\"col_stop\\\":20,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo = Foo { f: 6u8 };\\\"}\"}",
|
||||
"expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"6",
|
||||
{
|
||||
"line_start": 17,
|
||||
"line_stop": 17,
|
||||
"col_start": 22,
|
||||
"col_stop": 25,
|
||||
"path": "",
|
||||
"content": " let foo = Foo { f: 6u8 };"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 17,
|
||||
"line_stop": 17,
|
||||
"col_start": 13,
|
||||
"col_stop": 27,
|
||||
"path": "",
|
||||
"content": " let foo = Foo { f: 6u8 };"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 17,
|
||||
"line_stop": 17,
|
||||
"col_start": 3,
|
||||
"col_stop": 27,
|
||||
"path": "",
|
||||
"content": " let foo = Foo { f: 6u8 };"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"operation": "Assign",
|
||||
"assignee": {
|
||||
"identifier": "{\"name\":\"foo\",\"span\":\"{\\\"line_start\\\":18,\\\"line_stop\\\":18,\\\"col_start\\\":3,\\\"col_stop\\\":6,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" foo.f += 2u8;\\\"}\"}",
|
||||
"accesses": [
|
||||
{
|
||||
"Member": "{\"name\":\"f\",\"span\":\"{\\\"line_start\\\":18,\\\"line_stop\\\":18,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" foo.f += 2u8;\\\"}\"}"
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 18,
|
||||
"line_stop": 18,
|
||||
"col_start": 3,
|
||||
"col_stop": 8,
|
||||
"path": "",
|
||||
"content": " foo.f += 2u8;"
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"CircuitMemberAccess": {
|
||||
"circuit": {
|
||||
"Identifier": "{\"name\":\"foo\",\"span\":\"{\\\"line_start\\\":18,\\\"line_stop\\\":18,\\\"col_start\\\":3,\\\"col_stop\\\":6,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" foo.f += 2u8;\\\"}\"}"
|
||||
},
|
||||
"name": "{\"name\":\"f\",\"span\":\"{\\\"line_start\\\":18,\\\"line_stop\\\":18,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" foo.f += 2u8;\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 18,
|
||||
"line_stop": 18,
|
||||
"col_start": 3,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " foo.f += 2u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"2",
|
||||
{
|
||||
"line_start": 18,
|
||||
"line_stop": 18,
|
||||
"col_start": 12,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " foo.f += 2u8;"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Add",
|
||||
"span": {
|
||||
"line_start": 18,
|
||||
"line_stop": 18,
|
||||
"col_start": 3,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " foo.f += 2u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 18,
|
||||
"line_stop": 18,
|
||||
"col_start": 3,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " foo.f += 2u8;"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Console": {
|
||||
"function": {
|
||||
"Assert": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"CircuitMemberAccess": {
|
||||
"circuit": {
|
||||
"Identifier": "{\"name\":\"foo\",\"span\":\"{\\\"line_start\\\":19,\\\"line_stop\\\":19,\\\"col_start\\\":18,\\\"col_stop\\\":21,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" console.assert(foo.f == 8u8);\\\"}\"}"
|
||||
},
|
||||
"name": "{\"name\":\"f\",\"span\":\"{\\\"line_start\\\":19,\\\"line_stop\\\":19,\\\"col_start\\\":22,\\\"col_stop\\\":23,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" console.assert(foo.f == 8u8);\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 19,
|
||||
"line_stop": 19,
|
||||
"col_start": 18,
|
||||
"col_stop": 23,
|
||||
"path": "",
|
||||
"content": " console.assert(foo.f == 8u8);"
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"8",
|
||||
{
|
||||
"line_start": 19,
|
||||
"line_stop": 19,
|
||||
"col_start": 27,
|
||||
"col_stop": 30,
|
||||
"path": "",
|
||||
"content": " console.assert(foo.f == 8u8);"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Eq",
|
||||
"span": {
|
||||
"line_start": 19,
|
||||
"line_stop": 19,
|
||||
"col_start": 18,
|
||||
"col_stop": 30,
|
||||
"path": "",
|
||||
"content": " console.assert(foo.f == 8u8);"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 19,
|
||||
"line_stop": 19,
|
||||
"col_start": 3,
|
||||
"col_stop": 30,
|
||||
"path": "",
|
||||
"content": " console.assert(foo.f == 8u8);"
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 4,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
}
|
||||
},
|
||||
],
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 4,
|
||||
"col_start": 1,
|
||||
"line_start": 4,
|
||||
"line_stop": 20,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n} "
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 20,
|
||||
"col_start": 1,
|
||||
"col_stop": 2,
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n} \n\n\n\n\n\n\n\n\n\n\n\n\n\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,20 @@
|
||||
circuit Foo {
|
||||
f: u8,
|
||||
}
|
||||
function main() {
|
||||
let x = 10u32;
|
||||
x += 20;
|
||||
console.assert(x == 30u32);
|
||||
|
||||
let y = [1u8, 2u8];
|
||||
y[0] += 3u8;
|
||||
console.assert(y[0] == 4u8);
|
||||
|
||||
let z = (1u8, 2u8);
|
||||
z.1 += 3u8;
|
||||
console.assert(z.1 == 5u8);
|
||||
|
||||
let foo = Foo { f: 6u8 };
|
||||
foo.f += 2u8;
|
||||
console.assert(foo.f == 8u8);
|
||||
}
|
@ -308,3 +308,11 @@ fn test_duplicate_name_context() {
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutable_call_immutable_context() {
|
||||
let program_string = include_str!("mutable_call_immutable_context.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
12
compiler/tests/circuits/mutable_call_immutable_context.leo
Normal file
12
compiler/tests/circuits/mutable_call_immutable_context.leo
Normal file
@ -0,0 +1,12 @@
|
||||
circuit TestMe {
|
||||
x: u8,
|
||||
|
||||
function test_me(mut self) -> u8 {
|
||||
self.x += 1;
|
||||
return self.x
|
||||
}
|
||||
}
|
||||
|
||||
function main () {
|
||||
const t = TestMe {x: 6u8}.test_me();
|
||||
}
|
@ -74,6 +74,14 @@ fn test_field() {
|
||||
assert_satisfied(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_space_between_literal() {
|
||||
let program_string = include_str!("no_space_between_literal.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
use std::ops::Add;
|
||||
|
3
compiler/tests/field/no_space_between_literal.leo
Normal file
3
compiler/tests/field/no_space_between_literal.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main() {
|
||||
const f = 1 field;
|
||||
}
|
@ -5,5 +5,5 @@ function main() {
|
||||
|
||||
do_nothing(arr);
|
||||
do_nothing([...arr]);
|
||||
do_nothing(arr[1u32..]);
|
||||
do_nothing(arr[0u32..]);
|
||||
}
|
7
compiler/tests/function/duplicate_definition.leo
Normal file
7
compiler/tests/function/duplicate_definition.leo
Normal file
@ -0,0 +1,7 @@
|
||||
function main() {
|
||||
console.log("{}", 1u8);
|
||||
}
|
||||
|
||||
function main() {
|
||||
console.log("{}", 2u8);
|
||||
}
|
@ -211,3 +211,11 @@ fn test_array_params_direct_call() {
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_duplicate_function_definition() {
|
||||
let program_string = include_str!("duplicate_definition.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_asg_error(error);
|
||||
}
|
||||
|
@ -45,6 +45,14 @@ pub fn group_element_to_input_value(g: EdwardsAffine) -> GroupValue {
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_space_between_literal() {
|
||||
let program_string = include_str!("no_space_between_literal.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_one() {
|
||||
let program_string = include_str!("one.leo");
|
||||
|
3
compiler/tests/group/no_space_between_literal.leo
Normal file
3
compiler/tests/group/no_space_between_literal.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main() {
|
||||
const g = (0,1) group;
|
||||
}
|
@ -132,3 +132,11 @@ fn test_i128_assert_eq() {
|
||||
fn test_i128_ternary() {
|
||||
TestI128::test_ternary();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_space_between_literal() {
|
||||
let program_string = include_str!("no_space_between_literal.leo");
|
||||
let program = parse_program(program_string);
|
||||
|
||||
assert!(program.is_err());
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user