diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..b5ded344eb9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: + - name: Ideas + url: https://github.com/orgs/noir-lang/discussions/new?category=ideas + about: Share ideas for new features diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml deleted file mode 100644 index ae48534c009..00000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Feature Request -description: Suggest an idea. -labels: [enhancement] -body: - - type: markdown - attributes: - value: | - ## Description - Thanks for taking the time to create the Issue, and welcome to the Noirot family! - - type: textarea - id: problem - attributes: - label: Problem - description: Describe what you feel lacking. Supply code / step-by-step examples if applicable. - validations: - required: true - - type: textarea - id: solution - attributes: - label: Happy Case - description: Describe how you think it should work. Supply pseudocode / step-by-step examples if applicable. - validations: - required: true - - type: textarea - id: alternatives - attributes: - label: Alternatives Considered - description: Describe less-happy cases you have considered, if any. - - type: textarea - id: additional - attributes: - label: Additional Context - description: Supplement further information if applicable. - - type: markdown - attributes: - value: | - ## Pull Request - - type: dropdown - id: pr-preference - attributes: - label: Would you like to submit a PR for this Issue? - description: Fellow contributors are happy to provide support where applicable. - multiple: false - options: - - "No" - - "Maybe" - - "Yes" - validations: - required: true - - type: textarea - id: pr-support - attributes: - label: Support Needs - description: Support from other contributors you are looking for to create a PR for this Issue. diff --git a/.github/NIGHTLY_TEST_FAILURE.md b/.github/NIGHTLY_TEST_FAILURE.md new file mode 100644 index 00000000000..e86c01b25b7 --- /dev/null +++ b/.github/NIGHTLY_TEST_FAILURE.md @@ -0,0 +1,11 @@ +--- +title: "nightly test-integration failed" +assignees: kobyhallx, phated, tomafrench, jonybur +labels: bug +--- + +Something broke our nightly integration test. + +Check the [test]({{env.WORKFLOW_URL}}) workflow for details. + +This issue was raised by the workflow `{{env.WORKFLOW_NAME}}` diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 00000000000..98da1c2fb0c --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,26 @@ +name: Setup + +inputs: + working-directory: + default: ./ + required: false + +runs: + using: composite + steps: + - name: Install node + uses: actions/setup-node@v3 + with: + node-version: 18.15 + - name: Cache + uses: actions/cache@v3 + id: cache + with: + path: "**/node_modules" + key: yarn-v1-${{ hashFiles('**/yarn.lock') }} + - name: Install + run: | + cd ${{ inputs.working-directory }} + yarn --immutable + shell: bash + if: steps.cache.outputs.cache-hit != 'true' diff --git a/.github/workflows/abi_wasm.yml b/.github/workflows/abi_wasm.yml new file mode 100644 index 00000000000..3d261d58807 --- /dev/null +++ b/.github/workflows/abi_wasm.yml @@ -0,0 +1,138 @@ +name: ABI Wasm test + +on: + pull_request: + merge_group: + push: + branches: + - master + +# This will cancel previous runs when a branch or PR is updated +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + noirc-abi-wasm-build: + runs-on: ubuntu-latest + env: + CACHED_PATH: /tmp/nix-cache + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - uses: cachix/install-nix-action@v20 + with: + nix_path: nixpkgs=channel:nixos-23.05 + github_access_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Restore nix store cache + uses: actions/cache/restore@v3 + id: cache + with: + path: ${{ env.CACHED_PATH }} + key: ${{ runner.os }}-flake-abi-wasm-${{ hashFiles('*.lock') }} + + # Based on https://github.com/marigold-dev/deku/blob/b5016f0cf4bf6ac48db9111b70dd7fb49b969dfd/.github/workflows/build.yml#L26 + - name: Copy cache into nix store + if: steps.cache.outputs.cache-hit == 'true' + # We don't check the signature because we're the one that created the cache + run: | + for narinfo in ${{ env.CACHED_PATH }}/*.narinfo; do + path=$(head -n 1 "$narinfo" | awk '{print $2}') + nix copy --no-check-sigs --from "file://${{ env.CACHED_PATH }}" "$path" + done + + - name: Build noirc_abi_wasm + run: | + nix build -L .#noirc_abi_wasm + + - name: Export cache from nix store + if: ${{ steps.cache.outputs.cache-hit != 'true' && github.event_name != 'merge_group' }} + run: | + nix copy --to "file://${{ env.CACHED_PATH }}?compression=zstd¶llel-compression=true" .#noirc-abi-wasm-cargo-artifacts + + - uses: actions/cache/save@v3 + # Don't create cache entries for the merge queue. + if: ${{ steps.cache.outputs.cache-hit != 'true' && github.event_name != 'merge_group' }} + with: + path: ${{ env.CACHED_PATH }} + key: ${{ steps.cache.outputs.cache-primary-key }} + + - name: Dereference symlink + run: echo "UPLOAD_PATH=$(readlink -f result)" >> $GITHUB_ENV + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: noirc_abi_wasm + path: ${{ env.UPLOAD_PATH }} + retention-days: 10 + + noirc-abi-wasm-test-node: + needs: [noirc-abi-wasm-build] + name: Node.js Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: noirc_abi_wasm + path: ./result + + - name: Set up test environment + uses: ./.github/actions/setup + with: + working-directory: ./tooling/noirc_abi_wasm + + - name: Run node tests + working-directory: ./tooling/noirc_abi_wasm + run: yarn install && yarn test + + noirc-abi-wasm-test-browser: + needs: [noirc-abi-wasm-build] + name: Browser Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: noirc_abi_wasm + path: ./result + + - name: Query playwright version + working-directory: ./tooling/noirc_abi_wasm + run: echo "PLAYWRIGHT_VERSION=$(yarn info @web/test-runner-playwright --json | jq .children.Version)" >> $GITHUB_ENV + + - name: Cache playwright binaries + uses: actions/cache@v3 + id: playwright-cache + with: + path: | + ~/.cache/ms-playwright + key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }} + + - name: Set up test environment + uses: ./.github/actions/setup + with: + working-directory: ./tooling/noirc_abi_wasm + + - name: Install playwright deps + if: steps.playwright-cache.outputs.cache-hit != 'true' + working-directory: ./tooling/noirc_abi_wasm + run: | + npx playwright install + npx playwright install-deps + + - name: Run browser tests + working-directory: ./tooling/noirc_abi_wasm + run: yarn install && yarn test:browser diff --git a/.github/workflows/deny.yml b/.github/workflows/deny.yml new file mode 100644 index 00000000000..8ae7d03e076 --- /dev/null +++ b/.github/workflows/deny.yml @@ -0,0 +1,26 @@ +name: deny + +on: + push: + branches: [master] + paths: [Cargo.lock] + pull_request: + branches: [master] + paths: [Cargo.lock] + merge_group: + +env: + RUSTFLAGS: -D warnings + CARGO_TERM_COLOR: always + +concurrency: deny-${{ github.head_ref || github.run_id }} + +jobs: + deny: + name: deny + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: EmbarkStudios/cargo-deny-action@v1 + with: + command: check all \ No newline at end of file diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml new file mode 100644 index 00000000000..8d29886e40c --- /dev/null +++ b/.github/workflows/formatting.yml @@ -0,0 +1,49 @@ +name: Clippy + +on: + pull_request: + merge_group: + push: + branches: + - master + +# This will cancel previous runs when a branch or PR is updated +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + clippy: + name: cargo clippy + runs-on: ${{ matrix.runner }} + timeout-minutes: 30 + + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-latest + target: x86_64-unknown-linux-gnu + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable # We do not use MSRV so we can benefit from newer lints + targets: ${{ matrix.target }} + components: clippy, rustfmt + + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.target }} + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} + + - name: Run `cargo clippy` + run: cargo clippy --workspace --locked --release + + - name: Run `cargo fmt` + run: cargo fmt --all --check diff --git a/.github/workflows/publish-abi_wasm.yml b/.github/workflows/publish-abi_wasm.yml new file mode 100644 index 00000000000..ff0ea7f0cc7 --- /dev/null +++ b/.github/workflows/publish-abi_wasm.yml @@ -0,0 +1,46 @@ +name: Publish ABI Wasm + +on: + push: + tags: + - "*" + workflow_dispatch: + +jobs: + noirc-abi-wasm-build: + runs-on: ubuntu-latest + env: + CACHED_PATH: /tmp/nix-cache + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + registry-url: "https://registry.npmjs.org" + node-version: 18.15 + + - uses: cachix/install-nix-action@v22 + with: + nix_path: nixpkgs=channel:nixos-23.05 + github_access_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Build noirc_abi_wasm + run: | + nix build -L .#noirc_abi_wasm + + - name: Discover Build Output Path + run: echo "BUILD_OUTPUT_PATH=$(readlink -f ./result)" >> $GITHUB_ENV + + - name: Copy Build Output to Temporary Directory + run: | + mkdir temp_publish_dir + cp -r ${{ env.BUILD_OUTPUT_PATH }}/* temp_publish_dir/ + + - name: Publish to NPM + working-directory: ./temp_publish_dir + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 048d80a23c7..8995b270571 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,6 +7,9 @@ on: tag: description: The tag to build Nargo from (leave empty to build a nightly release from master) required: false + features: + description: Extra feature flags to release with + required: false publish: description: Whether to publish the build artifacts type: boolean @@ -22,59 +25,17 @@ permissions: contents: write jobs: - build-barretenberg: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - ref: ${{ inputs.tag || env.GITHUB_REF }} - - - name: Collect locked barretenberg rev - run: | - echo "BB_REV=$(jq -r .nodes.barretenberg.locked.rev ./flake.lock)" >> $GITHUB_ENV - - - uses: cachix/install-nix-action@v20 - with: - nix_path: nixpkgs=channel:nixos-22.11 - github_access_token: ${{ secrets.GITHUB_TOKEN }} - - - uses: cachix/cachix-action@v12 - with: - name: barretenberg - - # Upload does not work with symlinks, using this workaround: - # https://github.com/actions/upload-artifact/issues/92#issuecomment-1080347032 - - name: Build barretenberg as libbarretenberg-wasm32 - run: | - nix build "github:AztecProtocol/barretenberg/${{ env.BB_REV }}#wasm32" - echo "ARTIFACT_UPLOAD_PATH=$(readlink -f result)" >> $GITHUB_ENV - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: libbarretenberg-wasm32 - path: ${{ env.ARTIFACT_UPLOAD_PATH }} - retention-days: 3 - build-apple-darwin: - needs: [build-barretenberg] runs-on: macos-latest env: CROSS_CONFIG: ${{ github.workspace }}/.github/Cross.toml - CACHED_PATHS: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ strategy: matrix: target: [x86_64-apple-darwin, aarch64-apple-darwin] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ inputs.tag || env.GITHUB_REF }} @@ -85,35 +46,20 @@ jobs: echo "SDKROOT=$(xcrun -sdk macosx$(sw_vers -productVersion) --show-sdk-path)" >> $GITHUB_ENV echo "MACOSX_DEPLOYMENT_TARGET=$(xcrun -sdk macosx$(sw_vers -productVersion) --show-sdk-platform-version)" >> $GITHUB_ENV - - uses: actions/cache/restore@v3 - id: cache - with: - path: ${{ env.CACHED_PATHS }} - key: ${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Download artifact - uses: actions/download-artifact@v3 - with: - name: libbarretenberg-wasm32 - path: ${{ github.workspace }}/libbarretenberg-wasm32 - - name: Setup toolchain uses: dtolnay/rust-toolchain@1.66.0 with: targets: ${{ matrix.target }} + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.target }} + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} + - name: Build environment and Compile - env: - BARRETENBERG_BIN_DIR: ${{ github.workspace }}/libbarretenberg-wasm32/bin run: | - cargo build --package nargo_cli --release --target ${{ matrix.target }} --no-default-features --features plonk_bn254_wasm - - - uses: actions/cache/save@v3 - # Don't create cache entries for the merge queue. - if: ${{ steps.cache.outputs.cache-hit != 'true' && github.event_name != 'merge_group' }} - with: - path: ${{ env.CACHED_PATHS }} - key: ${{ steps.cache.outputs.cache-primary-key }} + cargo build --package nargo_cli --release --target ${{ matrix.target }} --no-default-features --features "${{ inputs.features }}" - name: Package artifacts run: | @@ -153,75 +99,50 @@ jobs: if: ${{ inputs.tag == '' && inputs.publish || github.event_name == 'schedule' }} run: echo "date=$(date '+%Y-%m-%d')" >> $GITHUB_OUTPUT - - name: Upload binaries to nightly release with date tag + - name: Upload binaries to release with date tag uses: svenstaro/upload-release-action@v2 if: ${{ inputs.tag == '' && inputs.publish || github.event_name == 'schedule' }} with: repo_name: noir-lang/noir repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./nargo-${{ matrix.target }}.zip - asset_name: nargo-${{ matrix.target }}.zip + file: ./nargo-${{ matrix.target }}.tar.gz + asset_name: nargo-${{ matrix.target }}.tar.gz overwrite: true tag: ${{ format('{0}-{1}', 'nightly', steps.date.outputs.date) }} build-linux: - needs: [build-barretenberg] runs-on: ubuntu-22.04 env: CROSS_CONFIG: ${{ github.workspace }}/.github/Cross.toml - CACHED_PATHS: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ strategy: fail-fast: false matrix: - target: - [ - x86_64-unknown-linux-gnu, - x86_64-unknown-linux-musl, - aarch64-unknown-linux-gnu, - aarch64-unknown-linux-musl, - ] + target: [x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ inputs.tag || env.GITHUB_REF }} - - uses: actions/cache/restore@v3 - id: cache - with: - path: ${{ env.CACHED_PATHS }} - key: ${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Download artifact - uses: actions/download-artifact@v3 - with: - name: libbarretenberg-wasm32 - path: ${{ github.workspace }}/libbarretenberg-wasm32 - - name: Setup toolchain uses: dtolnay/rust-toolchain@1.66.0 with: targets: ${{ matrix.target }} - - name: Build Nargo - env: - BARRETENBERG_BIN_DIR: ${{ github.workspace }}/libbarretenberg-wasm32/bin - run: | - cargo install cross --force --git https://github.com/cross-rs/cross - cross build --package nargo_cli --release --target=${{ matrix.target }} --no-default-features --features plonk_bn254_wasm + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.target }} + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} - - uses: actions/cache/save@v3 - # Don't create cache entries for the merge queue. - if: ${{ steps.cache.outputs.cache-hit != 'true' && github.event_name != 'merge_group' }} + - name: Install Cross + uses: taiki-e/install-action@v2 with: - path: ${{ env.CACHED_PATHS }} - key: ${{ steps.cache.outputs.cache-primary-key }} + tool: cross@0.2.5 + + - name: Build Nargo + run: cross build --package nargo_cli --release --target=${{ matrix.target }} --no-default-features --features "${{ inputs.features }}" - name: Package artifacts run: | @@ -261,113 +182,13 @@ jobs: if: ${{ inputs.tag == '' && inputs.publish || github.event_name == 'schedule' }} run: echo "date=$(date '+%Y-%m-%d')" >> $GITHUB_OUTPUT - - name: Upload binaries to nightly release with date tag - uses: svenstaro/upload-release-action@v2 - if: ${{ inputs.tag == '' && inputs.publish || github.event_name == 'schedule' }} - with: - repo_name: noir-lang/noir - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./nargo-${{ matrix.target }}.zip - asset_name: nargo-${{ matrix.target }}.zip - overwrite: true - tag: ${{ format('{0}-{1}', 'nightly', steps.date.outputs.date) }} - - build-windows: - needs: [build-barretenberg] - runs-on: windows-2022 - env: - CROSS_CONFIG: ${{ github.workspace }}/.github/Cross.toml - CACHED_PATHS: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - strategy: - matrix: - target: [x86_64-pc-windows-msvc] - - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - ref: ${{ inputs.tag || env.GITHUB_REF }} - - - uses: actions/cache/restore@v3 - id: cache - with: - path: ${{ env.CACHED_PATHS }} - key: ${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Download artifact - uses: actions/download-artifact@v3 - with: - name: libbarretenberg-wasm32 - path: ${{ github.workspace }}/libbarretenberg-wasm32 - - - name: Setup toolchain - uses: dtolnay/rust-toolchain@1.66.0 - with: - targets: ${{ matrix.target }} - - - name: Build environment and Compile - env: - BARRETENBERG_BIN_DIR: ${{ github.workspace }}/libbarretenberg-wasm32/bin - run: | - cargo build --package nargo_cli --release --target ${{ matrix.target }} --no-default-features --features plonk_bn254_wasm - - - uses: actions/cache/save@v3 - # Don't create cache entries for the merge queue. - if: ${{ steps.cache.outputs.cache-hit != 'true' && github.event_name != 'merge_group' }} - with: - path: ${{ env.CACHED_PATHS }} - key: ${{ steps.cache.outputs.cache-primary-key }} - - - name: Package artifacts - run: | - mkdir dist - cp ./target/${{ matrix.target }}/release/nargo.exe ./dist/nargo.exe - 7z a -tzip nargo-${{ matrix.target }}.zip ./dist/* - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: nargo-${{ matrix.target }} - path: ./dist/* - retention-days: 3 - - - name: Test built artifact - shell: powershell - run: | - cp ./target/${{ matrix.target }}/release/nargo.exe ~/.cargo/bin/ - - cd release-tests - yarn install - yarn test - - - name: Upload binaries to release tag - uses: svenstaro/upload-release-action@v2 - if: ${{ inputs.publish || github.event_name == 'schedule' }} - with: - repo_name: noir-lang/noir - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./nargo-${{ matrix.target }}.zip - asset_name: nargo-${{ matrix.target }}.zip - overwrite: true - tag: ${{ inputs.tag || 'nightly' }} # This will fail if `inputs.tag` is not a tag (e.g. testing a branch) - - - name: Get formatted date - id: date - if: ${{ inputs.tag == '' && inputs.publish || github.event_name == 'schedule' }} - run: echo "date=$(date '+%Y-%m-%d')" >> $GITHUB_OUTPUT - - - name: Upload binaries to nightly release with date tag + - name: Upload binaries to release with date tag uses: svenstaro/upload-release-action@v2 if: ${{ inputs.tag == '' && inputs.publish || github.event_name == 'schedule' }} with: repo_name: noir-lang/noir repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./nargo-${{ matrix.target }}.zip - asset_name: nargo-${{ matrix.target }}.zip + file: ./nargo-${{ matrix.target }}.tar.gz + asset_name: nargo-${{ matrix.target }}.tar.gz overwrite: true tag: ${{ format('{0}-{1}', 'nightly', steps.date.outputs.date) }} diff --git a/.github/workflows/release-source-resolver.yml b/.github/workflows/release-source-resolver.yml new file mode 100644 index 00000000000..9a1a3381dd8 --- /dev/null +++ b/.github/workflows/release-source-resolver.yml @@ -0,0 +1,53 @@ +name: Release and Publish Source Resolver + +on: + workflow_dispatch: + inputs: + version: + description: "Version number" + required: false + +jobs: + release-source-resolver: + name: Release and Publish Source Resolver + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Bump version + working-directory: ./compiler/source-resolver + id: bump_version + run: | + if [ -z "${{ github.event.inputs.version }}" ]; then + NEW_VERSION=$(npm version patch --no-git-tag-version) + else + NEW_VERSION=$(npm version ${{ github.event.inputs.version }} --no-git-tag-version) + fi + echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV + + - name: Install dependencies + working-directory: ./compiler/source-resolver + run: npm install + + - name: Build noir-source-resolver + working-directory: ./compiler/source-resolver + run: npm run build + + - name: Publish to NPM + working-directory: ./compiler/source-resolver + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} + + - name: Configure git + run: | + git config user.name kevaundray + git config user.email kevtheappdev@gmail.com + + - name: Commit updates + run: | + git add compiler/source-resolver/package-lock.json + git add compiler/source-resolver/package.json + git commit -m "chore: Update source-resolver to ${{ env.NEW_VERSION }}" + git push diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 37136df68d8..eb030f41f82 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout release branch - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ fromJSON(needs.release-please.outputs.release-pr).headBranchName }} token: ${{ secrets.NOIR_RELEASES_TOKEN }} diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml new file mode 100644 index 00000000000..96a177a9bde --- /dev/null +++ b/.github/workflows/test-integration.yml @@ -0,0 +1,113 @@ +name: test-integration + +on: + workflow_dispatch: + schedule: + - cron: "0 2 * * *" # Run nightly at 2 AM UTC + +jobs: + wasm-packages-build-test: + runs-on: ubuntu-latest + env: + CACHED_PATH: /tmp/nix-cache + + steps: + - name: Checkout noir sources + uses: actions/checkout@v4 + + - name: Checkout acvm sources + uses: actions/checkout@v3 # v3 is needed here otherwise this fails in local execution + with: + repository: noir-lang/acvm + path: acvm + + - name: Setup Nix + uses: cachix/install-nix-action@v22 + with: + nix_path: nixpkgs=channel:nixos-23.05 + github_access_token: ${{ secrets.GITHUB_TOKEN }} + + - uses: cachix/cachix-action@v12 + with: + name: barretenberg + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Restore nix store cache + uses: actions/cache/restore@v3 + id: cache + with: + path: ${{ env.CACHED_PATH }} + key: ${{ runner.os }}-flake-wasm-${{ hashFiles('*.lock') }} + + # Based on https://github.com/marigold-dev/deku/blob/b5016f0cf4bf6ac48db9111b70dd7fb49b969dfd/.github/workflows/build.yml#L26 + - name: Copy cache into nix store + if: steps.cache.outputs.cache-hit == 'true' + # We don't check the signature because we're the one that created the cache + run: | + for narinfo in ${{ env.CACHED_PATH }}/*.narinfo; do + path=$(head -n 1 "$narinfo" | awk '{print $2}') + nix copy --no-check-sigs --from "file://${{ env.CACHED_PATH }}" "$path" + done + + - name: Build noir_wasm package + run: | + nix build -L .#wasm + mkdir -p ./.packages/noir_wasm + cp -r ./result/* ./.packages/noir_wasm/ + echo "UPLOAD_PATH=$(readlink -f result)" >> $GITHUB_ENV + + - name: Upload `noir_wasm` artifact + uses: actions/upload-artifact@v3 + with: + name: noir_wasm + path: ${{ env.UPLOAD_PATH }} + retention-days: 3 + + - name: Build noirc_abi_wasm package + run: | + nix build -L .#noirc_abi_wasm + mkdir -p ./.packages/noirc_abi_wasm + cp -r ./result/* ./.packages/noirc_abi_wasm/ + echo "UPLOAD_PATH=$(readlink -f result)" >> $GITHUB_ENV + + - name: Upload `noirc_abi_wasm` artifact + uses: actions/upload-artifact@v3 + with: + name: noirc_abi_wasm + path: ${{ env.UPLOAD_PATH }} + retention-days: 3 + + - name: Build `acvm_js` package + working-directory: ./acvm + run: | + nix build -L .# + mkdir -p ../.packages/acvm_js + cp -r ./result/* ../.packages/acvm_js/ + echo "UPLOAD_PATH=$(readlink -f result)" >> $GITHUB_ENV + + - name: Upload `acvm_js` artifact + uses: actions/upload-artifact@v3 + with: + name: acvm_js + path: ${{ env.UPLOAD_PATH }} + retention-days: 3 + + - name: Install `integration-tests` dependencies + working-directory: ./compiler/integration-tests + run: yarn install + + - name: Run `integration-tests` + working-directory: ./compiler/integration-tests + run: | + yarn test:browser + + - name: Alert on nightly test failure + uses: JasonEtco/create-an-issue@v2 + if: ${{ failure() && github.event_name == 'schedule' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + WORKFLOW_NAME: ${{ github.workflow }} + WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + with: + update_existing: true + filename: .github/NIGHTLY_TEST_FAILURE.md diff --git a/.github/workflows/test-source-resolver.yml b/.github/workflows/test-source-resolver.yml new file mode 100644 index 00000000000..1b69d38302d --- /dev/null +++ b/.github/workflows/test-source-resolver.yml @@ -0,0 +1,29 @@ +name: Test Source Resolver + +on: + push: + paths: + - "compiler/source-resolver/**" + pull_request: + paths: + - "compiler/source-resolver/**" + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install dependencies + working-directory: ./compiler/source-resolver + run: npm install + + - name: Build noir-source-resolver + working-directory: ./compiler/source-resolver + run: npm run build + + - name: Run tests + working-directory: ./compiler/source-resolver + run: npm run test diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 23a6716ab59..e5a94aaac4b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,6 +3,9 @@ name: Test on: pull_request: merge_group: + push: + branches: + - master # This will cancel previous runs when a branch or PR is updated concurrency: @@ -14,8 +17,6 @@ jobs: name: Test on ${{ matrix.os }} runs-on: ${{ matrix.runner }} timeout-minutes: 30 - env: - CACHED_PATH: /tmp/nix-cache strategy: fail-fast: false @@ -23,50 +24,22 @@ jobs: include: - os: ubuntu runner: ubuntu-latest - target: x86_64-linux + target: x86_64-unknown-linux-gnu steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v22 + - name: Setup toolchain + uses: dtolnay/rust-toolchain@1.66.0 with: - nix_path: nixpkgs=channel:nixos-22.11 - github_access_token: ${{ secrets.GITHUB_TOKEN }} + targets: ${{ matrix.target }} - - uses: cachix/cachix-action@v12 + - uses: Swatinem/rust-cache@v2 with: - name: barretenberg + key: ${{ matrix.target }} + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} - - name: Restore nix store cache - uses: actions/cache/restore@v3 - id: cache - with: - path: ${{ env.CACHED_PATH }} - key: ${{ runner.os }}-flake-${{ hashFiles('*.lock') }} - - # Based on https://github.com/marigold-dev/deku/blob/b5016f0cf4bf6ac48db9111b70dd7fb49b969dfd/.github/workflows/build.yml#L26 - - name: Copy cache into nix store - if: steps.cache.outputs.cache-hit == 'true' - # We don't check the signature because we're the one that created the cache - run: | - for narinfo in ${{ env.CACHED_PATH }}/*.narinfo; do - path=$(head -n 1 "$narinfo" | awk '{print $2}') - nix copy --no-check-sigs --from "file://${{ env.CACHED_PATH }}" "$path" - done - - - name: Run `nix flake check` - run: | - nix flake check -L - - - name: Export cache from nix store - if: ${{ always() && steps.cache.outputs.cache-hit != 'true' && github.event_name != 'merge_group' }} - run: | - nix copy --to "file://${{ env.CACHED_PATH }}?compression=zstd¶llel-compression=true" .#native-cargo-artifacts - - - uses: actions/cache/save@v3 - # Write a cache entry even if the tests fail but don't create any for the merge queue. - if: ${{ always() && steps.cache.outputs.cache-hit != 'true' && github.event_name != 'merge_group' }} - with: - path: ${{ env.CACHED_PATH }} - key: ${{ steps.cache.outputs.cache-primary-key }} + - name: Run tests + run: cargo test --workspace --locked --release diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index f052e9eb071..f02e71be4e6 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -3,91 +3,36 @@ name: Wasm on: pull_request: merge_group: + push: + branches: + - master concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} cancel-in-progress: true jobs: - # TODO: Replace this step with downloading a wasm binary from a set release of Barretenberg - build-barretenberg: - runs-on: ubuntu-latest - steps: - - name: Checkout Noir repo - uses: actions/checkout@v3 - - - name: Collect locked barretenberg rev - run: | - echo "BB_REV=$(jq -r .nodes.barretenberg.locked.rev ./flake.lock)" >> $GITHUB_ENV - echo "BB_REV is ${{ env.BB_REV }}" - - - uses: cachix/install-nix-action@v20 - with: - nix_path: nixpkgs=channel:nixos-22.11 - github_access_token: ${{ secrets.GITHUB_TOKEN }} - - - uses: cachix/cachix-action@v12 - with: - name: barretenberg - authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - - # Upload does not work with symlinks, using this workaround: - # https://github.com/actions/upload-artifact/issues/92#issuecomment-1080347032 - - name: Build barretenberg as libbarretenberg-wasm32 - run: | - echo "BB_REV is ${{ env.BB_REV }}" - nix build "github:AztecProtocol/barretenberg/${{ env.BB_REV }}#wasm32" - echo "ARTIFACT_UPLOAD_PATH=$(readlink -f result)" >> $GITHUB_ENV - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: libbarretenberg-wasm32 - path: ${{ env.ARTIFACT_UPLOAD_PATH }} - retention-days: 3 - build-nargo: - needs: [build-barretenberg] runs-on: ubuntu-22.04 - env: - CACHED_PATHS: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - + strategy: + matrix: + target: [x86_64-unknown-linux-gnu] + steps: - name: Checkout Noir repo - uses: actions/checkout@v3 - - - uses: actions/cache/restore@v3 - id: cache - with: - path: ${{ env.CACHED_PATHS }} - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Download artifact - uses: actions/download-artifact@v3 - with: - name: libbarretenberg-wasm32 - path: ${{ github.workspace }}/libbarretenberg-wasm32 + uses: actions/checkout@v4 - name: Setup toolchain uses: dtolnay/rust-toolchain@1.66.0 - - name: Build Nargo - env: - BARRETENBERG_BIN_DIR: ${{ github.workspace }}/libbarretenberg-wasm32/bin - run: | - cargo build --package nargo_cli --release --no-default-features --features plonk_bn254_wasm - - - uses: actions/cache/save@v3 - # Don't create cache entries for the merge queue. - if: ${{ steps.cache.outputs.cache-hit != 'true' && github.event_name != 'merge_group' }} + - uses: Swatinem/rust-cache@v2 with: - path: ${{ env.CACHED_PATHS }} - key: ${{ steps.cache.outputs.cache-primary-key }} + key: ${{ matrix.target }} + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} + + - name: Build Nargo + run: cargo build --package nargo_cli --release - name: Package artifacts run: | @@ -109,7 +54,7 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Nix uses: cachix/install-nix-action@v22 @@ -166,13 +111,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout noir-lang/noir - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Download wasm package artifact uses: actions/download-artifact@v3 with: name: noir_wasm - path: ./crates/wasm/result + path: ./compiler/wasm/result - name: Download nargo binary uses: actions/download-artifact@v3 @@ -181,22 +126,29 @@ jobs: path: ./nargo - name: Compile test program with Nargo CLI - working-directory: ./crates/wasm/noir-script + working-directory: ./compiler/wasm/noir-script run: | nargo_binary=${{ github.workspace }}/nargo/nargo chmod +x $nargo_binary $nargo_binary compile + - name: Set up test environment + uses: ./.github/actions/setup + with: + working-directory: ./compiler/wasm + - name: Install dependencies - working-directory: ./crates/wasm + working-directory: ./compiler/wasm run: yarn install - name: Install playwright deps - working-directory: ./crates/wasm + working-directory: ./compiler/wasm run: | npx playwright install npx playwright install-deps - name: Run tests - working-directory: ./crates/wasm - run: yarn test:browser + working-directory: ./compiler/wasm + run: | + yarn test:browser + yarn test:node diff --git a/.gitignore b/.gitignore index d339e5b9d3b..29749dca10f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,11 @@ examples/9 node_modules pkg/ +# Source resolver +compiler/source-resolver/node_modules +compiler/source-resolver/lib +compiler/source-resolver/lib-node + # Nix stuff **/outputs result @@ -20,8 +25,8 @@ result *.vk **/Verifier.toml **/target -!crates/nargo_cli/tests/execution_success/*/target -!crates/nargo_cli/tests/execution_success/*/target/witness.tr +!tooling/nargo_cli/tests/acir_artifacts/*/target +!tooling/nargo_cli/tests/acir_artifacts/*/target/witness.gz # Github Actions scratch space # This gives a location to download artifacts into the repository in CI without making git dirty. diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8c7bf663c11..ddfa3e36c2e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.10.3" + ".": "0.11.1" } diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 64ae238015f..710e88b34df 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -6,7 +6,8 @@ "mkhl.direnv", "jnoortheen.nix-ide", "rust-lang.rust-analyzer", - "redhat.vscode-yaml" + "redhat.vscode-yaml", + "esbenp.prettier-vscode" ], // List of extensions recommended by VS Code that should not be recommended for users of this workspace. "unwantedRecommendations": [] diff --git a/.vscode/settings.json b/.vscode/settings.json index 6c6ec87be51..171d36f4e04 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,4 +16,7 @@ "yaml.schemas": { "https://json.schemastore.org/github-workflow.json": "${workspaceRoot}/.github/workflows/*.yml" }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index eb93c131b04..7dc8c64779d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,117 @@ # Changelog +## [0.11.1](https://github.com/noir-lang/noir/compare/v0.11.0...v0.11.1) (2023-09-07) + + +### Features + +* Enable dynamic indices on slices ([#2446](https://github.com/noir-lang/noir/issues/2446)) ([c5c4052](https://github.com/noir-lang/noir/commit/c5c40529d8c000ba61f3372b336e57947673646a)) + + +### Bug Fixes + +* Disable loop unrolling in brillig ([#2590](https://github.com/noir-lang/noir/issues/2590)) ([464f878](https://github.com/noir-lang/noir/commit/464f87834ada04320ea396cb4bdbab3317e036db)) + +## [0.11.0](https://github.com/noir-lang/noir/compare/v0.10.5...v0.11.0) (2023-09-07) + + +### ⚠ BREAKING CHANGES + +* **stdlib:** Rename `fixed_base_scalar_mul` to be more descriptive ([#2488](https://github.com/noir-lang/noir/issues/2488)) +* ACVM 0.24 ([#2504](https://github.com/noir-lang/noir/issues/2504)) +* Update to `acvm-backend-barretenberg` v0.12.0 ([#2377](https://github.com/noir-lang/noir/issues/2377)) +* **abi:** Replace struct name with fully qualified struct path ([#2374](https://github.com/noir-lang/noir/issues/2374)) +* Remove keys from preprocessed artifacts ([#2283](https://github.com/noir-lang/noir/issues/2283)) + +### Features + +* Add `nargo backend ls` and `nargo backend use` command to switch between backends ([#2552](https://github.com/noir-lang/noir/issues/2552)) ([7471147](https://github.com/noir-lang/noir/commit/7471147e4239410557f2f98d6e5102d8090dd09c)) +* Add `noirc_abi_wasm` crate for ABI encoding in JS ([#1945](https://github.com/noir-lang/noir/issues/1945)) ([669e0da](https://github.com/noir-lang/noir/commit/669e0dab56f7368e805aaf651eb4052f476029e4)) +* Add support for brillig call stacks in runtime errors ([#2549](https://github.com/noir-lang/noir/issues/2549)) ([a077391](https://github.com/noir-lang/noir/commit/a07739112ca8928d2211dd09adf89692d8b429d0)) +* Apply optimizations to unconstrained code ([#2348](https://github.com/noir-lang/noir/issues/2348)) ([8e0f6c4](https://github.com/noir-lang/noir/commit/8e0f6c4e1004d50b6392941ccf72a78f3a5870da)) +* **aztec_noir:** Abstract kernel return types ([#2521](https://github.com/noir-lang/noir/issues/2521)) ([2668ac2](https://github.com/noir-lang/noir/commit/2668ac2a8380ac362de34e7b8f1c231608d3606a)) +* **nargo:** Add commands to install and uninstall custom backends. ([#2575](https://github.com/noir-lang/noir/issues/2575)) ([28a413c](https://github.com/noir-lang/noir/commit/28a413c5b6a92cbfdb94eca5787e7369ef03f4a3)) +* **nargo:** Add hidden option to produce JSON output from `nargo info` ([#2542](https://github.com/noir-lang/noir/issues/2542)) ([14d31a5](https://github.com/noir-lang/noir/commit/14d31a543e0dd53476d35a0f32b048323f277f7c)) +* Pull `Language` and `Opcode` support from backend ([#2563](https://github.com/noir-lang/noir/issues/2563)) ([2d0a5e4](https://github.com/noir-lang/noir/commit/2d0a5e447b02b11426ad80b64fba817dfce38e44)) +* **ssa:** Replace values which have previously been constrained with simplified value ([#2483](https://github.com/noir-lang/noir/issues/2483)) ([9be750a](https://github.com/noir-lang/noir/commit/9be750a713485ff84b111128db62b56fc0d0c5a5)) +* **stdlib:** Grumpkin scalar multiplication API ([#2586](https://github.com/noir-lang/noir/issues/2586)) ([dc34bc4](https://github.com/noir-lang/noir/commit/dc34bc46a7ee1ac7f1bcfbcdcbaccd4680a4ca31)) +* Support for optional assertion messages ([#2491](https://github.com/noir-lang/noir/issues/2491)) ([5f78772](https://github.com/noir-lang/noir/commit/5f78772fefdc84b67f28fe8b671a56e280313f38)) + + +### Bug Fixes + +* Allow usage of decimal string encoding for fields larger than a `i128` ([#2547](https://github.com/noir-lang/noir/issues/2547)) ([d73f30e](https://github.com/noir-lang/noir/commit/d73f30e9ce53acd0866281f331bd2ee8ff6112bd)) +* **aztec_noir:** Fix compilation of `aztec_library.rs` ([#2567](https://github.com/noir-lang/noir/issues/2567)) ([a8d0328](https://github.com/noir-lang/noir/commit/a8d03285e0c54fae525b3019dd7cc4807c6437c8)) +* **aztec_noir:** Generalise loop to not always inject a hasher instance ([#2529](https://github.com/noir-lang/noir/issues/2529)) ([9fe4cfd](https://github.com/noir-lang/noir/commit/9fe4cfd05b46d1d8867bc2583a11da32480366fc)) +* Black box func slice handling ([#2562](https://github.com/noir-lang/noir/issues/2562)) ([c67cd7d](https://github.com/noir-lang/noir/commit/c67cd7df9b5b47a554cc35a50f5bb80d1a4a12f0)) +* Initialize structs during def collection, not name resolution ([#2528](https://github.com/noir-lang/noir/issues/2528)) ([f170529](https://github.com/noir-lang/noir/commit/f170529bfcd9044bc685ed0f49af27c2e527964b)) +* Make def collector ordering more deterministic ([#2515](https://github.com/noir-lang/noir/issues/2515)) ([d49e0af](https://github.com/noir-lang/noir/commit/d49e0affa00fd29e7e5033ef464dbdd217980c8e)) +* Modulo with divisor of zero should fail constraints ([#2578](https://github.com/noir-lang/noir/issues/2578)) ([fe6e2e6](https://github.com/noir-lang/noir/commit/fe6e2e6775a9b1b9fbcab96947fa6047eb80371e)) + + +### Miscellaneous Chores + +* **abi:** Replace struct name with fully qualified struct path ([#2374](https://github.com/noir-lang/noir/issues/2374)) ([0920dd0](https://github.com/noir-lang/noir/commit/0920dd03d67c50da36bfb87db2e50f6a4aa155bd)) +* ACVM 0.24 ([#2504](https://github.com/noir-lang/noir/issues/2504)) ([f06fbdb](https://github.com/noir-lang/noir/commit/f06fbdb37d77b4e17d4f8eec103a93848b013963)) +* Remove keys from preprocessed artifacts ([#2283](https://github.com/noir-lang/noir/issues/2283)) ([4554287](https://github.com/noir-lang/noir/commit/45542870c85ff59487ad14c25f3e1d6692623644)) +* **stdlib:** Rename `fixed_base_scalar_mul` to be more descriptive ([#2488](https://github.com/noir-lang/noir/issues/2488)) ([6efc007](https://github.com/noir-lang/noir/commit/6efc007d3f53cf0ab52491e73c7bb9e2520938e0)) +* Update to `acvm-backend-barretenberg` v0.12.0 ([#2377](https://github.com/noir-lang/noir/issues/2377)) ([1467275](https://github.com/noir-lang/noir/commit/1467275666a01fe1dfdaf54527440df06303eb93)) + +## [0.10.5](https://github.com/noir-lang/noir/compare/v0.10.4...v0.10.5) (2023-08-30) + + +### Features + +* Basic implementation of traits ([#2368](https://github.com/noir-lang/noir/issues/2368)) ([df9f09e](https://github.com/noir-lang/noir/commit/df9f09eda62b7d09ed8ade8cad907453ea91d3e2)) + + +### Bug Fixes + +* Implement constant folding during the mem2reg pass ([#2464](https://github.com/noir-lang/noir/issues/2464)) ([5361ebd](https://github.com/noir-lang/noir/commit/5361ebd8a66648678702258bd07c9d221c748c8c)) +* **ssa:** Handle right shift with constants ([#2481](https://github.com/noir-lang/noir/issues/2481)) ([13a8c87](https://github.com/noir-lang/noir/commit/13a8c878422f03c33c924ff9cb56d5fd08195357)) + +## [0.10.4](https://github.com/noir-lang/noir/compare/v0.10.3...v0.10.4) (2023-08-29) + + +### Features + +* Add `assert_eq` keyword ([#2137](https://github.com/noir-lang/noir/issues/2137)) ([b467a2d](https://github.com/noir-lang/noir/commit/b467a2d72659d28195ea2015a6fba2738eae1f16)) +* Add `test(should_fail)` attribute for tests that are meant to fail ([#2418](https://github.com/noir-lang/noir/issues/2418)) ([74af99d](https://github.com/noir-lang/noir/commit/74af99d7230abf453e00ef4a48a79e4f0ed17a10)) +* Add syntax for specifying function type environments ([#2357](https://github.com/noir-lang/noir/issues/2357)) ([495a479](https://github.com/noir-lang/noir/commit/495a4796ff224f70fcd7408a7818d9f9e627b827)) +* Add trait definition representation in DefCollector and HIR ([#2338](https://github.com/noir-lang/noir/issues/2338)) ([406a595](https://github.com/noir-lang/noir/commit/406a59564ec31c43e72229d2f97663e5223785d7)) +* **attributes:** Enable custom attributes ([#2395](https://github.com/noir-lang/noir/issues/2395)) ([179611b](https://github.com/noir-lang/noir/commit/179611b646ce59a26cea6a4f3a61fc84f3ae9be3)) +* **brillig:** Added locations for brillig artifacts ([#2415](https://github.com/noir-lang/noir/issues/2415)) ([3771e52](https://github.com/noir-lang/noir/commit/3771e521110da845a14058b97c5e5037daf599b0)) +* Create equivalence relationships for intermediate witnesses from multiplication ([#2414](https://github.com/noir-lang/noir/issues/2414)) ([cc2a2d8](https://github.com/noir-lang/noir/commit/cc2a2d83bf6cf12406a690ca4b2f43032270ef5d)) +* **frontend:** Aztec syntactic sugar (feature flagged) ([#2403](https://github.com/noir-lang/noir/issues/2403)) ([a894a6e](https://github.com/noir-lang/noir/commit/a894a6eda49d8ba565a83be75489e710cc968895)) +* **nargo:** Support optional directory in git dependencies ([#2436](https://github.com/noir-lang/noir/issues/2436)) ([84fdc55](https://github.com/noir-lang/noir/commit/84fdc55a635ea6198e877621f0ca97be558bda77)) +* Perform more checks for compile-time arithmetic ([#2380](https://github.com/noir-lang/noir/issues/2380)) ([1be2b1e](https://github.com/noir-lang/noir/commit/1be2b1ea702991df6ea80a8d9fbe2fb08154a3d9)) +* Report compilation warnings before errors ([#2398](https://github.com/noir-lang/noir/issues/2398)) ([a1d1267](https://github.com/noir-lang/noir/commit/a1d12675a8bc75651d9634776c9d6c7cbf81ff7c)) +* **ssa:** Merge slices in if statements with witness conditions ([#2347](https://github.com/noir-lang/noir/issues/2347)) ([76f7e43](https://github.com/noir-lang/noir/commit/76f7e43bde28ae60b1def6cfdede2b6e76031cc1)) +* **ssa:** Reuse existing results for duplicated instructions with no side-effects ([#2460](https://github.com/noir-lang/noir/issues/2460)) ([93726c4](https://github.com/noir-lang/noir/commit/93726c4b4938512db6e36de47dc6ad77487c1acb)) +* Standard library functions can now be called with closure args ([#2471](https://github.com/noir-lang/noir/issues/2471)) ([feb8d0e](https://github.com/noir-lang/noir/commit/feb8d0e1840d2f297de53e0aaa3587ab6d7c55d6)) +* Syntax for environment types now works with generics ([#2383](https://github.com/noir-lang/noir/issues/2383)) ([4609c1a](https://github.com/noir-lang/noir/commit/4609c1addc8d1a63ab8d47212c0328927483d4d0)) +* Update to `acvm` 0.22.0 ([#2363](https://github.com/noir-lang/noir/issues/2363)) ([e050fab](https://github.com/noir-lang/noir/commit/e050fab89935cde96a972c2300145063687ebf5a)) +* Use equivalence information from equality assertions to simplify circuit ([#2378](https://github.com/noir-lang/noir/issues/2378)) ([ec5b021](https://github.com/noir-lang/noir/commit/ec5b0216ee3889c5e926d0d1ddcb74ef983269f6)) + + +### Bug Fixes + +* **acir_gen:** Pass accurate contents to slice inputs for bb func calls ([#2435](https://github.com/noir-lang/noir/issues/2435)) ([054642b](https://github.com/noir-lang/noir/commit/054642b0daa325476bb085f5a03b55fc63a8e5fc)) +* **acir:** Attach locations to MemoryOps in ACIR ([#2389](https://github.com/noir-lang/noir/issues/2389)) ([d7d7f22](https://github.com/noir-lang/noir/commit/d7d7f2273685606e8023ec90e93c48fdcb60202e)) +* Closure lvalue capture bugfix ([#2457](https://github.com/noir-lang/noir/issues/2457)) ([632006a](https://github.com/noir-lang/noir/commit/632006abd2400cca9a5a7ba21380ab5e33988a6b)) +* Correct off-by-one errors in lexer spans ([#2393](https://github.com/noir-lang/noir/issues/2393)) ([bbda9b0](https://github.com/noir-lang/noir/commit/bbda9b04be6c4f1ca3510f32d1abd8c2373aea54)) +* Divide by zero should fail to satisfy constraints for `Field` and ints ([#2475](https://github.com/noir-lang/noir/issues/2475)) ([1b85816](https://github.com/noir-lang/noir/commit/1b85816cb1f7539917ed9212c411613f29168add)) +* Implement handling of array aliasing in the mem2reg optimization pass ([#2463](https://github.com/noir-lang/noir/issues/2463)) ([7123fa9](https://github.com/noir-lang/noir/commit/7123fa9a4a55f5ea0ebdc502e8ff5eeb1a031709)) +* Implement new mem2reg pass ([#2420](https://github.com/noir-lang/noir/issues/2420)) ([7714cd0](https://github.com/noir-lang/noir/commit/7714cd01858d816d67b5b1319022ef849977d0da)) +* **lsp:** Remove duplicated creation of lenses ([#2433](https://github.com/noir-lang/noir/issues/2433)) ([41b568d](https://github.com/noir-lang/noir/commit/41b568d1950f45049a322e316fd9acfa52a43208)) +* **parser:** Fixes for the parsing of 'where' clauses ([#2430](https://github.com/noir-lang/noir/issues/2430)) ([fa31015](https://github.com/noir-lang/noir/commit/fa31015e76e5f747a218acb4dad8af3c3b7a78ef)) +* Remove duplicate `T` in `expected T, found T` error on tuple assignment ([#2360](https://github.com/noir-lang/noir/issues/2360)) ([c964ee8](https://github.com/noir-lang/noir/commit/c964ee8b54d8496b4de738395b4519d4cb36fb43)) +* Run `wasm` nodejs tests with no fails ([#2387](https://github.com/noir-lang/noir/issues/2387)) ([67b6710](https://github.com/noir-lang/noir/commit/67b67100bf46d3f101538bd3552ed63e5fbf654c)) +* Show types in error message in same order as in source code ([#2353](https://github.com/noir-lang/noir/issues/2353)) ([feebee4](https://github.com/noir-lang/noir/commit/feebee4cf567fa9cfd16db141851efb9a467a9cd)) +* **ssa:** Codegen missing check for unary minus ([#2413](https://github.com/noir-lang/noir/issues/2413)) ([1435a86](https://github.com/noir-lang/noir/commit/1435a86b0ae315abf7553e140dd091d0161ed7b5)) +* **ssa:** Do not optimize for allocates in constant folding ([#2466](https://github.com/noir-lang/noir/issues/2466)) ([9e272f3](https://github.com/noir-lang/noir/commit/9e272f39403afd61ff6a8fbe7655ac1698d9f845)) +* **ssa:** Remove padding from ToRadix call with constant inputs ([#2479](https://github.com/noir-lang/noir/issues/2479)) ([37bb781](https://github.com/noir-lang/noir/commit/37bb78192521fe5a2b1ae6b053772cf0fe472102)) + ## [0.10.3](https://github.com/noir-lang/noir/compare/v0.10.2...v0.10.3) (2023-08-16) diff --git a/Cargo.lock b/Cargo.lock index 647acb20e05..8e05b6a767c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "acir" -version = "0.22.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86577747c44f23e2e8e6d972287d01341c0eea42a78ce15c5efd212a39d0fc27" +checksum = "ddfd6bb6cb07ac4869c58d6e0219f447c2d550a9b2f135f27a6bc6ae0178c379" dependencies = [ "acir_field", "bincode", @@ -18,9 +18,9 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.22.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4239156a8eddd55b2ae8bd25aa169d012bae70e0fd7c635f08f68ada54a8cb6c" +checksum = "7f41bc6e6dab8bd68516970371d7dd897d09e9bf0aa17a72c5e51cefcdad6573" dependencies = [ "ark-bn254", "ark-ff", @@ -32,14 +32,13 @@ dependencies = [ [[package]] name = "acvm" -version = "0.22.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74351bab6e0fd2ec1bd631abc73260f374cc28d2baf85c0e11300c0c989d5e53" +checksum = "79eb3b6adc177c907e03b9414a45ef5b37100eb51503c573b3eaf383e93a7543" dependencies = [ "acir", "acvm_blackbox_solver", "acvm_stdlib", - "async-trait", "brillig_vm", "indexmap 1.9.3", "num-bigint", @@ -50,43 +49,52 @@ dependencies = [ [[package]] name = "acvm-backend-barretenberg" version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "438eb3837cfc37e0798e18f4a0ebae595e4cbe32a3f4cecfb47ccc1354180dc8" dependencies = [ "acvm", - "barretenberg-sys", - "bincode", - "bytesize", - "getrandom", - "pkg-config", + "build-target", + "const_format", + "dirs", + "flate2", "reqwest", - "rust-embed", "serde", - "serde-big-array", + "serde_json", + "tar", + "tempfile", + "test-binary", "thiserror", - "wasmer", ] [[package]] name = "acvm_blackbox_solver" -version = "0.22.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a362499180c6498acc0ebf77bd919be8ccd9adabc84a695d4af44ca180ba0709" +checksum = "3aac4ad683de5aebb590168405c46cdfd76dc7706a7d2c51d029258772d1933e" dependencies = [ "acir", "blake2", + "flate2", + "getrandom", + "hex", + "js-sys", "k256", + "num-bigint", "p256", + "pkg-config", + "reqwest", + "rust-embed", "sha2", "sha3", + "tar", "thiserror", + "wasm-bindgen-futures", + "wasmer", ] [[package]] name = "acvm_stdlib" -version = "0.22.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e485b3bc3331eaa10bc92fb092ca14275936c8935c3ae7ec89fb0bd48246ab42" +checksum = "e3344180fe2a59d57cdb0e6251cdc7d9978f15c06eace1af7d82bab12dd3ced9" dependencies = [ "acir", ] @@ -210,7 +218,7 @@ dependencies = [ [[package]] name = "arena" -version = "0.10.3" +version = "0.11.1" dependencies = [ "generational-arena", ] @@ -329,7 +337,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.5", + "rand", ] [[package]] @@ -388,17 +396,6 @@ dependencies = [ "waitpid-any", ] -[[package]] -name = "async-trait" -version = "0.1.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.26", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -420,20 +417,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "barretenberg-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f8fd58d1ca43e920a1a3b55d52c65ac25cd29f2820d4b2b1c24adafa2c403c" -dependencies = [ - "bindgen", - "cc", - "color-eyre", - "link-cplusplus", - "pkg-config", - "thiserror", -] - [[package]] name = "base16ct" version = "0.1.1" @@ -461,28 +444,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.64.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 1.0.109", - "which", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -536,9 +497,9 @@ dependencies = [ [[package]] name = "brillig" -version = "0.22.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64df3df7d2d96fc2519e4dd64bc6bc23eee2949ee86725d9041ef7703c283ab" +checksum = "448a380e86405ad785c235907654bea2080386d03c77a2003063ddabb853d744" dependencies = [ "acir_field", "serde", @@ -546,9 +507,9 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "0.22.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b306b3d79b6da192fd2ed68b94ab07712496f39bb5d50fedce44dac3f4953065" +checksum = "ed1097a496ff44eb2b8f01789dfefb5bbd9364b132d9c2446a4ca18090259bf6" dependencies = [ "acir", "acvm_blackbox_solver", @@ -578,6 +539,12 @@ dependencies = [ "safe-regex", ] +[[package]] +name = "build-target" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b" + [[package]] name = "bumpalo" version = "3.13.0" @@ -625,10 +592,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] -name = "bytesize" -version = "1.2.0" +name = "camino" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38fcc2979eff34a4b84e1cf9a1e3da42a7d44b3b690a40cdcb23e3d556cfb2e5" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] [[package]] name = "cast" @@ -642,15 +635,6 @@ version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -659,18 +643,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] @@ -679,7 +662,6 @@ version = "0.8.0" source = "git+https://github.com/jfecher/chumsky?rev=ad9d312#ad9d312d9ffbc66c14514fa2b5752f4127b44f1e" dependencies = [ "hashbrown 0.11.2", - "stacker", ] [[package]] @@ -709,17 +691,6 @@ dependencies = [ "half", ] -[[package]] -name = "clang-sys" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.3.19" @@ -1077,7 +1048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -1296,7 +1267,7 @@ dependencies = [ "generic-array", "group", "pkcs8", - "rand_core 0.6.4", + "rand_core", "sec1", "subtle", "zeroize", @@ -1416,10 +1387,22 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ - "rand_core 0.6.4", + "rand_core", "subtle", ] +[[package]] +name = "filetime" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "windows-sys 0.48.0", +] + [[package]] name = "findshlibs" version = "0.10.2" @@ -1453,7 +1436,7 @@ dependencies = [ [[package]] name = "fm" -version = "0.10.3" +version = "0.11.1" dependencies = [ "cfg-if", "codespan-reporting", @@ -1479,12 +1462,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "funty" version = "2.0.0" @@ -1605,7 +1582,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -1626,12 +1603,6 @@ version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "globset" version = "0.4.11" @@ -1676,7 +1647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -1906,7 +1877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" dependencies = [ "bitmaps", - "rand_core 0.6.4", + "rand_core", "rand_xoshiro", "sized-chunks", "typenum", @@ -1998,7 +1969,7 @@ dependencies = [ [[package]] name = "iter-extended" -version = "0.10.3" +version = "0.11.1" [[package]] name = "itertools" @@ -2051,12 +2022,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "leb128" version = "0.2.5" @@ -2069,25 +2034,6 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "link-cplusplus" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" -dependencies = [ - "cc", -] - [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -2190,12 +2136,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -2212,7 +2152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -2224,10 +2164,11 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "nargo" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "base64", + "codespan-reporting", "fm", "iter-extended", "noirc_abi", @@ -2242,7 +2183,7 @@ dependencies = [ [[package]] name = "nargo_cli" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "acvm-backend-barretenberg", @@ -2270,11 +2211,13 @@ dependencies = [ "pprof", "predicates 2.1.5", "prettytable-rs", + "rayon", "rustc_version", "serde", "serde_json", - "tempdir", + "tempfile", "termcolor", + "test-binary", "thiserror", "tokio", "tokio-util", @@ -2284,7 +2227,7 @@ dependencies = [ [[package]] name = "nargo_toml" -version = "0.10.3" +version = "0.11.1" dependencies = [ "dirs", "fm", @@ -2310,7 +2253,7 @@ dependencies = [ [[package]] name = "noir_lsp" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "async-lsp", @@ -2323,6 +2266,7 @@ dependencies = [ "noirc_driver", "noirc_errors", "noirc_frontend", + "serde", "serde_json", "tokio", "toml", @@ -2331,7 +2275,7 @@ dependencies = [ [[package]] name = "noir_wasm" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "build-data", @@ -2340,6 +2284,7 @@ dependencies = [ "getrandom", "gloo-utils", "log", + "nargo", "noirc_driver", "noirc_frontend", "serde", @@ -2349,11 +2294,13 @@ dependencies = [ [[package]] name = "noirc_abi" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "iter-extended", "noirc_frontend", + "num-bigint", + "num-traits", "serde", "serde_json", "strum", @@ -2362,9 +2309,26 @@ dependencies = [ "toml", ] +[[package]] +name = "noirc_abi_wasm" +version = "0.11.1" +dependencies = [ + "acvm", + "build-data", + "console_error_panic_hook", + "getrandom", + "gloo-utils", + "iter-extended", + "js-sys", + "noirc_abi", + "serde", + "wasm-bindgen", + "wasm-bindgen-test", +] + [[package]] name = "noirc_driver" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "base64", @@ -2379,7 +2343,7 @@ dependencies = [ [[package]] name = "noirc_errors" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "chumsky", @@ -2392,9 +2356,10 @@ dependencies = [ [[package]] name = "noirc_evaluator" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", + "fxhash", "im", "iter-extended", "noirc_abi", @@ -2406,7 +2371,7 @@ dependencies = [ [[package]] name = "noirc_frontend" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "arena", @@ -2427,7 +2392,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "0.10.3" +version = "0.11.1" dependencies = [ "acvm", "iter-extended", @@ -2437,16 +2402,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "normalize-line-endings" version = "0.3.0" @@ -2570,12 +2525,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "percent-encoding" version = "2.3.0" @@ -2755,15 +2704,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "psm" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" -dependencies = [ - "cc", -] - [[package]] name = "ptr_meta" version = "0.1.4" @@ -2808,19 +2748,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi", -] - [[package]] name = "rand" version = "0.8.5" @@ -2828,7 +2755,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "rand_chacha", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -2838,24 +2765,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.6.4" @@ -2871,7 +2783,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" dependencies = [ - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -2896,15 +2808,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redox_syscall" version = "0.2.16" @@ -2987,15 +2890,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" version = "0.4.0" @@ -3297,6 +3191,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -3338,6 +3238,9 @@ name = "semver" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +dependencies = [ + "serde", +] [[package]] name = "serde" @@ -3348,15 +3251,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-big-array" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" -dependencies = [ - "serde", -] - [[package]] name = "serde-wasm-bindgen" version = "0.4.5" @@ -3436,7 +3330,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.25", + "time", ] [[package]] @@ -3490,12 +3384,6 @@ dependencies = [ "dirs", ] -[[package]] -name = "shlex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" - [[package]] name = "signature" version = "1.6.4" @@ -3503,7 +3391,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ "digest", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -3593,19 +3481,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "stacker" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" -dependencies = [ - "cc", - "cfg-if", - "libc", - "psm", - "winapi", -] - [[package]] name = "static_assertions" version = "1.1.0" @@ -3701,20 +3576,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "target-lexicon" -version = "0.12.10" +name = "tar" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] [[package]] -name = "tempdir" -version = "0.3.7" +name = "target-lexicon" +version = "0.12.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -dependencies = [ - "rand 0.4.6", - "remove_dir_all", -] +checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" [[package]] name = "tempfile" @@ -3756,6 +3632,19 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +[[package]] +name = "test-binary" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb28771e7854f02e5705f2a1b09451d932a273f5a4ec1c9fa4c65882b8b7b6ca" +dependencies = [ + "camino", + "cargo_metadata", + "once_cell", + "paste", + "thiserror", +] + [[package]] name = "thiserror" version = "1.0.43" @@ -3786,17 +3675,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.25" @@ -3861,6 +3739,7 @@ dependencies = [ "bytes", "libc", "mio", + "num_cpus", "pin-project-lite", "socket2", "tokio-macros", @@ -4140,12 +4019,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4243,6 +4116,30 @@ version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +[[package]] +name = "wasm-bindgen-test" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e636f3a428ff62b3742ebc3c70e254dfe12b8c2b469d688ea59cdd4abcf502" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18c1fad2f7c4958e7bcce014fa212f59a65d5e3721d0f77e6c0b27ede936ba3" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "wasm-encoder" version = "0.31.0" @@ -4287,6 +4184,8 @@ dependencies = [ "wasmer-derive", "wasmer-types", "wasmer-vm", + "wasmparser 0.83.0", + "wasmparser 0.95.0", "wat", "winapi", ] @@ -4310,7 +4209,7 @@ dependencies = [ "thiserror", "wasmer-types", "wasmer-vm", - "wasmparser", + "wasmparser 0.95.0", "winapi", ] @@ -4388,6 +4287,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "wasmparser" +version = "0.83.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" + [[package]] name = "wasmparser" version = "0.95.0" @@ -4431,9 +4336,9 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" dependencies = [ "ring", "untrusted", @@ -4448,17 +4353,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "which" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" -dependencies = [ - "either", - "libc", - "once_cell", -] - [[package]] name = "winapi" version = "0.3.9" @@ -4635,6 +4529,15 @@ dependencies = [ "tap", ] +[[package]] +name = "xattr" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +dependencies = [ + "libc", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 998eb2bb65b..0120cb3cb8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,52 +1,61 @@ [workspace] members = [ - "crates/noirc_evaluator", - "crates/noirc_frontend", - "crates/noirc_errors", - "crates/noirc_driver", - "crates/noirc_printable_type", - "crates/nargo", - "crates/nargo_cli", - "crates/nargo_toml", - "crates/fm", - "crates/arena", - "crates/noirc_abi", - "crates/iter-extended", - "crates/wasm", + "compiler/noirc_evaluator", + "compiler/noirc_frontend", + "compiler/noirc_errors", + "compiler/noirc_driver", + "compiler/noirc_printable_type", + "compiler/fm", + "compiler/wasm", + # Utility crates used by the Noir compiler + "compiler/utils/arena", + "compiler/utils/iter-extended", + # Crates related to tooling built ontop of the Noir compiler + "tooling/acvm_backend_barretenberg", + "tooling/nargo", + "tooling/nargo_cli", + "tooling/nargo_toml", + "tooling/noirc_abi", + "tooling/noirc_abi_wasm", ] -default-members = ["crates/nargo_cli"] +default-members = ["tooling/nargo_cli"] +resolver = "2" [workspace.package] # x-release-please-start-version -version = "0.10.3" +version = "0.11.1" # x-release-please-end authors = ["The Noir Team "] edition = "2021" rust-version = "1.66" +license = "MIT OR Apache-2.0" [workspace.dependencies] -acvm = "0.22.0" -arena = { path = "crates/arena" } -fm = { path = "crates/fm" } -iter-extended = { path = "crates/iter-extended" } -nargo = { path = "crates/nargo" } -nargo_cli = { path = "crates/nargo_cli" } -nargo_toml = { path = "crates/nargo_toml" } -noir_lsp = { path = "crates/lsp" } -noirc_abi = { path = "crates/noirc_abi" } -noirc_driver = { path = "crates/noirc_driver" } -noirc_errors = { path = "crates/noirc_errors" } -noirc_evaluator = { path = "crates/noirc_evaluator" } -noirc_frontend = { path = "crates/noirc_frontend" } -noirc_printable_type = { path = "crates/noirc_printable_type" } -noir_wasm = { path = "crates/wasm" } +acvm = "0.26.1" +arena = { path = "compiler/utils/arena" } +fm = { path = "compiler/fm" } +iter-extended = { path = "compiler/utils/iter-extended" } +nargo = { path = "tooling/nargo" } +nargo_cli = { path = "tooling/nargo_cli" } +nargo_toml = { path = "tooling/nargo_toml" } +noir_lsp = { path = "tooling/lsp" } +noirc_abi = { path = "tooling/noirc_abi" } +noirc_driver = { path = "compiler/noirc_driver" } +noirc_errors = { path = "compiler/noirc_errors" } +noirc_evaluator = { path = "compiler/noirc_evaluator" } +noirc_frontend = { path = "compiler/noirc_frontend" } +noirc_printable_type = { path = "compiler/noirc_printable_type" } +noir_wasm = { path = "compiler/wasm" } cfg-if = "1.0.0" clap = { version = "4.3.19", features = ["derive"] } codespan = { version = "0.11.1", features = ["serialization"] } codespan-lsp = "0.11.1" codespan-reporting = "0.11.1" -chumsky = { git = "https://github.com/jfecher/chumsky", rev = "ad9d312" } +chumsky = { git = "https://github.com/jfecher/chumsky", rev = "ad9d312", default-features = false, features = [ + "ahash", + "std", +] } dirs = "4" lsp-types = "0.94" serde = { version = "1.0.136", features = ["derive"] } diff --git a/README.md b/README.md index 6958840fae8..22ace1fd3b4 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,6 @@ ACIR Supported OPCODES: - Sha256 - Blake2s - Schnorr signature verification -- MerkleMembership - Pedersen - HashToField diff --git a/compiler/fm/Cargo.toml b/compiler/fm/Cargo.toml new file mode 100644 index 00000000000..1f6d6dabcb1 --- /dev/null +++ b/compiler/fm/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "fm" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +codespan-reporting.workspace = true +cfg-if.workspace = true +rust-embed = "6.6.0" +serde.workspace = true + +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen.workspace = true + +[dev-dependencies] +tempfile = "3.2.0" +iter-extended.workspace = true diff --git a/crates/fm/build.rs b/compiler/fm/build.rs similarity index 100% rename from crates/fm/build.rs rename to compiler/fm/build.rs diff --git a/compiler/fm/src/file_map.rs b/compiler/fm/src/file_map.rs new file mode 100644 index 00000000000..199723a28b5 --- /dev/null +++ b/compiler/fm/src/file_map.rs @@ -0,0 +1,96 @@ +use codespan_reporting::files::{Error, Files, SimpleFile, SimpleFiles}; +use serde::{Deserialize, Serialize}; +use std::{ops::Range, path::PathBuf}; + +// XXX: File and FileMap serve as opaque types, so that the rest of the library does not need to import the dependency +// or worry about when we change the dep + +#[derive(Clone, Debug)] +pub struct PathString(PathBuf); + +impl std::fmt::Display for PathString { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + f.write_str(&self.0.to_string_lossy()) + } +} + +impl PathString { + pub fn from_path(p: PathBuf) -> Self { + PathString(p) + } +} +impl From for PathString { + fn from(pb: PathBuf) -> PathString { + PathString::from_path(pb) + } +} +impl From<&PathBuf> for PathString { + fn from(pb: &PathBuf) -> PathString { + PathString::from(pb.to_owned()) + } +} +#[derive(Debug)] +pub struct FileMap(SimpleFiles); + +// XXX: Note that we derive Default here due to ModuleOrigin requiring us to set a FileId +#[derive( + Default, Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize, PartialOrd, Ord, +)] +pub struct FileId(usize); + +impl FileId { + //XXX: find a way to remove the need for this. Errors do not need to attach their FileIds immediately! + pub fn as_usize(&self) -> usize { + self.0 + } + + pub fn dummy() -> FileId { + FileId(0) + } +} + +pub struct File<'input>(&'input SimpleFile); + +impl<'input> File<'input> { + pub fn source(self) -> &'input str { + self.0.source() + } +} + +impl FileMap { + pub fn add_file(&mut self, file_name: PathString, code: String) -> FileId { + let file_id = self.0.add(file_name, code); + FileId(file_id) + } + pub fn get_file(&self, file_id: FileId) -> Option { + self.0.get(file_id.0).map(File).ok() + } +} + +impl Default for FileMap { + fn default() -> Self { + FileMap(SimpleFiles::new()) + } +} + +impl<'a> Files<'a> for FileMap { + type FileId = FileId; + type Name = PathString; + type Source = &'a str; + + fn name(&self, file_id: Self::FileId) -> Result { + Ok(self.0.get(file_id.as_usize())?.name().clone()) + } + + fn source(&'a self, file_id: Self::FileId) -> Result { + Ok(self.0.get(file_id.as_usize())?.source().as_ref()) + } + + fn line_index(&self, file_id: Self::FileId, byte_index: usize) -> Result { + self.0.get(file_id.as_usize())?.line_index((), byte_index) + } + + fn line_range(&self, file_id: Self::FileId, line_index: usize) -> Result, Error> { + self.0.get(file_id.as_usize())?.line_range((), line_index) + } +} diff --git a/crates/fm/src/file_reader.rs b/compiler/fm/src/file_reader.rs similarity index 85% rename from crates/fm/src/file_reader.rs rename to compiler/fm/src/file_reader.rs index df4e49b919a..1a9b31ed949 100644 --- a/crates/fm/src/file_reader.rs +++ b/compiler/fm/src/file_reader.rs @@ -1,5 +1,5 @@ use rust_embed::RustEmbed; -use std::io::Error; +use std::io::{Error, ErrorKind}; use std::path::Path; // Based on the environment, we either read files using the rust standard library or we @@ -34,8 +34,6 @@ cfg_if::cfg_if! { } pub(crate) fn read_file_to_string(path_to_file: &Path) -> Result { - use std::io::ErrorKind; - let path_str = path_to_file.to_str().unwrap(); match StdLibAssets::get(path_str) { @@ -43,6 +41,10 @@ cfg_if::cfg_if! { Ok(std::str::from_utf8(std_lib_asset.data.as_ref()).unwrap().to_string()) }, + None if is_stdlib_asset(path_to_file) => { + Err(Error::new(ErrorKind::NotFound, "invalid stdlib path")) + } + None => match read_file(path_str) { Ok(buffer) => Ok(buffer), Err(_) => Err(Error::new(ErrorKind::Other, "could not read file using wasm")), @@ -60,6 +62,10 @@ cfg_if::cfg_if! { Ok(std::str::from_utf8(std_lib_asset.data.as_ref()).unwrap().to_string()) }, + None if is_stdlib_asset(path_to_file) => { + Err(Error::new(ErrorKind::NotFound, "invalid stdlib path")) + } + None => std::fs::read_to_string(path_to_file) } diff --git a/compiler/fm/src/lib.rs b/compiler/fm/src/lib.rs new file mode 100644 index 00000000000..f615555601c --- /dev/null +++ b/compiler/fm/src/lib.rs @@ -0,0 +1,296 @@ +#![forbid(unsafe_code)] +#![warn(unused_crate_dependencies, unused_extern_crates)] +#![warn(unreachable_pub)] +#![warn(clippy::semicolon_if_nothing_returned)] + +mod file_map; +mod file_reader; + +pub use file_map::{File, FileId, FileMap, PathString}; +use file_reader::is_stdlib_asset; + +use std::{ + collections::HashMap, + path::{Component, Path, PathBuf}, +}; + +pub const FILE_EXTENSION: &str = "nr"; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +struct VirtualPath(PathBuf); + +#[derive(Debug)] +pub struct FileManager { + root: PathBuf, + file_map: file_map::FileMap, + id_to_path: HashMap, + path_to_id: HashMap, +} + +impl FileManager { + pub fn new(root: &Path) -> Self { + Self { + root: root.normalize(), + file_map: Default::default(), + id_to_path: Default::default(), + path_to_id: Default::default(), + } + } + + pub fn as_file_map(&self) -> &FileMap { + &self.file_map + } + + pub fn add_file(&mut self, file_name: &Path) -> Option { + // Handle both relative file paths and std/lib virtual paths. + let resolved_path: PathBuf = if is_stdlib_asset(file_name) { + // Special case for stdlib where we want to read specifically the `std/` relative path + // TODO: The stdlib path should probably be an absolute path rooted in something people would never create + file_name.to_path_buf() + } else { + self.root.join(file_name).normalize() + }; + + // Check that the resolved path already exists in the file map, if it is, we return it. + let path_to_file = virtualize_path(&resolved_path); + if let Some(file_id) = self.path_to_id.get(&path_to_file) { + return Some(*file_id); + } + + // Otherwise we add the file + let source = file_reader::read_file_to_string(&resolved_path).ok()?; + let file_id = self.file_map.add_file(resolved_path.into(), source); + self.register_path(file_id, path_to_file); + Some(file_id) + } + + fn register_path(&mut self, file_id: FileId, path: VirtualPath) { + let old_value = self.id_to_path.insert(file_id, path.clone()); + assert!( + old_value.is_none(), + "ice: the same file id was inserted into the file manager twice" + ); + let old_value = self.path_to_id.insert(path, file_id); + assert!(old_value.is_none(), "ice: the same path was inserted into the file manager twice"); + } + + pub fn fetch_file(&self, file_id: FileId) -> File { + // Unwrap as we ensure that all file_id's map to a corresponding file in the file map + self.file_map.get_file(file_id).unwrap() + } + pub fn path(&self, file_id: FileId) -> &Path { + // Unwrap as we ensure that all file_ids are created by the file manager + // So all file_ids will points to a corresponding path + self.id_to_path.get(&file_id).unwrap().0.as_path() + } + + pub fn find_module(&mut self, anchor: FileId, mod_name: &str) -> Result { + let mut candidate_files = Vec::new(); + + let anchor_path = self.path(anchor).to_path_buf(); + let anchor_dir = anchor_path.parent().unwrap(); + + // First we attempt to look at `base/anchor/mod_name.nr` (child of the anchor) + candidate_files.push(anchor_path.join(format!("{mod_name}.{FILE_EXTENSION}"))); + // If not found, we attempt to look at `base/mod_name.nr` (sibling of the anchor) + candidate_files.push(anchor_dir.join(format!("{mod_name}.{FILE_EXTENSION}"))); + + for candidate in candidate_files.iter() { + if let Some(file_id) = self.add_file(candidate) { + return Ok(file_id); + } + } + + Err(candidate_files.remove(0).as_os_str().to_str().unwrap().to_owned()) + } +} + +pub trait NormalizePath { + /// Replacement for `std::fs::canonicalize` that doesn't verify the path exists. + /// + /// Plucked from https://github.com/rust-lang/cargo/blob/fede83ccf973457de319ba6fa0e36ead454d2e20/src/cargo/util/paths.rs#L61 + /// Advice from https://www.reddit.com/r/rust/comments/hkkquy/comment/fwtw53s/ + fn normalize(&self) -> PathBuf; +} + +impl NormalizePath for PathBuf { + fn normalize(&self) -> PathBuf { + let components = self.components(); + resolve_components(components) + } +} + +impl NormalizePath for &Path { + fn normalize(&self) -> PathBuf { + let components = self.components(); + resolve_components(components) + } +} + +fn resolve_components<'a>(components: impl Iterator>) -> PathBuf { + let mut components = components.peekable(); + + // Preserve path prefix if one exists. + let mut normalized_path = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { + components.next(); + PathBuf::from(c.as_os_str()) + } else { + PathBuf::new() + }; + + for component in components { + match component { + Component::Prefix(..) => unreachable!("Path cannot contain multiple prefixes"), + Component::RootDir => { + normalized_path.push(component.as_os_str()); + } + Component::CurDir => {} + Component::ParentDir => { + normalized_path.pop(); + } + Component::Normal(c) => { + normalized_path.push(c); + } + } + } + + normalized_path +} + +#[cfg(test)] +mod path_normalization { + use iter_extended::vecmap; + use std::path::PathBuf; + + use crate::NormalizePath; + + #[test] + fn normalizes_paths_correctly() { + // Note that tests are run on unix so prefix handling can't be tested (as these only exist on Windows) + let test_cases = vecmap( + [ + ("/", "/"), // Handles root + ("/foo/bar/../baz/../bar", "/foo/bar"), // Handles backtracking + ("/././././././././baz", "/baz"), // Removes no-ops + ], + |(unnormalized, normalized)| (PathBuf::from(unnormalized), PathBuf::from(normalized)), + ); + + for (path, expected_result) in test_cases { + assert_eq!(path.normalize(), expected_result); + } + } +} + +/// Takes a path to a noir file. This will panic on paths to directories +/// Returns the file path with the extension removed +fn virtualize_path(path: &Path) -> VirtualPath { + let path = path.to_path_buf(); + let base = path.parent().unwrap(); + let path_no_ext: PathBuf = + path.file_stem().expect("ice: this should have been the path to a file").into(); + let path = base.join(path_no_ext); + VirtualPath(path) +} +#[cfg(test)] +mod tests { + use super::*; + use tempfile::{tempdir, TempDir}; + + fn create_dummy_file(dir: &TempDir, file_name: &Path) { + let file_path = dir.path().join(file_name); + let _file = std::fs::File::create(file_path).unwrap(); + } + + #[test] + fn path_resolve_file_module() { + let dir = tempdir().unwrap(); + + let entry_file_name = Path::new("my_dummy_file.nr"); + create_dummy_file(&dir, entry_file_name); + + let mut fm = FileManager::new(dir.path()); + + let file_id = fm.add_file(entry_file_name).unwrap(); + + let dep_file_name = Path::new("foo.nr"); + create_dummy_file(&dir, dep_file_name); + fm.find_module(file_id, "foo").unwrap(); + } + #[test] + fn path_resolve_file_module_other_ext() { + let dir = tempdir().unwrap(); + let file_name = Path::new("foo.noir"); + create_dummy_file(&dir, file_name); + + let mut fm = FileManager::new(dir.path()); + + let file_id = fm.add_file(file_name).unwrap(); + + assert!(fm.path(file_id).ends_with("foo")); + } + #[test] + fn path_resolve_sub_module() { + let dir = tempdir().unwrap(); + let mut fm = FileManager::new(dir.path()); + + // Create a lib.nr file at the root. + // we now have dir/lib.nr + let file_name = Path::new("lib.nr"); + create_dummy_file(&dir, file_name); + + let file_id = fm.add_file(file_name).unwrap(); + + // Create a sub directory + // we now have: + // - dir/lib.nr + // - dir/sub_dir + let sub_dir = TempDir::new_in(&dir).unwrap(); + let sub_dir_name = sub_dir.path().file_name().unwrap().to_str().unwrap(); + + // Add foo.nr to the subdirectory + // we no have: + // - dir/lib.nr + // - dir/sub_dir/foo.nr + create_dummy_file(&sub_dir, Path::new("foo.nr")); + + // Add a parent module for the sub_dir + // we no have: + // - dir/lib.nr + // - dir/sub_dir.nr + // - dir/sub_dir/foo.nr + create_dummy_file(&dir, Path::new(&format!("{}.nr", sub_dir_name))); + + // First check for the sub_dir.nr file and add it to the FileManager + let sub_dir_file_id = fm.find_module(file_id, sub_dir_name).unwrap(); + + // Now check for files in it's subdirectory + fm.find_module(sub_dir_file_id, "foo").unwrap(); + } + + /// Tests that two identical files that have different paths are treated as the same file + /// e.g. if we start in the dir ./src and have a file ../../foo.nr + /// that should be treated as the same file as ../ starting in ./ + /// they should both resolve to ../foo.nr + #[test] + fn path_resolve_modules_with_different_paths_as_same_file() { + let dir = tempdir().unwrap(); + let sub_dir = TempDir::new_in(&dir).unwrap(); + let sub_sub_dir = TempDir::new_in(&sub_dir).unwrap(); + + let mut fm = FileManager::new(dir.path()); + + // Create a lib.nr file at the root. + let file_name = Path::new("lib.nr"); + create_dummy_file(&dir, file_name); + + // Create another path with `./` and `../` inside it + let second_file_name = PathBuf::from(sub_sub_dir.path()).join("./../../lib.nr"); + + // Add both files to the file manager + let file_id = fm.add_file(file_name).unwrap(); + let second_file_id = fm.add_file(&second_file_name).unwrap(); + + assert_eq!(file_id, second_file_id); + } +} diff --git a/compiler/integration-tests/.eslintrc.js b/compiler/integration-tests/.eslintrc.js new file mode 100644 index 00000000000..d17e4ef520c --- /dev/null +++ b/compiler/integration-tests/.eslintrc.js @@ -0,0 +1,19 @@ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint", "prettier"], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + rules: { + "comma-spacing": ["error", { before: false, after: true }], + // "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", // or "error" + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + caughtErrorsIgnorePattern: "^_", + }, + ], + "prettier/prettier": "error", + } +}; diff --git a/compiler/integration-tests/package.json b/compiler/integration-tests/package.json new file mode 100644 index 00000000000..71437172d9d --- /dev/null +++ b/compiler/integration-tests/package.json @@ -0,0 +1,35 @@ +{ + "name": "integration-tests", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", + "test:browser": "web-test-runner", + "test:node": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", + "test:integration:browser": "web-test-runner test//integration/browser/**/*.test.ts", + "test:integration:browser:watch": "web-test-runner test/integration/browser/**/*.test.ts --watch" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@esm-bundle/chai": "^4.3.4-fix.0", + "@web/dev-server-esbuild": "^0.3.6", + "@web/test-runner": "^0.15.3", + "@web/test-runner-webdriver": "^0.7.0", + "chai": "^4.3.7", + "fflate": "^0.8.0", + "mocha": "^10.2.0", + "smol-toml": "^1.1.2", + "ts-node": "^10.9.1", + "typescript": "^5.0.4" + }, + "dependencies": { + "@aztec/bb.js": "^0.5.1", + "@noir-lang/acvm_js": "./../../.packages/acvm_js", + "@noir-lang/noir-source-resolver": "^1.1.4", + "@noir-lang/noir_wasm": "./../../.packages/noir_wasm", + "@noir-lang/noirc_abi": "./../../.packages/noirc_abi_wasm" + } +} diff --git a/compiler/integration-tests/test/integration/browser/compile_prove_verify.test.ts b/compiler/integration-tests/test/integration/browser/compile_prove_verify.test.ts new file mode 100644 index 00000000000..e48a75acb51 --- /dev/null +++ b/compiler/integration-tests/test/integration/browser/compile_prove_verify.test.ts @@ -0,0 +1,157 @@ +import { expect } from '@esm-bundle/chai'; +import { initialiseResolver } from "@noir-lang/noir-source-resolver"; +import newCompiler, { + compile, + init_log_level as compilerLogLevel +} from "@noir-lang/noir_wasm"; +import { decompressSync as gunzip } from 'fflate'; +import newABICoder, { abiEncode } from "@noir-lang/noirc_abi"; +import initACVM, { + executeCircuit, + WitnessMap, + compressWitness, +} from "@noir-lang/acvm_js"; + +// @ts-ignore +import { Barretenberg, RawBuffer, Crs } from '@aztec/bb.js'; + +import * as TOML from 'smol-toml' + + +await newCompiler(); +await newABICoder(); +await initACVM(); + +compilerLogLevel("DEBUG"); + +async function getFile(url: URL): Promise { + + const response = await fetch(url) + + if (!response.ok) throw new Error('Network response was not OK'); + + return await response.text(); +} + +const CIRCUIT_SIZE = 2 ** 19; + + +const test_cases = [ + { + case: "tooling/nargo_cli/tests/execution_success/1_mul" + }, + { + case: "tooling/nargo_cli/tests/execution_success/double_verify_proof" + } +]; + +const numberOfThreads = navigator.hardwareConcurrency || 1; + +let suite = Mocha.Suite.create(mocha.suite, "Noir end to end test"); + +suite.timeout(60*20e3);//20mins + +test_cases.forEach((testInfo) => { + const test_name = testInfo.case.split("/").pop(); + const mochaTest = new Mocha.Test(`${test_name} (Compile, Execute, Prove, Verify)`, async () => { + + const base_relative_path = "../../../../.."; + const test_case = testInfo.case; + + const noir_source_url = new URL(`${base_relative_path}/${test_case}/src/main.nr`, import.meta.url); + const prover_toml_url = new URL(`${base_relative_path}/${test_case}/Prover.toml`, import.meta.url); + + const noir_source = await getFile(noir_source_url); + const prover_toml = await getFile(prover_toml_url); + + expect(noir_source).to.be.a.string; + + initialiseResolver((id: String) => { + console.log("Resolving:", id); + return noir_source; + }); + + const inputs = TOML.parse(prover_toml); + + expect(inputs, "Prover.toml").to.be.an('object'); + + let compile_output; + + try { + + compile_output = await compile({}); + + expect(await compile_output, "Compile output ").to.be.an('object'); + + } catch (e) { + expect(e, "Compilation Step").to.not.be.an('error'); + throw e; + } + + + let witnessMap: WitnessMap; + try { + + witnessMap = abiEncode(compile_output.abi, inputs, null); + + } catch (e) { + expect(e, "Abi Encoding Step").to.not.be.an('error'); + throw e; + } + + let solvedWitness: WitnessMap; + let compressedByteCode; + try { + compressedByteCode = Uint8Array.from(atob(compile_output.circuit), c => c.charCodeAt(0)); + + solvedWitness = await executeCircuit( + compressedByteCode, + witnessMap, + () => { + throw Error("unexpected oracle"); + } + ); + + } catch (e) { + expect(e, "Abi Encoding Step").to.not.be.an('error'); + throw e; + } + + try { + const compressedWitness = compressWitness(solvedWitness); + const acirUint8Array = gunzip(compressedByteCode); + const witnessUint8Array = gunzip(compressedWitness); + + const isRecursive = true; + const api = await Barretenberg.new(numberOfThreads); + await api.commonInitSlabAllocator(CIRCUIT_SIZE); + + // Plus 1 needed! + const crs = await Crs.new(CIRCUIT_SIZE + 1); + await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); + + const acirComposer = await api.acirNewAcirComposer(CIRCUIT_SIZE); + + // This took ~6.5 minutes! + const proof = await api.acirCreateProof( + acirComposer, + acirUint8Array, + witnessUint8Array, + isRecursive + ); + + // And this took ~5 minutes! + const verified = await api.acirVerifyProof(acirComposer, proof, isRecursive); + + expect(verified).to.be.true; + + } catch (e) { + expect(e, "Proving and Verifying").to.not.be.an('error'); + throw e; + } + + }); + + suite.addTest(mochaTest); + +}); diff --git a/compiler/integration-tests/web-test-runner.config.mjs b/compiler/integration-tests/web-test-runner.config.mjs new file mode 100644 index 00000000000..1f8b74c3b3b --- /dev/null +++ b/compiler/integration-tests/web-test-runner.config.mjs @@ -0,0 +1,31 @@ +import { fileURLToPath } from "url"; +import { esbuildPlugin } from "@web/dev-server-esbuild"; +import { webdriverLauncher } from "@web/test-runner-webdriver"; + +export default { + browsers: [ + webdriverLauncher({ + automationProtocol: "webdriver", + capabilities: { + browserName: "firefox", + "moz:firefoxOptions": { + args: ["-headless"], + }, + }, + }), + ], + plugins: [ + esbuildPlugin({ + ts: true, + }), + ], + files: ["test/integration/browser/**/*.test.ts"], + nodeResolve: { browser: true }, + testFramework: { + config: { + ui: "bdd", + }, + }, + rootDir: fileURLToPath(new URL("./../..", import.meta.url)), + testsFinishTimeout: 60 * 20e3, // 20 minutes +}; diff --git a/compiler/integration-tests/yarn.lock b/compiler/integration-tests/yarn.lock new file mode 100644 index 00000000000..4afb20e071e --- /dev/null +++ b/compiler/integration-tests/yarn.lock @@ -0,0 +1,4200 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@75lb/deep-merge@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@75lb/deep-merge/-/deep-merge-1.1.1.tgz#3b06155b90d34f5f8cc2107d796f1853ba02fd6d" + integrity sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw== + dependencies: + lodash.assignwith "^4.2.0" + typical "^7.1.1" + +"@aztec/bb.js@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@aztec/bb.js/-/bb.js-0.5.1.tgz#3c322a82834fc8c78aebc0d39add62f7bc08e78d" + integrity sha512-6464VrHgztws/rejJG0b3RUbycQ6subNoYODtuz7yDSZ9/s32ikjYOYADcAqSdK3QsohCifIvmkyis+KOpyJYQ== + dependencies: + comlink "^4.4.1" + commander "^10.0.1" + debug "^4.3.4" + tslib "^2.4.0" + +"@babel/code-frame@^7.12.11", "@babel/code-frame@^7.21.4": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz#601fa28e4cc06786c18912dca138cec73b882044" + integrity sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ== + +"@babel/highlight@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.13.tgz#9cda839e5d3be9ca9e8c26b6dd69e7548f0cbf16" + integrity sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== + +"@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + +"@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + +"@esbuild/darwin-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" + integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== + +"@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + +"@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + +"@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + +"@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + +"@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + +"@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== + +"@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + +"@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + +"@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + +"@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + +"@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + +"@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + +"@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + +"@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + +"@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + +"@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + +"@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + +"@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== + +"@esm-bundle/chai@^4.3.4-fix.0": + version "4.3.4-fix.0" + resolved "https://registry.yarnpkg.com/@esm-bundle/chai/-/chai-4.3.4-fix.0.tgz#3084cff7eb46d741749f47f3a48dbbdcbaf30a92" + integrity sha512-26SKdM4uvDWlY8/OOOxSB1AqQWeBosCX3wRYUZO7enTAj03CtVxIiCimYVG2WpULcyV51qapK4qTovwkUr5Mlw== + dependencies: + "@types/chai" "^4.2.12" + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.12": + version "0.3.19" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@mdn/browser-compat-data@^4.0.0": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@mdn/browser-compat-data/-/browser-compat-data-4.2.1.tgz#1fead437f3957ceebe2e8c3f46beccdb9bc575b8" + integrity sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@noir-lang/acvm_js@./../../.packages/acvm_js": + version "0.26.0" + +"@noir-lang/noir-source-resolver@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@noir-lang/noir-source-resolver/-/noir-source-resolver-1.1.4.tgz#ed18247c8c30ac45d71f115c0834c1276a4b106f" + integrity sha512-jmUcEoRXRSyhPyOqeDGi3E/7rYRVyqiNR0YQkwqH2G/WyvlHL2o2Ltk2N9iYKMNm1la0ri35Nz9OvIeeXjI4wA== + +"@noir-lang/noir_wasm@./../../.packages/noir_wasm": + version "0.11.1" + +"@noir-lang/noirc_abi@./../../.packages/noirc_abi_wasm": + version "0.8.0" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@puppeteer/browsers@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-0.5.0.tgz#1a1ee454b84a986b937ca2d93146f25a3fe8b670" + integrity sha512-Uw6oB7VvmPRLE4iKsjuOh8zgDabhNX67dzo8U/BB0f9527qx+4eeUs+korU98OhG5C4ubg7ufBgVi63XYwS6TQ== + dependencies: + debug "4.3.4" + extract-zip "2.0.1" + https-proxy-agent "5.0.1" + progress "2.0.3" + proxy-from-env "1.1.0" + tar-fs "2.1.1" + unbzip2-stream "1.4.3" + yargs "17.7.1" + +"@puppeteer/browsers@1.4.6": + version "1.4.6" + resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-1.4.6.tgz#1f70fd23d5d2ccce9d29b038e5039d7a1049ca77" + integrity sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ== + dependencies: + debug "4.3.4" + extract-zip "2.0.1" + progress "2.0.3" + proxy-agent "6.3.0" + tar-fs "3.0.4" + unbzip2-stream "1.4.3" + yargs "17.7.1" + +"@puppeteer/browsers@^1.6.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-1.7.0.tgz#714a25ad6963f5478e36004ea7eda254870a4659" + integrity sha512-sl7zI0IkbQGak/+IE3VEEZab5SSOlI5F6558WvzWGC1n3+C722rfewC1ZIkcF9dsoGSsxhsONoseVlNQG4wWvQ== + dependencies: + debug "4.3.4" + extract-zip "2.0.1" + progress "2.0.3" + proxy-agent "6.3.0" + tar-fs "3.0.4" + unbzip2-stream "1.4.3" + yargs "17.7.1" + +"@rollup/plugin-node-resolve@^13.0.4": + version "13.3.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz#da1c5c5ce8316cef96a2f823d111c1e4e498801c" + integrity sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + deepmerge "^4.2.2" + is-builtin-module "^3.1.0" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@sindresorhus/is@^5.2.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" + integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== + +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + +"@tootallnate/quickjs-emscripten@^0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c" + integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA== + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@types/accepts@*": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== + dependencies: + "@types/node" "*" + +"@types/babel__code-frame@^7.0.2": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@types/babel__code-frame/-/babel__code-frame-7.0.3.tgz#eda94e1b7c9326700a4b69c485ebbc9498a0b63f" + integrity sha512-2TN6oiwtNjOezilFVl77zwdNPwQWaDBBCCWWxyo1ctiO3vAtd7H/aB/CBJdw9+kqq3+latD0SXoedIuHySSZWw== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/chai@^4.2.12": + version "4.3.6" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.6.tgz#7b489e8baf393d5dd1266fb203ddd4ea941259e6" + integrity sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw== + +"@types/co-body@^6.1.0": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@types/co-body/-/co-body-6.1.1.tgz#28d253c95cfbe30c8e8c5d69d4c0dbbcffc101c2" + integrity sha512-I9A1k7o4m8m6YPYJIGb1JyNTLqRWtSPg1JOZPWlE19w8Su2VRgRVp/SkKftQSwoxWHGUxGbON4jltONMumC8bQ== + dependencies: + "@types/node" "*" + "@types/qs" "*" + +"@types/command-line-args@^5.0.0": + version "5.2.1" + resolved "https://registry.yarnpkg.com/@types/command-line-args/-/command-line-args-5.2.1.tgz#233bd1ba687e84ecbec0388e09f9ec9ebf63c55b" + integrity sha512-U2OcmS2tj36Yceu+mRuPyUV0ILfau/h5onStcSCzqTENsq0sBiAp2TmaXu1k8fY4McLcPKSYl9FRzn2hx5bI+w== + +"@types/connect@*": + version "3.4.36" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.36.tgz#e511558c15a39cb29bd5357eebb57bd1459cd1ab" + integrity sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w== + dependencies: + "@types/node" "*" + +"@types/content-disposition@*": + version "0.5.6" + resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.6.tgz#0f5fa03609f308a7a1a57e0b0afe4b95f1d19740" + integrity sha512-GmShTb4qA9+HMPPaV2+Up8tJafgi38geFi7vL4qAM7k8BwjoelgHZqEUKJZLvughUw22h6vD/wvwN4IUCaWpDA== + +"@types/convert-source-map@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/convert-source-map/-/convert-source-map-2.0.1.tgz#e72e8a3de9d6fe3d8e43d5c101c346de2ff6abdf" + integrity sha512-tm5Eb3AwhibN6ULRaad5TbNO83WoXVZLh2YRGAFH+qWkUz48l9Hu1jc+wJswB7T+ACWAG0cFnTeeQGpwedvlNw== + +"@types/cookies@*": + version "0.7.8" + resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.7.8.tgz#16fccd6d58513a9833c527701a90cc96d216bc18" + integrity sha512-y6KhF1GtsLERUpqOV+qZJrjUGzc0GE6UTa0b5Z/LZ7Nm2mKSdCXmS6Kdnl7fctPNnMSouHjxqEWI12/YqQfk5w== + dependencies: + "@types/connect" "*" + "@types/express" "*" + "@types/keygrip" "*" + "@types/node" "*" + +"@types/debounce@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/debounce/-/debounce-1.2.1.tgz#79b65710bc8b6d44094d286aecf38e44f9627852" + integrity sha512-epMsEE85fi4lfmJUH/89/iV/LI+F5CvNIvmgs5g5jYFPfhO2S/ae8WSsLOKWdwtoaZw9Q2IhJ4tQ5tFCcS/4HA== + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/express-serve-static-core@^4.17.33": + version "4.17.36" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz#baa9022119bdc05a4adfe740ffc97b5f9360e545" + integrity sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*": + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/http-assert@*": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.3.tgz#ef8e3d1a8d46c387f04ab0f2e8ab8cb0c5078661" + integrity sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA== + +"@types/http-cache-semantics@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + +"@types/http-errors@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65" + integrity sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.1", "@types/istanbul-lib-coverage@^2.0.3": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/keygrip@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" + integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw== + +"@types/koa-compose@*": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.5.tgz#85eb2e80ac50be95f37ccf8c407c09bbe3468e9d" + integrity sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ== + dependencies: + "@types/koa" "*" + +"@types/koa@*", "@types/koa@^2.11.6": + version "2.13.8" + resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.8.tgz#4302d2f2712348aadb6c0b03eb614f30afde486b" + integrity sha512-Ugmxmgk/yPRW3ptBTh9VjOLwsKWJuGbymo1uGX0qdaqqL18uJiiG1ZoV0rxCOYSaDGhvEp5Ece02Amx0iwaxQQ== + dependencies: + "@types/accepts" "*" + "@types/content-disposition" "*" + "@types/cookies" "*" + "@types/http-assert" "*" + "@types/http-errors" "*" + "@types/keygrip" "*" + "@types/koa-compose" "*" + "@types/node" "*" + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/mocha@^8.2.0": + version "8.2.3" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" + integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== + +"@types/node@*", "@types/node@^20.1.0": + version "20.5.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.9.tgz#a70ec9d8fa0180a314c3ede0e20ea56ff71aed9a" + integrity sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ== + +"@types/normalize-package-data@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + +"@types/parse5@^6.0.1": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb" + integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g== + +"@types/qs@*": + version "6.9.8" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.8.tgz#f2a7de3c107b89b441e071d5472e6b726b4adf45" + integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + +"@types/send@*": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.1.tgz#ed4932b8a2a805f1fe362a70f4e62d0ac994e301" + integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.2.tgz#3e5419ecd1e40e7405d34093f10befb43f63381a" + integrity sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + +"@types/which@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/which/-/which-2.0.2.tgz#54541d02d6b1daee5ec01ac0d1b37cecf37db1ae" + integrity sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw== + +"@types/ws@^7.4.0": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.3": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb" + integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg== + dependencies: + "@types/node" "*" + +"@types/yauzl@^2.9.1": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" + integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== + dependencies: + "@types/node" "*" + +"@wdio/config@8.16.3": + version "8.16.3" + resolved "https://registry.yarnpkg.com/@wdio/config/-/config-8.16.3.tgz#c9b6636a1eefffc268b7ca64c5b597210e086bea" + integrity sha512-jSiv+lG/hHmVz933oXw+7rI51wGQSsxpxZTOjSylrQz6pngUrB/RxApPSX4VLPZfKxkucxHQ4PO5nuJ8satusg== + dependencies: + "@wdio/logger" "8.11.0" + "@wdio/types" "8.16.3" + "@wdio/utils" "8.16.3" + decamelize "^6.0.0" + deepmerge-ts "^5.0.0" + glob "^10.2.2" + import-meta-resolve "^3.0.0" + read-pkg-up "^10.0.0" + +"@wdio/logger@8.11.0", "@wdio/logger@^8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@wdio/logger/-/logger-8.11.0.tgz#df28cb65d7b9e308a0cd1445a99adc8b5730174c" + integrity sha512-IsuKSaYi7NKEdgA57h8muzlN/MVp1dQG+V4C//7g4m03YJUnNQLvDhJzLjdeNTfvZy61U7foQSyt+3ktNzZkXA== + dependencies: + chalk "^5.1.2" + loglevel "^1.6.0" + loglevel-plugin-prefix "^0.8.4" + strip-ansi "^7.1.0" + +"@wdio/protocols@8.14.6": + version "8.14.6" + resolved "https://registry.yarnpkg.com/@wdio/protocols/-/protocols-8.14.6.tgz#357db1b304244039e8befb036cdf891d826d69fd" + integrity sha512-KM2taEMUDEt1of0Na/6kIv/aNzX0pmr0etpKRci4QrWPQ1O11dXxWjkatFILQz6qOVKvQ0v+vkTPQRUllmH+uQ== + +"@wdio/repl@8.10.1": + version "8.10.1" + resolved "https://registry.yarnpkg.com/@wdio/repl/-/repl-8.10.1.tgz#4f1858335d510b3a73432be163ef303aa79db362" + integrity sha512-VZ1WFHTNKjR8Ga97TtV2SZM6fvRjWbYI2i/f4pJB4PtusorKvONAMJf2LQcUBIyzbVobqr7KSrcjmSwRolI+yw== + dependencies: + "@types/node" "^20.1.0" + +"@wdio/types@8.16.3": + version "8.16.3" + resolved "https://registry.yarnpkg.com/@wdio/types/-/types-8.16.3.tgz#0d11cf2027aa5b62d82c0ffb4664ef209e565e70" + integrity sha512-cH6eKNKkx5ZVJxf7omwtqt88N/mI8Hn2qnXe4DHIYNC4wSDFPhSsuurRhH7s7fnk3biLEQfinuc3cxV0HefSVw== + dependencies: + "@types/node" "^20.1.0" + +"@wdio/utils@8.16.3": + version "8.16.3" + resolved "https://registry.yarnpkg.com/@wdio/utils/-/utils-8.16.3.tgz#4c67928a61ab25b0862a9a44210ed0134501d619" + integrity sha512-bX/sYOM+tI4hjMIcvSdL522c2xwkas6pII6AUhuBT2UIUkJnp7+OHijJ1l5kHAzRewCdcL3W4dm9exPH2URU+Q== + dependencies: + "@puppeteer/browsers" "^1.6.0" + "@wdio/logger" "8.11.0" + "@wdio/types" "8.16.3" + decamelize "^6.0.0" + deepmerge-ts "^5.1.0" + edgedriver "^5.3.5" + geckodriver "^4.2.0" + get-port "^7.0.0" + got "^13.0.0" + import-meta-resolve "^3.0.0" + locate-app "^2.1.0" + safaridriver "^0.1.0" + wait-port "^1.0.4" + +"@web/browser-logs@^0.2.6": + version "0.2.6" + resolved "https://registry.yarnpkg.com/@web/browser-logs/-/browser-logs-0.2.6.tgz#ec936f78c7cf7b0ef9fb990c0097a3da1a756b20" + integrity sha512-CNjNVhd4FplRY8PPWIAt02vAowJAVcOoTNrR/NNb/o9pka7yI9qdjpWrWhEbPr2pOXonWb52AeAgdK66B8ZH7w== + dependencies: + errorstacks "^2.2.0" + +"@web/browser-logs@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@web/browser-logs/-/browser-logs-0.3.3.tgz#121e5b662db2707c4b8cd1628d86903f059f5031" + integrity sha512-wt8arj0x7ghXbnipgCvLR+xQ90cFg16ae23cFbInCrJvAxvyI22bAtT24W4XOXMPXwWLBVUJwBgBcXo3oKIvDw== + dependencies: + errorstacks "^2.2.0" + +"@web/config-loader@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@web/config-loader/-/config-loader-0.1.3.tgz#8325ea54f75ef2ee7166783e64e66936db25bff7" + integrity sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ== + dependencies: + semver "^7.3.4" + +"@web/dev-server-core@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@web/dev-server-core/-/dev-server-core-0.4.1.tgz#803faff45281ee296d0dda02dfdd905c330db4d8" + integrity sha512-KdYwejXZwIZvb6tYMCqU7yBiEOPfKLQ3V9ezqqEz8DA9V9R3oQWaowckvCpFB9IxxPfS/P8/59OkdzGKQjcIUw== + dependencies: + "@types/koa" "^2.11.6" + "@types/ws" "^7.4.0" + "@web/parse5-utils" "^1.3.1" + chokidar "^3.4.3" + clone "^2.1.2" + es-module-lexer "^1.0.0" + get-stream "^6.0.0" + is-stream "^2.0.0" + isbinaryfile "^5.0.0" + koa "^2.13.0" + koa-etag "^4.0.0" + koa-send "^5.0.1" + koa-static "^5.0.0" + lru-cache "^6.0.0" + mime-types "^2.1.27" + parse5 "^6.0.1" + picomatch "^2.2.2" + ws "^7.4.2" + +"@web/dev-server-core@^0.5.1": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@web/dev-server-core/-/dev-server-core-0.5.2.tgz#27fe5448e587a87272b556b44ce84c6453655cdb" + integrity sha512-7YjWmwzM+K5fPvBCXldUIMTK4EnEufi1aWQWinQE81oW1CqzEwmyUNCtnWV9fcPA4kJC4qrpcjWNGF4YDWxuSg== + dependencies: + "@types/koa" "^2.11.6" + "@types/ws" "^7.4.0" + "@web/parse5-utils" "^2.0.0" + chokidar "^3.4.3" + clone "^2.1.2" + es-module-lexer "^1.0.0" + get-stream "^6.0.0" + is-stream "^2.0.0" + isbinaryfile "^5.0.0" + koa "^2.13.0" + koa-etag "^4.0.0" + koa-send "^5.0.1" + koa-static "^5.0.0" + lru-cache "^8.0.4" + mime-types "^2.1.27" + parse5 "^6.0.1" + picomatch "^2.2.2" + ws "^7.4.2" + +"@web/dev-server-esbuild@^0.3.6": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@web/dev-server-esbuild/-/dev-server-esbuild-0.3.6.tgz#838100894937443b96bfc4266c7795d27ed4afac" + integrity sha512-VDcZOzvmbg/z/8Q54hHqFwt9U4cacQJZxgS8YXAvyFuG85HAJ/Q55P7Tr++1NlRS8wQEos6QK2ERUWNjEVOhqQ== + dependencies: + "@mdn/browser-compat-data" "^4.0.0" + "@web/dev-server-core" "^0.4.1" + esbuild "^0.16 || ^0.17" + parse5 "^6.0.1" + ua-parser-js "^1.0.33" + +"@web/dev-server-rollup@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@web/dev-server-rollup/-/dev-server-rollup-0.4.1.tgz#3c6606bac8e497498b5b47bf9e0c544c321b38ef" + integrity sha512-Ebsv7Ovd9MufeH3exvikBJ7GmrZA5OmHnOgaiHcwMJ2eQBJA5/I+/CbRjsLX97ICj/ZwZG//p2ITRz8W3UfSqg== + dependencies: + "@rollup/plugin-node-resolve" "^13.0.4" + "@web/dev-server-core" "^0.4.1" + nanocolors "^0.2.1" + parse5 "^6.0.1" + rollup "^2.67.0" + whatwg-url "^11.0.0" + +"@web/dev-server@^0.1.38": + version "0.1.38" + resolved "https://registry.yarnpkg.com/@web/dev-server/-/dev-server-0.1.38.tgz#d755092d66aeb923c546237a6c460439ea3ddd29" + integrity sha512-WUq7Zi8KeJ5/UZmmpZ+kzUpUlFlMP/rcreJKYg9Lxiz998KYl4G5Rv24akX0piTuqXG7r6h+zszg8V/hdzjCoA== + dependencies: + "@babel/code-frame" "^7.12.11" + "@types/command-line-args" "^5.0.0" + "@web/config-loader" "^0.1.3" + "@web/dev-server-core" "^0.4.1" + "@web/dev-server-rollup" "^0.4.1" + camelcase "^6.2.0" + command-line-args "^5.1.1" + command-line-usage "^7.0.1" + debounce "^1.2.0" + deepmerge "^4.2.2" + ip "^1.1.5" + nanocolors "^0.2.1" + open "^8.0.2" + portfinder "^1.0.32" + +"@web/parse5-utils@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@web/parse5-utils/-/parse5-utils-1.3.1.tgz#6727be4d7875a9ecb96a5b3003bd271da763f8b4" + integrity sha512-haCgDchZrAOB9EhBJ5XqiIjBMsS/exsM5Ru7sCSyNkXVEJWskyyKuKMFk66BonnIGMPpDtqDrTUfYEis5Zi3XA== + dependencies: + "@types/parse5" "^6.0.1" + parse5 "^6.0.1" + +"@web/parse5-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@web/parse5-utils/-/parse5-utils-2.0.1.tgz#11b91417165a838954dcf228383cfd8e1bdaf914" + integrity sha512-FQI72BU5CXhpp7gLRskOQGGCcwvagLZnMnDwAfjrxo3pm1KOQzr8Vl+438IGpHV62xvjNdF1pjXwXcf7eekWGw== + dependencies: + "@types/parse5" "^6.0.1" + parse5 "^6.0.1" + +"@web/test-runner-chrome@^0.12.1": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@web/test-runner-chrome/-/test-runner-chrome-0.12.1.tgz#3f4d7b83565807d75a84907ffd91ae1bd2298a52" + integrity sha512-QxzinqYHelZQpMHAuc5TYyWVhtHUEGhL3m1p2U+mTTTWrZYX3D0s6Q0oL2+XYT1dsja5sd71h7yiBTb9ctkKOg== + dependencies: + "@web/test-runner-core" "^0.10.29" + "@web/test-runner-coverage-v8" "^0.5.0" + chrome-launcher "^0.15.0" + puppeteer-core "^19.8.1" + +"@web/test-runner-commands@^0.6.6": + version "0.6.6" + resolved "https://registry.yarnpkg.com/@web/test-runner-commands/-/test-runner-commands-0.6.6.tgz#e0e8c4ce6dcd91e5b18cf2212511ee6108e31070" + integrity sha512-2DcK/+7f8QTicQpGFq/TmvKHDK/6Zald6rn1zqRlmj3pcH8fX6KHNVMU60Za9QgAKdorMBPfd8dJwWba5otzdw== + dependencies: + "@web/test-runner-core" "^0.10.29" + mkdirp "^1.0.4" + +"@web/test-runner-core@^0.10.20", "@web/test-runner-core@^0.10.29": + version "0.10.29" + resolved "https://registry.yarnpkg.com/@web/test-runner-core/-/test-runner-core-0.10.29.tgz#d8d909c849151cf19013d6084f89a31e400557d5" + integrity sha512-0/ZALYaycEWswHhpyvl5yqo0uIfCmZe8q14nGPi1dMmNiqLcHjyFGnuIiLexI224AW74ljHcHllmDlXK9FUKGA== + dependencies: + "@babel/code-frame" "^7.12.11" + "@types/babel__code-frame" "^7.0.2" + "@types/co-body" "^6.1.0" + "@types/convert-source-map" "^2.0.0" + "@types/debounce" "^1.2.0" + "@types/istanbul-lib-coverage" "^2.0.3" + "@types/istanbul-reports" "^3.0.0" + "@web/browser-logs" "^0.2.6" + "@web/dev-server-core" "^0.4.1" + chokidar "^3.4.3" + cli-cursor "^3.1.0" + co-body "^6.1.0" + convert-source-map "^2.0.0" + debounce "^1.2.0" + dependency-graph "^0.11.0" + globby "^11.0.1" + ip "^1.1.5" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-report "^3.0.0" + istanbul-reports "^3.0.2" + log-update "^4.0.0" + nanocolors "^0.2.1" + nanoid "^3.1.25" + open "^8.0.2" + picomatch "^2.2.2" + source-map "^0.7.3" + +"@web/test-runner-core@^0.11.1": + version "0.11.4" + resolved "https://registry.yarnpkg.com/@web/test-runner-core/-/test-runner-core-0.11.4.tgz#590994c3fc69337e2c5411bf11c293dd061cc07a" + integrity sha512-E7BsKAP8FAAEsfj4viASjmuaYfOw4UlKP9IFqo4W20eVyd1nbUWU3Amq4Jksh7W/j811qh3VaFNjDfCwklQXMg== + dependencies: + "@babel/code-frame" "^7.12.11" + "@types/babel__code-frame" "^7.0.2" + "@types/co-body" "^6.1.0" + "@types/convert-source-map" "^2.0.0" + "@types/debounce" "^1.2.0" + "@types/istanbul-lib-coverage" "^2.0.3" + "@types/istanbul-reports" "^3.0.0" + "@web/browser-logs" "^0.3.2" + "@web/dev-server-core" "^0.5.1" + chokidar "^3.4.3" + cli-cursor "^3.1.0" + co-body "^6.1.0" + convert-source-map "^2.0.0" + debounce "^1.2.0" + dependency-graph "^0.11.0" + globby "^11.0.1" + ip "^1.1.5" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-report "^3.0.1" + istanbul-reports "^3.0.2" + log-update "^4.0.0" + nanocolors "^0.2.1" + nanoid "^3.1.25" + open "^8.0.2" + picomatch "^2.2.2" + source-map "^0.7.3" + +"@web/test-runner-coverage-v8@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.5.0.tgz#d1b033fd4baddaf5636a41cd017e321a338727a6" + integrity sha512-4eZs5K4JG7zqWEhVSO8utlscjbVScV7K6JVwoWWcObFTGAaBMbDVzwGRimyNSzvmfTdIO/Arze4CeUUfCl4iLQ== + dependencies: + "@web/test-runner-core" "^0.10.20" + istanbul-lib-coverage "^3.0.0" + picomatch "^2.2.2" + v8-to-istanbul "^9.0.1" + +"@web/test-runner-mocha@^0.7.5": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@web/test-runner-mocha/-/test-runner-mocha-0.7.5.tgz#696f8cb7f5118a72bd7ac5778367ae3bd3fb92cd" + integrity sha512-12/OBq6efPCAvJpcz3XJs2OO5nHe7GtBibZ8Il1a0QtsGpRmuJ4/m1EF0Fj9f6KHg7JdpGo18A37oE+5hXjHwg== + dependencies: + "@types/mocha" "^8.2.0" + "@web/test-runner-core" "^0.10.20" + +"@web/test-runner-webdriver@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@web/test-runner-webdriver/-/test-runner-webdriver-0.7.0.tgz#cbe64cddbc84e4a7739f2211b3aa85bbe83bf9cd" + integrity sha512-E36l4mvJeHF7KvU26Mv+iGGk20Yi94lhz7xcu7l51yJFpUxNPYbl4d2xzYIFY8+FjtKaBjFNAwfFyXMUGZMetA== + dependencies: + "@web/test-runner-core" "^0.11.1" + webdriverio "^8.8.6" + +"@web/test-runner@^0.15.3": + version "0.15.3" + resolved "https://registry.yarnpkg.com/@web/test-runner/-/test-runner-0.15.3.tgz#8cf51293e5889c5db63c75fb7d422b5c820dcf01" + integrity sha512-unwBymuQpI8yc/129K9H0aIzLIIQFrr2/mhdcIWFeZjjw5X3TJh57p5NFOA76nhlBSjFHyu0U0FXw9uOzXUCuQ== + dependencies: + "@web/browser-logs" "^0.2.6" + "@web/config-loader" "^0.1.3" + "@web/dev-server" "^0.1.38" + "@web/test-runner-chrome" "^0.12.1" + "@web/test-runner-commands" "^0.6.6" + "@web/test-runner-core" "^0.10.29" + "@web/test-runner-mocha" "^0.7.5" + camelcase "^6.2.0" + command-line-args "^5.1.1" + command-line-usage "^7.0.1" + convert-source-map "^2.0.0" + diff "^5.0.0" + globby "^11.0.1" + nanocolors "^0.2.1" + portfinder "^1.0.32" + source-map "^0.7.3" + +accepts@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + dependencies: + debug "^4.3.4" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +archiver-utils@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-4.0.1.tgz#66ad15256e69589a77f706c90c6dbcc1b2775d2a" + integrity sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg== + dependencies: + glob "^8.0.0" + graceful-fs "^4.2.0" + lazystream "^1.0.0" + lodash "^4.17.15" + normalize-path "^3.0.0" + readable-stream "^3.6.0" + +archiver@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-6.0.1.tgz#d56968d4c09df309435adb5a1bbfc370dae48133" + integrity sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ== + dependencies: + archiver-utils "^4.0.1" + async "^3.2.4" + buffer-crc32 "^0.2.1" + readable-stream "^3.6.0" + readdir-glob "^1.1.2" + tar-stream "^3.0.0" + zip-stream "^5.0.1" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-query@^5.0.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-6.2.2.tgz#f567d99e9af88a6d3d2f9dfcc21db6f9ba9fd157" + integrity sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +ast-types@^0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" + integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w== + dependencies: + tslib "^2.0.1" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +async@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + +b4a@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" + integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +basic-ftp@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.3.tgz#b14c0fe8111ce001ec913686434fe0c2fb461228" + integrity sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g== + +big-integer@^1.6.17: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +binary@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + integrity sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg== + dependencies: + buffers "~0.1.1" + chainsaw "~0.1.0" + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bluebird@~3.4.1: + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + integrity sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +buffer-crc32@^0.2.1, buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-indexof-polyfill@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" + integrity sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A== + +buffer@^5.2.1, buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +buffers@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + integrity sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ== + +builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cache-content-type@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" + integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA== + dependencies: + mime-types "^2.1.18" + ylru "^1.2.0" + +cacheable-lookup@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== + +cacheable-request@^10.2.8: + version "10.2.13" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.13.tgz#b7012bb4a2acdb18cb54d2dff751d766b3500842" + integrity sha512-3SD4rrMu1msNGEtNSt8Od6enwdo//U9s4ykmXfA2TD58kcLkCobtCDiby7kNyj7a/Q7lz/mAesAFI54rTdnvBA== + dependencies: + "@types/http-cache-semantics" "^4.0.1" + get-stream "^6.0.1" + http-cache-semantics "^4.1.1" + keyv "^4.5.3" + mimic-response "^4.0.0" + normalize-url "^8.0.0" + responselike "^3.0.0" + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^6.0.0, camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chai@^4.3.7: + version "4.3.8" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.8.tgz#40c59718ad6928da6629c70496fe990b2bb5b17c" + integrity sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^4.1.2" + get-func-name "^2.0.0" + loupe "^2.3.1" + pathval "^1.1.1" + type-detect "^4.0.5" + +chainsaw@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + integrity sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ== + dependencies: + traverse ">=0.3.0 <0.4" + +chalk-template@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-0.4.0.tgz#692c034d0ed62436b9062c1707fadcd0f753204b" + integrity sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg== + dependencies: + chalk "^4.1.2" + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^5.1.2: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== + +chokidar@3.5.3, chokidar@^3.4.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-launcher@^0.15.0: + version "0.15.2" + resolved "https://registry.yarnpkg.com/chrome-launcher/-/chrome-launcher-0.15.2.tgz#4e6404e32200095fdce7f6a1e1004f9bd36fa5da" + integrity sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ== + dependencies: + "@types/node" "*" + escape-string-regexp "^4.0.0" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + +chromium-bidi@0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-0.4.16.tgz#8a67bfdf6bb8804efc22765a82859d20724b46ab" + integrity sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA== + dependencies: + mitt "3.0.0" + +chromium-bidi@0.4.7: + version "0.4.7" + resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-0.4.7.tgz#4c022c2b0fb1d1c9b571fadf373042160e71d236" + integrity sha512-6+mJuFXwTMU6I3vYLs6IL8A1DyQTPjCfIL971X0aMPVGRbGnNfl6i6Cl0NMbxi2bRYLGESt9T2ZIMRM5PAEcIQ== + dependencies: + mitt "3.0.0" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +clone@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + +co-body@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.1.0.tgz#d87a8efc3564f9bfe3aced8ef5cd04c7a8766547" + integrity sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ== + dependencies: + inflation "^2.0.0" + qs "^6.5.2" + raw-body "^2.3.3" + type-is "^1.6.16" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +comlink@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/comlink/-/comlink-4.4.1.tgz#e568b8e86410b809e8600eb2cf40c189371ef981" + integrity sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q== + +command-line-args@^5.1.1, command-line-args@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@^7.0.0, command-line-usage@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-7.0.1.tgz#e540afef4a4f3bc501b124ffde33956309100655" + integrity sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ== + dependencies: + array-back "^6.2.2" + chalk-template "^0.4.0" + table-layout "^3.0.0" + typical "^7.1.1" + +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^9.3.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + +compress-commons@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-5.0.1.tgz#e46723ebbab41b50309b27a0e0f6f3baed2d6590" + integrity sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag== + dependencies: + crc-32 "^1.2.0" + crc32-stream "^5.0.0" + normalize-path "^3.0.0" + readable-stream "^3.6.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +content-disposition@~0.5.2: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^1.6.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookies@~0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" + integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow== + dependencies: + depd "~2.0.0" + keygrip "~1.1.0" + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +crc-32@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + +crc32-stream@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-5.0.0.tgz#a97d3a802c8687f101c27cc17ca5253327354720" + integrity sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw== + dependencies: + crc-32 "^1.2.0" + readable-stream "^3.4.0" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-fetch@3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + +cross-fetch@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== + dependencies: + node-fetch "^2.6.12" + +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-shorthand-properties@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz#1c808e63553c283f289f2dd56fcee8f3337bd935" + integrity sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A== + +css-value@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/css-value/-/css-value-0.0.1.tgz#5efd6c2eea5ea1fd6b6ac57ec0427b18452424ea" + integrity sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q== + +data-uri-to-buffer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + +data-uri-to-buffer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-5.0.1.tgz#db89a9e279c2ffe74f50637a59a32fb23b3e4d7c" + integrity sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg== + +debounce@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.0, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +decamelize@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-6.0.0.tgz#8cad4d916fde5c41a264a43d0ecc56fe3d31749e" + integrity sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA== + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-eql@^4.1.2: + version "4.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" + integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== + dependencies: + type-detect "^4.0.0" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw== + +deepmerge-ts@^5.0.0, deepmerge-ts@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/deepmerge-ts/-/deepmerge-ts-5.1.0.tgz#c55206cc4c7be2ded89b9c816cf3608884525d7a" + integrity sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +degenerator@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5" + integrity sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ== + dependencies: + ast-types "^0.13.4" + escodegen "^2.1.0" + esprima "^4.0.1" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +depd@2.0.0, depd@^2.0.0, depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +dependency-graph@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" + integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== + +dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +destroy@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +devtools-protocol@0.0.1107588: + version "0.0.1107588" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz#f8cac707840b97cc30b029359341bcbbb0ad8ffa" + integrity sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg== + +devtools-protocol@0.0.1147663: + version "0.0.1147663" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz#4ec5610b39a6250d1f87e6b9c7e16688ed0ac78e" + integrity sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ== + +devtools-protocol@^0.0.1188743: + version "0.0.1188743" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1188743.tgz#ac6246b2c55cba0725896d42c371e3a46e8efe16" + integrity sha512-FZDQC58vLiGR2mjSgsMzU8aEJieovMonIyxf38b775eYdIfAYgSzyAWnDf0Eq6ouF/L9qcbqR8jcQeIC34jp/w== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diff@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +duplexer2@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA== + dependencies: + readable-stream "^2.0.2" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +edge-paths@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/edge-paths/-/edge-paths-3.0.5.tgz#9a35361d701d9b5dc07f641cebe8da01ede80937" + integrity sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg== + dependencies: + "@types/which" "^2.0.1" + which "^2.0.2" + +edgedriver@^5.3.5: + version "5.3.6" + resolved "https://registry.yarnpkg.com/edgedriver/-/edgedriver-5.3.6.tgz#da19a06b7d2619c12f1a49cd0453b4d81c08ec9a" + integrity sha512-AvrkKsaMx8X5M64NVgPTfA+XTnOv6bvxH1Cp1m8cBQQVD0HEaC9OJMwPV9Kmqnxh0fCL7VJiBKZH5YOfikbB0g== + dependencies: + "@wdio/logger" "^8.11.0" + decamelize "^6.0.0" + edge-paths "^3.0.5" + node-fetch "^3.3.2" + unzipper "^0.10.14" + which "^4.0.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +encodeurl@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +error-ex@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +errorstacks@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/errorstacks/-/errorstacks-2.4.0.tgz#2155674dd9e741aacda3f3b8b967d9c40a4a0baf" + integrity sha512-5ecWhU5gt0a5G05nmQcgCxP5HperSMxLDzvWlT5U+ZSKkuDK0rJ3dbCQny6/vSCIXjwrhwSecXBbw1alr295hQ== + +es-module-lexer@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" + integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA== + +"esbuild@^0.16 || ^0.17": + version "0.17.19" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" + integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== + optionalDependencies: + "@esbuild/android-arm" "0.17.19" + "@esbuild/android-arm64" "0.17.19" + "@esbuild/android-x64" "0.17.19" + "@esbuild/darwin-arm64" "0.17.19" + "@esbuild/darwin-x64" "0.17.19" + "@esbuild/freebsd-arm64" "0.17.19" + "@esbuild/freebsd-x64" "0.17.19" + "@esbuild/linux-arm" "0.17.19" + "@esbuild/linux-arm64" "0.17.19" + "@esbuild/linux-ia32" "0.17.19" + "@esbuild/linux-loong64" "0.17.19" + "@esbuild/linux-mips64el" "0.17.19" + "@esbuild/linux-ppc64" "0.17.19" + "@esbuild/linux-riscv64" "0.17.19" + "@esbuild/linux-s390x" "0.17.19" + "@esbuild/linux-x64" "0.17.19" + "@esbuild/netbsd-x64" "0.17.19" + "@esbuild/openbsd-x64" "0.17.19" + "@esbuild/sunos-x64" "0.17.19" + "@esbuild/win32-arm64" "0.17.19" + "@esbuild/win32-ia32" "0.17.19" + "@esbuild/win32-x64" "0.17.19" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escodegen@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionalDependencies: + source-map "~0.6.1" + +esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== + +fast-fifo@^1.1.0, fast-fifo@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + +fast-glob@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + +fflate@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.0.tgz#f93ad1dcbe695a25ae378cf2386624969a7cda32" + integrity sha512-FAdS4qMuFjsJj6XHbBaZeXOgaypXp8iw/Tpyuq/w3XA41jjLHT8NPA+n7czH/DDhdncq0nAyDZmPeWXh2qmdIg== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== + dependencies: + locate-path "^7.1.0" + path-exists "^5.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +form-data-encoder@^2.1.2: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" + integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== + +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + +fresh@~0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +geckodriver@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-4.2.0.tgz#a385370011ae29fa8c68351b01d054a92b92d945" + integrity sha512-I2BlybeMFMzpxHRrh8X4VwP4ys74JHszyUgfezOrbTR7PEybFneDcuEjKIQxKV6vFPmsdwhwF1x8AshdQo56xA== + dependencies: + "@wdio/logger" "^8.11.0" + decamelize "^6.0.0" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.1" + node-fetch "^3.3.1" + tar-fs "^3.0.4" + unzipper "^0.10.14" + which "^3.0.1" + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== + +get-intrinsic@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + +get-port@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-7.0.0.tgz#ffcd83da826146529e307a341d7801cae351daff" + integrity sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw== + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-uri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.1.tgz#cff2ba8d456c3513a04b70c45de4dbcca5b1527c" + integrity sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q== + dependencies: + basic-ftp "^5.0.2" + data-uri-to-buffer "^5.0.1" + debug "^4.3.4" + fs-extra "^8.1.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^10.2.2: + version "10.3.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.4.tgz#c85c9c7ab98669102b6defda76d35c5b1ef9766f" + integrity sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +globby@^11.0.1: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +"got@^ 12.6.1": + version "12.6.1" + resolved "https://registry.yarnpkg.com/got/-/got-12.6.1.tgz#8869560d1383353204b5a9435f782df9c091f549" + integrity sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.8" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + +got@^13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/got/-/got-13.0.0.tgz#a2402862cef27a5d0d1b07c0fb25d12b58175422" + integrity sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.8" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +grapheme-splitter@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hosted-git-info@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.0.tgz#276330b8ad9f4566e82c8ccb16050decc096076b" + integrity sha512-ICclEpTLhHj+zCuSb2/usoNXSVkxUSIopre+b1w8NDY9Dntp9LO4vLdHYI336TH8sAqwrRgnSfdkBG2/YpisHA== + dependencies: + lru-cache "^10.0.1" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-assert@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f" + integrity sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w== + dependencies: + deep-equal "~1.0.1" + http-errors "~1.8.0" + +http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.8.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" + integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + +http2-wrapper@^2.1.10: + version "2.2.0" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.0.tgz#b80ad199d216b7d3680195077bd7b9060fa9d7f3" + integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + +https-proxy-agent@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +https-proxy-agent@^7.0.0, https-proxy-agent@^7.0.1, https-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" + integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== + dependencies: + agent-base "^7.0.2" + debug "4" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-meta-resolve@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-3.0.0.tgz#94a6aabc623874fbc2f3525ec1300db71c6cbc11" + integrity sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg== + +inflation@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" + integrity sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ip@^1.1.5, ip@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" + integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== + +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-builtin-module@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + +is-core-module@^2.13.0, is-core-module@^2.8.1: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isbinaryfile@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.0.tgz#034b7e54989dab8986598cbcea41f66663c65234" + integrity sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isexe@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d" + integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ== + +istanbul-lib-coverage@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-report@^3.0.0, istanbul-lib-report@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-reports@^3.0.2: + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jackspeak@^2.0.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.3.tgz#95e4cbcc03b3eb357bf6bcce14a903fb3d1151e1" + integrity sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7" + integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +keygrip@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" + integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== + dependencies: + tsscmp "1.0.6" + +keyv@^4.5.3: + version "4.5.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.3.tgz#00873d2b046df737963157bd04f294ca818c9c25" + integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug== + dependencies: + json-buffer "3.0.1" + +koa-compose@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" + integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== + +koa-convert@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5" + integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA== + dependencies: + co "^4.6.0" + koa-compose "^4.1.0" + +koa-etag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/koa-etag/-/koa-etag-4.0.0.tgz#2c2bb7ae69ca1ac6ced09ba28dcb78523c810414" + integrity sha512-1cSdezCkBWlyuB9l6c/IFoe1ANCDdPBxkDkRiaIup40xpUub6U/wwRXoKBZw/O5BifX9OlqAjYnDyzM6+l+TAg== + dependencies: + etag "^1.8.1" + +koa-send@^5.0.0, koa-send@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.1.tgz#39dceebfafb395d0d60beaffba3a70b4f543fe79" + integrity sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ== + dependencies: + debug "^4.1.1" + http-errors "^1.7.3" + resolve-path "^1.4.0" + +koa-static@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943" + integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ== + dependencies: + debug "^3.1.0" + koa-send "^5.0.0" + +koa@^2.13.0: + version "2.14.2" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.14.2.tgz#a57f925c03931c2b4d94b19d2ebf76d3244863fc" + integrity sha512-VFI2bpJaodz6P7x2uyLiX6RLYpZmOJqNmoCst/Yyd7hQlszyPwG/I9CQJ63nOtKSxpt5M7NH67V6nJL2BwCl7g== + dependencies: + accepts "^1.3.5" + cache-content-type "^1.0.0" + content-disposition "~0.5.2" + content-type "^1.0.4" + cookies "~0.8.0" + debug "^4.3.2" + delegates "^1.0.0" + depd "^2.0.0" + destroy "^1.0.4" + encodeurl "^1.0.2" + escape-html "^1.0.3" + fresh "~0.5.2" + http-assert "^1.3.0" + http-errors "^1.6.3" + is-generator-function "^1.0.7" + koa-compose "^4.1.0" + koa-convert "^2.0.0" + on-finished "^2.3.0" + only "~0.0.2" + parseurl "^1.3.2" + statuses "^1.5.0" + type-is "^1.6.16" + vary "^1.1.2" + +ky@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ky/-/ky-1.0.1.tgz#3b167f0bf75097240ffc5505e6b4f7b3be8161d0" + integrity sha512-UvcwpQO0LOuZwG0Ti3VDo6w57KYt+r4bWEYlNaMt82hgyFtse86QtOGum1RzsZni31FndXQl6NvtDArfunt2JQ== + +lazystream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== + dependencies: + readable-stream "^2.0.5" + +lighthouse-logger@^1.0.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz#aef90f9e97cd81db367c7634292ee22079280aaa" + integrity sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g== + dependencies: + debug "^2.6.9" + marky "^1.2.2" + +lines-and-columns@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" + integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + +listenercount@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" + integrity sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ== + +locate-app@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/locate-app/-/locate-app-2.1.0.tgz#97bbbeb3be59eec55368d20f69c77ebaaddacac1" + integrity sha512-rcVo/iLUxrd9d0lrmregK/Z5Y5NCpSwf9KlMbPpOHmKmdxdQY1Fj8NDQ5QymJTryCsBLqwmniFv2f3JKbk9Bvg== + dependencies: + n12 "0.4.0" + type-fest "2.13.0" + userhome "1.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +locate-path@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + +lodash.assignwith@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" + integrity sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g== + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + +lodash.zip@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" + integrity sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg== + +lodash@^4.17.14, lodash@^4.17.15: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +loglevel-plugin-prefix@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz#2fe0e05f1a820317d98d8c123e634c1bd84ff644" + integrity sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g== + +loglevel@^1.6.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4" + integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg== + +loupe@^2.3.1: + version "2.3.6" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" + integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== + dependencies: + get-func-name "^2.0.0" + +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + +lru-cache@^10.0.1, "lru-cache@^9.1.1 || ^10.0.0": + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru-cache@^7.14.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lru-cache@^8.0.4: + version "8.0.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-8.0.5.tgz#983fe337f3e176667f8e567cfcce7cb064ea214e" + integrity sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA== + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +marky@^1.2.2: + version "1.2.5" + resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0" + integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.18, mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +mimic-response@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" + integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1, minimatch@^5.1.0: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.0, minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.3.tgz#05ea638da44e475037ed94d1c7efcc76a25e1974" + integrity sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg== + +mitt@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.0.tgz#69ef9bd5c80ff6f57473e8d89326d01c414be0bd" + integrity sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ== + +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +"mkdirp@>=0.5 0", mkdirp@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mocha@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +n12@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/n12/-/n12-0.4.0.tgz#363058560b435e6857b5e039ed5eab08c5122e5e" + integrity sha512-p/hj4zQ8d3pbbFLQuN1K9honUxiDDhueOWyFLw/XgBv+wZCE44bcLH4CIcsolOceJQduh4Jf7m/LfaTxyGmGtQ== + +nanocolors@^0.2.1: + version "0.2.13" + resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.2.13.tgz#dfd1ed0bfab05e9fe540eb6874525f0a1684099b" + integrity sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +nanoid@^3.1.25: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +netmask@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" + integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== + +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@^2.6.12: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@^3.3.1, node-fetch@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" + integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + +normalize-package-data@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.0.tgz#68a96b3c11edd462af7189c837b6b1064a484196" + integrity sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg== + dependencies: + hosted-git-info "^7.0.0" + is-core-module "^2.8.1" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.0.tgz#593dbd284f743e8dcf6a5ddf8fadff149c82701a" + integrity sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw== + +object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +on-finished@^2.3.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +only@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" + integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ== + +open@^8.0.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + +pac-proxy-agent@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz#6b9ddc002ec3ff0ba5fdf4a8a21d363bcc612d75" + integrity sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A== + dependencies: + "@tootallnate/quickjs-emscripten" "^0.23.0" + agent-base "^7.0.2" + debug "^4.3.4" + get-uri "^6.0.1" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.2" + pac-resolver "^7.0.0" + socks-proxy-agent "^8.0.2" + +pac-resolver@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-7.0.0.tgz#79376f1ca26baf245b96b34c339d79bff25e900c" + integrity sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg== + dependencies: + degenerator "^5.0.0" + ip "^1.1.8" + netmask "^2.0.2" + +parse-json@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-7.1.0.tgz#4cffd0ee00ffa597b995fd70a9811993c4f95023" + integrity sha512-ihtdrgbqdONYD156Ap6qTcaGcGdkdAxodO1wLqQ/j7HP1u2sFYppINiq4jyC8F+Nm+4fVufylCV00QmkTHkSUg== + dependencies: + "@babel/code-frame" "^7.21.4" + error-ex "^1.3.2" + json-parse-even-better-errors "^3.0.0" + lines-and-columns "^2.0.3" + type-fest "^3.8.0" + +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + +path-is-absolute@1.0.1, path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +portfinder@^1.0.32: + version "1.0.32" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81" + integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== + dependencies: + async "^2.6.4" + debug "^3.2.7" + mkdirp "^0.5.6" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +proxy-agent@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.3.0.tgz#72f7bb20eb06049db79f7f86c49342c34f9ba08d" + integrity sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og== + dependencies: + agent-base "^7.0.2" + debug "^4.3.4" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.0" + lru-cache "^7.14.1" + pac-proxy-agent "^7.0.0" + proxy-from-env "^1.1.0" + socks-proxy-agent "^8.0.1" + +proxy-from-env@1.1.0, proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +puppeteer-core@^19.8.1: + version "19.11.1" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-19.11.1.tgz#4c63d7a0a6cd268ff054ebcac315b646eee32667" + integrity sha512-qcuC2Uf0Fwdj9wNtaTZ2OvYRraXpAK+puwwVW8ofOhOgLPZyz1c68tsorfIZyCUOpyBisjr+xByu7BMbEYMepA== + dependencies: + "@puppeteer/browsers" "0.5.0" + chromium-bidi "0.4.7" + cross-fetch "3.1.5" + debug "4.3.4" + devtools-protocol "0.0.1107588" + extract-zip "2.0.1" + https-proxy-agent "5.0.1" + proxy-from-env "1.1.0" + tar-fs "2.1.1" + unbzip2-stream "1.4.3" + ws "8.13.0" + +puppeteer-core@^20.9.0: + version "20.9.0" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-20.9.0.tgz#6f4b420001b64419deab38d398a4d9cd071040e6" + integrity sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg== + dependencies: + "@puppeteer/browsers" "1.4.6" + chromium-bidi "0.4.16" + cross-fetch "4.0.0" + debug "4.3.4" + devtools-protocol "0.0.1147663" + ws "8.13.0" + +qs@^6.5.2: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + +query-selector-shadow-dom@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz#1c7b0058eff4881ac44f45d8f84ede32e9a2f349" + integrity sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +raw-body@^2.3.3: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg-up@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-10.1.0.tgz#2d13ab732d2f05d6e8094167c2112e2ee50644f4" + integrity sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA== + dependencies: + find-up "^6.3.0" + read-pkg "^8.1.0" + type-fest "^4.2.0" + +read-pkg@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-8.1.0.tgz#6cf560b91d90df68bce658527e7e3eee75f7c4c7" + integrity sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ== + dependencies: + "@types/normalize-package-data" "^2.4.1" + normalize-package-data "^6.0.0" + parse-json "^7.0.0" + type-fest "^4.2.0" + +readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdir-glob@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.3.tgz#c3d831f51f5e7bfa62fa2ffbe4b508c640f09584" + integrity sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA== + dependencies: + minimatch "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + +resolve-path@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" + integrity sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w== + dependencies: + http-errors "~1.6.2" + path-is-absolute "1.0.1" + +resolve@^1.19.0: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" + integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== + dependencies: + lowercase-keys "^3.0.0" + +resq@^1.9.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/resq/-/resq-1.11.0.tgz#edec8c58be9af800fd628118c0ca8815283de196" + integrity sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw== + dependencies: + fast-deep-equal "^2.0.1" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rgb2hex@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.2.5.tgz#f82230cd3ab1364fa73c99be3a691ed688f8dbdc" + integrity sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw== + +rimraf@2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rollup@^2.67.0: + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safaridriver@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/safaridriver/-/safaridriver-0.1.0.tgz#8ff901e847b003c6a52b534028f57cddc82d6b14" + integrity sha512-azzzIP3gR1TB9bVPv7QO4Zjw0rR1BWEU/s2aFdUMN48gxDjxEB13grAEuXDmkKPgE74cObymDxmAmZnL3clj4w== + +safe-buffer@5.2.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^7.3.4, semver@^7.3.5, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +serialize-error@^11.0.1: + version "11.0.2" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-11.0.2.tgz#8c1a44f0ab872ee2c3ca6736ca5c750003bc1d04" + integrity sha512-o43i0jLcA0LXA5Uu+gI1Vj+lF66KR9IAcy0ThbGq1bAMPN+k5IgSHsulfnqf/ddKAz6dWf+k8PD5hAr9oCSHEQ== + dependencies: + type-fest "^2.12.2" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +setimmediate@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +smol-toml@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/smol-toml/-/smol-toml-1.1.2.tgz#817420d666b9f0bb7be0e8a89a52a6fa6cb2d6c6" + integrity sha512-opeweddRVyIFjnNPmEodUn4LlVeiZNE3OZ3QiLvyC/pWxNgW3z02oCTVOFVgYI1w1sSO4nifFCcvw1ADOMs5ag== + +socks-proxy-agent@^8.0.1, socks-proxy-agent@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad" + integrity sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g== + dependencies: + agent-base "^7.0.2" + debug "^4.3.4" + socks "^2.7.1" + +socks@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + +source-map@^0.7.3: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.13" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +stream-read-all@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/stream-read-all/-/stream-read-all-3.0.1.tgz#60762ae45e61d93ba0978cda7f3913790052ad96" + integrity sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A== + +streamx@^2.15.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.1.tgz#396ad286d8bc3eeef8f5cea3f029e81237c024c6" + integrity sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA== + dependencies: + fast-fifo "^1.1.0" + queue-tick "^1.0.1" + +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1, strip-ansi@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +table-layout@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-3.0.2.tgz#69c2be44388a5139b48c59cf21e73b488021769a" + integrity sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw== + dependencies: + "@75lb/deep-merge" "^1.1.1" + array-back "^6.2.2" + command-line-args "^5.2.1" + command-line-usage "^7.0.0" + stream-read-all "^3.0.1" + typical "^7.1.1" + wordwrapjs "^5.1.0" + +tar-fs@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-fs@3.0.4, tar-fs@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.4.tgz#a21dc60a2d5d9f55e0089ccd78124f1d3771dbbf" + integrity sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w== + dependencies: + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^3.1.5" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar-stream@^3.0.0, tar-stream@^3.1.5: + version "3.1.6" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab" + integrity sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== + dependencies: + punycode "^2.1.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + integrity sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ== + +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +tslib@^2.0.1, tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tsscmp@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== + +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.13.0.tgz#d1ecee38af29eb2e863b22299a3d68ef30d2abfb" + integrity sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^2.12.2: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +type-fest@^3.8.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" + integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== + +type-fest@^4.2.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.3.1.tgz#5cb58cdab5120f7ab0b40cfdc35073fb9adb651d" + integrity sha512-pphNW/msgOUSkJbH58x8sqpq8uQj6b0ZKGxEsLKMUnGorRcDjrUaLS+39+/ub41JNTwrrMyJcUB8+YZs3mbwqw== + +type-is@^1.6.16: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@^5.0.4: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/typical/-/typical-7.1.1.tgz#ba177ab7ab103b78534463ffa4c0c9754523ac1f" + integrity sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA== + +ua-parser-js@^1.0.33: + version "1.0.35" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.35.tgz#c4ef44343bc3db0a3cbefdf21822f1b1fc1ab011" + integrity sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA== + +unbzip2-stream@1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +unzipper@^0.10.14: + version "0.10.14" + resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.10.14.tgz#d2b33c977714da0fbc0f82774ad35470a7c962b1" + integrity sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g== + dependencies: + big-integer "^1.6.17" + binary "~0.3.0" + bluebird "~3.4.1" + buffer-indexof-polyfill "~1.0.0" + duplexer2 "~0.1.4" + fstream "^1.0.12" + graceful-fs "^4.2.2" + listenercount "~1.0.1" + readable-stream "~2.3.6" + setimmediate "~1.0.4" + +userhome@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/userhome/-/userhome-1.0.0.tgz#b6491ff12d21a5e72671df9ccc8717e1c6688c0b" + integrity sha512-ayFKY3H+Pwfy4W98yPdtH1VqH4psDeyW8lYYFzfecR9d6hqLpqhecktvYR3SEEXt7vG0S1JEpciI3g94pMErig== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +v8-to-istanbul@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + +validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +wait-port@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/wait-port/-/wait-port-1.0.4.tgz#6f9474645ddbf7701ac100ab6762438edf6e5689" + integrity sha512-w8Ftna3h6XSFWWc2JC5gZEgp64nz8bnaTp5cvzbJSZ53j+omktWTDdwXxEF0jM8YveviLgFWvNGrSvRHnkyHyw== + dependencies: + chalk "^4.1.2" + commander "^9.3.0" + debug "^4.3.4" + +web-streams-polyfill@^3.0.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + +webdriver@8.16.4: + version "8.16.4" + resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-8.16.4.tgz#999815ce295708ea75ca415ebb5f8e53002bc3e3" + integrity sha512-iL8yt6JrH6GqWCMyyZ8/4UMH1Pkez0VCYtkF5Fwwy6gLbP7q4iOVIFjKXP6Cg5gA2aoJvf9TLZ4cFbGOvsZXCw== + dependencies: + "@types/node" "^20.1.0" + "@types/ws" "^8.5.3" + "@wdio/config" "8.16.3" + "@wdio/logger" "8.11.0" + "@wdio/protocols" "8.14.6" + "@wdio/types" "8.16.3" + "@wdio/utils" "8.16.3" + deepmerge-ts "^5.1.0" + got "^ 12.6.1" + ky "^1.0.0" + ws "^8.8.0" + +webdriverio@^8.8.6: + version "8.16.4" + resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-8.16.4.tgz#186fe62bcc87e69e565318da836d684a60b2b6ef" + integrity sha512-gt1f7qlfGzx8kKvGBxeOtYqbxYAi929fIFNnE4nDDxOzBL6Pd2ctStiqMjxeCOsZ5Z5sDDKw//P6FSRYnhNiaA== + dependencies: + "@types/node" "^20.1.0" + "@wdio/config" "8.16.3" + "@wdio/logger" "8.11.0" + "@wdio/protocols" "8.14.6" + "@wdio/repl" "8.10.1" + "@wdio/types" "8.16.3" + "@wdio/utils" "8.16.3" + archiver "^6.0.0" + aria-query "^5.0.0" + css-shorthand-properties "^1.1.1" + css-value "^0.0.1" + devtools-protocol "^0.0.1188743" + grapheme-splitter "^1.0.2" + import-meta-resolve "^3.0.0" + is-plain-obj "^4.1.0" + lodash.clonedeep "^4.5.0" + lodash.zip "^4.2.0" + minimatch "^9.0.0" + puppeteer-core "^20.9.0" + query-selector-shadow-dom "^1.0.0" + resq "^1.9.1" + rgb2hex "0.2.5" + serialize-error "^11.0.1" + webdriver "8.16.4" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + +whatwg-url@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" + integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" + integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== + dependencies: + isexe "^2.0.0" + +which@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/which/-/which-4.0.0.tgz#cd60b5e74503a3fbcfbf6cd6b4138a8bae644c1a" + integrity sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg== + dependencies: + isexe "^3.1.1" + +wordwrapjs@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-5.1.0.tgz#4c4d20446dcc670b14fa115ef4f8fd9947af2b3a" + integrity sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg== + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + +ws@^7.4.2: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +ws@^8.8.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.0.tgz#6c5792c5316dc9266ba8e780433fc45e6680aecd" + integrity sha512-WR0RJE9Ehsio6U4TuM+LmunEsjQ5ncHlw4sn9ihD6RoJKZrVyH9FWV3dmnwu8B2aNib1OvG2X6adUCyFpQyWcg== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@17.7.1: + version "17.7.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" + integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +ylru@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.3.2.tgz#0de48017473275a4cbdfc83a1eaf67c01af8a785" + integrity sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA== + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== + +zip-stream@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-5.0.1.tgz#cf3293bba121cad98be2ec7f05991d81d9f18134" + integrity sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA== + dependencies: + archiver-utils "^4.0.1" + compress-commons "^5.0.1" + readable-stream "^3.6.0" diff --git a/compiler/noirc_driver/Cargo.toml b/compiler/noirc_driver/Cargo.toml new file mode 100644 index 00000000000..4b67afb73ff --- /dev/null +++ b/compiler/noirc_driver/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "noirc_driver" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap.workspace = true +noirc_errors.workspace = true +noirc_frontend.workspace = true +noirc_evaluator.workspace = true +noirc_abi.workspace = true +acvm.workspace = true +fm.workspace = true +serde.workspace = true +base64.workspace = true diff --git a/compiler/noirc_driver/src/contract.rs b/compiler/noirc_driver/src/contract.rs new file mode 100644 index 00000000000..69a92764318 --- /dev/null +++ b/compiler/noirc_driver/src/contract.rs @@ -0,0 +1,70 @@ +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +use acvm::acir::circuit::Circuit; +use fm::FileId; +use noirc_abi::Abi; +use noirc_errors::debug_info::DebugInfo; + +use super::debug::DebugFile; +use crate::program::{deserialize_circuit, serialize_circuit}; + +/// Describes the types of smart contract functions that are allowed. +/// Unlike the similar enum in noirc_frontend, 'open' and 'unconstrained' +/// are mutually exclusive here. In the case a function is both, 'unconstrained' +/// takes precedence. +#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] +pub enum ContractFunctionType { + /// This function will be executed in a private + /// context. + Secret, + /// This function will be executed in a public + /// context. + Open, + /// This function cannot constrain any values and can use nondeterministic features + /// like arrays of a dynamic size. + Unconstrained, +} + +#[derive(Serialize, Deserialize)] +pub struct CompiledContract { + /// The name of the contract. + pub name: String, + /// Each of the contract's functions are compiled into a separate `CompiledProgram` + /// stored in this `Vector`. + pub functions: Vec, + + pub file_map: BTreeMap, +} + +/// Each function in the contract will be compiled +/// as a separate noir program. +/// +/// A contract function unlike a regular Noir program +/// however can have additional properties. +/// One of these being a function type. +#[derive(Debug, Serialize, Deserialize)] +pub struct ContractFunction { + pub name: String, + + pub function_type: ContractFunctionType, + + pub is_internal: bool, + + pub abi: Abi, + + #[serde(serialize_with = "serialize_circuit", deserialize_with = "deserialize_circuit")] + pub bytecode: Circuit, + + pub debug: DebugInfo, +} + +impl ContractFunctionType { + pub(super) fn new(kind: noirc_frontend::ContractFunctionType, is_unconstrained: bool) -> Self { + match (kind, is_unconstrained) { + (_, true) => Self::Unconstrained, + (noirc_frontend::ContractFunctionType::Secret, false) => Self::Secret, + (noirc_frontend::ContractFunctionType::Open, false) => Self::Open, + } + } +} diff --git a/compiler/noirc_driver/src/debug.rs b/compiler/noirc_driver/src/debug.rs new file mode 100644 index 00000000000..9808c9b54a2 --- /dev/null +++ b/compiler/noirc_driver/src/debug.rs @@ -0,0 +1,45 @@ +use fm::{FileId, FileManager}; +use noirc_errors::debug_info::DebugInfo; +use serde::{Deserialize, Serialize}; +use std::{ + collections::{BTreeMap, BTreeSet}, + path::PathBuf, +}; + +/// For a given file, we store the source code and the path to the file +/// so consumers of the debug artifact can reconstruct the original source code structure. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DebugFile { + pub source: String, + pub path: PathBuf, +} + +pub(crate) fn filter_relevant_files( + debug_symbols: &[DebugInfo], + file_manager: &FileManager, +) -> BTreeMap { + let files_with_debug_symbols: BTreeSet = debug_symbols + .iter() + .flat_map(|function_symbols| { + function_symbols + .locations + .values() + .filter_map(|call_stack| call_stack.last().map(|location| location.file)) + }) + .collect(); + + let mut file_map = BTreeMap::new(); + + for file_id in files_with_debug_symbols { + let file_source = file_manager.fetch_file(file_id).source(); + + file_map.insert( + file_id, + DebugFile { + source: file_source.to_string(), + path: file_manager.path(file_id).to_path_buf(), + }, + ); + } + file_map +} diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs new file mode 100644 index 00000000000..1b627adb3e4 --- /dev/null +++ b/compiler/noirc_driver/src/lib.rs @@ -0,0 +1,289 @@ +#![forbid(unsafe_code)] +#![warn(unused_crate_dependencies, unused_extern_crates)] +#![warn(unreachable_pub)] +#![warn(clippy::semicolon_if_nothing_returned)] + +use clap::Args; +use debug::filter_relevant_files; +use fm::FileId; +use noirc_abi::{AbiParameter, AbiType}; +use noirc_errors::{CustomDiagnostic, FileDiagnostic}; +use noirc_evaluator::{create_circuit, into_abi_params}; +use noirc_frontend::graph::{CrateId, CrateName}; +use noirc_frontend::hir::def_map::{Contract, CrateDefMap}; +use noirc_frontend::hir::Context; +use noirc_frontend::monomorphization::monomorphize; +use noirc_frontend::node_interner::FuncId; +use serde::{Deserialize, Serialize}; +use std::path::Path; + +mod contract; +mod debug; +mod program; + +pub use contract::{CompiledContract, ContractFunction, ContractFunctionType}; +pub use debug::DebugFile; +pub use program::CompiledProgram; + +const STD_CRATE_NAME: &str = "std"; + +#[derive(Args, Clone, Debug, Default, Serialize, Deserialize)] +pub struct CompileOptions { + /// Emit debug information for the intermediate SSA IR + #[arg(long, hide = true)] + pub show_ssa: bool, + + #[arg(long, hide = true)] + pub show_brillig: bool, + + /// Display the ACIR for compiled circuit + #[arg(long)] + pub print_acir: bool, + + /// Treat all warnings as errors + #[arg(long)] + pub deny_warnings: bool, +} + +/// Helper type used to signify where only warnings are expected in file diagnostics +pub type Warnings = Vec; + +/// Helper type used to signify where errors or warnings are expected in file diagnostics +pub type ErrorsAndWarnings = Vec; + +/// Helper type for connecting a compilation artifact to the errors or warnings which were produced during compilation. +pub type CompilationResult = Result<(T, Warnings), ErrorsAndWarnings>; + +// This is here for backwards compatibility +// with the restricted version which only uses one file +pub fn compile_file(context: &mut Context, root_file: &Path) -> CompilationResult { + let crate_id = prepare_crate(context, root_file); + compile_main(context, crate_id, &CompileOptions::default()) +} + +/// Adds the file from the file system at `Path` to the crate graph as a root file +pub fn prepare_crate(context: &mut Context, file_name: &Path) -> CrateId { + let path_to_std_lib_file = Path::new(STD_CRATE_NAME).join("lib.nr"); + let std_file_id = context.file_manager.add_file(&path_to_std_lib_file).unwrap(); + let std_crate_id = context.crate_graph.add_stdlib(std_file_id); + + let root_file_id = context.file_manager.add_file(file_name).unwrap(); + + let root_crate_id = context.crate_graph.add_crate_root(root_file_id); + + add_dep(context, root_crate_id, std_crate_id, STD_CRATE_NAME.parse().unwrap()); + + root_crate_id +} + +// Adds the file from the file system at `Path` to the crate graph +pub fn prepare_dependency(context: &mut Context, file_name: &Path) -> CrateId { + let root_file_id = context.file_manager.add_file(file_name).unwrap(); + + let crate_id = context.crate_graph.add_crate(root_file_id); + + // Every dependency has access to stdlib + let std_crate_id = context.stdlib_crate_id(); + add_dep(context, crate_id, *std_crate_id, STD_CRATE_NAME.parse().unwrap()); + + crate_id +} + +/// Adds a edge in the crate graph for two crates +pub fn add_dep( + context: &mut Context, + this_crate: CrateId, + depends_on: CrateId, + crate_name: CrateName, +) { + context + .crate_graph + .add_dep(this_crate, crate_name, depends_on) + .expect("cyclic dependency triggered"); +} + +/// Run the lexing, parsing, name resolution, and type checking passes. +/// +/// This returns a (possibly empty) vector of any warnings found on success. +/// On error, this returns a non-empty vector of warnings and error messages, with at least one error. +pub fn check_crate( + context: &mut Context, + crate_id: CrateId, + deny_warnings: bool, +) -> CompilationResult<()> { + let mut errors = vec![]; + CrateDefMap::collect_defs(crate_id, context, &mut errors); + + if has_errors(&errors, deny_warnings) { + Err(errors) + } else { + Ok(((), errors)) + } +} + +pub fn compute_function_abi( + context: &Context, + crate_id: &CrateId, +) -> Option<(Vec, Option)> { + let main_function = context.get_main_function(crate_id)?; + + let func_meta = context.def_interner.function_meta(&main_function); + + let (parameters, return_type) = func_meta.into_function_signature(); + let parameters = into_abi_params(context, parameters); + let return_type = return_type.map(|typ| AbiType::from_type(context, &typ)); + Some((parameters, return_type)) +} + +/// Run the frontend to check the crate for errors then compile the main function if there were none +/// +/// On success this returns the compiled program alongside any warnings that were found. +/// On error this returns the non-empty list of warnings and errors. +pub fn compile_main( + context: &mut Context, + crate_id: CrateId, + options: &CompileOptions, +) -> CompilationResult { + let (_, warnings) = check_crate(context, crate_id, options.deny_warnings)?; + + let main = match context.get_main_function(&crate_id) { + Some(m) => m, + None => { + // TODO(#2155): This error might be a better to exist in Nargo + let err = CustomDiagnostic::from_message( + "cannot compile crate into a program as it does not contain a `main` function", + ) + .in_file(FileId::default()); + return Err(vec![err]); + } + }; + + let compiled_program = compile_no_check(context, options, main)?; + + if options.print_acir { + println!("Compiled ACIR for main (unoptimized):"); + println!("{}", compiled_program.circuit); + } + + Ok((compiled_program, warnings)) +} + +/// Run the frontend to check the crate for errors then compile all contracts if there were none +pub fn compile_contract( + context: &mut Context, + crate_id: CrateId, + options: &CompileOptions, +) -> CompilationResult { + let (_, warnings) = check_crate(context, crate_id, options.deny_warnings)?; + + // TODO: We probably want to error if contracts is empty + let contracts = context.get_all_contracts(&crate_id); + + let mut compiled_contracts = vec![]; + let mut errors = warnings; + + if contracts.len() > 1 { + let err = CustomDiagnostic::from_message("Packages are limited to a single contract") + .in_file(FileId::default()); + return Err(vec![err]); + }; + + for contract in contracts { + match compile_contract_inner(context, contract, options) { + Ok(contract) => compiled_contracts.push(contract), + Err(mut more_errors) => errors.append(&mut more_errors), + } + } + + if has_errors(&errors, options.deny_warnings) { + Err(errors) + } else { + assert_eq!(compiled_contracts.len(), 1); + let compiled_contract = compiled_contracts.remove(0); + + if options.print_acir { + for contract_function in &compiled_contract.functions { + println!( + "Compiled ACIR for {}::{} (unoptimized):", + compiled_contract.name, contract_function.name + ); + println!("{}", contract_function.bytecode); + } + } + // errors here is either empty or contains only warnings + Ok((compiled_contract, errors)) + } +} + +/// True if there are (non-warning) errors present and we should halt compilation +fn has_errors(errors: &[FileDiagnostic], deny_warnings: bool) -> bool { + if deny_warnings { + !errors.is_empty() + } else { + errors.iter().any(|error| error.diagnostic.is_error()) + } +} + +/// Compile all of the functions associated with a Noir contract. +fn compile_contract_inner( + context: &Context, + contract: Contract, + options: &CompileOptions, +) -> Result { + let mut functions = Vec::new(); + let mut errors = Vec::new(); + for function_id in &contract.functions { + let name = context.function_name(function_id).to_owned(); + let function = match compile_no_check(context, options, *function_id) { + Ok(function) => function, + Err(new_error) => { + errors.push(new_error); + continue; + } + }; + let func_meta = context.def_interner.function_meta(function_id); + let func_type = func_meta + .contract_function_type + .expect("Expected contract function to have a contract visibility"); + + let function_type = ContractFunctionType::new(func_type, func_meta.is_unconstrained); + + functions.push(ContractFunction { + name, + function_type, + is_internal: func_meta.is_internal.unwrap_or(false), + abi: function.abi, + bytecode: function.circuit, + debug: function.debug, + }); + } + + if errors.is_empty() { + let debug_infos: Vec<_> = functions.iter().map(|function| function.debug.clone()).collect(); + let file_map = filter_relevant_files(&debug_infos, &context.file_manager); + + Ok(CompiledContract { name: contract.name, functions, file_map }) + } else { + Err(errors) + } +} + +/// Compile the current crate. Assumes self.check_crate is called beforehand! +/// +/// This function also assumes all errors in experimental_create_circuit and create_circuit +/// are not warnings. +#[allow(deprecated)] +pub fn compile_no_check( + context: &Context, + options: &CompileOptions, + main_function: FuncId, +) -> Result { + let program = monomorphize(main_function, &context.def_interner); + + let (circuit, debug, abi) = + create_circuit(context, program, options.show_ssa, options.show_brillig)?; + + let file_map = filter_relevant_files(&[debug.clone()], &context.file_manager); + + Ok(CompiledProgram { circuit, debug, abi, file_map }) +} diff --git a/compiler/noirc_driver/src/program.rs b/compiler/noirc_driver/src/program.rs new file mode 100644 index 00000000000..1ed2b0ddddc --- /dev/null +++ b/compiler/noirc_driver/src/program.rs @@ -0,0 +1,40 @@ +use std::collections::BTreeMap; + +use acvm::acir::circuit::Circuit; +use fm::FileId; + +use base64::Engine; +use noirc_errors::debug_info::DebugInfo; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +use super::debug::DebugFile; + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct CompiledProgram { + #[serde(serialize_with = "serialize_circuit", deserialize_with = "deserialize_circuit")] + pub circuit: Circuit, + pub abi: noirc_abi::Abi, + pub debug: DebugInfo, + pub file_map: BTreeMap, +} + +pub(crate) fn serialize_circuit(circuit: &Circuit, s: S) -> Result +where + S: Serializer, +{ + let mut circuit_bytes: Vec = Vec::new(); + circuit.write(&mut circuit_bytes).unwrap(); + + let encoded_b64 = base64::engine::general_purpose::STANDARD.encode(circuit_bytes); + s.serialize_str(&encoded_b64) +} + +pub(crate) fn deserialize_circuit<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let bytecode_b64: String = serde::Deserialize::deserialize(deserializer)?; + let circuit_bytes = base64::engine::general_purpose::STANDARD.decode(bytecode_b64).unwrap(); + let circuit = Circuit::read(&*circuit_bytes).unwrap(); + Ok(circuit) +} diff --git a/compiler/noirc_errors/Cargo.toml b/compiler/noirc_errors/Cargo.toml new file mode 100644 index 00000000000..0cb6afc73bd --- /dev/null +++ b/compiler/noirc_errors/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "noirc_errors" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +acvm.workspace = true +codespan-reporting.workspace = true +codespan.workspace = true +fm.workspace = true +chumsky.workspace = true +serde.workspace = true +serde_with = "3.2.0" diff --git a/crates/noirc_errors/src/debug_info.rs b/compiler/noirc_errors/src/debug_info.rs similarity index 77% rename from crates/noirc_errors/src/debug_info.rs rename to compiler/noirc_errors/src/debug_info.rs index 79237d773a8..946841c279b 100644 --- a/crates/noirc_errors/src/debug_info.rs +++ b/compiler/noirc_errors/src/debug_info.rs @@ -4,6 +4,7 @@ use acvm::compiler::AcirTransformationMap; use serde_with::serde_as; use serde_with::DisplayFromStr; use std::collections::BTreeMap; +use std::mem; use crate::Location; use serde::{Deserialize, Serialize}; @@ -29,16 +30,13 @@ impl DebugInfo { /// renders the old `OpcodeLocation`s invalid. The AcirTransformationMap is able to map the old `OpcodeLocation` to the new ones. /// Note: One old `OpcodeLocation` might have transformed into more than one new `OpcodeLocation`. pub fn update_acir(&mut self, update_map: AcirTransformationMap) { - let mut new_locations_map = BTreeMap::new(); + let old_locations = mem::take(&mut self.locations); - for (old_opcode_location, source_locations) in &self.locations { - let new_opcode_locations = update_map.new_locations(*old_opcode_location); - for new_opcode_location in new_opcode_locations { - new_locations_map.insert(new_opcode_location, source_locations.clone()); - } + for (old_opcode_location, source_locations) in old_locations { + update_map.new_locations(old_opcode_location).for_each(|new_opcode_location| { + self.locations.insert(new_opcode_location, source_locations.clone()); + }); } - - self.locations = new_locations_map; } pub fn opcode_location(&self, loc: &OpcodeLocation) -> Option> { diff --git a/crates/noirc_errors/src/lib.rs b/compiler/noirc_errors/src/lib.rs similarity index 100% rename from crates/noirc_errors/src/lib.rs rename to compiler/noirc_errors/src/lib.rs diff --git a/crates/noirc_errors/src/position.rs b/compiler/noirc_errors/src/position.rs similarity index 90% rename from crates/noirc_errors/src/position.rs rename to compiler/noirc_errors/src/position.rs index 09c59da1980..4cbf934138c 100644 --- a/crates/noirc_errors/src/position.rs +++ b/compiler/noirc_errors/src/position.rs @@ -33,7 +33,7 @@ impl Hash for Spanned { impl Spanned { pub fn from_position(start: Position, end: Position, contents: T) -> Spanned { - Spanned { span: Span(ByteSpan::new(start, end)), contents } + Spanned { span: Span::inclusive(start, end), contents } } pub const fn from(t_span: Span, contents: T) -> Spanned { @@ -57,16 +57,8 @@ impl std::borrow::Borrow for Spanned { pub struct Span(ByteSpan); impl Span { - pub fn new(range: Range) -> Span { - Span(ByteSpan::from(range)) - } - - pub fn exclusive(start: u32, end: u32) -> Span { - Span::new(start..end) - } - pub fn inclusive(start: u32, end: u32) -> Span { - Span::exclusive(start, end + 1) + Span(ByteSpan::from(start..end + 1)) } pub fn single_char(start: u32) -> Span { @@ -103,7 +95,7 @@ impl chumsky::Span for Span { type Offset = u32; fn new(_context: Self::Context, range: Range) -> Self { - Span::new(range) + Span(ByteSpan::from(range)) } fn context(&self) -> Self::Context {} diff --git a/crates/noirc_errors/src/reporter.rs b/compiler/noirc_errors/src/reporter.rs similarity index 83% rename from crates/noirc_errors/src/reporter.rs rename to compiler/noirc_errors/src/reporter.rs index d55189e80ac..d695b2007bc 100644 --- a/crates/noirc_errors/src/reporter.rs +++ b/compiler/noirc_errors/src/reporter.rs @@ -1,5 +1,6 @@ use crate::{FileDiagnostic, Location, Span}; use codespan_reporting::diagnostic::{Diagnostic, Label}; +use codespan_reporting::files::Files; use codespan_reporting::term; use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; @@ -110,8 +111,8 @@ impl CustomLabel { /// Writes the given diagnostics to stderr and returns the count /// of diagnostics that were errors. -pub fn report_all( - files: &fm::FileManager, +pub fn report_all<'files>( + files: &'files impl Files<'files, FileId = fm::FileId>, diagnostics: &[FileDiagnostic], deny_warnings: bool, ) -> ReportedErrors { @@ -126,14 +127,18 @@ pub fn report_all( } impl FileDiagnostic { - pub fn report(&self, files: &fm::FileManager, deny_warnings: bool) -> bool { + pub fn report<'files>( + &self, + files: &'files impl Files<'files, FileId = fm::FileId>, + deny_warnings: bool, + ) -> bool { report(files, &self.diagnostic, Some(self.file_id), &self.call_stack, deny_warnings) } } /// Report the given diagnostic, and return true if it was an error -pub fn report( - files: &fm::FileManager, +pub fn report<'files>( + files: &'files impl Files<'files, FileId = fm::FileId>, custom_diagnostic: &CustomDiagnostic, file: Option, call_stack: &[Location], @@ -144,7 +149,7 @@ pub fn report( let stack_trace = stack_trace(files, call_stack); let diagnostic = convert_diagnostic(custom_diagnostic, file, stack_trace, deny_warnings); - term::emit(&mut writer.lock(), &config, files.as_simple_files(), &diagnostic).unwrap(); + term::emit(&mut writer.lock(), &config, files, &diagnostic).unwrap(); deny_warnings || custom_diagnostic.is_error() } @@ -154,7 +159,7 @@ fn convert_diagnostic( file: Option, stack_trace: String, deny_warnings: bool, -) -> Diagnostic { +) -> Diagnostic { let diagnostic = match (cd.kind, deny_warnings) { (DiagnosticKind::Warning, false) => Diagnostic::warning(), _ => Diagnostic::error(), @@ -165,8 +170,8 @@ fn convert_diagnostic( .iter() .map(|sl| { let start_span = sl.span.start() as usize; - let end_span = sl.span.end() as usize + 1; - Label::secondary(file_id.as_usize(), start_span..end_span).with_message(&sl.message) + let end_span = sl.span.end() as usize; + Label::secondary(file_id, start_span..end_span).with_message(&sl.message) }) .collect() } else { @@ -179,7 +184,10 @@ fn convert_diagnostic( diagnostic.with_message(&cd.message).with_labels(secondary_labels).with_notes(notes) } -fn stack_trace(files: &fm::FileManager, call_stack: &[Location]) -> String { +fn stack_trace<'files>( + files: &'files impl Files<'files, FileId = fm::FileId>, + call_stack: &[Location], +) -> String { if call_stack.is_empty() { return String::new(); } @@ -187,11 +195,11 @@ fn stack_trace(files: &fm::FileManager, call_stack: &[Location]) -> String { let mut result = "Call stack:\n".to_string(); for (i, call_item) in call_stack.iter().enumerate() { - let path = files.path(call_item.file); - let source = files.fetch_file(call_item.file).source(); + let path = files.name(call_item.file).expect("should get file path"); + let source = files.source(call_item.file).expect("should get file source"); - let (line, column) = location(source, call_item.span.start()); - result += &format!("{}. {}.nr:{}:{}\n", i + 1, path.display(), line, column); + let (line, column) = location(source.as_ref(), call_item.span.start()); + result += &format!("{}. {}:{}:{}\n", i + 1, path, line, column); } result diff --git a/compiler/noirc_evaluator/Cargo.toml b/compiler/noirc_evaluator/Cargo.toml new file mode 100644 index 00000000000..2b207e3d43c --- /dev/null +++ b/compiler/noirc_evaluator/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "noirc_evaluator" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +noirc_frontend.workspace = true +noirc_errors.workspace = true +noirc_abi.workspace = true +acvm.workspace = true +fxhash = "0.2.1" +iter-extended.workspace = true +thiserror.workspace = true +num-bigint = "0.4" +im = "15.1" diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen.rs similarity index 84% rename from crates/noirc_evaluator/src/brillig/brillig_gen.rs rename to compiler/noirc_evaluator/src/brillig/brillig_gen.rs index a1e82bbf443..53e86a00e75 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_gen.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen.rs @@ -4,13 +4,10 @@ pub(crate) mod brillig_directive; pub(crate) mod brillig_fn; pub(crate) mod brillig_slice_ops; -use crate::ssa::ir::{function::Function, post_order::PostOrder}; - -use std::collections::HashMap; - use self::{brillig_block::BrilligBlock, brillig_fn::FunctionContext}; - use super::brillig_ir::{artifact::BrilligArtifact, BrilligContext}; +use crate::ssa::ir::{function::Function, post_order::PostOrder}; +use fxhash::FxHashMap as HashMap; /// Converting an SSA function into Brillig bytecode. pub(crate) fn convert_ssa_function(func: &Function, enable_debug_trace: bool) -> BrilligArtifact { @@ -18,8 +15,10 @@ pub(crate) fn convert_ssa_function(func: &Function, enable_debug_trace: bool) -> reverse_post_order.extend_from_slice(PostOrder::with_function(func).as_slice()); reverse_post_order.reverse(); - let mut function_context = - FunctionContext { function_id: func.id(), ssa_value_to_brillig_variable: HashMap::new() }; + let mut function_context = FunctionContext { + function_id: func.id(), + ssa_value_to_brillig_variable: HashMap::default(), + }; let mut brillig_context = BrilligContext::new(enable_debug_trace); diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs new file mode 100644 index 00000000000..e1d3f333f59 --- /dev/null +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -0,0 +1,165 @@ +use acvm::acir::{ + brillig::{BlackBoxOp, HeapVector, RegisterOrMemory}, + BlackBoxFunc, +}; + +use crate::brillig::brillig_ir::BrilligContext; + +/// Transforms SSA's black box function calls into the corresponding brillig instructions +/// Extracting arguments and results from the SSA function call +/// And making any necessary type conversions to adapt noir's blackbox calls to brillig's +pub(crate) fn convert_black_box_call( + brillig_context: &mut BrilligContext, + bb_func: &BlackBoxFunc, + function_arguments: &[RegisterOrMemory], + function_results: &[RegisterOrMemory], +) { + match bb_func { + BlackBoxFunc::SHA256 => { + if let ([message], [RegisterOrMemory::HeapArray(result_array)]) = + (function_arguments, function_results) + { + let message_vector = convert_array_or_vector(brillig_context, message, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::Sha256 { + message: message_vector, + output: *result_array, + }); + } else { + unreachable!("ICE: SHA256 expects one array argument and one array result") + } + } + BlackBoxFunc::Blake2s => { + if let ([message], [RegisterOrMemory::HeapArray(result_array)]) = + (function_arguments, function_results) + { + let message_vector = convert_array_or_vector(brillig_context, message, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::Blake2s { + message: message_vector, + output: *result_array, + }); + } else { + unreachable!("ICE: Blake2s expects one array argument and one array result") + } + } + BlackBoxFunc::Keccak256 => { + if let ( + [message, RegisterOrMemory::RegisterIndex(array_size)], + [RegisterOrMemory::HeapArray(result_array)], + ) = (function_arguments, function_results) + { + let mut message_vector = convert_array_or_vector(brillig_context, message, bb_func); + message_vector.size = *array_size; + + brillig_context.black_box_op_instruction(BlackBoxOp::Keccak256 { + message: message_vector, + output: *result_array, + }); + } else { + unreachable!("ICE: Keccak256 expects message, message size and result array") + } + } + BlackBoxFunc::HashToField128Security => { + if let ([message], [RegisterOrMemory::RegisterIndex(result_register)]) = + (function_arguments, function_results) + { + let message_vector = convert_array_or_vector(brillig_context, message, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::HashToField128Security { + message: message_vector, + output: *result_register, + }); + } else { + unreachable!("ICE: HashToField128Security expects one array argument and one register result") + } + } + BlackBoxFunc::EcdsaSecp256k1 => { + if let ( + [RegisterOrMemory::HeapArray(public_key_x), RegisterOrMemory::HeapArray(public_key_y), RegisterOrMemory::HeapArray(signature), message], + [RegisterOrMemory::RegisterIndex(result_register)], + ) = (function_arguments, function_results) + { + let message_hash_vector = + convert_array_or_vector(brillig_context, message, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::EcdsaSecp256k1 { + hashed_msg: message_hash_vector, + public_key_x: *public_key_x, + public_key_y: *public_key_y, + signature: *signature, + result: *result_register, + }); + } else { + unreachable!( + "ICE: EcdsaSecp256k1 expects four array arguments and one register result" + ) + } + } + BlackBoxFunc::Pedersen => { + if let ( + [message, RegisterOrMemory::RegisterIndex(domain_separator)], + [RegisterOrMemory::HeapArray(result_array)], + ) = (function_arguments, function_results) + { + let message_vector = convert_array_or_vector(brillig_context, message, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::Pedersen { + inputs: message_vector, + domain_separator: *domain_separator, + output: *result_array, + }); + } else { + unreachable!("ICE: Pedersen expects one array argument, a register for the domain separator, and one array result") + } + } + BlackBoxFunc::SchnorrVerify => { + if let ( + [RegisterOrMemory::RegisterIndex(public_key_x), RegisterOrMemory::RegisterIndex(public_key_y), RegisterOrMemory::HeapArray(signature), message], + [RegisterOrMemory::RegisterIndex(result_register)], + ) = (function_arguments, function_results) + { + let message_hash = convert_array_or_vector(brillig_context, message, bb_func); + let signature = brillig_context.array_to_vector(signature); + brillig_context.black_box_op_instruction(BlackBoxOp::SchnorrVerify { + public_key_x: *public_key_x, + public_key_y: *public_key_y, + message: message_hash, + signature, + result: *result_register, + }); + } else { + unreachable!("ICE: Schnorr verify expects two registers for the public key, an array for signature, an array for the message hash and one result register") + } + } + BlackBoxFunc::FixedBaseScalarMul => { + if let ( + [RegisterOrMemory::RegisterIndex(low), RegisterOrMemory::RegisterIndex(high)], + [RegisterOrMemory::HeapArray(result_array)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::FixedBaseScalarMul { + low: *low, + high: *high, + result: *result_array, + }); + } else { + unreachable!( + "ICE: FixedBaseScalarMul expects one register argument and one array result" + ) + } + } + _ => unimplemented!("ICE: Black box function {:?} is not implemented", bb_func), + } +} + +fn convert_array_or_vector( + brillig_context: &mut BrilligContext, + array_or_vector: &RegisterOrMemory, + bb_func: &BlackBoxFunc, +) -> HeapVector { + match array_or_vector { + RegisterOrMemory::HeapArray(array) => brillig_context.array_to_vector(array), + RegisterOrMemory::HeapVector(vector) => *vector, + _ => unreachable!( + "ICE: {} expected an array or a vector, but got {:?}", + bb_func.name(), + array_or_vector + ), + } +} diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs similarity index 95% rename from crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs rename to compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 831ad3d5d2a..c54be4faa50 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -87,7 +87,7 @@ impl<'block> BrilligBlock<'block> { /// /// This is so that during linking there are no duplicates or labels being overwritten. fn create_block_label(function_id: FunctionId, block_id: BasicBlockId) -> String { - format!("{}-{}", function_id, block_id) + format!("{function_id}-{block_id}") } /// Converts an SSA terminator instruction into the necessary opcodes. @@ -214,9 +214,17 @@ impl<'block> BrilligBlock<'block> { ); self.convert_ssa_binary(binary, dfg, result_register); } - Instruction::Constrain(value) => { - let condition = self.convert_ssa_register_value(*value, dfg); - self.brillig_context.constrain_instruction(condition); + Instruction::Constrain(lhs, rhs, assert_message) => { + let condition = self.brillig_context.allocate_register(); + + self.convert_ssa_binary( + &Binary { lhs: *lhs, rhs: *rhs, operator: BinaryOp::Eq }, + dfg, + condition, + ); + + self.brillig_context.constrain_instruction(condition, assert_message.clone()); + self.brillig_context.deallocate_register(condition); } Instruction::Allocate => { let result_value = dfg.instruction_results(instruction_id)[0]; @@ -300,8 +308,29 @@ impl<'block> BrilligBlock<'block> { self.convert_ssa_function_call(*func_id, arguments, dfg, instruction_id); } Value::Intrinsic(Intrinsic::BlackBox(bb_func)) => { + // Slices are represented as a tuple of (length, slice contents). + // We must check the inputs to determine if there are slices + // and make sure that we pass the correct inputs to the black box function call. + // The loop below only keeps the slice contents, so that + // setting up a black box function with slice inputs matches the expected + // number of arguments specified in the function signature. + let mut arguments_no_slice_len = Vec::new(); + for (i, arg) in arguments.iter().enumerate() { + if matches!(dfg.type_of_value(*arg), Type::Numeric(_)) { + if i < arguments.len() - 1 { + if !matches!(dfg.type_of_value(arguments[i + 1]), Type::Slice(_)) { + arguments_no_slice_len.push(*arg); + } + } else { + arguments_no_slice_len.push(*arg); + } + } else { + arguments_no_slice_len.push(*arg); + } + } + let function_arguments = - vecmap(arguments, |arg| self.convert_ssa_value(*arg, dfg)); + vecmap(&arguments_no_slice_len, |arg| self.convert_ssa_value(*arg, dfg)); let function_results = dfg.instruction_results(instruction_id); let function_results = vecmap(function_results, |result| { self.allocate_external_call_result(*result, dfg) @@ -342,7 +371,7 @@ impl<'block> BrilligBlock<'block> { ) => { self.convert_ssa_slice_intrinsic_call( dfg, - &dfg[*func], + &dfg[dfg.resolve(*func)], instruction_id, arguments, ); @@ -463,7 +492,7 @@ impl<'block> BrilligBlock<'block> { destination_variable, ); } - Instruction::ArraySet { array, index, value } => { + Instruction::ArraySet { array, index, value, .. } => { let source_variable = self.convert_ssa_value(*array, dfg); let index_register = self.convert_ssa_register_value(*index, dfg); let value_variable = self.convert_ssa_value(*value, dfg); @@ -929,13 +958,13 @@ impl<'block> BrilligBlock<'block> { /// Converts an SSA `ValueId` into a `RegisterOrMemory`. Initializes if necessary. fn convert_ssa_value(&mut self, value_id: ValueId, dfg: &DataFlowGraph) -> RegisterOrMemory { - let value = &dfg[value_id]; + let value = &dfg[dfg.resolve(value_id)]; match value { Value::Param { .. } | Value::Instruction { .. } => { // All block parameters and instruction results should have already been // converted to registers so we fetch from the cache. - self.function_context.get_variable(value_id) + self.function_context.get_variable(value_id, dfg) } Value::NumericConstant { constant, .. } => { // Constants might have been converted previously or not, so we get or create and @@ -1081,7 +1110,7 @@ impl<'block> BrilligBlock<'block> { /// Returns the type of the operation considering the types of the operands /// TODO: SSA issues binary operations between fields and integers. /// This probably should be explicitly casted in SSA to avoid having to coerce at this level. -pub(crate) fn type_of_binary_operation(lhs_type: Type, rhs_type: Type) -> Type { +pub(crate) fn type_of_binary_operation(lhs_type: &Type, rhs_type: &Type) -> Type { match (lhs_type, rhs_type) { (_, Type::Function) | (Type::Function, _) => { unreachable!("Functions are invalid in binary operations") @@ -1098,7 +1127,7 @@ pub(crate) fn type_of_binary_operation(lhs_type: Type, rhs_type: Type) -> Type { // If either side is a Field constant then, we coerce into the type // of the other operand (Type::Numeric(NumericType::NativeField), typ) - | (typ, Type::Numeric(NumericType::NativeField)) => typ, + | (typ, Type::Numeric(NumericType::NativeField)) => typ.clone(), // If both sides are numeric type, then we expect their types to be // the same. (Type::Numeric(lhs_type), Type::Numeric(rhs_type)) => { @@ -1106,7 +1135,7 @@ pub(crate) fn type_of_binary_operation(lhs_type: Type, rhs_type: Type) -> Type { lhs_type, rhs_type, "lhs and rhs types in a binary operation are always the same" ); - Type::Numeric(lhs_type) + Type::Numeric(*lhs_type) } } } diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs similarity index 97% rename from crates/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs rename to compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs index 6b53b7c2069..ee7bbeed46e 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs @@ -33,6 +33,7 @@ pub(crate) fn directive_invert() -> GeneratedBrillig { }, BrilligOpcode::Stop, ], + assert_messages: Default::default(), locations: Default::default(), } } @@ -101,6 +102,7 @@ pub(crate) fn directive_quotient(bit_size: u32) -> GeneratedBrillig { }, BrilligOpcode::Stop, ], + assert_messages: Default::default(), locations: Default::default(), } } diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs similarity index 96% rename from crates/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs rename to compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs index 7c4cb5e2ced..1ea16fd375e 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use acvm::brillig_vm::brillig::{HeapArray, HeapVector, RegisterIndex, RegisterOrMemory}; use iter_extended::vecmap; @@ -15,6 +13,7 @@ use crate::{ value::ValueId, }, }; +use fxhash::FxHashMap as HashMap; pub(crate) struct FunctionContext { pub(crate) function_id: FunctionId, @@ -31,6 +30,7 @@ impl FunctionContext { value: ValueId, dfg: &DataFlowGraph, ) -> RegisterOrMemory { + let value = dfg.resolve(value); let typ = dfg.type_of_value(value); let variable = match typ { @@ -70,7 +70,8 @@ impl FunctionContext { } /// For a given SSA value id, return the corresponding cached variable. - pub(crate) fn get_variable(&mut self, value: ValueId) -> RegisterOrMemory { + pub(crate) fn get_variable(&mut self, value: ValueId, dfg: &DataFlowGraph) -> RegisterOrMemory { + let value = dfg.resolve(value); *self .ssa_value_to_brillig_variable .get(&value) @@ -83,6 +84,7 @@ impl FunctionContext { value: ValueId, dfg: &DataFlowGraph, ) -> RegisterOrMemory { + let value = dfg.resolve(value); if let Some(variable) = self.ssa_value_to_brillig_variable.get(&value) { return *variable; } diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs similarity index 99% rename from crates/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs rename to compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs index facc4766722..e46cc55c3ea 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs @@ -311,7 +311,6 @@ impl<'block> BrilligBlock<'block> { #[cfg(test)] mod tests { - use std::collections::HashMap; use std::vec; use acvm::acir::brillig::{HeapVector, Value}; @@ -323,11 +322,12 @@ mod tests { use crate::brillig::brillig_ir::tests::{create_and_run_vm, create_context}; use crate::brillig::brillig_ir::BrilligContext; use crate::ssa::ir::map::Id; + use fxhash::FxHashMap as HashMap; fn create_test_environment() -> (FunctionContext, BrilligContext) { let function_context = FunctionContext { function_id: Id::test_new(0), - ssa_value_to_brillig_variable: HashMap::new(), + ssa_value_to_brillig_variable: HashMap::default(), }; let brillig_context = create_context(); (function_context, brillig_context) diff --git a/crates/noirc_evaluator/src/brillig/brillig_ir.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs similarity index 99% rename from crates/noirc_evaluator/src/brillig/brillig_ir.rs rename to compiler/noirc_evaluator/src/brillig/brillig_ir.rs index 41e52434009..2b5ccaeb88c 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -361,13 +361,20 @@ impl BrilligContext { impl BrilligContext { /// Emits brillig bytecode to jump to a trap condition if `condition` /// is false. - pub(crate) fn constrain_instruction(&mut self, condition: RegisterIndex) { + pub(crate) fn constrain_instruction( + &mut self, + condition: RegisterIndex, + assert_message: Option, + ) { self.debug_show.constrain_instruction(condition); self.add_unresolved_jump( BrilligOpcode::JumpIf { condition, location: 0 }, self.next_section_label(), ); self.push_opcode(BrilligOpcode::Trap); + if let Some(assert_message) = assert_message { + self.obj.add_assert_message_to_last_opcode(assert_message); + } self.enter_next_section(); } @@ -1001,7 +1008,8 @@ pub(crate) mod tests { } fn fixed_base_scalar_mul( &self, - _input: &FieldElement, + _low: &FieldElement, + _high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { Ok((4_u128.into(), 5_u128.into())) } diff --git a/crates/noirc_evaluator/src/brillig/brillig_ir/artifact.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs similarity index 91% rename from crates/noirc_evaluator/src/brillig/brillig_ir/artifact.rs rename to compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs index 627e096bfc9..9b8c3913123 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_ir/artifact.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs @@ -17,13 +17,16 @@ pub(crate) enum BrilligParameter { pub(crate) struct GeneratedBrillig { pub(crate) byte_code: Vec, pub(crate) locations: BTreeMap, + pub(crate) assert_messages: BTreeMap, } #[derive(Default, Debug, Clone)] /// Artifacts resulting from the compilation of a function into brillig byte code. -/// Currently it is just the brillig bytecode of the function. +/// It includes the bytecode of the function and all the metadata that allows linking with other functions. pub(crate) struct BrilligArtifact { - byte_code: Vec, + pub(crate) byte_code: Vec, + /// A map of bytecode positions to assertion messages + pub(crate) assert_messages: BTreeMap, /// The set of jumps that need to have their locations /// resolved. unresolved_jumps: Vec<(JumpInstructionPosition, UnresolvedJumpLocation)>, @@ -68,7 +71,11 @@ impl BrilligArtifact { /// Resolves all jumps and generates the final bytecode pub(crate) fn finish(mut self) -> GeneratedBrillig { self.resolve_jumps(); - GeneratedBrillig { byte_code: self.byte_code, locations: self.locations } + GeneratedBrillig { + byte_code: self.byte_code, + locations: self.locations, + assert_messages: self.assert_messages, + } } /// Gets the first unresolved function call of this artifact. @@ -131,6 +138,10 @@ impl BrilligArtifact { .push((position_in_bytecode + offset, label_id.clone())); } + for (position_in_bytecode, message) in &obj.assert_messages { + self.assert_messages.insert(position_in_bytecode + offset, message.clone()); + } + for (position_in_bytecode, call_stack) in obj.locations.iter() { self.locations.insert(position_in_bytecode + offset, call_stack.clone()); } @@ -242,4 +253,9 @@ impl BrilligArtifact { pub(crate) fn set_call_stack(&mut self, call_stack: CallStack) { self.call_stack = call_stack; } + + pub(crate) fn add_assert_message_to_last_opcode(&mut self, message: String) { + let position = self.index_of_next_opcode() - 1; + self.assert_messages.insert(position, message); + } } diff --git a/crates/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs similarity index 98% rename from crates/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs rename to compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index 7a968c6ea08..cc13b959095 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -99,7 +99,7 @@ impl DebugToString for BrilligBinaryOp { if *bit_size >= BRILLIG_MEMORY_ADDRESSING_BIT_SIZE { op.into() } else { - format!("{}:{}", op, bit_size) + format!("{op}:{bit_size}") } } } @@ -395,11 +395,12 @@ impl DebugShow { result ); } - BlackBoxOp::FixedBaseScalarMul { input, result } => { + BlackBoxOp::FixedBaseScalarMul { low, high, result } => { debug_println!( self.enable_debug_trace, - " FIXED_BASE_SCALAR_MUL {} -> {}", - input, + " FIXED_BASE_SCALAR_MUL {} {} -> {}", + low, + high, result ); } diff --git a/crates/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs similarity index 100% rename from crates/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs rename to compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs diff --git a/crates/noirc_evaluator/src/brillig/brillig_ir/registers.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/registers.rs similarity index 100% rename from crates/noirc_evaluator/src/brillig/brillig_ir/registers.rs rename to compiler/noirc_evaluator/src/brillig/brillig_ir/registers.rs diff --git a/compiler/noirc_evaluator/src/brillig/mod.rs b/compiler/noirc_evaluator/src/brillig/mod.rs new file mode 100644 index 00000000000..eda1ac97c1e --- /dev/null +++ b/compiler/noirc_evaluator/src/brillig/mod.rs @@ -0,0 +1,67 @@ +pub(crate) mod brillig_gen; +pub(crate) mod brillig_ir; + +use self::{ + brillig_gen::{brillig_fn::FunctionContext, convert_ssa_function}, + brillig_ir::artifact::{BrilligArtifact, Label}, +}; +use crate::ssa::{ + ir::function::{Function, FunctionId, RuntimeType}, + ssa_gen::Ssa, +}; +use std::collections::{BTreeSet, HashMap}; + +/// Context structure for the brillig pass. +/// It stores brillig-related data required for brillig generation. +#[derive(Default)] +pub struct Brillig { + /// Maps SSA function labels to their brillig artifact + ssa_function_to_brillig: HashMap, +} + +impl Brillig { + /// Compiles a function into brillig and store the compilation artifacts + pub(crate) fn compile(&mut self, func: &Function, enable_debug_trace: bool) { + let obj = convert_ssa_function(func, enable_debug_trace); + self.ssa_function_to_brillig.insert(func.id(), obj); + } + + /// Finds a brillig function artifact by its function label + pub(crate) fn find_by_function_label(&self, function_label: Label) -> Option<&BrilligArtifact> { + self.ssa_function_to_brillig.iter().find_map(|(function_id, obj)| { + if FunctionContext::function_id_to_function_label(*function_id) == function_label { + Some(obj) + } else { + None + } + }) + } +} + +impl std::ops::Index for Brillig { + type Output = BrilligArtifact; + fn index(&self, id: FunctionId) -> &Self::Output { + &self.ssa_function_to_brillig[&id] + } +} + +impl Ssa { + /// Compile to brillig brillig functions and ACIR functions reachable from them + pub(crate) fn to_brillig(&self, enable_debug_trace: bool) -> Brillig { + // Collect all the function ids that are reachable from brillig + // That means all the functions marked as brillig and ACIR functions called by them + let brillig_reachable_function_ids = self + .functions + .iter() + .filter_map(|(id, func)| (func.runtime() == RuntimeType::Brillig).then_some(*id)) + .collect::>(); + + let mut brillig = Brillig::default(); + for brillig_function_id in brillig_reachable_function_ids { + let func = &self.functions[&brillig_function_id]; + brillig.compile(func, enable_debug_trace); + } + + brillig + } +} diff --git a/compiler/noirc_evaluator/src/errors.rs b/compiler/noirc_evaluator/src/errors.rs new file mode 100644 index 00000000000..2d0d73e9c87 --- /dev/null +++ b/compiler/noirc_evaluator/src/errors.rs @@ -0,0 +1,126 @@ +//! Noir Evaluator has two types of errors +//! +//! [RuntimeError]s that should be displayed to the user +//! +//! [InternalError]s that are used for checking internal logics of the SSA +//! +//! An Error of the former is a user Error +//! +//! An Error of the latter is an error in the implementation of the compiler +use acvm::acir::native_types::Expression; +use iter_extended::vecmap; +use noirc_errors::{CustomDiagnostic as Diagnostic, FileDiagnostic}; +use thiserror::Error; + +use crate::ssa::ir::dfg::CallStack; + +#[derive(Debug, PartialEq, Eq, Clone, Error)] +pub enum RuntimeError { + #[error("{}", format_failed_constraint(.assert_message))] + FailedConstraint { + lhs: Box, + rhs: Box, + call_stack: CallStack, + assert_message: Option, + }, + #[error(transparent)] + InternalError(#[from] InternalError), + #[error("Index out of bounds, array has size {index:?}, but index was {array_size:?}")] + IndexOutOfBounds { index: usize, array_size: usize, call_stack: CallStack }, + #[error("Range constraint of {num_bits} bits is too large for the Field size")] + InvalidRangeConstraint { num_bits: u32, call_stack: CallStack }, + #[error("Expected array index to fit into a u64")] + TypeConversion { from: String, into: String, call_stack: CallStack }, + #[error("{name:?} is not initialized")] + UnInitialized { name: String, call_stack: CallStack }, + #[error("Integer sized {num_bits:?} is over the max supported size of {max_num_bits:?}")] + UnsupportedIntegerSize { num_bits: u32, max_num_bits: u32, call_stack: CallStack }, + #[error("Could not determine loop bound at compile-time")] + UnknownLoopBound { call_stack: CallStack }, + #[error("Argument is not constant")] + AssertConstantFailed { call_stack: CallStack }, +} + +// We avoid showing the actual lhs and rhs since most of the time they are just 0 +// and 1 respectively. This would confuse users if a constraint such as +// assert(foo < bar) fails with "failed constraint: 0 = 1." +fn format_failed_constraint(message: &Option) -> String { + match message { + Some(message) => format!("Failed constraint: '{message}'"), + None => "Failed constraint".to_owned(), + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Error)] +pub enum InternalError { + #[error("ICE: Both expressions should have degree<=1")] + DegreeNotReduced { call_stack: CallStack }, + #[error("Try to get element from empty array")] + EmptyArray { call_stack: CallStack }, + #[error("ICE: {message:?}")] + General { message: String, call_stack: CallStack }, + #[error("ICE: {name:?} missing {arg:?} arg")] + MissingArg { name: String, arg: String, call_stack: CallStack }, + #[error("ICE: {name:?} should be a constant")] + NotAConstant { name: String, call_stack: CallStack }, + #[error("ICE: Undeclared AcirVar")] + UndeclaredAcirVar { call_stack: CallStack }, + #[error("ICE: Expected {expected:?}, found {found:?}")] + UnExpected { expected: String, found: String, call_stack: CallStack }, +} + +impl RuntimeError { + fn call_stack(&self) -> &CallStack { + match self { + RuntimeError::InternalError( + InternalError::DegreeNotReduced { call_stack } + | InternalError::EmptyArray { call_stack } + | InternalError::General { call_stack, .. } + | InternalError::MissingArg { call_stack, .. } + | InternalError::NotAConstant { call_stack, .. } + | InternalError::UndeclaredAcirVar { call_stack } + | InternalError::UnExpected { call_stack, .. }, + ) + | RuntimeError::FailedConstraint { call_stack, .. } + | RuntimeError::IndexOutOfBounds { call_stack, .. } + | RuntimeError::InvalidRangeConstraint { call_stack, .. } + | RuntimeError::TypeConversion { call_stack, .. } + | RuntimeError::UnInitialized { call_stack, .. } + | RuntimeError::UnknownLoopBound { call_stack } + | RuntimeError::AssertConstantFailed { call_stack } + | RuntimeError::UnsupportedIntegerSize { call_stack, .. } => call_stack, + } + } +} + +impl From for FileDiagnostic { + fn from(error: RuntimeError) -> FileDiagnostic { + let call_stack = vecmap(error.call_stack(), |location| *location); + let diagnostic = error.into_diagnostic(); + let file_id = call_stack.last().map(|location| location.file).unwrap_or_default(); + + diagnostic.in_file(file_id).with_call_stack(call_stack) + } +} + +impl RuntimeError { + fn into_diagnostic(self) -> Diagnostic { + match self { + RuntimeError::InternalError(cause) => { + Diagnostic::simple_error( + "Internal Consistency Evaluators Errors: \n + This is likely a bug. Consider Opening an issue at https://github.com/noir-lang/noir/issues".to_owned(), + cause.to_string(), + noirc_errors::Span::inclusive(0, 0) + ) + } + _ => { + let message = self.to_string(); + let location = + self.call_stack().back().expect("Expected RuntimeError to have a location"); + + Diagnostic::simple_error(message, String::new(), location.span) + } + } + } +} diff --git a/crates/noirc_evaluator/src/lib.rs b/compiler/noirc_evaluator/src/lib.rs similarity index 100% rename from crates/noirc_evaluator/src/lib.rs rename to compiler/noirc_evaluator/src/lib.rs diff --git a/compiler/noirc_evaluator/src/ssa.rs b/compiler/noirc_evaluator/src/ssa.rs new file mode 100644 index 00000000000..92bbe21b20d --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa.rs @@ -0,0 +1,158 @@ +//! SSA stands for Single Static Assignment +//! The IR presented in this module will already +//! be in SSA form and will be used to apply +//! conventional optimizations like Common Subexpression +//! elimination and constant folding. +//! +//! This module heavily borrows from Cranelift +#![allow(dead_code)] + +use std::collections::BTreeSet; + +use crate::errors::RuntimeError; +use acvm::acir::{ + circuit::{Circuit, PublicInputs}, + native_types::Witness, +}; + +use noirc_errors::debug_info::DebugInfo; + +use noirc_abi::Abi; + +use noirc_frontend::{hir::Context, monomorphization::ast::Program}; + +use self::{abi_gen::gen_abi, acir_gen::GeneratedAcir, ssa_gen::Ssa}; + +pub mod abi_gen; +mod acir_gen; +mod function_builder; +pub mod ir; +mod opt; +pub mod ssa_gen; + +/// Optimize the given program by converting it into SSA +/// form and performing optimizations there. When finished, +/// convert the final SSA into ACIR and return it. +pub(crate) fn optimize_into_acir( + program: Program, + print_ssa_passes: bool, + print_brillig_trace: bool, +) -> Result { + let abi_distinctness = program.return_distinctness; + let ssa = SsaBuilder::new(program, print_ssa_passes) + .run_pass(Ssa::defunctionalize, "After Defunctionalization:") + .run_pass(Ssa::inline_functions, "After Inlining:") + // Run mem2reg with the CFG separated into blocks + .run_pass(Ssa::mem2reg, "After Mem2Reg:") + .try_run_pass(Ssa::evaluate_assert_constant, "After Assert Constant:")? + .try_run_pass(Ssa::unroll_loops, "After Unrolling:")? + .run_pass(Ssa::simplify_cfg, "After Simplifying:") + // Run mem2reg before flattening to handle any promotion + // of values that can be accessed after loop unrolling. + // If there are slice mergers uncovered by loop unrolling + // and this pass is missed, slice merging will fail inside of flattening. + .run_pass(Ssa::mem2reg, "After Mem2Reg:") + .run_pass(Ssa::flatten_cfg, "After Flattening:") + // Run mem2reg once more with the flattened CFG to catch any remaining loads/stores + .run_pass(Ssa::mem2reg, "After Mem2Reg:") + .run_pass(Ssa::fold_constants, "After Constant Folding:") + .run_pass(Ssa::dead_instruction_elimination, "After Dead Instruction Elimination:") + .finish(); + + let brillig = ssa.to_brillig(print_brillig_trace); + let last_array_uses = ssa.find_last_array_uses(); + ssa.into_acir(brillig, abi_distinctness, &last_array_uses) +} + +/// Compiles the [`Program`] into [`ACIR`][acvm::acir::circuit::Circuit]. +/// +/// The output ACIR is is backend-agnostic and so must go through a transformation pass before usage in proof generation. +pub fn create_circuit( + context: &Context, + program: Program, + enable_ssa_logging: bool, + enable_brillig_logging: bool, +) -> Result<(Circuit, DebugInfo, Abi), RuntimeError> { + let func_sig = program.main_function_signature.clone(); + let mut generated_acir = + optimize_into_acir(program, enable_ssa_logging, enable_brillig_logging)?; + let opcodes = generated_acir.take_opcodes(); + let GeneratedAcir { + current_witness_index, + return_witnesses, + locations, + input_witnesses, + assert_messages, + .. + } = generated_acir; + + let abi = gen_abi(context, func_sig, &input_witnesses, return_witnesses.clone()); + let public_abi = abi.clone().public_abi(); + + let public_parameters = + PublicInputs(public_abi.param_witnesses.values().flatten().copied().collect()); + + let all_parameters: BTreeSet = + abi.param_witnesses.values().flatten().copied().collect(); + let private_parameters = all_parameters.difference(&public_parameters.0).copied().collect(); + + let return_values = PublicInputs(return_witnesses.into_iter().collect()); + + let circuit = Circuit { + current_witness_index, + opcodes, + private_parameters, + public_parameters, + return_values, + assert_messages: assert_messages.into_iter().collect(), + }; + + // This converts each im::Vector in the BTreeMap to a Vec + let locations = locations + .into_iter() + .map(|(index, locations)| (index, locations.into_iter().collect())) + .collect(); + + let debug_info = DebugInfo::new(locations); + + Ok((circuit, debug_info, abi)) +} + +// This is just a convenience object to bundle the ssa with `print_ssa_passes` for debug printing. +struct SsaBuilder { + ssa: Ssa, + print_ssa_passes: bool, +} + +impl SsaBuilder { + fn new(program: Program, print_ssa_passes: bool) -> SsaBuilder { + SsaBuilder { print_ssa_passes, ssa: ssa_gen::generate_ssa(program) }.print("Initial SSA:") + } + + fn finish(self) -> Ssa { + self.ssa + } + + /// Runs the given SSA pass and prints the SSA afterward if `print_ssa_passes` is true. + fn run_pass(mut self, pass: fn(Ssa) -> Ssa, msg: &str) -> Self { + self.ssa = pass(self.ssa); + self.print(msg) + } + + /// The same as `run_pass` but for passes that may fail + fn try_run_pass( + mut self, + pass: fn(Ssa) -> Result, + msg: &str, + ) -> Result { + self.ssa = pass(self.ssa)?; + Ok(self.print(msg)) + } + + fn print(self, msg: &str) -> Self { + if self.print_ssa_passes { + println!("{msg}\n{}", self.ssa); + } + self + } +} diff --git a/compiler/noirc_evaluator/src/ssa/abi_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/abi_gen/mod.rs new file mode 100644 index 00000000000..e4b4026bf21 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/abi_gen/mod.rs @@ -0,0 +1,68 @@ +use std::collections::BTreeMap; + +use acvm::acir::native_types::Witness; +use iter_extended::{btree_map, vecmap}; +use noirc_abi::{Abi, AbiParameter, AbiType}; +use noirc_frontend::{ + hir::Context, + hir_def::{ + function::{FunctionSignature, Param}, + stmt::HirPattern, + }, + node_interner::NodeInterner, +}; + +/// Attempts to retrieve the name of this parameter. Returns None +/// if this parameter is a tuple or struct pattern. +fn get_param_name<'a>(pattern: &HirPattern, interner: &'a NodeInterner) -> Option<&'a str> { + match pattern { + HirPattern::Identifier(ident) => Some(interner.definition_name(ident.id)), + HirPattern::Mutable(pattern, _) => get_param_name(pattern, interner), + HirPattern::Tuple(_, _) => None, + HirPattern::Struct(_, _, _) => None, + } +} + +pub fn into_abi_params(context: &Context, params: Vec) -> Vec { + vecmap(params, |(pattern, typ, vis)| { + let param_name = get_param_name(&pattern, &context.def_interner) + .expect("Abi for tuple and struct parameters is unimplemented") + .to_owned(); + let as_abi = AbiType::from_type(context, &typ); + AbiParameter { name: param_name, typ: as_abi, visibility: vis.into() } + }) +} + +/// Arranges a function signature and a generated circuit's return witnesses into a +/// `noirc_abi::Abi`. +pub(crate) fn gen_abi( + context: &Context, + func_sig: FunctionSignature, + input_witnesses: &[Witness], + return_witnesses: Vec, +) -> Abi { + let (parameters, return_type) = func_sig; + let parameters = into_abi_params(context, parameters); + let return_type = return_type.map(|typ| AbiType::from_type(context, &typ)); + let param_witnesses = param_witnesses_from_abi_param(¶meters, input_witnesses); + Abi { parameters, return_type, param_witnesses, return_witnesses } +} + +// Takes each abi parameter and shallowly maps to the expected witness range in which the +// parameter's constituent values live. +fn param_witnesses_from_abi_param( + abi_params: &Vec, + input_witnesses: &[Witness], +) -> BTreeMap> { + let mut idx = 0_usize; + + btree_map(abi_params, |param| { + let num_field_elements_needed = param.typ.field_count(); + let mut wit = Vec::new(); + for _ in 0..num_field_elements_needed { + wit.push(input_witnesses[idx]); + idx += 1; + } + (param.name.clone(), wit) + }) +} diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/acir_gen/acir_ir.rs rename to compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir.rs diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs similarity index 93% rename from crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs rename to compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index fe31608db8d..b5461269f4a 100644 --- a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -6,15 +6,13 @@ use crate::ssa::acir_gen::{AcirDynamicArray, AcirValue}; use crate::ssa::ir::dfg::CallStack; use crate::ssa::ir::types::Type as SsaType; use crate::ssa::ir::{instruction::Endian, types::NumericType}; +use acvm::acir::circuit::brillig::{BrilligInputs, BrilligOutputs}; use acvm::acir::circuit::opcodes::{BlockId, MemOp}; use acvm::acir::circuit::Opcode; -use acvm::acir::{ - brillig::Opcode as BrilligOpcode, - circuit::brillig::{BrilligInputs, BrilligOutputs}, -}; use acvm::brillig_vm::{brillig::Value, Registers, VMStatus, VM}; use acvm::{ acir::{ + brillig::Opcode as BrilligOpcode, circuit::opcodes::FunctionInput, native_types::{Expression, Witness}, BlackBoxFunc, @@ -22,8 +20,8 @@ use acvm::{ FieldElement, }; use acvm::{BlackBoxFunctionSolver, BlackBoxResolutionError}; +use fxhash::FxHashMap as HashMap; use iter_extended::{try_vecmap, vecmap}; -use std::collections::HashMap; use std::{borrow::Cow, hash::Hash}; #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -221,6 +219,20 @@ impl AcirContext { self.acir_ir.call_stack = call_stack; } + fn get_or_create_witness_var(&mut self, var: AcirVar) -> Result { + if self.var_to_expression(var)?.to_witness().is_some() { + // If called with a variable which is already a witness then return the same variable. + return Ok(var); + } + + let var_as_witness = self.var_to_witness(var)?; + + let witness_var = self.add_data(AcirVarData::Witness(var_as_witness)); + self.mark_variables_equivalent(var, witness_var)?; + + Ok(witness_var) + } + /// Converts an [`AcirVar`] to a [`Witness`] fn var_to_witness(&mut self, var: AcirVar) -> Result { let expression = self.var_to_expression(var)?; @@ -228,7 +240,7 @@ impl AcirContext { } /// Converts an [`AcirVar`] to an [`Expression`] - fn var_to_expression(&self, var: AcirVar) -> Result { + pub(crate) fn var_to_expression(&self, var: AcirVar) -> Result { let var_data = match self.vars.get(&var) { Some(var_data) => var_data, None => { @@ -270,8 +282,14 @@ impl AcirContext { let var_data = &self.vars[&var]; if let AcirVarData::Const(constant) = var_data { // Note that this will return a 0 if the inverse is not available - let result_var = self.add_data(AcirVarData::Const(constant.inverse())); - return Ok(result_var); + let inverted_var = self.add_data(AcirVarData::Const(constant.inverse())); + + // Check that the inverted var is valid. + // This check prevents invalid divisons by zero. + let should_be_one = self.mul_var(inverted_var, var)?; + self.maybe_eq_predicate(should_be_one, predicate)?; + + return Ok(inverted_var); } // Compute the inverse with brillig code @@ -286,6 +304,8 @@ impl AcirContext { )?; let inverted_var = Self::expect_one_var(results); + // Check that the inverted var is valid. + // This check prevents invalid divisons by zero. let should_be_one = self.mul_var(inverted_var, var)?; self.maybe_eq_predicate(should_be_one, predicate)?; @@ -293,9 +313,14 @@ impl AcirContext { } // Constrains `var` to be equal to the constant value `1` - pub(crate) fn assert_eq_one(&mut self, var: AcirVar) -> Result<(), RuntimeError> { + pub(crate) fn assert_eq_one( + &mut self, + var: AcirVar, + assert_message: Option, + ) -> Result<(), RuntimeError> { let one = self.add_constant(FieldElement::one()); - self.assert_eq_var(var, one) + self.assert_eq_var(var, one, assert_message)?; + Ok(()) } // Constrains `var` to be equal to predicate if the predicate is true @@ -308,7 +333,7 @@ impl AcirContext { predicate: AcirVar, ) -> Result<(), RuntimeError> { let pred_mul_var = self.mul_var(var, predicate)?; - self.assert_eq_var(pred_mul_var, predicate) + self.assert_eq_var(pred_mul_var, predicate, None) } // Returns the variable from the results, assuming it is the only result @@ -394,7 +419,12 @@ impl AcirContext { } /// Constrains the `lhs` and `rhs` to be equal. - pub(crate) fn assert_eq_var(&mut self, lhs: AcirVar, rhs: AcirVar) -> Result<(), RuntimeError> { + pub(crate) fn assert_eq_var( + &mut self, + lhs: AcirVar, + rhs: AcirVar, + assert_message: Option, + ) -> Result<(), RuntimeError> { let lhs_expr = self.var_to_expression(lhs)?; let rhs_expr = self.var_to_expression(rhs)?; @@ -413,11 +443,15 @@ impl AcirContext { lhs: Box::new(lhs_expr), rhs: Box::new(rhs_expr), call_stack: self.get_call_stack(), + assert_message, }); }; } self.acir_ir.assert_is_zero(diff_expr); + if let Some(message) = assert_message { + self.acir_ir.assert_messages.insert(self.acir_ir.last_acir_opcode_location(), message); + } self.mark_variables_equivalent(lhs, rhs)?; Ok(()) @@ -459,45 +493,35 @@ impl AcirContext { /// Adds a new Variable to context whose value will /// be constrained to be the multiplication of `lhs` and `rhs` pub(crate) fn mul_var(&mut self, lhs: AcirVar, rhs: AcirVar) -> Result { - let lhs_data = &self.vars[&lhs]; - let rhs_data = &self.vars[&rhs]; + let lhs_data = self.vars[&lhs].clone(); + let rhs_data = self.vars[&rhs].clone(); let result = match (lhs_data, rhs_data) { - (AcirVarData::Witness(witness), AcirVarData::Expr(expr)) - | (AcirVarData::Expr(expr), AcirVarData::Witness(witness)) => { - let expr_as_witness = self.acir_ir.get_or_create_witness(expr); - let mut expr = Expression::default(); - expr.push_multiplication_term(FieldElement::one(), *witness, expr_as_witness); - - self.add_data(AcirVarData::Expr(expr)) + (AcirVarData::Const(lhs_constant), AcirVarData::Const(rhs_constant)) => { + self.add_data(AcirVarData::Const(lhs_constant * rhs_constant)) } (AcirVarData::Witness(witness), AcirVarData::Const(constant)) | (AcirVarData::Const(constant), AcirVarData::Witness(witness)) => { let mut expr = Expression::default(); - expr.push_addition_term(*constant, *witness); + expr.push_addition_term(constant, witness); self.add_data(AcirVarData::Expr(expr)) } (AcirVarData::Const(constant), AcirVarData::Expr(expr)) | (AcirVarData::Expr(expr), AcirVarData::Const(constant)) => { - self.add_data(AcirVarData::Expr(expr * *constant)) + self.add_data(AcirVarData::Expr(&expr * constant)) } (AcirVarData::Witness(lhs_witness), AcirVarData::Witness(rhs_witness)) => { let mut expr = Expression::default(); - expr.push_multiplication_term(FieldElement::one(), *lhs_witness, *rhs_witness); + expr.push_multiplication_term(FieldElement::one(), lhs_witness, rhs_witness); self.add_data(AcirVarData::Expr(expr)) } - (AcirVarData::Const(lhs_constant), AcirVarData::Const(rhs_constant)) => { - self.add_data(AcirVarData::Const(*lhs_constant * *rhs_constant)) - } - (AcirVarData::Expr(lhs_expr), AcirVarData::Expr(rhs_expr)) => { - let lhs_expr_as_witness = self.acir_ir.get_or_create_witness(lhs_expr); - let rhs_expr_as_witness = self.acir_ir.get_or_create_witness(rhs_expr); - let mut expr = Expression::default(); - expr.push_multiplication_term( - FieldElement::one(), - lhs_expr_as_witness, - rhs_expr_as_witness, - ); - self.add_data(AcirVarData::Expr(expr)) + ( + AcirVarData::Expr(_) | AcirVarData::Witness(_), + AcirVarData::Expr(_) | AcirVarData::Witness(_), + ) => { + let lhs = self.get_or_create_witness_var(lhs)?; + let rhs = self.get_or_create_witness_var(rhs)?; + + self.mul_var(lhs, rhs)? } }; Ok(result) @@ -662,7 +686,7 @@ impl AcirContext { } /// Returns an `AcirVar` which will be constrained to be lhs mod 2^{rhs} - /// In order to do this, we simply perform euclidian division of lhs by 2^{rhs} + /// In order to do this, we 'simply' perform euclidian division of lhs by 2^{rhs} /// The remainder of the division is then lhs mod 2^{rhs} pub(crate) fn truncate_var( &mut self, @@ -670,11 +694,12 @@ impl AcirContext { rhs: u32, max_bit_size: u32, ) -> Result { - let lhs_expr = self.var_to_expression(lhs)?; - // 2^{rhs} let divisor = FieldElement::from(2_i128).pow(&FieldElement::from(rhs as i128)); - // Computes lhs = 2^{rhs} * q + r + + let lhs_data = &self.vars[&lhs]; + let lhs_expr = lhs_data.to_expression(); + // Computes lhs = 2^{rhs} * q + r let (_, remainder) = self.acir_ir.euclidean_division( &lhs_expr, &Expression::from_field(divisor), @@ -940,7 +965,6 @@ impl AcirContext { } // Otherwise we must generate ACIR for it and execute at runtime. - let mut b_outputs = Vec::new(); let outputs_var = vecmap(outputs, |output| match output { AcirType::NumericType(_) => { @@ -1147,7 +1171,7 @@ impl AcirContext { // Add the memory read operation to the list of opcodes let op = MemOp::read_at_mem_index(index_witness.into(), value_read_witness); - self.acir_ir.push_opcode(Opcode::MemoryOp { block_id, op }); + self.acir_ir.push_opcode(Opcode::MemoryOp { block_id, op, predicate: None }); Ok(value_read_var) } @@ -1168,7 +1192,7 @@ impl AcirContext { // Add the memory write operation to the list of opcodes let op = MemOp::write_to_mem_index(index_witness.into(), value_write_witness.into()); - self.acir_ir.push_opcode(Opcode::MemoryOp { block_id, op }); + self.acir_ir.push_opcode(Opcode::MemoryOp { block_id, op, predicate: None }); Ok(()) } @@ -1183,19 +1207,31 @@ impl AcirContext { ) -> Result<(), InternalError> { // If the optional values are supplied, then we fill the initialized // array with those values. If not, then we fill it with zeros. + let mut nested = false; let initialized_values = match optional_values { None => { let zero = self.add_constant(FieldElement::zero()); let zero_witness = self.var_to_witness(zero)?; vec![zero_witness; len] } - Some(optional_values) => try_vecmap(optional_values, |value| { - let value = value.clone().into_var()?; - self.var_to_witness(value) - })?, + Some(optional_values) => { + let mut values = Vec::new(); + for value in optional_values { + if let Ok(some_value) = value.clone().into_var() { + values.push(self.var_to_witness(some_value)?); + } else { + nested = true; + break; + } + } + values + } }; + // we do not initialize nested arrays. This means that non-const indexes are not supported for nested arrays + if !nested { + self.acir_ir.push_opcode(Opcode::MemoryInit { block_id, init: initialized_values }); + } - self.acir_ir.push_opcode(Opcode::MemoryInit { block_id, init: initialized_values }); Ok(()) } } @@ -1305,7 +1341,8 @@ fn execute_brillig( } fn fixed_base_scalar_mul( &self, - _input: &FieldElement, + _low: &FieldElement, + _high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { Err(BlackBoxResolutionError::Unsupported(BlackBoxFunc::FixedBaseScalarMul)) } diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs similarity index 87% rename from crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs rename to compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 29ca4fa3892..33f55e76de4 100644 --- a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -44,12 +44,15 @@ pub(crate) struct GeneratedAcir { /// All witness indices which are inputs to the main function pub(crate) input_witnesses: Vec, - /// Correspondance between an opcode index (in opcodes) and the source code call stack which generated it + /// Correspondence between an opcode index (in opcodes) and the source code call stack which generated it pub(crate) locations: BTreeMap, /// Source code location of the current instruction being processed /// None if we do not know the location pub(crate) call_stack: CallStack, + + /// Correspondence between an opcode index and the error message associated with it. + pub(crate) assert_messages: BTreeMap, } impl GeneratedAcir { @@ -62,8 +65,7 @@ impl GeneratedAcir { pub(crate) fn push_opcode(&mut self, opcode: AcirOpcode) { self.opcodes.push(opcode); if !self.call_stack.is_empty() { - self.locations - .insert(OpcodeLocation::Acir(self.opcodes.len() - 1), self.call_stack.clone()); + self.locations.insert(self.last_acir_opcode_location(), self.call_stack.clone()); } } @@ -155,41 +157,48 @@ impl GeneratedAcir { inputs: inputs[0].clone(), output: outputs[0], }, - BlackBoxFunc::SchnorrVerify => BlackBoxFuncCall::SchnorrVerify { - public_key_x: inputs[0][0], - public_key_y: inputs[1][0], - // Schnorr signature is an r & s, 32 bytes each - signature: inputs[2].clone(), - message: inputs[3].clone(), - output: outputs[0], - }, + BlackBoxFunc::SchnorrVerify => { + BlackBoxFuncCall::SchnorrVerify { + public_key_x: inputs[0][0], + public_key_y: inputs[1][0], + // Schnorr signature is an r & s, 32 bytes each + signature: inputs[2].clone(), + message: inputs[3].clone(), + output: outputs[0], + } + } BlackBoxFunc::Pedersen => BlackBoxFuncCall::Pedersen { inputs: inputs[0].clone(), outputs: (outputs[0], outputs[1]), domain_separator: constants[0].to_u128() as u32, }, - BlackBoxFunc::EcdsaSecp256k1 => BlackBoxFuncCall::EcdsaSecp256k1 { - // 32 bytes for each public key co-ordinate - public_key_x: inputs[0].clone(), - public_key_y: inputs[1].clone(), - // (r,s) are both 32 bytes each, so signature - // takes up 64 bytes - signature: inputs[2].clone(), - hashed_message: inputs[3].clone(), - output: outputs[0], - }, - BlackBoxFunc::EcdsaSecp256r1 => BlackBoxFuncCall::EcdsaSecp256r1 { - // 32 bytes for each public key co-ordinate - public_key_x: inputs[0].clone(), - public_key_y: inputs[1].clone(), - // (r,s) are both 32 bytes each, so signature - // takes up 64 bytes - signature: inputs[2].clone(), - hashed_message: inputs[3].clone(), - output: outputs[0], - }, + BlackBoxFunc::EcdsaSecp256k1 => { + BlackBoxFuncCall::EcdsaSecp256k1 { + // 32 bytes for each public key co-ordinate + public_key_x: inputs[0].clone(), + public_key_y: inputs[1].clone(), + // (r,s) are both 32 bytes each, so signature + // takes up 64 bytes + signature: inputs[2].clone(), + hashed_message: inputs[3].clone(), + output: outputs[0], + } + } + BlackBoxFunc::EcdsaSecp256r1 => { + BlackBoxFuncCall::EcdsaSecp256r1 { + // 32 bytes for each public key co-ordinate + public_key_x: inputs[0].clone(), + public_key_y: inputs[1].clone(), + // (r,s) are both 32 bytes each, so signature + // takes up 64 bytes + signature: inputs[2].clone(), + hashed_message: inputs[3].clone(), + output: outputs[0], + } + } BlackBoxFunc::FixedBaseScalarMul => BlackBoxFuncCall::FixedBaseScalarMul { - input: inputs[0][0], + low: inputs[0][0], + high: inputs[1][0], outputs: (outputs[0], outputs[1]), }, BlackBoxFunc::Keccak256 => { @@ -203,6 +212,7 @@ impl GeneratedAcir { }); } }; + BlackBoxFuncCall::Keccak256VariableLength { inputs: inputs[0].clone(), var_message_size, @@ -425,6 +435,16 @@ impl GeneratedAcir { // // If predicate is zero, `q_witness` and `r_witness` will be 0 + // Check that we the rhs is not zero. + // Otherwise, when executing the brillig quotient we may attempt to divide by zero, causing a VM panic. + // + // When the predicate is 0, the equation always passes. + // When the predicate is 1, the rhs must not be 0. + let rhs_is_zero = self.is_equal(&Expression::zero(), rhs); + let rhs_is_not_zero = &self.mul_with_witness(&rhs_is_zero.into(), predicate) + - &self.mul_with_witness(&Expression::zero(), predicate); + self.push_opcode(AcirOpcode::Arithmetic(rhs_is_not_zero)); + // maximum bit size for q and for [r and rhs] let mut max_q_bits = max_bit_size; let mut max_rhs_bits = max_bit_size; @@ -436,15 +456,33 @@ impl GeneratedAcir { } } + // Avoids overflow: 'q*b+r < 2^max_q_bits*2^max_rhs_bits' + let mut avoid_overflow = false; + if max_q_bits + max_rhs_bits >= FieldElement::max_num_bits() - 1 { + // q*b+r can overflow; we avoid this when b is constant + if rhs.is_const() { + avoid_overflow = true; + } else { + // we do not support unbounded division + unreachable!("overflow in unbounded division"); + } + } + let (q_witness, r_witness) = self.brillig_quotient(lhs.clone(), rhs.clone(), predicate.clone(), max_bit_size + 1); - // Apply range constraints to injected witness values. - // Constrains `q` to be 0 <= q < 2^{q_max_bits}, etc. + // Constrain `q < 2^{max_q_bits}`. self.range_constraint(q_witness, max_q_bits)?; + + // Constrain `r < 2^{max_rhs_bits}`. + // + // If `rhs` is a power of 2, then is just a looser version of the following bound constraint. + // In the case where `rhs` isn't a power of 2 then this range constraint is required + // as the bound constraint creates a new witness. + // This opcode will be optimized out if it is redundant so we always add it for safety. self.range_constraint(r_witness, max_rhs_bits)?; - // Constrain r < rhs + // Constrain `r < rhs`. self.bound_constraint_with_offset(&r_witness.into(), rhs, predicate, max_rhs_bits)?; // a * predicate == (b * q + r) * predicate @@ -456,6 +494,32 @@ impl GeneratedAcir { let div_euclidean = &self.mul_with_witness(lhs, predicate) - &self.mul_with_witness(&rhs_constraint, predicate); + if let Some(rhs_const) = rhs.to_const() { + if avoid_overflow { + // we compute q0 = p/rhs + let rhs_big = BigUint::from_bytes_be(&rhs_const.to_be_bytes()); + let q0_big = FieldElement::modulus() / &rhs_big; + let q0 = FieldElement::from_be_bytes_reduce(&q0_big.to_bytes_be()); + // when q == q0, b*q+r can overflow so we need to bound r to avoid the overflow. + let size_predicate = + self.is_equal(&Expression::from_field(q0), &Expression::from(q_witness)); + let predicate = self.mul_with_witness(&size_predicate.into(), predicate); + // Ensure that there is no overflow, under q == q0 predicate + let max_r_big = FieldElement::modulus() - q0_big * rhs_big; + let max_r = FieldElement::from_be_bytes_reduce(&max_r_big.to_bytes_be()); + let max_r_predicate = + self.mul_with_witness(&predicate, &Expression::from_field(max_r)); + let r_predicate = self.mul_with_witness(&Expression::from(r_witness), &predicate); + // Bound the remainder to be OpcodeLocation { + OpcodeLocation::Acir(self.opcodes.len() - 1) + } } /// This function will return the number of inputs that a blackbox function @@ -866,8 +940,8 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { | BlackBoxFunc::EcdsaSecp256k1 | BlackBoxFunc::EcdsaSecp256r1 => None, // Inputs for fixed based scalar multiplication - // is just a scalar - BlackBoxFunc::FixedBaseScalarMul => Some(1), + // is the low and high limbs of the scalar + BlackBoxFunc::FixedBaseScalarMul => Some(2), // Recursive aggregation has a variable number of inputs BlackBoxFunc::RecursiveAggregation => None, } diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/sort.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/sort.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/sort.rs rename to compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/sort.rs diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs new file mode 100644 index 00000000000..a2943596a53 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -0,0 +1,1516 @@ +//! This file holds the pass to convert from Noir's SSA IR to ACIR. +mod acir_ir; + +use std::collections::HashSet; +use std::fmt::Debug; +use std::ops::RangeInclusive; + +use self::acir_ir::acir_variable::{AcirContext, AcirType, AcirVar}; +use super::ir::dfg::CallStack; +use super::{ + ir::{ + dfg::DataFlowGraph, + function::{Function, RuntimeType}, + instruction::{ + Binary, BinaryOp, Instruction, InstructionId, Intrinsic, TerminatorInstruction, + }, + map::Id, + types::{NumericType, Type}, + value::{Value, ValueId}, + }, + ssa_gen::Ssa, +}; +use crate::brillig::brillig_ir::artifact::GeneratedBrillig; +use crate::brillig::brillig_ir::BrilligContext; +use crate::brillig::{brillig_gen::brillig_fn::FunctionContext as BrilligFunctionContext, Brillig}; +use crate::errors::{InternalError, RuntimeError}; +pub(crate) use acir_ir::generated_acir::GeneratedAcir; +use acvm::{ + acir::{circuit::opcodes::BlockId, native_types::Expression}, + FieldElement, +}; +use fxhash::FxHashMap as HashMap; +use im::Vector; +use iter_extended::{try_vecmap, vecmap}; +use noirc_frontend::Distinctness; + +/// Context struct for the acir generation pass. +/// May be similar to the Evaluator struct in the current SSA IR. +struct Context { + /// Maps SSA values to `AcirVar`. + /// + /// This is needed so that we only create a single + /// AcirVar per SSA value. Before creating an `AcirVar` + /// for an SSA value, we check this map. If an `AcirVar` + /// already exists for this Value, we return the `AcirVar`. + ssa_values: HashMap, AcirValue>, + + /// The `AcirVar` that describes the condition belonging to the most recently invoked + /// `SideEffectsEnabled` instruction. + current_side_effects_enabled_var: AcirVar, + + /// Manages and builds the `AcirVar`s to which the converted SSA values refer. + acir_context: AcirContext, + + /// Track initialized acir dynamic arrays + /// + /// An acir array must start with a MemoryInit ACIR opcodes + /// and then have MemoryOp opcodes + /// This set is used to ensure that a MemoryOp opcode is only pushed to the circuit + /// if there is already a MemoryInit opcode. + initialized_arrays: HashSet, + + /// Maps SSA values to BlockId + /// A BlockId is an ACIR structure which identifies a memory block + /// Each acir memory block corresponds to a different SSA array. + memory_blocks: HashMap, BlockId>, + + /// Number of the next BlockId, it is used to construct + /// a new BlockId + max_block_id: u32, +} + +#[derive(Clone)] +pub(crate) struct AcirDynamicArray { + /// Identification for the Acir dynamic array + /// This is essentially a ACIR pointer to the array + block_id: BlockId, + /// Length of the array + len: usize, +} +impl Debug for AcirDynamicArray { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "id: {}, len: {}", self.block_id.0, self.len) + } +} + +#[derive(Debug, Clone)] +pub(crate) enum AcirValue { + Var(AcirVar, AcirType), + Array(im::Vector), + DynamicArray(AcirDynamicArray), +} + +impl AcirValue { + fn into_var(self) -> Result { + match self { + AcirValue::Var(var, _) => Ok(var), + AcirValue::DynamicArray(_) | AcirValue::Array(_) => Err(InternalError::General { + message: "Called AcirValue::into_var on an array".to_string(), + call_stack: CallStack::new(), + }), + } + } + + fn flatten(self) -> Vec<(AcirVar, AcirType)> { + match self { + AcirValue::Var(var, typ) => vec![(var, typ)], + AcirValue::Array(array) => array.into_iter().flat_map(AcirValue::flatten).collect(), + AcirValue::DynamicArray(_) => unimplemented!("Cannot flatten a dynamic array"), + } + } +} + +impl Ssa { + pub(crate) fn into_acir( + self, + brillig: Brillig, + abi_distinctness: Distinctness, + last_array_uses: &HashMap, + ) -> Result { + let context = Context::new(); + let mut generated_acir = context.convert_ssa(self, brillig, last_array_uses)?; + + match abi_distinctness { + Distinctness::Distinct => { + // Create a witness for each return witness we have + // to guarantee that the return witnesses are distinct + let distinct_return_witness: Vec<_> = generated_acir + .return_witnesses + .clone() + .into_iter() + .map(|return_witness| { + generated_acir + .create_witness_for_expression(&Expression::from(return_witness)) + }) + .collect(); + + generated_acir.return_witnesses = distinct_return_witness; + Ok(generated_acir) + } + Distinctness::DuplicationAllowed => Ok(generated_acir), + } + } +} + +impl Context { + fn new() -> Context { + let mut acir_context = AcirContext::default(); + let current_side_effects_enabled_var = acir_context.add_constant(FieldElement::one()); + + Context { + ssa_values: HashMap::default(), + current_side_effects_enabled_var, + acir_context, + initialized_arrays: HashSet::new(), + memory_blocks: HashMap::default(), + max_block_id: 0, + } + } + + /// Converts SSA into ACIR + fn convert_ssa( + self, + ssa: Ssa, + brillig: Brillig, + last_array_uses: &HashMap, + ) -> Result { + let main_func = ssa.main(); + match main_func.runtime() { + RuntimeType::Acir => self.convert_acir_main(main_func, &ssa, brillig, last_array_uses), + RuntimeType::Brillig => self.convert_brillig_main(main_func, brillig), + } + } + + fn convert_acir_main( + mut self, + main_func: &Function, + ssa: &Ssa, + brillig: Brillig, + last_array_uses: &HashMap, + ) -> Result { + let dfg = &main_func.dfg; + let entry_block = &dfg[main_func.entry_block()]; + let input_witness = self.convert_ssa_block_params(entry_block.parameters(), dfg)?; + + for instruction_id in entry_block.instructions() { + self.convert_ssa_instruction(*instruction_id, dfg, ssa, &brillig, last_array_uses)?; + } + + self.convert_ssa_return(entry_block.unwrap_terminator(), dfg)?; + + Ok(self.acir_context.finish(input_witness.collect())) + } + + fn convert_brillig_main( + mut self, + main_func: &Function, + brillig: Brillig, + ) -> Result { + let dfg = &main_func.dfg; + + let inputs = try_vecmap(dfg[main_func.entry_block()].parameters(), |param_id| { + let typ = dfg.type_of_value(*param_id); + self.create_value_from_type(&typ, &mut |this, _| Ok(this.acir_context.add_variable())) + })?; + let witness_inputs = self.acir_context.extract_witness(&inputs); + + let outputs: Vec = + vecmap(main_func.returns(), |result_id| dfg.type_of_value(*result_id).into()); + + let code = self.gen_brillig_for(main_func, &brillig)?; + + let output_values = self.acir_context.brillig( + self.current_side_effects_enabled_var, + code, + inputs, + outputs, + )?; + let output_vars: Vec<_> = output_values + .iter() + .flat_map(|value| value.clone().flatten()) + .map(|value| value.0) + .collect(); + + for acir_var in output_vars { + self.acir_context.return_var(acir_var)?; + } + + Ok(self.acir_context.finish(witness_inputs)) + } + + /// Adds and binds `AcirVar`s for each numeric block parameter or block parameter array element. + fn convert_ssa_block_params( + &mut self, + params: &[ValueId], + dfg: &DataFlowGraph, + ) -> Result, RuntimeError> { + // The first witness (if any) is the next one + let start_witness = self.acir_context.current_witness_index().0 + 1; + for param_id in params { + let typ = dfg.type_of_value(*param_id); + let value = self.convert_ssa_block_param(&typ)?; + match &value { + AcirValue::Var(_, _) => (), + AcirValue::Array(values) => { + let block_id = self.block_id(param_id); + let v = vecmap(values, |v| v.clone()); + self.initialize_array(block_id, values.len(), Some(&v))?; + } + AcirValue::DynamicArray(_) => unreachable!( + "The dynamic array type is created in Acir gen and therefore cannot be a block parameter" + ), + } + self.ssa_values.insert(*param_id, value); + } + let end_witness = self.acir_context.current_witness_index().0; + Ok(start_witness..=end_witness) + } + + fn convert_ssa_block_param(&mut self, param_type: &Type) -> Result { + self.create_value_from_type(param_type, &mut |this, typ| this.add_numeric_input_var(&typ)) + } + + fn create_value_from_type( + &mut self, + param_type: &Type, + make_var: &mut impl FnMut(&mut Self, NumericType) -> Result, + ) -> Result { + match param_type { + Type::Numeric(numeric_type) => { + let typ = AcirType::new(*numeric_type); + Ok(AcirValue::Var(make_var(self, *numeric_type)?, typ)) + } + Type::Array(element_types, length) => { + let mut elements = im::Vector::new(); + + for _ in 0..*length { + for element in element_types.iter() { + elements.push_back(self.create_value_from_type(element, make_var)?); + } + } + + Ok(AcirValue::Array(elements)) + } + _ => unreachable!("ICE: Params to the program should only contains numbers and arrays"), + } + } + + /// Get the BlockId corresponding to the ValueId + /// If there is no matching BlockId, we create a new one. + fn block_id(&mut self, value: &ValueId) -> BlockId { + if let Some(block_id) = self.memory_blocks.get(value) { + return *block_id; + } + let block_id = BlockId(self.max_block_id); + self.max_block_id += 1; + self.memory_blocks.insert(*value, block_id); + block_id + } + + /// Creates an `AcirVar` corresponding to a parameter witness to appears in the abi. A range + /// constraint is added if the numeric type requires it. + /// + /// This function is used not only for adding numeric block parameters, but also for adding + /// any array elements that belong to reference type block parameters. + fn add_numeric_input_var( + &mut self, + numeric_type: &NumericType, + ) -> Result { + let acir_var = self.acir_context.add_variable(); + if matches!(numeric_type, NumericType::Signed { .. } | NumericType::Unsigned { .. }) { + self.acir_context.range_constrain_var(acir_var, numeric_type)?; + } + Ok(acir_var) + } + + /// Converts an SSA instruction into its ACIR representation + fn convert_ssa_instruction( + &mut self, + instruction_id: InstructionId, + dfg: &DataFlowGraph, + ssa: &Ssa, + brillig: &Brillig, + last_array_uses: &HashMap, + ) -> Result<(), RuntimeError> { + let instruction = &dfg[instruction_id]; + self.acir_context.set_call_stack(dfg.get_call_stack(instruction_id)); + match instruction { + Instruction::Binary(binary) => { + let result_acir_var = self.convert_ssa_binary(binary, dfg)?; + self.define_result_var(dfg, instruction_id, result_acir_var); + } + Instruction::Constrain(lhs, rhs, assert_message) => { + let lhs = self.convert_value(*lhs, dfg); + let rhs = self.convert_value(*rhs, dfg); + + fn get_var_equality_assertions( + lhs: AcirValue, + rhs: AcirValue, + read_from_index: &mut impl FnMut(BlockId, usize) -> Result, + ) -> Result, InternalError> { + match (lhs, rhs) { + (AcirValue::Var(lhs, _), AcirValue::Var(rhs, _)) => Ok(vec![(lhs, rhs)]), + (AcirValue::Array(lhs_values), AcirValue::Array(rhs_values)) => { + let var_equality_assertions = lhs_values + .into_iter() + .zip(rhs_values) + .map(|(lhs, rhs)| { + get_var_equality_assertions(lhs, rhs, read_from_index) + }) + .collect::, _>>()? + .into_iter() + .flatten() + .collect(); + Ok(var_equality_assertions) + } + ( + AcirValue::DynamicArray(AcirDynamicArray { + block_id: lhs_block_id, + len, + }), + AcirValue::DynamicArray(AcirDynamicArray { + block_id: rhs_block_id, + .. + }), + ) => try_vecmap(0..len, |i| { + let lhs_var = read_from_index(lhs_block_id, i)?; + let rhs_var = read_from_index(rhs_block_id, i)?; + Ok((lhs_var, rhs_var)) + }), + _ => unreachable!("ICE: lhs and rhs should be of the same type"), + } + } + + let mut read_dynamic_array_index = + |block_id: BlockId, array_index: usize| -> Result { + let index = AcirValue::Var( + self.acir_context.add_constant(FieldElement::from(array_index as u128)), + AcirType::NumericType(NumericType::NativeField), + ); + let index_var = index.into_var()?; + + self.acir_context.read_from_memory(block_id, &index_var) + }; + + for (lhs, rhs) in + get_var_equality_assertions(lhs, rhs, &mut read_dynamic_array_index)? + { + self.acir_context.assert_eq_var(lhs, rhs, assert_message.clone())?; + } + } + Instruction::Cast(value_id, typ) => { + let result_acir_var = self.convert_ssa_cast(value_id, typ, dfg)?; + self.define_result_var(dfg, instruction_id, result_acir_var); + } + Instruction::Call { func, arguments } => { + let result_ids = dfg.instruction_results(instruction_id); + match &dfg[*func] { + Value::Function(id) => { + let func = &ssa.functions[id]; + match func.runtime() { + RuntimeType::Acir => unimplemented!( + "expected an intrinsic/brillig call, but found {func:?}. All ACIR methods should be inlined" + ), + RuntimeType::Brillig => { + let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); + + let code = self.gen_brillig_for(func, brillig)?; + + let outputs: Vec = vecmap(result_ids, |result_id| dfg.type_of_value(*result_id).into()); + + let output_values = self.acir_context.brillig(self.current_side_effects_enabled_var, code, inputs, outputs)?; + + // Compiler sanity check + assert_eq!(result_ids.len(), output_values.len(), "ICE: The number of Brillig output values should match the result ids in SSA"); + + for result in result_ids.iter().zip(output_values) { + if let AcirValue::Array(values) = &result.1 { + let block_id = self.block_id(&dfg.resolve(*result.0)); + let values: Vec = values.iter().cloned().collect(); + self.initialize_array(block_id, values.len(), Some(&values))?; + } + self.ssa_values.insert(*result.0, result.1); + } + } + } + } + Value::Intrinsic(intrinsic) => { + let outputs = self + .convert_ssa_intrinsic_call(*intrinsic, arguments, dfg, result_ids)?; + + // Issue #1438 causes this check to fail with intrinsics that return 0 + // results but the ssa form instead creates 1 unit result value. + // assert_eq!(result_ids.len(), outputs.len()); + + for (result, output) in result_ids.iter().zip(outputs) { + match &output { + // We need to make sure we initialize arrays returned from intrinsic calls + // or else they will fail if accessed with a dynamic index + AcirValue::Array(values) => { + let block_id = self.block_id(result); + let values = vecmap(values, |v| v.clone()); + + self.initialize_array(block_id, values.len(), Some(&values))?; + } + AcirValue::DynamicArray(_) => { + unreachable!("The output from an intrinsic call is expected to be a single value or an array but got {output:?}"); + } + AcirValue::Var(_, _) => { + // Do nothing + } + } + self.ssa_values.insert(*result, output); + } + } + Value::ForeignFunction(_) => unreachable!( + "All `oracle` methods should be wrapped in an unconstrained fn" + ), + _ => unreachable!("expected calling a function"), + } + } + Instruction::Not(value_id) => { + let (acir_var, typ) = match self.convert_value(*value_id, dfg) { + AcirValue::Var(acir_var, typ) => (acir_var, typ), + _ => unreachable!("NOT is only applied to numerics"), + }; + let result_acir_var = self.acir_context.not_var(acir_var, typ)?; + self.define_result_var(dfg, instruction_id, result_acir_var); + } + Instruction::Truncate { value, bit_size, max_bit_size } => { + let result_acir_var = + self.convert_ssa_truncate(*value, *bit_size, *max_bit_size, dfg)?; + self.define_result_var(dfg, instruction_id, result_acir_var); + } + Instruction::EnableSideEffects { condition } => { + let acir_var = self.convert_numeric_value(*condition, dfg)?; + self.current_side_effects_enabled_var = acir_var; + } + Instruction::ArrayGet { .. } | Instruction::ArraySet { .. } => { + self.handle_array_operation(instruction_id, dfg, last_array_uses)?; + } + Instruction::Allocate => { + unreachable!("Expected all allocate instructions to be removed before acir_gen") + } + Instruction::Store { .. } => { + unreachable!("Expected all store instructions to be removed before acir_gen") + } + Instruction::Load { .. } => { + unreachable!("Expected all load instructions to be removed before acir_gen") + } + } + self.acir_context.set_call_stack(CallStack::new()); + Ok(()) + } + + fn gen_brillig_for( + &self, + func: &Function, + brillig: &Brillig, + ) -> Result { + // Create the entry point artifact + let mut entry_point = BrilligContext::new_entry_point_artifact( + BrilligFunctionContext::parameters(func), + BrilligFunctionContext::return_values(func), + BrilligFunctionContext::function_id_to_function_label(func.id()), + ); + // Link the entry point with all dependencies + while let Some(unresolved_fn_label) = entry_point.first_unresolved_function_call() { + let artifact = &brillig.find_by_function_label(unresolved_fn_label.clone()); + let artifact = match artifact { + Some(artifact) => artifact, + None => { + return Err(InternalError::General { + message: format!("Cannot find linked fn {unresolved_fn_label}"), + call_stack: CallStack::new(), + }) + } + }; + entry_point.link_with(artifact); + } + // Generate the final bytecode + Ok(entry_point.finish()) + } + + /// Handles an ArrayGet or ArraySet instruction. + /// To set an index of the array (and create a new array in doing so), pass Some(value) for + /// store_value. To just retrieve an index of the array, pass None for store_value. + fn handle_array_operation( + &mut self, + instruction: InstructionId, + dfg: &DataFlowGraph, + last_array_uses: &HashMap, + ) -> Result<(), RuntimeError> { + // Pass the instruction between array methods rather than the internal fields themselves + let (array, index, store_value) = match dfg[instruction] { + Instruction::ArrayGet { array, index } => (array, index, None), + Instruction::ArraySet { array, index, value, .. } => (array, index, Some(value)), + _ => { + return Err(InternalError::UnExpected { + expected: "Instruction should be an ArrayGet or ArraySet".to_owned(), + found: format!("Instead got {:?}", dfg[instruction]), + call_stack: self.acir_context.get_call_stack(), + } + .into()) + } + }; + + // We compute some AcirVars: + // - index_var is the index of the array + // - predicate_index is 0, or the index if the predicate is true + // - new_value is the optional value when the operation is an array_set + // When there is a predicate, it is predicate*value + (1-predicate)*dummy, where dummy is the value of the array at the requested index. + // It is a dummy value because in the case of a false predicate, the value stored at the requested index will be itself. + let index_const = dfg.get_numeric_constant(index); + let index_var = self.convert_numeric_value(index, dfg)?; + let predicate_index = + self.acir_context.mul_var(index_var, self.current_side_effects_enabled_var)?; + let new_value = if let Some(store) = store_value { + let store_var = Some(self.convert_value(store, dfg).into_var()?); + if self.acir_context.is_constant_one(&self.current_side_effects_enabled_var) { + store_var + } else { + let dummy = self.array_get(instruction, array, predicate_index, dfg)?; + let true_pred = self + .acir_context + .mul_var(store_var.unwrap(), self.current_side_effects_enabled_var)?; + let one = self.acir_context.add_constant(FieldElement::one()); + let not_pred = + self.acir_context.sub_var(one, self.current_side_effects_enabled_var)?; + let false_pred = self.acir_context.mul_var(not_pred, dummy)?; + // predicate*value + (1-predicate)*dummy + Some(self.acir_context.add_var(true_pred, false_pred)?) + } + } else { + None + }; + + // Handle constant index: if there is no predicate and we have the array values, we can perform the operation directly on the array + match dfg.type_of_value(array) { + Type::Array(_, _) => { + match self.convert_value(array, dfg) { + AcirValue::Var(acir_var, _) => { + return Err(RuntimeError::InternalError(InternalError::UnExpected { + expected: "an array value".to_string(), + found: format!("{acir_var:?}"), + call_stack: self.acir_context.get_call_stack(), + })) + } + AcirValue::Array(array) => { + if let Some(index_const) = index_const { + let array_size = array.len(); + let index = match index_const.try_to_u64() { + Some(index_const) => index_const as usize, + None => { + let call_stack = self.acir_context.get_call_stack(); + return Err(RuntimeError::TypeConversion { + from: "array index".to_string(), + into: "u64".to_string(), + call_stack, + }); + } + }; + if self + .acir_context + .is_constant_one(&self.current_side_effects_enabled_var) + { + // Report the error if side effects are enabled. + if index >= array_size { + let call_stack = self.acir_context.get_call_stack(); + return Err(RuntimeError::IndexOutOfBounds { + index, + array_size, + call_stack, + }); + } else { + let value = match store_value { + Some(store_value) => { + let store_value = self.convert_value(store_value, dfg); + AcirValue::Array(array.update(index, store_value)) + } + None => array[index].clone(), + }; + + self.define_result(dfg, instruction, value); + return Ok(()); + } + } + // If there is a predicate and the index is not out of range, we can directly perform the read + else if index < array_size && store_value.is_none() { + self.define_result(dfg, instruction, array[index].clone()); + return Ok(()); + } + } + } + AcirValue::DynamicArray(_) => (), + } + } + Type::Slice(_) => { + // Do nothing we only want dynamic checks here + } + _ => unreachable!("ICE: expected array or slice type"), + } + + let new_index = if self.acir_context.is_constant_one(&self.current_side_effects_enabled_var) + { + index_var + } else { + predicate_index + }; + + let resolved_array = dfg.resolve(array); + let map_array = last_array_uses.get(&resolved_array) == Some(&instruction); + + if let Some(new_value) = new_value { + self.array_set(instruction, new_index, new_value, dfg, map_array)?; + } else { + self.array_get(instruction, array, new_index, dfg)?; + } + + Ok(()) + } + + /// Generates a read opcode for the array + fn array_get( + &mut self, + instruction: InstructionId, + array: ValueId, + var_index: AcirVar, + dfg: &DataFlowGraph, + ) -> Result { + let array = dfg.resolve(array); + let block_id = self.block_id(&array); + if !self.initialized_arrays.contains(&block_id) { + match &dfg[array] { + Value::Array { array, .. } => { + let values: Vec = + array.iter().map(|i| self.convert_value(*i, dfg)).collect(); + self.initialize_array(block_id, array.len(), Some(&values))?; + } + _ => { + return Err(RuntimeError::UnInitialized { + name: "array".to_string(), + call_stack: self.acir_context.get_call_stack(), + }); + } + } + } + + let read = self.acir_context.read_from_memory(block_id, &var_index)?; + let typ = match dfg.type_of_value(array) { + Type::Array(typ, _) => { + if typ.len() != 1 { + // TODO(#2461) + unimplemented!( + "Non-const array indices is not implemented for non-homogenous array" + ); + } + typ[0].clone() + } + Type::Slice(typ) => { + if typ.len() != 1 { + // TODO(#2461) + unimplemented!( + "Non-const array indices is not implemented for non-homogenous array" + ); + } + typ[0].clone() + } + _ => unreachable!("ICE - expected an array"), + }; + let typ = AcirType::from(typ); + self.define_result(dfg, instruction, AcirValue::Var(read, typ)); + Ok(read) + } + + /// Copy the array and generates a write opcode on the new array + /// + /// Note: Copying the array is inefficient and is not the way we want to do it in the end. + fn array_set( + &mut self, + instruction: InstructionId, + var_index: AcirVar, + store_value: AcirVar, + dfg: &DataFlowGraph, + map_array: bool, + ) -> Result<(), InternalError> { + // Pass the instruction between array methods rather than the internal fields themselves + let (array, length) = match dfg[instruction] { + Instruction::ArraySet { array, length, .. } => (array, length), + _ => { + return Err(InternalError::UnExpected { + expected: "Instruction should be an ArraySet".to_owned(), + found: format!("Instead got {:?}", dfg[instruction]), + call_stack: self.acir_context.get_call_stack(), + }) + } + }; + + // Fetch the internal SSA ID for the array + let array = dfg.resolve(array); + + // Use the SSA ID to get or create its block ID + let block_id = self.block_id(&array); + + // Every array has a length in its type, so we fetch that from + // the SSA IR. + let len = match dfg.type_of_value(array) { + Type::Array(_, len) => len, + Type::Slice(_) => { + let length = length + .expect("ICE: array set on slice must have a length associated with the call"); + let length_acir_var = self.convert_value(length, dfg).into_var()?; + let len = self.acir_context.var_to_expression(length_acir_var)?.to_const(); + let len = len + .expect("ICE: slice length should be fully tracked and constant by ACIR gen"); + len.to_u128() as usize + } + _ => unreachable!("ICE - expected an array"), + }; + + // Check if the array has already been initialized in ACIR gen + // if not, we initialize it using the values from SSA + let already_initialized = self.initialized_arrays.contains(&block_id); + if !already_initialized { + match &dfg[array] { + Value::Array { array, .. } => { + let values: Vec = + array.iter().map(|i| self.convert_value(*i, dfg)).collect(); + self.initialize_array(block_id, array.len(), Some(&values))?; + } + _ => { + return Err(InternalError::General { + message: format!("Array {array} should be initialized"), + call_stack: self.acir_context.get_call_stack(), + }) + } + } + } + + // Since array_set creates a new array, we create a new block ID for this + // array, unless map_array is true. In that case, we operate directly on block_id + // and we do not create a new block ID. + let result_id = dfg + .instruction_results(instruction) + .first() + .expect("Array set does not have one result"); + let result_block_id; + if map_array { + self.memory_blocks.insert(*result_id, block_id); + result_block_id = block_id; + } else { + // Initialize the new array with the values from the old array + result_block_id = self.block_id(result_id); + let init_values = try_vecmap(0..len, |i| { + let index = AcirValue::Var( + self.acir_context.add_constant(FieldElement::from(i as u128)), + AcirType::NumericType(NumericType::NativeField), + ); + let var = index.into_var()?; + let read = self.acir_context.read_from_memory(block_id, &var)?; + Ok(AcirValue::Var(read, AcirType::NumericType(NumericType::NativeField))) + })?; + self.initialize_array(result_block_id, len, Some(&init_values))?; + } + + // Write the new value into the new array at the specified index + self.acir_context.write_to_memory(result_block_id, &var_index, &store_value)?; + + let result_value = + AcirValue::DynamicArray(AcirDynamicArray { block_id: result_block_id, len }); + self.define_result(dfg, instruction, result_value); + Ok(()) + } + + /// Initializes an array with the given values and caches the fact that we + /// have initialized this array. + fn initialize_array( + &mut self, + array: BlockId, + len: usize, + values: Option<&[AcirValue]>, + ) -> Result<(), InternalError> { + self.acir_context.initialize_array(array, len, values)?; + self.initialized_arrays.insert(array); + Ok(()) + } + + /// Remember the result of an instruction returning a single value + fn define_result( + &mut self, + dfg: &DataFlowGraph, + instruction: InstructionId, + result: AcirValue, + ) { + let result_ids = dfg.instruction_results(instruction); + self.ssa_values.insert(result_ids[0], result); + } + + /// Remember the result of instruction returning a single numeric value + fn define_result_var( + &mut self, + dfg: &DataFlowGraph, + instruction: InstructionId, + result: AcirVar, + ) { + let result_ids = dfg.instruction_results(instruction); + let typ = dfg.type_of_value(result_ids[0]).into(); + self.define_result(dfg, instruction, AcirValue::Var(result, typ)); + } + + /// Converts an SSA terminator's return values into their ACIR representations + fn convert_ssa_return( + &mut self, + terminator: &TerminatorInstruction, + dfg: &DataFlowGraph, + ) -> Result<(), InternalError> { + let return_values = match terminator { + TerminatorInstruction::Return { return_values } => return_values, + _ => unreachable!("ICE: Program must have a singular return"), + }; + + // The return value may or may not be an array reference. Calling `flatten_value_list` + // will expand the array if there is one. + let return_acir_vars = self.flatten_value_list(return_values, dfg); + for acir_var in return_acir_vars { + self.acir_context.return_var(acir_var)?; + } + Ok(()) + } + + /// Gets the cached `AcirVar` that was converted from the corresponding `ValueId`. If it does + /// not already exist in the cache, a conversion is attempted and cached for simple values + /// that require no further context such as numeric types - values requiring more context + /// should have already been cached elsewhere. + /// + /// Conversion is assumed to have already been performed for instruction results and block + /// parameters. This is because block parameters are converted before anything else, and + /// because instructions results are converted when the corresponding instruction is + /// encountered. (An instruction result cannot be referenced before the instruction occurs.) + /// + /// It is not safe to call this function on value ids that represent addresses. Instructions + /// involving such values are evaluated via a separate path and stored in + /// `ssa_value_to_array_address` instead. + fn convert_value(&mut self, value_id: ValueId, dfg: &DataFlowGraph) -> AcirValue { + let value_id = dfg.resolve(value_id); + let value = &dfg[value_id]; + if let Some(acir_value) = self.ssa_values.get(&value_id) { + return acir_value.clone(); + } + + let acir_value = match value { + Value::NumericConstant { constant, typ } => { + AcirValue::Var(self.acir_context.add_constant(*constant), typ.into()) + } + Value::Array { array, .. } => { + let elements = array.iter().map(|element| self.convert_value(*element, dfg)); + AcirValue::Array(elements.collect()) + } + Value::Intrinsic(..) => todo!(), + Value::Function(..) => unreachable!("ICE: All functions should have been inlined"), + Value::ForeignFunction(_) => unimplemented!( + "Oracle calls directly in constrained functions are not yet available." + ), + Value::Instruction { .. } | Value::Param { .. } => { + unreachable!("ICE: Should have been in cache {value_id} {value:?}") + } + }; + self.ssa_values.insert(value_id, acir_value.clone()); + acir_value + } + + fn convert_numeric_value( + &mut self, + value_id: ValueId, + dfg: &DataFlowGraph, + ) -> Result { + match self.convert_value(value_id, dfg) { + AcirValue::Var(acir_var, _) => Ok(acir_var), + AcirValue::Array(array) => Err(InternalError::UnExpected { + expected: "a numeric value".to_string(), + found: format!("{array:?}"), + call_stack: self.acir_context.get_call_stack(), + }), + AcirValue::DynamicArray(_) => Err(InternalError::UnExpected { + expected: "a numeric value".to_string(), + found: "an array".to_string(), + call_stack: self.acir_context.get_call_stack(), + }), + } + } + + /// Processes a binary operation and converts the result into an `AcirVar` + fn convert_ssa_binary( + &mut self, + binary: &Binary, + dfg: &DataFlowGraph, + ) -> Result { + let lhs = self.convert_numeric_value(binary.lhs, dfg)?; + let rhs = self.convert_numeric_value(binary.rhs, dfg)?; + + let binary_type = self.type_of_binary_operation(binary, dfg); + match &binary_type { + Type::Numeric(NumericType::Unsigned { bit_size }) + | Type::Numeric(NumericType::Signed { bit_size }) => { + // Conservative max bit size that is small enough such that two operands can be + // multiplied and still fit within the field modulus. This is necessary for the + // truncation technique: result % 2^bit_size to be valid. + let max_integer_bit_size = FieldElement::max_num_bits() / 2; + if *bit_size > max_integer_bit_size { + return Err(RuntimeError::UnsupportedIntegerSize { + num_bits: *bit_size, + max_num_bits: max_integer_bit_size, + call_stack: self.acir_context.get_call_stack(), + }); + } + } + _ => {} + } + + let binary_type = AcirType::from(binary_type); + let bit_count = binary_type.bit_size(); + + match binary.operator { + BinaryOp::Add => self.acir_context.add_var(lhs, rhs), + BinaryOp::Sub => self.acir_context.sub_var(lhs, rhs), + BinaryOp::Mul => self.acir_context.mul_var(lhs, rhs), + BinaryOp::Div => self.acir_context.div_var( + lhs, + rhs, + binary_type, + self.current_side_effects_enabled_var, + ), + // Note: that this produces unnecessary constraints when + // this Eq instruction is being used for a constrain statement + BinaryOp::Eq => self.acir_context.eq_var(lhs, rhs), + BinaryOp::Lt => self.acir_context.less_than_var( + lhs, + rhs, + bit_count, + self.current_side_effects_enabled_var, + ), + BinaryOp::Xor => self.acir_context.xor_var(lhs, rhs, binary_type), + BinaryOp::And => self.acir_context.and_var(lhs, rhs, binary_type), + BinaryOp::Or => self.acir_context.or_var(lhs, rhs, binary_type), + BinaryOp::Mod => self.acir_context.modulo_var( + lhs, + rhs, + bit_count, + self.current_side_effects_enabled_var, + ), + } + } + + /// Operands in a binary operation are checked to have the same type. + /// + /// In Noir, binary operands should have the same type due to the language + /// semantics. + /// + /// There are some edge cases to consider: + /// - Constants are not explicitly type casted, so we need to check for this and + /// return the type of the other operand, if we have a constant. + /// - 0 is not seen as `Field 0` but instead as `Unit 0` + /// TODO: The latter seems like a bug, if we cannot differentiate between a function returning + /// TODO nothing and a 0. + /// + /// TODO: This constant coercion should ideally be done in the type checker. + fn type_of_binary_operation(&self, binary: &Binary, dfg: &DataFlowGraph) -> Type { + let lhs_type = dfg.type_of_value(binary.lhs); + let rhs_type = dfg.type_of_value(binary.rhs); + + match (lhs_type, rhs_type) { + // Function type should not be possible, since all functions + // have been inlined. + (_, Type::Function) | (Type::Function, _) => { + unreachable!("all functions should be inlined") + } + (_, Type::Reference) | (Type::Reference, _) => { + unreachable!("References are invalid in binary operations") + } + (_, Type::Array(..)) | (Type::Array(..), _) => { + unreachable!("Arrays are invalid in binary operations") + } + (_, Type::Slice(..)) | (Type::Slice(..), _) => { + unreachable!("Arrays are invalid in binary operations") + } + // If either side is a Field constant then, we coerce into the type + // of the other operand + (Type::Numeric(NumericType::NativeField), typ) + | (typ, Type::Numeric(NumericType::NativeField)) => typ, + // If either side is a numeric type, then we expect their types to be + // the same. + (Type::Numeric(lhs_type), Type::Numeric(rhs_type)) => { + assert_eq!(lhs_type, rhs_type, "lhs and rhs types in {binary:?} are not the same"); + Type::Numeric(lhs_type) + } + } + } + + /// Returns an `AcirVar` that is constrained to fit in the target type by truncating the input. + /// If the target cast is to a `NativeField`, no truncation is required so the cast becomes a + /// no-op. + fn convert_ssa_cast( + &mut self, + value_id: &ValueId, + typ: &Type, + dfg: &DataFlowGraph, + ) -> Result { + let (variable, incoming_type) = match self.convert_value(*value_id, dfg) { + AcirValue::Var(variable, typ) => (variable, typ), + AcirValue::DynamicArray(_) | AcirValue::Array(_) => { + unreachable!("Cast is only applied to numerics") + } + }; + let target_numeric = match typ { + Type::Numeric(numeric) => numeric, + _ => unreachable!("Can only cast to a numeric"), + }; + match target_numeric { + NumericType::NativeField => { + // Casting into a Field as a no-op + Ok(variable) + } + NumericType::Unsigned { bit_size } => { + if incoming_type.is_signed() { + todo!("Cast from unsigned to signed") + } + let max_bit_size = incoming_type.bit_size(); + if max_bit_size <= *bit_size { + // Incoming variable already fits into target bit size - this is a no-op + return Ok(variable); + } + self.acir_context.truncate_var(variable, *bit_size, max_bit_size) + } + NumericType::Signed { .. } => todo!("Cast into signed"), + } + } + + /// Returns an `AcirVar`that is constrained to be result of the truncation. + fn convert_ssa_truncate( + &mut self, + value_id: ValueId, + bit_size: u32, + max_bit_size: u32, + dfg: &DataFlowGraph, + ) -> Result { + let mut var = self.convert_numeric_value(value_id, dfg)?; + match &dfg[value_id] { + Value::Instruction { instruction, .. } => { + if matches!( + &dfg[*instruction], + Instruction::Binary(Binary { operator: BinaryOp::Sub, .. }) + ) { + // Subtractions must first have the integer modulus added before truncation can be + // applied. This is done in order to prevent underflow. + let integer_modulus = + self.acir_context.add_constant(FieldElement::from(2_u128.pow(bit_size))); + var = self.acir_context.add_var(var, integer_modulus)?; + } + } + Value::Param { .. } => { + // Binary operations on params may have been entirely simplified if the operation + // results in the identity of the parameter + } + _ => unreachable!( + "ICE: Truncates are only ever applied to the result of a binary op or a param" + ), + }; + + self.acir_context.truncate_var(var, bit_size, max_bit_size) + } + + /// Returns a vector of `AcirVar`s constrained to be result of the function call. + /// + /// The function being called is required to be intrinsic. + fn convert_ssa_intrinsic_call( + &mut self, + intrinsic: Intrinsic, + arguments: &[ValueId], + dfg: &DataFlowGraph, + result_ids: &[ValueId], + ) -> Result, RuntimeError> { + match intrinsic { + Intrinsic::BlackBox(black_box) => { + // Slices are represented as a tuple of (length, slice contents). + // We must check the inputs to determine if there are slices + // and make sure that we pass the correct inputs to the black box function call. + // The loop below only keeps the slice contents, so that + // setting up a black box function with slice inputs matches the expected + // number of arguments specified in the function signature. + let mut arguments_no_slice_len = Vec::new(); + for (i, arg) in arguments.iter().enumerate() { + if matches!(dfg.type_of_value(*arg), Type::Numeric(_)) { + if i < arguments.len() - 1 { + if !matches!(dfg.type_of_value(arguments[i + 1]), Type::Slice(_)) { + arguments_no_slice_len.push(*arg); + } + } else { + arguments_no_slice_len.push(*arg); + } + } else { + arguments_no_slice_len.push(*arg); + } + } + + let inputs = vecmap(&arguments_no_slice_len, |arg| self.convert_value(*arg, dfg)); + + let output_count = result_ids.iter().fold(0usize, |sum, result_id| { + sum + dfg.try_get_array_length(*result_id).unwrap_or(1) + }); + + let vars = self.acir_context.black_box_function(black_box, inputs, output_count)?; + + Ok(Self::convert_vars_to_values(vars, dfg, result_ids)) + } + Intrinsic::ToRadix(endian) => { + let field = self.convert_value(arguments[0], dfg).into_var()?; + let radix = self.convert_value(arguments[1], dfg).into_var()?; + let limb_size = self.convert_value(arguments[2], dfg).into_var()?; + + let result_type = Self::array_element_type(dfg, result_ids[1]); + + self.acir_context.radix_decompose(endian, field, radix, limb_size, result_type) + } + Intrinsic::ToBits(endian) => { + let field = self.convert_value(arguments[0], dfg).into_var()?; + let bit_size = self.convert_value(arguments[1], dfg).into_var()?; + + let result_type = Self::array_element_type(dfg, result_ids[1]); + + self.acir_context.bit_decompose(endian, field, bit_size, result_type) + } + Intrinsic::Sort => { + let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); + // We flatten the inputs and retrieve the bit_size of the elements + let mut input_vars = Vec::new(); + let mut bit_size = 0; + for input in inputs { + for (var, typ) in input.flatten() { + input_vars.push(var); + if bit_size == 0 { + bit_size = typ.bit_size(); + } else { + assert_eq!( + bit_size, + typ.bit_size(), + "cannot sort element of different bit size" + ); + } + } + } + // Generate the sorted output variables + let out_vars = self + .acir_context + .sort(input_vars, bit_size, self.current_side_effects_enabled_var) + .expect("Could not sort"); + + Ok(Self::convert_vars_to_values(out_vars, dfg, result_ids)) + } + Intrinsic::ArrayLen => { + let len = match self.convert_value(arguments[0], dfg) { + AcirValue::Var(_, _) => unreachable!("Non-array passed to array.len() method"), + AcirValue::Array(values) => (values.len() as u128).into(), + AcirValue::DynamicArray(array) => (array.len as u128).into(), + }; + Ok(vec![AcirValue::Var(self.acir_context.add_constant(len), AcirType::field())]) + } + Intrinsic::SlicePushBack => { + let slice_length = self.convert_value(arguments[0], dfg).into_var()?; + let slice = self.convert_value(arguments[1], dfg); + // TODO(#2461): make sure that we have handled nested struct inputs + let element = self.convert_value(arguments[2], dfg); + + let one = self.acir_context.add_constant(FieldElement::one()); + let new_slice_length = self.acir_context.add_var(slice_length, one)?; + + let mut new_slice = Vector::new(); + self.slice_intrinsic_input(&mut new_slice, slice)?; + new_slice.push_back(element); + + Ok(vec![ + AcirValue::Var(new_slice_length, AcirType::field()), + AcirValue::Array(new_slice), + ]) + } + Intrinsic::SlicePushFront => { + let slice_length = self.convert_value(arguments[0], dfg).into_var()?; + let slice = self.convert_value(arguments[1], dfg); + // TODO(#2461): make sure that we have handled nested struct inputs + let element = self.convert_value(arguments[2], dfg); + + let one = self.acir_context.add_constant(FieldElement::one()); + let new_slice_length = self.acir_context.add_var(slice_length, one)?; + + let mut new_slice = Vector::new(); + self.slice_intrinsic_input(&mut new_slice, slice)?; + new_slice.push_front(element); + + Ok(vec![ + AcirValue::Var(new_slice_length, AcirType::field()), + AcirValue::Array(new_slice), + ]) + } + Intrinsic::SlicePopBack => { + let slice_length = self.convert_value(arguments[0], dfg).into_var()?; + let slice = self.convert_value(arguments[1], dfg); + + let one = self.acir_context.add_constant(FieldElement::one()); + let new_slice_length = self.acir_context.sub_var(slice_length, one)?; + + let mut new_slice = Vector::new(); + self.slice_intrinsic_input(&mut new_slice, slice)?; + // TODO(#2461): make sure that we have handled nested struct inputs + let elem = new_slice + .pop_back() + .expect("There are no elements in this slice to be removed"); + + Ok(vec![ + AcirValue::Var(new_slice_length, AcirType::field()), + AcirValue::Array(new_slice), + elem, + ]) + } + Intrinsic::SlicePopFront => { + let slice_length = self.convert_value(arguments[0], dfg).into_var()?; + let slice = self.convert_value(arguments[1], dfg); + + let one = self.acir_context.add_constant(FieldElement::one()); + let new_slice_length = self.acir_context.sub_var(slice_length, one)?; + + let mut new_slice = Vector::new(); + self.slice_intrinsic_input(&mut new_slice, slice)?; + // TODO(#2461): make sure that we have handled nested struct inputs + let elem = new_slice + .pop_front() + .expect("There are no elements in this slice to be removed"); + + Ok(vec![ + elem, + AcirValue::Var(new_slice_length, AcirType::field()), + AcirValue::Array(new_slice), + ]) + } + Intrinsic::SliceInsert => { + // Slice insert with a constant index + let slice_length = self.convert_value(arguments[0], dfg).into_var()?; + let slice = self.convert_value(arguments[1], dfg); + let index = self.convert_value(arguments[2], dfg).into_var()?; + let element = self.convert_value(arguments[3], dfg); + + let one = self.acir_context.add_constant(FieldElement::one()); + let new_slice_length = self.acir_context.add_var(slice_length, one)?; + + // TODO(#2462): Slice insert is a little less obvious on how to implement due to the case + // of having a dynamic index + // The slice insert logic will need a more involved codegen + let index = self.acir_context.var_to_expression(index)?.to_const(); + let index = index + .expect("ICE: slice length should be fully tracked and constant by ACIR gen"); + let index = index.to_u128() as usize; + + let mut new_slice = Vector::new(); + self.slice_intrinsic_input(&mut new_slice, slice)?; + // TODO(#2461): make sure that we have handled nested struct inputs + new_slice.insert(index, element); + + Ok(vec![ + AcirValue::Var(new_slice_length, AcirType::field()), + AcirValue::Array(new_slice), + ]) + } + Intrinsic::SliceRemove => { + // Slice insert with a constant index + let slice_length = self.convert_value(arguments[0], dfg).into_var()?; + let slice = self.convert_value(arguments[1], dfg); + let index = self.convert_value(arguments[2], dfg).into_var()?; + + let one = self.acir_context.add_constant(FieldElement::one()); + let new_slice_length = self.acir_context.sub_var(slice_length, one)?; + + // TODO(#2462): allow slice remove with a constant index + // Slice remove is a little less obvious on how to implement due to the case + // of having a dynamic index + // The slice remove logic will need a more involved codegen + let index = self.acir_context.var_to_expression(index)?.to_const(); + let index = index + .expect("ICE: slice length should be fully tracked and constant by ACIR gen"); + let index = index.to_u128() as usize; + + let mut new_slice = Vector::new(); + self.slice_intrinsic_input(&mut new_slice, slice)?; + // TODO(#2461): make sure that we have handled nested struct inputs + let removed_elem = new_slice.remove(index); + + Ok(vec![ + AcirValue::Var(new_slice_length, AcirType::field()), + AcirValue::Array(new_slice), + removed_elem, + ]) + } + _ => todo!("expected a black box function"), + } + } + + fn slice_intrinsic_input( + &mut self, + old_slice: &mut Vector, + input: AcirValue, + ) -> Result<(), RuntimeError> { + match input { + AcirValue::Var(_, _) => { + old_slice.push_back(input); + } + AcirValue::Array(vars) => { + for var in vars { + self.slice_intrinsic_input(old_slice, var)?; + } + } + AcirValue::DynamicArray(AcirDynamicArray { block_id, len }) => { + for i in 0..len { + // We generate witnesses corresponding to the array values + let index = AcirValue::Var( + self.acir_context.add_constant(FieldElement::from(i as u128)), + AcirType::NumericType(NumericType::NativeField), + ); + + let index_var = index.into_var()?; + let value_read_var = + self.acir_context.read_from_memory(block_id, &index_var)?; + let value_read = AcirValue::Var( + value_read_var, + AcirType::NumericType(NumericType::NativeField), + ); + + old_slice.push_back(value_read); + } + } + } + Ok(()) + } + + /// Given an array value, return the numerical type of its element. + /// Panics if the given value is not an array or has a non-numeric element type. + fn array_element_type(dfg: &DataFlowGraph, value: ValueId) -> AcirType { + match dfg.type_of_value(value) { + Type::Array(elements, _) => { + assert_eq!(elements.len(), 1); + (&elements[0]).into() + } + Type::Slice(elements) => { + assert_eq!(elements.len(), 1); + (&elements[0]).into() + } + _ => unreachable!("Expected array type"), + } + } + + /// Maps an ssa value list, for which some values may be references to arrays, by inlining + /// the `AcirVar`s corresponding to the contents of each array into the list of `AcirVar`s + /// that correspond to other values. + fn flatten_value_list(&mut self, arguments: &[ValueId], dfg: &DataFlowGraph) -> Vec { + let mut acir_vars = Vec::with_capacity(arguments.len()); + for value_id in arguments { + let value = self.convert_value(*value_id, dfg); + AcirContext::flatten_value(&mut acir_vars, value); + } + acir_vars + } + + fn bit_count(&self, lhs: ValueId, dfg: &DataFlowGraph) -> u32 { + match dfg.type_of_value(lhs) { + Type::Numeric(NumericType::Signed { bit_size }) => bit_size, + Type::Numeric(NumericType::Unsigned { bit_size }) => bit_size, + Type::Numeric(NumericType::NativeField) => FieldElement::max_num_bits(), + _ => 0, + } + } + + /// Convert a Vec into a Vec using the given result ids. + /// If the type of a result id is an array, several acir vars are collected into + /// a single AcirValue::Array of the same length. + fn convert_vars_to_values( + vars: Vec, + dfg: &DataFlowGraph, + result_ids: &[ValueId], + ) -> Vec { + let mut vars = vars.into_iter(); + vecmap(result_ids, |result| { + let result_type = dfg.type_of_value(*result); + Self::convert_var_type_to_values(&result_type, &mut vars) + }) + } + + /// Recursive helper for convert_vars_to_values. + /// If the given result_type is an array of length N, this will create an AcirValue::Array with + /// the first N elements of the given iterator. Otherwise, the result is a single + /// AcirValue::Var wrapping the first element of the iterator. + fn convert_var_type_to_values( + result_type: &Type, + vars: &mut impl Iterator, + ) -> AcirValue { + match result_type { + Type::Array(elements, size) => { + let mut element_values = im::Vector::new(); + for _ in 0..*size { + for element_type in elements.iter() { + let element = Self::convert_var_type_to_values(element_type, vars); + element_values.push_back(element); + } + } + AcirValue::Array(element_values) + } + typ => { + let var = vars.next().unwrap(); + AcirValue::Var(var, typ.into()) + } + } + } + + /// Creates a default, meaningless value meant only to be a valid value of the given type. + fn create_default_value(&mut self, param_type: &Type) -> Result { + self.create_value_from_type(param_type, &mut |this, _| { + Ok(this.acir_context.add_constant(FieldElement::zero())) + }) + } +} + +#[cfg(test)] +mod tests { + use std::{collections::HashMap, rc::Rc}; + + use acvm::{ + acir::{ + circuit::Opcode, + native_types::{Expression, Witness}, + }, + FieldElement, + }; + + use crate::{ + brillig::Brillig, + ssa::{ + function_builder::FunctionBuilder, + ir::{function::RuntimeType, map::Id, types::Type}, + }, + }; + + use super::Context; + + #[test] + fn returns_body_scoped_arrays() { + // fn main { + // b0(): + // return [Field 1] + // } + let func_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); + + let one = builder.field_constant(FieldElement::one()); + + let element_type = Rc::new(vec![Type::field()]); + let array_type = Type::Array(element_type, 1); + let array = builder.array_constant(im::Vector::unit(one), array_type); + + builder.terminate_with_return(vec![array]); + + let ssa = builder.finish(); + + let context = Context::new(); + let mut acir = context.convert_ssa(ssa, Brillig::default(), &HashMap::default()).unwrap(); + + let expected_opcodes = + vec![Opcode::Arithmetic(&Expression::one() - &Expression::from(Witness(1)))]; + assert_eq!(acir.take_opcodes(), expected_opcodes); + assert_eq!(acir.return_witnesses, vec![Witness(1)]); + } +} diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs new file mode 100644 index 00000000000..961ff8cc33e --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs @@ -0,0 +1,424 @@ +use std::borrow::Cow; + +use acvm::FieldElement; +use noirc_errors::Location; + +use crate::ssa::ir::{ + basic_block::BasicBlockId, + function::{Function, FunctionId}, + instruction::{Binary, BinaryOp, Instruction, TerminatorInstruction}, + types::Type, + value::{Value, ValueId}, +}; + +use super::{ + ir::{ + basic_block::BasicBlock, + dfg::{CallStack, InsertInstructionResult}, + function::RuntimeType, + instruction::{InstructionId, Intrinsic}, + }, + ssa_gen::Ssa, +}; + +/// The per-function context for each ssa function being generated. +/// +/// This is split from the global SsaBuilder context to allow each function +/// to be potentially built concurrently. +/// +/// Contrary to the name, this struct has the capacity to build as many +/// functions as needed, although it is limited to one function at a time. +pub(crate) struct FunctionBuilder { + pub(super) current_function: Function, + current_block: BasicBlockId, + finished_functions: Vec, + call_stack: CallStack, +} + +impl FunctionBuilder { + /// Creates a new FunctionBuilder to build the function with the given FunctionId. + /// + /// This creates the new function internally so there is no need to call .new_function() + /// right after constructing a new FunctionBuilder. + pub(crate) fn new( + function_name: String, + function_id: FunctionId, + runtime: RuntimeType, + ) -> Self { + let mut new_function = Function::new(function_name, function_id); + new_function.set_runtime(runtime); + let current_block = new_function.entry_block(); + + Self { + current_function: new_function, + current_block, + finished_functions: Vec::new(), + call_stack: CallStack::new(), + } + } + + /// Finish the current function and create a new function. + /// + /// A FunctionBuilder can always only work on one function at a time, so care + /// should be taken not to finish a function that is still in progress by calling + /// new_function before the current function is finished. + fn new_function_with_type( + &mut self, + name: String, + function_id: FunctionId, + runtime_type: RuntimeType, + ) { + let mut new_function = Function::new(name, function_id); + new_function.set_runtime(runtime_type); + self.current_block = new_function.entry_block(); + + let old_function = std::mem::replace(&mut self.current_function, new_function); + self.finished_functions.push(old_function); + } + + /// Finish the current function and create a new ACIR function. + pub(crate) fn new_function(&mut self, name: String, function_id: FunctionId) { + self.new_function_with_type(name, function_id, RuntimeType::Acir); + } + + /// Finish the current function and create a new unconstrained function. + pub(crate) fn new_brillig_function(&mut self, name: String, function_id: FunctionId) { + self.new_function_with_type(name, function_id, RuntimeType::Brillig); + } + + /// Consume the FunctionBuilder returning all the functions it has generated. + pub(crate) fn finish(mut self) -> Ssa { + self.finished_functions.push(self.current_function); + Ssa::new(self.finished_functions) + } + + /// Add a parameter to the current function with the given parameter type. + /// Returns the newly-added parameter. + pub(crate) fn add_parameter(&mut self, typ: Type) -> ValueId { + let entry = self.current_function.entry_block(); + self.current_function.dfg.add_block_parameter(entry, typ) + } + + /// Insert a numeric constant into the current function + pub(crate) fn numeric_constant( + &mut self, + value: impl Into, + typ: Type, + ) -> ValueId { + self.current_function.dfg.make_constant(value.into(), typ) + } + + /// Insert a numeric constant into the current function of type Field + pub(crate) fn field_constant(&mut self, value: impl Into) -> ValueId { + self.numeric_constant(value.into(), Type::field()) + } + + /// Insert an array constant into the current function with the given element values. + pub(crate) fn array_constant(&mut self, elements: im::Vector, typ: Type) -> ValueId { + self.current_function.dfg.make_array(elements, typ) + } + + /// Returns the type of the given value. + pub(crate) fn type_of_value(&self, value: ValueId) -> Type { + self.current_function.dfg.type_of_value(value) + } + + /// Insert a new block into the current function and return it. + /// Note that this block is unreachable until another block is set to jump to it. + pub(crate) fn insert_block(&mut self) -> BasicBlockId { + self.current_function.dfg.make_block() + } + + /// Adds a parameter with the given type to the given block. + /// Returns the newly-added parameter. + pub(crate) fn add_block_parameter(&mut self, block: BasicBlockId, typ: Type) -> ValueId { + self.current_function.dfg.add_block_parameter(block, typ) + } + + /// Returns the parameters of the given block in the current function. + pub(crate) fn block_parameters(&self, block: BasicBlockId) -> &[ValueId] { + self.current_function.dfg.block_parameters(block) + } + + /// Inserts a new instruction at the end of the current block and returns its results + pub(crate) fn insert_instruction( + &mut self, + instruction: Instruction, + ctrl_typevars: Option>, + ) -> InsertInstructionResult { + self.current_function.dfg.insert_instruction_and_results( + instruction, + self.current_block, + ctrl_typevars, + self.call_stack.clone(), + ) + } + + /// Switch to inserting instructions in the given block. + /// Expects the given block to be within the same function. If you want to insert + /// instructions into a new function, call new_function instead. + pub(crate) fn switch_to_block(&mut self, block: BasicBlockId) { + self.current_block = block; + } + + /// Returns the block currently being inserted into + pub(crate) fn current_block(&mut self) -> BasicBlockId { + self.current_block + } + + /// Insert an allocate instruction at the end of the current block, allocating the + /// given amount of field elements. Returns the result of the allocate instruction, + /// which is always a Reference to the allocated data. + pub(crate) fn insert_allocate(&mut self) -> ValueId { + self.insert_instruction(Instruction::Allocate, None).first() + } + + pub(crate) fn set_location(&mut self, location: Location) -> &mut FunctionBuilder { + self.call_stack = im::Vector::unit(location); + self + } + + pub(crate) fn set_call_stack(&mut self, call_stack: CallStack) -> &mut FunctionBuilder { + self.call_stack = call_stack; + self + } + + /// Insert a Load instruction at the end of the current block, loading from the given offset + /// of the given address which should point to a previous Allocate instruction. Note that + /// this is limited to loading a single value. Loading multiple values (such as a tuple) + /// will require multiple loads. + /// 'offset' is in units of FieldElements here. So loading the fourth FieldElement stored in + /// an array will have an offset of 3. + /// Returns the element that was loaded. + pub(crate) fn insert_load(&mut self, address: ValueId, type_to_load: Type) -> ValueId { + self.insert_instruction(Instruction::Load { address }, Some(vec![type_to_load])).first() + } + + /// Insert a Store instruction at the end of the current block, storing the given element + /// at the given address. Expects that the address points somewhere + /// within a previous Allocate instruction. + pub(crate) fn insert_store(&mut self, address: ValueId, value: ValueId) { + self.insert_instruction(Instruction::Store { address, value }, None); + } + + /// Insert a binary instruction at the end of the current block. + /// Returns the result of the binary instruction. + pub(crate) fn insert_binary( + &mut self, + lhs: ValueId, + operator: BinaryOp, + rhs: ValueId, + ) -> ValueId { + let instruction = Instruction::Binary(Binary { lhs, rhs, operator }); + self.insert_instruction(instruction, None).first() + } + + /// Insert a not instruction at the end of the current block. + /// Returns the result of the instruction. + pub(crate) fn insert_not(&mut self, rhs: ValueId) -> ValueId { + self.insert_instruction(Instruction::Not(rhs), None).first() + } + + /// Insert a cast instruction at the end of the current block. + /// Returns the result of the cast instruction. + pub(crate) fn insert_cast(&mut self, value: ValueId, typ: Type) -> ValueId { + self.insert_instruction(Instruction::Cast(value, typ), None).first() + } + + /// Insert a truncate instruction at the end of the current block. + /// Returns the result of the truncate instruction. + pub(crate) fn insert_truncate( + &mut self, + value: ValueId, + bit_size: u32, + max_bit_size: u32, + ) -> ValueId { + self.insert_instruction(Instruction::Truncate { value, bit_size, max_bit_size }, None) + .first() + } + + /// Insert a constrain instruction at the end of the current block. + pub(crate) fn insert_constrain( + &mut self, + lhs: ValueId, + rhs: ValueId, + assert_message: Option, + ) { + self.insert_instruction(Instruction::Constrain(lhs, rhs, assert_message), None); + } + + /// Insert a call instruction at the end of the current block and return + /// the results of the call. + pub(crate) fn insert_call( + &mut self, + func: ValueId, + arguments: Vec, + result_types: Vec, + ) -> Cow<[ValueId]> { + self.insert_instruction(Instruction::Call { func, arguments }, Some(result_types)).results() + } + + /// Insert an instruction to extract an element from an array + pub(crate) fn insert_array_get( + &mut self, + array: ValueId, + index: ValueId, + element_type: Type, + ) -> ValueId { + let element_type = Some(vec![element_type]); + self.insert_instruction(Instruction::ArrayGet { array, index }, element_type).first() + } + + /// Insert an instruction to create a new array with the given index replaced with a new value + pub(crate) fn insert_array_set( + &mut self, + array: ValueId, + index: ValueId, + value: ValueId, + length: Option, + ) -> ValueId { + self.insert_instruction(Instruction::ArraySet { array, index, value, length }, None).first() + } + + /// Terminates the current block with the given terminator instruction + fn terminate_block_with(&mut self, terminator: TerminatorInstruction) { + self.current_function.dfg.set_block_terminator(self.current_block, terminator); + } + + /// Terminate the current block with a jmp instruction to jmp to the given + /// block with the given arguments. + pub(crate) fn terminate_with_jmp( + &mut self, + destination: BasicBlockId, + arguments: Vec, + ) { + let call_stack = self.call_stack.clone(); + self.terminate_block_with(TerminatorInstruction::Jmp { + destination, + arguments, + call_stack, + }); + } + + /// Terminate the current block with a jmpif instruction to jmp with the given arguments + /// block with the given arguments. + pub(crate) fn terminate_with_jmpif( + &mut self, + condition: ValueId, + then_destination: BasicBlockId, + else_destination: BasicBlockId, + ) { + self.terminate_block_with(TerminatorInstruction::JmpIf { + condition, + then_destination, + else_destination, + }); + } + + /// Terminate the current block with a return instruction + pub(crate) fn terminate_with_return(&mut self, return_values: Vec) { + self.terminate_block_with(TerminatorInstruction::Return { return_values }); + } + + /// Returns a ValueId pointing to the given function or imports the function + /// into the current function if it was not already, and returns that ID. + pub(crate) fn import_function(&mut self, function: FunctionId) -> ValueId { + self.current_function.dfg.import_function(function) + } + + /// Returns a ValueId pointing to the given oracle/foreign function or imports the oracle + /// into the current function if it was not already, and returns that ID. + pub(crate) fn import_foreign_function(&mut self, function: &str) -> ValueId { + self.current_function.dfg.import_foreign_function(function) + } + + /// Retrieve a value reference to the given intrinsic operation. + /// Returns None if there is no intrinsic matching the given name. + pub(crate) fn import_intrinsic(&mut self, name: &str) -> Option { + Intrinsic::lookup(name).map(|intrinsic| self.import_intrinsic_id(intrinsic)) + } + + /// Retrieve a value reference to the given intrinsic operation. + pub(crate) fn import_intrinsic_id(&mut self, intrinsic: Intrinsic) -> ValueId { + self.current_function.dfg.import_intrinsic(intrinsic) + } + + /// Removes the given instruction from the current block or panics otherwise. + pub(crate) fn remove_instruction_from_current_block(&mut self, instruction: InstructionId) { + self.current_function.dfg[self.current_block].remove_instruction(instruction); + } +} + +impl std::ops::Index for FunctionBuilder { + type Output = Value; + + fn index(&self, id: ValueId) -> &Self::Output { + &self.current_function.dfg[id] + } +} + +impl std::ops::Index for FunctionBuilder { + type Output = Instruction; + + fn index(&self, id: InstructionId) -> &Self::Output { + &self.current_function.dfg[id] + } +} + +impl std::ops::Index for FunctionBuilder { + type Output = BasicBlock; + + fn index(&self, id: BasicBlockId) -> &Self::Output { + &self.current_function.dfg[id] + } +} + +#[cfg(test)] +mod tests { + use std::rc::Rc; + + use acvm::FieldElement; + + use crate::ssa::ir::{ + function::RuntimeType, + instruction::{Endian, Intrinsic}, + map::Id, + types::Type, + value::Value, + }; + + use super::FunctionBuilder; + + #[test] + fn insert_constant_call() { + // `bits` should be an array of constants [1, 1, 1, 0...] of length 8: + // let x = 7; + // let bits = x.to_le_bits(8); + let func_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); + let one = builder.numeric_constant(FieldElement::one(), Type::bool()); + let zero = builder.numeric_constant(FieldElement::zero(), Type::bool()); + + let to_bits_id = builder.import_intrinsic_id(Intrinsic::ToBits(Endian::Little)); + let input = builder.numeric_constant(FieldElement::from(7_u128), Type::field()); + let length = builder.numeric_constant(FieldElement::from(8_u128), Type::field()); + let result_types = vec![Type::Array(Rc::new(vec![Type::bool()]), 8)]; + let call_results = + builder.insert_call(to_bits_id, vec![input, length], result_types).into_owned(); + + let slice_len = match &builder.current_function.dfg[call_results[0]] { + Value::NumericConstant { constant, .. } => *constant, + _ => panic!(), + }; + assert_eq!(slice_len, FieldElement::from(8_u128)); + + let slice = match &builder.current_function.dfg[call_results[1]] { + Value::Array { array, .. } => array, + _ => panic!(), + }; + assert_eq!(slice[0], one); + assert_eq!(slice[1], one); + assert_eq!(slice[2], one); + assert_eq!(slice[3], zero); + } +} diff --git a/crates/noirc_evaluator/src/ssa/ir.rs b/compiler/noirc_evaluator/src/ssa/ir.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/ir.rs rename to compiler/noirc_evaluator/src/ssa/ir.rs diff --git a/crates/noirc_evaluator/src/ssa/ir/basic_block.rs b/compiler/noirc_evaluator/src/ssa/ir/basic_block.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/ir/basic_block.rs rename to compiler/noirc_evaluator/src/ssa/ir/basic_block.rs diff --git a/crates/noirc_evaluator/src/ssa/ir/cfg.rs b/compiler/noirc_evaluator/src/ssa/ir/cfg.rs similarity index 98% rename from crates/noirc_evaluator/src/ssa/ir/cfg.rs rename to compiler/noirc_evaluator/src/ssa/ir/cfg.rs index eccb9ce587c..dbc4c29183e 100644 --- a/crates/noirc_evaluator/src/ssa/ir/cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/cfg.rs @@ -1,9 +1,10 @@ -use std::collections::{BTreeSet, HashMap}; +use std::collections::BTreeSet; use super::{ basic_block::{BasicBlock, BasicBlockId}, function::Function, }; +use fxhash::FxHashMap as HashMap; /// A container for the successors and predecessors of some Block. #[derive(Clone, Default)] @@ -33,7 +34,8 @@ impl ControlFlowGraph { // it later comes to describe any edges after calling compute. let entry_block = func.entry_block(); let empty_node = CfgNode { predecessors: BTreeSet::new(), successors: BTreeSet::new() }; - let data = HashMap::from([(entry_block, empty_node)]); + let mut data = HashMap::default(); + data.insert(entry_block, empty_node); let mut cfg = ControlFlowGraph { data }; cfg.compute(func); diff --git a/crates/noirc_evaluator/src/ssa/ir/dfg.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs similarity index 95% rename from crates/noirc_evaluator/src/ssa/ir/dfg.rs rename to compiler/noirc_evaluator/src/ssa/ir/dfg.rs index 7dcf652c6e6..73914c54674 100644 --- a/crates/noirc_evaluator/src/ssa/ir/dfg.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, collections::HashMap}; +use std::borrow::Cow; use crate::ssa::ir::instruction::SimplifyResult; @@ -14,6 +14,7 @@ use super::{ }; use acvm::FieldElement; +use fxhash::FxHashMap as HashMap; use iter_extended::vecmap; use noirc_errors::Location; @@ -106,7 +107,7 @@ impl DataFlowGraph { let parameters = self.blocks[block].parameters(); let parameters = vecmap(parameters.iter().enumerate(), |(position, param)| { - let typ = self.values[*param].get_type(); + let typ = self.values[*param].get_type().clone(); self.values.insert(Value::Param { block: new_block, position, typ }) }); @@ -171,7 +172,7 @@ impl DataFlowGraph { let id = self.make_instruction(instruction, ctrl_typevars); self.blocks[block].insert_instruction(id); self.locations.insert(id, call_stack); - InsertInstructionResult::Results(self.instruction_results(id)) + InsertInstructionResult::Results(id, self.instruction_results(id)) } } } @@ -314,7 +315,13 @@ impl DataFlowGraph { /// Returns the type of a given value pub(crate) fn type_of_value(&self, value: ValueId) -> Type { - self.values[value].get_type() + self.values[value].get_type().clone() + } + + /// True if the type of this value is Type::Reference. + /// Using this method over type_of_value avoids cloning the value's type. + pub(crate) fn value_is_reference(&self, value: ValueId) -> bool { + matches!(self.values[value].get_type(), Type::Reference) } /// Appends a result type to the instruction. @@ -472,7 +479,8 @@ impl std::ops::IndexMut for DataFlowGraph { // be a list of results or a single ValueId if the instruction was simplified // to an existing value. pub(crate) enum InsertInstructionResult<'dfg> { - Results(&'dfg [ValueId]), + /// Results is the standard case containing the instruction id and the results of that instruction. + Results(InstructionId, &'dfg [ValueId]), SimplifiedTo(ValueId), SimplifiedToMultiple(Vec), InstructionRemoved, @@ -484,7 +492,7 @@ impl<'dfg> InsertInstructionResult<'dfg> { match self { InsertInstructionResult::SimplifiedTo(value) => *value, InsertInstructionResult::SimplifiedToMultiple(values) => values[0], - InsertInstructionResult::Results(results) => results[0], + InsertInstructionResult::Results(_, results) => results[0], InsertInstructionResult::InstructionRemoved => { panic!("Instruction was removed, no results") } @@ -495,7 +503,7 @@ impl<'dfg> InsertInstructionResult<'dfg> { /// This is used for instructions returning multiple results like function calls. pub(crate) fn results(self) -> Cow<'dfg, [ValueId]> { match self { - InsertInstructionResult::Results(results) => Cow::Borrowed(results), + InsertInstructionResult::Results(_, results) => Cow::Borrowed(results), InsertInstructionResult::SimplifiedTo(result) => Cow::Owned(vec![result]), InsertInstructionResult::SimplifiedToMultiple(results) => Cow::Owned(results), InsertInstructionResult::InstructionRemoved => Cow::Owned(vec![]), @@ -507,7 +515,7 @@ impl<'dfg> InsertInstructionResult<'dfg> { match self { InsertInstructionResult::SimplifiedTo(_) => 1, InsertInstructionResult::SimplifiedToMultiple(results) => results.len(), - InsertInstructionResult::Results(results) => results.len(), + InsertInstructionResult::Results(_, results) => results.len(), InsertInstructionResult::InstructionRemoved => 0, } } diff --git a/crates/noirc_evaluator/src/ssa/ir/dom.rs b/compiler/noirc_evaluator/src/ssa/ir/dom.rs similarity index 98% rename from crates/noirc_evaluator/src/ssa/ir/dom.rs rename to compiler/noirc_evaluator/src/ssa/ir/dom.rs index b7b1728d035..da55a593f9e 100644 --- a/crates/noirc_evaluator/src/ssa/ir/dom.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dom.rs @@ -4,11 +4,12 @@ //! Dominator trees are useful for tasks such as identifying back-edges in loop analysis or //! calculating dominance frontiers. -use std::{cmp::Ordering, collections::HashMap}; +use std::cmp::Ordering; use super::{ basic_block::BasicBlockId, cfg::ControlFlowGraph, function::Function, post_order::PostOrder, }; +use fxhash::FxHashMap as HashMap; /// Dominator tree node. We keep one of these per reachable block. #[derive(Clone, Default)] @@ -121,7 +122,7 @@ impl DominatorTree { /// Allocate and compute a dominator tree from a pre-computed control flow graph and /// post-order counterpart. pub(crate) fn with_cfg_and_post_order(cfg: &ControlFlowGraph, post_order: &PostOrder) -> Self { - let mut dom_tree = DominatorTree { nodes: HashMap::new(), cache: HashMap::new() }; + let mut dom_tree = DominatorTree { nodes: HashMap::default(), cache: HashMap::default() }; dom_tree.compute_dominator_tree(cfg, post_order); dom_tree } @@ -246,6 +247,7 @@ mod tests { use std::cmp::Ordering; use crate::ssa::{ + function_builder::FunctionBuilder, ir::{ basic_block::BasicBlockId, dom::DominatorTree, @@ -254,7 +256,6 @@ mod tests { map::Id, types::Type, }, - ssa_builder::FunctionBuilder, }; #[test] diff --git a/crates/noirc_evaluator/src/ssa/ir/function.rs b/compiler/noirc_evaluator/src/ssa/ir/function.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/ir/function.rs rename to compiler/noirc_evaluator/src/ssa/ir/function.rs diff --git a/crates/noirc_evaluator/src/ssa/ir/function_inserter.rs b/compiler/noirc_evaluator/src/ssa/ir/function_inserter.rs similarity index 75% rename from crates/noirc_evaluator/src/ssa/ir/function_inserter.rs rename to compiler/noirc_evaluator/src/ssa/ir/function_inserter.rs index bc0084b6d4e..68ece87c7c7 100644 --- a/crates/noirc_evaluator/src/ssa/ir/function_inserter.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/function_inserter.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use iter_extended::vecmap; use super::{ @@ -9,6 +7,7 @@ use super::{ instruction::{Instruction, InstructionId}, value::ValueId, }; +use fxhash::FxHashMap as HashMap; /// The FunctionInserter can be used to help modify existing Functions /// and map old values to new values after re-inserting optimized versions @@ -21,7 +20,7 @@ pub(crate) struct FunctionInserter<'f> { impl<'f> FunctionInserter<'f> { pub(crate) fn new(function: &'f mut Function) -> FunctionInserter<'f> { - Self { function, values: HashMap::new() } + Self { function, values: HashMap::default() } } /// Resolves a ValueId to its new, updated value. @@ -30,7 +29,7 @@ impl<'f> FunctionInserter<'f> { pub(crate) fn resolve(&mut self, mut value: ValueId) -> ValueId { value = self.function.dfg.resolve(value); match self.values.get(&value) { - Some(value) => *value, + Some(value) => self.resolve(*value), None => match &self.function.dfg[value] { super::value::Value::Array { array, typ } => { let array = array.clone(); @@ -47,12 +46,22 @@ impl<'f> FunctionInserter<'f> { /// Insert a key, value pair if the key isn't already present in the map pub(crate) fn try_map_value(&mut self, key: ValueId, value: ValueId) { - self.values.entry(key).or_insert(value); + if key == value { + // This case is technically not needed since try_map_value isn't meant to change + // existing entries, but we should never have a value in the map referring to itself anyway. + self.values.remove(&key); + } else { + self.values.entry(key).or_insert(value); + } } /// Insert a key, value pair in the map pub(crate) fn map_value(&mut self, key: ValueId, value: ValueId) { - self.values.insert(key, value); + if key == value { + self.values.remove(&key); + } else { + self.values.insert(key, value); + } } pub(crate) fn map_instruction(&mut self, id: InstructionId) -> (Instruction, CallStack) { @@ -62,9 +71,27 @@ impl<'f> FunctionInserter<'f> { ) } - pub(crate) fn push_instruction(&mut self, id: InstructionId, block: BasicBlockId) { + /// Maps a terminator in place, replacing any ValueId in the terminator with the + /// resolved version of that value id from this FunctionInserter's internal value mapping. + pub(crate) fn map_terminator_in_place(&mut self, block: BasicBlockId) { + let mut terminator = self.function.dfg[block].take_terminator(); + terminator.mutate_values(|value| self.resolve(value)); + self.function.dfg[block].set_terminator(terminator); + } + + /// Push a new instruction to the given block and return its new InstructionId. + /// If the instruction was simplified out of the program, None is returned. + pub(crate) fn push_instruction( + &mut self, + id: InstructionId, + block: BasicBlockId, + ) -> Option { let (instruction, location) = self.map_instruction(id); - self.push_instruction_value(instruction, id, block, location); + + match self.push_instruction_value(instruction, id, block, location) { + InsertInstructionResult::Results(new_id, _) => Some(new_id), + _ => None, + } } pub(crate) fn push_instruction_value( @@ -110,7 +137,7 @@ impl<'f> FunctionInserter<'f> { values.insert(*old_result, *new_result); } } - InsertInstructionResult::Results(new_results) => { + InsertInstructionResult::Results(_, new_results) => { for (old_result, new_result) in old_results.iter().zip(*new_results) { values.insert(*old_result, *new_result); } diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs similarity index 88% rename from crates/noirc_evaluator/src/ssa/ir/instruction.rs rename to compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 6b68b0f85a4..1dd2368b1a0 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -139,8 +139,8 @@ pub(crate) enum Instruction { /// Truncates `value` to `bit_size` Truncate { value: ValueId, bit_size: u32, max_bit_size: u32 }, - /// Constrains a value to be equal to true - Constrain(ValueId), + /// Constrains two values to be equal to one another. + Constrain(ValueId, ValueId, Option), /// Performs a function call with a list of its arguments. Call { func: ValueId, arguments: Vec }, @@ -170,7 +170,9 @@ pub(crate) enum Instruction { /// Creates a new array with the new value at the given index. All other elements are identical /// to those in the given array. This will not modify the original array. - ArraySet { array: ValueId, index: ValueId, value: ValueId }, + /// + /// An optional length can be provided to enable handling of dynamic slice indices. + ArraySet { array: ValueId, index: ValueId, value: ValueId, length: Option }, } impl Instruction { @@ -189,7 +191,7 @@ impl Instruction { InstructionResultType::Operand(*value) } Instruction::ArraySet { array, .. } => InstructionResultType::Operand(*array), - Instruction::Constrain(_) + Instruction::Constrain(..) | Instruction::Store { .. } | Instruction::EnableSideEffects { .. } => InstructionResultType::None, Instruction::Load { .. } | Instruction::ArrayGet { .. } | Instruction::Call { .. } => { @@ -204,6 +206,31 @@ impl Instruction { matches!(self.result_type(), InstructionResultType::Unknown) } + /// Pure `Instructions` are instructions which have no side-effects and results are a function of the inputs only, + /// i.e. there are no interactions with memory. + /// + /// Pure instructions can be replaced with the results of another pure instruction with the same inputs. + pub(crate) fn is_pure(&self, dfg: &DataFlowGraph) -> bool { + use Instruction::*; + + match self { + Binary(_) | Cast(_, _) | Not(_) | ArrayGet { .. } | ArraySet { .. } => true, + + // Unclear why this instruction causes problems. + Truncate { .. } => false, + + // These either have side-effects or interact with memory + Constrain(..) | EnableSideEffects { .. } | Allocate | Load { .. } | Store { .. } => { + false + } + + Call { func, .. } => match dfg[*func] { + Value::Intrinsic(intrinsic) => !intrinsic.has_side_effects(), + _ => false, + }, + } + } + pub(crate) fn has_side_effects(&self, dfg: &DataFlowGraph) -> bool { use Instruction::*; @@ -217,7 +244,7 @@ impl Instruction { | ArrayGet { .. } | ArraySet { .. } => false, - Constrain(_) | Store { .. } | EnableSideEffects { .. } => true, + Constrain(..) | Store { .. } | EnableSideEffects { .. } => true, // Some `Intrinsic`s have side effects so we must check what kind of `Call` this is. Call { func, .. } => match dfg[*func] { @@ -253,7 +280,9 @@ impl Instruction { bit_size: *bit_size, max_bit_size: *max_bit_size, }, - Instruction::Constrain(value) => Instruction::Constrain(f(*value)), + Instruction::Constrain(lhs, rhs, assert_message) => { + Instruction::Constrain(f(*lhs), f(*rhs), assert_message.clone()) + } Instruction::Call { func, arguments } => Instruction::Call { func: f(*func), arguments: vecmap(arguments.iter().copied(), f), @@ -269,9 +298,12 @@ impl Instruction { Instruction::ArrayGet { array, index } => { Instruction::ArrayGet { array: f(*array), index: f(*index) } } - Instruction::ArraySet { array, index, value } => { - Instruction::ArraySet { array: f(*array), index: f(*index), value: f(*value) } - } + Instruction::ArraySet { array, index, value, length } => Instruction::ArraySet { + array: f(*array), + index: f(*index), + value: f(*value), + length: length.map(f), + }, } } @@ -291,10 +323,14 @@ impl Instruction { Instruction::Cast(value, _) | Instruction::Not(value) | Instruction::Truncate { value, .. } - | Instruction::Constrain(value) | Instruction::Load { address: value } => { f(*value); } + Instruction::Constrain(lhs, rhs, _) => { + f(*lhs); + f(*rhs); + } + Instruction::Store { address, value } => { f(*address); f(*value); @@ -304,10 +340,11 @@ impl Instruction { f(*array); f(*index); } - Instruction::ArraySet { array, index, value } => { + Instruction::ArraySet { array, index, value, length } => { f(*array); f(*index); f(*value); + length.map(&mut f); } Instruction::EnableSideEffects { condition } => { f(*condition); @@ -345,13 +382,13 @@ impl Instruction { _ => None, } } - Instruction::Constrain(value) => { - if let Some(constant) = dfg.get_numeric_constant(*value) { - if constant.is_one() { - return Remove; - } + Instruction::Constrain(lhs, rhs, ..) => { + if dfg.resolve(*lhs) == dfg.resolve(*rhs) { + // Remove trivial case `assert_eq(x, x)` + SimplifyResult::Remove + } else { + SimplifyResult::None } - None } Instruction::ArrayGet { array, index } => { let array = dfg.get_array_constant(*array); @@ -365,7 +402,7 @@ impl Instruction { } None } - Instruction::ArraySet { array, index, value } => { + Instruction::ArraySet { array, index, value, .. } => { let array = dfg.get_array_constant(*array); let index = dfg.get_numeric_constant(*index); if let (Some((array, element_type)), Some(index)) = (array, index) { @@ -388,7 +425,7 @@ impl Instruction { None } } - Instruction::Call { func, arguments } => simplify_call(*func, arguments, dfg), + Instruction::Call { func, arguments } => simplify_call(*func, arguments, dfg, block), Instruction::EnableSideEffects { condition } => { if let Some(last) = dfg[block].instructions().last().copied() { let last = &mut dfg[last]; @@ -517,6 +554,26 @@ impl TerminatorInstruction { } } + /// Mutate each ValueId to a new ValueId using the given mapping function + pub(crate) fn mutate_values(&mut self, mut f: impl FnMut(ValueId) -> ValueId) { + use TerminatorInstruction::*; + match self { + JmpIf { condition, .. } => { + *condition = f(*condition); + } + Jmp { arguments, .. } => { + for argument in arguments { + *argument = f(*argument); + } + } + Return { return_values } => { + for return_value in return_values { + *return_value = f(*return_value); + } + } + } + } + /// Apply a function to each value pub(crate) fn for_each_value(&self, mut f: impl FnMut(ValueId) -> T) { use TerminatorInstruction::*; @@ -580,6 +637,13 @@ impl Binary { let operand_type = dfg.type_of_value(self.lhs); if let (Some(lhs), Some(rhs)) = (lhs, rhs) { + // If the rhs of a division is zero, attempting to evaluate the divison will cause a compiler panic. + // Thus, we do not evaluate this divison as we want to avoid triggering a panic, + // and division by zero should be handled by laying down constraints during ACIR generation. + if matches!(self.operator, BinaryOp::Div | BinaryOp::Mod) && rhs == FieldElement::zero() + { + return SimplifyResult::None; + } return match self.eval_constants(dfg, lhs, rhs, operand_type) { Some(value) => SimplifyResult::SimplifiedTo(value), None => SimplifyResult::None, @@ -721,6 +785,16 @@ impl Binary { let lhs = truncate(lhs.try_into_u128()?, *bit_size); let rhs = truncate(rhs.try_into_u128()?, *bit_size); + + // The divisor is being truncated into the type of the operand, which can potentially + // lead to the rhs being zero. + // If the rhs of a division is zero, attempting to evaluate the divison will cause a compiler panic. + // Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic, + // and the operation should be handled by ACIR generation. + if matches!(self.operator, BinaryOp::Div) && rhs == 0 { + return None; + } + let result = function(lhs, rhs); truncate(result, *bit_size).into() } @@ -837,7 +911,7 @@ pub(crate) enum SimplifyResult { /// a function such as a tuple SimplifiedToMultiple(Vec), - /// Replace this function with an simpler but equivalent function. + /// Replace this function with an simpler but equivalent instruction. SimplifiedToInstruction(Instruction), /// Remove the instruction, it is unnecessary diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs similarity index 95% rename from crates/noirc_evaluator/src/ssa/ir/instruction/call.rs rename to compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index 713bc8b0997..42d0aa0a4e4 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -5,6 +5,7 @@ use iter_extended::vecmap; use num_bigint::BigUint; use crate::ssa::ir::{ + basic_block::BasicBlockId, dfg::DataFlowGraph, instruction::Intrinsic, map::Id, @@ -16,10 +17,16 @@ use super::{Binary, BinaryOp, Endian, Instruction, SimplifyResult}; /// Try to simplify this call instruction. If the instruction can be simplified to a known value, /// that value is returned. Otherwise None is returned. +/// +/// The `block` parameter indicates the block any new instructions that are part of a call's +/// simplification will be inserted into. For example, all slice intrinsics require updates +/// to the slice length, which requires inserting a binary instruction. This update instruction +/// must be inserted into the same block that the call itself is being simplified into. pub(super) fn simplify_call( func: ValueId, arguments: &[ValueId], dfg: &mut DataFlowGraph, + block: BasicBlockId, ) -> SimplifyResult { let intrinsic = match &dfg[func] { Value::Intrinsic(intrinsic) => *intrinsic, @@ -88,7 +95,7 @@ pub(super) fn simplify_call( slice.push_back(*elem); } - let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Add); + let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Add, block); let new_slice = dfg.make_array(slice, element_type); SimplifyResult::SimplifiedToMultiple(vec![new_slice_length, new_slice]) @@ -103,7 +110,7 @@ pub(super) fn simplify_call( slice.push_front(*elem); } - let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Add); + let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Add, block); let new_slice = dfg.make_array(slice, element_type); SimplifyResult::SimplifiedToMultiple(vec![new_slice_length, new_slice]) @@ -128,7 +135,7 @@ pub(super) fn simplify_call( let new_slice = dfg.make_array(slice, typ); results.push_front(new_slice); - let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Sub); + let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Sub, block); results.push_front(new_slice_length); SimplifyResult::SimplifiedToMultiple(results.into()) @@ -146,7 +153,7 @@ pub(super) fn simplify_call( slice.pop_front().expect("There are no elements in this slice to be removed") }); - let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Sub); + let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Sub, block); results.push(new_slice_length); @@ -171,7 +178,7 @@ pub(super) fn simplify_call( index += 1; } - let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Add); + let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Add, block); let new_slice = dfg.make_array(slice, typ); SimplifyResult::SimplifiedToMultiple(vec![new_slice_length, new_slice]) @@ -194,7 +201,7 @@ pub(super) fn simplify_call( let new_slice = dfg.make_array(slice, typ); results.insert(0, new_slice); - let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Sub); + let new_slice_length = update_slice_length(arguments[0], dfg, BinaryOp::Sub, block); results.insert(0, new_slice_length); @@ -226,9 +233,13 @@ pub(super) fn simplify_call( /// The binary operation performed on the slice length is always an addition or subtraction of `1`. /// This is because the slice length holds the user length (length as displayed by a `.len()` call), /// and not a flattened length used internally to represent arrays of tuples. -fn update_slice_length(slice_len: ValueId, dfg: &mut DataFlowGraph, operator: BinaryOp) -> ValueId { +fn update_slice_length( + slice_len: ValueId, + dfg: &mut DataFlowGraph, + operator: BinaryOp, + block: BasicBlockId, +) -> ValueId { let one = dfg.make_constant(FieldElement::one(), Type::field()); - let block = dfg.make_block(); let instruction = Instruction::Binary(Binary { lhs: slice_len, operator, rhs: one }); let call_stack = dfg.get_value_call_stack(slice_len); dfg.insert_instruction_and_results(instruction, block, None, call_stack).first() @@ -334,15 +345,6 @@ fn constant_to_radix( limbs.reverse(); } - // For legacy reasons (see #617) the to_radix interface supports 256 bits even though - // FieldElement::max_num_bits() is only 254 bits. Any limbs beyond the specified count - // become zero padding. - let max_decomposable_bits: u32 = 256; - let limb_count_with_padding = max_decomposable_bits / bit_size; - while limbs.len() < limb_count_with_padding as usize { - limbs.push(FieldElement::zero()); - } - make_constant_array(dfg, limbs, Type::unsigned(bit_size)) } diff --git a/crates/noirc_evaluator/src/ssa/ir/map.rs b/compiler/noirc_evaluator/src/ssa/ir/map.rs similarity index 97% rename from crates/noirc_evaluator/src/ssa/ir/map.rs rename to compiler/noirc_evaluator/src/ssa/ir/map.rs index bb0da6a8558..10d6adfbd6a 100644 --- a/crates/noirc_evaluator/src/ssa/ir/map.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/map.rs @@ -1,5 +1,5 @@ +use fxhash::FxHashMap as HashMap; use std::{ - collections::HashMap, hash::Hash, sync::atomic::{AtomicUsize, Ordering}, }; @@ -74,7 +74,7 @@ impl Copy for Id {} impl Clone for Id { fn clone(&self) -> Self { - Self { index: self.index, _marker: self._marker } + *self } } @@ -218,7 +218,7 @@ impl SparseMap { impl Default for SparseMap { fn default() -> Self { - Self { storage: HashMap::new() } + Self { storage: HashMap::default() } } } @@ -272,7 +272,7 @@ impl TwoWayMap { impl Default for TwoWayMap { fn default() -> Self { - Self { key_to_value: HashMap::new(), value_to_key: HashMap::new() } + Self { key_to_value: HashMap::default(), value_to_key: HashMap::default() } } } diff --git a/crates/noirc_evaluator/src/ssa/ir/post_order.rs b/compiler/noirc_evaluator/src/ssa/ir/post_order.rs similarity index 99% rename from crates/noirc_evaluator/src/ssa/ir/post_order.rs rename to compiler/noirc_evaluator/src/ssa/ir/post_order.rs index e3bdbd491df..3cae86829ed 100644 --- a/crates/noirc_evaluator/src/ssa/ir/post_order.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/post_order.rs @@ -72,13 +72,13 @@ impl PostOrder { #[cfg(test)] mod tests { use crate::ssa::{ + function_builder::FunctionBuilder, ir::{ function::{Function, RuntimeType}, map::Id, post_order::PostOrder, types::Type, }, - ssa_builder::FunctionBuilder, }; #[test] diff --git a/crates/noirc_evaluator/src/ssa/ir/printer.rs b/compiler/noirc_evaluator/src/ssa/ir/printer.rs similarity index 91% rename from crates/noirc_evaluator/src/ssa/ir/printer.rs rename to compiler/noirc_evaluator/src/ssa/ir/printer.rs index e8cea151ad1..537b474a8d9 100644 --- a/crates/noirc_evaluator/src/ssa/ir/printer.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/printer.rs @@ -145,9 +145,10 @@ pub(crate) fn display_instruction( let value = show(*value); writeln!(f, "truncate {value} to {bit_size} bits, max_bit_size: {max_bit_size}",) } - Instruction::Constrain(value) => { - writeln!(f, "constrain {}", show(*value)) - } + Instruction::Constrain(lhs, rhs, message) => match message { + Some(message) => writeln!(f, "constrain {} == {} '{message}'", show(*lhs), show(*rhs)), + None => writeln!(f, "constrain {} == {}", show(*lhs), show(*rhs)), + }, Instruction::Call { func, arguments } => { writeln!(f, "call {}({})", show(*func), value_list(function, arguments)) } @@ -162,14 +163,19 @@ pub(crate) fn display_instruction( Instruction::ArrayGet { array, index } => { writeln!(f, "array_get {}, index {}", show(*array), show(*index)) } - Instruction::ArraySet { array, index, value } => { - writeln!( + Instruction::ArraySet { array, index, value, length } => { + write!( f, "array_set {}, index {}, value {}", show(*array), show(*index), show(*value) - ) + )?; + if let Some(length) = length { + writeln!(f, ", length {}", show(*length)) + } else { + writeln!(f) + } } } } diff --git a/crates/noirc_evaluator/src/ssa/ir/types.rs b/compiler/noirc_evaluator/src/ssa/ir/types.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/ir/types.rs rename to compiler/noirc_evaluator/src/ssa/ir/types.rs diff --git a/crates/noirc_evaluator/src/ssa/ir/value.rs b/compiler/noirc_evaluator/src/ssa/ir/value.rs similarity index 84% rename from crates/noirc_evaluator/src/ssa/ir/value.rs rename to compiler/noirc_evaluator/src/ssa/ir/value.rs index 54831eb4a07..8c2a4e88ef3 100644 --- a/crates/noirc_evaluator/src/ssa/ir/value.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/value.rs @@ -57,15 +57,15 @@ pub(crate) enum Value { impl Value { /// Retrieves the type of this Value - pub(crate) fn get_type(&self) -> Type { + pub(crate) fn get_type(&self) -> &Type { match self { - Value::Instruction { typ, .. } => typ.clone(), - Value::Param { typ, .. } => typ.clone(), - Value::NumericConstant { typ, .. } => typ.clone(), - Value::Array { typ, .. } => typ.clone(), - Value::Function { .. } => Type::Function, - Value::Intrinsic { .. } => Type::Function, - Value::ForeignFunction { .. } => Type::Function, + Value::Instruction { typ, .. } => typ, + Value::Param { typ, .. } => typ, + Value::NumericConstant { typ, .. } => typ, + Value::Array { typ, .. } => typ, + Value::Function { .. } => &Type::Function, + Value::Intrinsic { .. } => &Type::Function, + Value::ForeignFunction { .. } => &Type::Function, } } } diff --git a/crates/noirc_evaluator/src/ssa/opt/array_use.rs b/compiler/noirc_evaluator/src/ssa/opt/array_use.rs similarity index 95% rename from crates/noirc_evaluator/src/ssa/opt/array_use.rs rename to compiler/noirc_evaluator/src/ssa/opt/array_use.rs index 5b45d768e1f..cfa97cee551 100644 --- a/crates/noirc_evaluator/src/ssa/opt/array_use.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/array_use.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use crate::ssa::{ ir::{ basic_block::BasicBlockId, @@ -10,13 +8,14 @@ use crate::ssa::{ }, ssa_gen::Ssa, }; +use fxhash::FxHashMap as HashMap; impl Ssa { /// Map arrays with the last instruction that uses it /// For this we simply process all the instructions in execution order /// and update the map whenever there is a match pub(crate) fn find_last_array_uses(&self) -> HashMap { - let mut array_use = HashMap::new(); + let mut array_use = HashMap::default(); for func in self.functions.values() { let mut reverse_post_order = PostOrder::with_function(func).into_vec(); reverse_post_order.reverse(); diff --git a/crates/noirc_evaluator/src/ssa/opt/assert_constant.rs b/compiler/noirc_evaluator/src/ssa/opt/assert_constant.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/opt/assert_constant.rs rename to compiler/noirc_evaluator/src/ssa/opt/assert_constant.rs diff --git a/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs b/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs new file mode 100644 index 00000000000..9eda52e0475 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs @@ -0,0 +1,445 @@ +//! The goal of the constant folding optimization pass is to propagate any constants forwards into +//! later [`Instruction`]s to maximize the impact of [compile-time simplifications][Instruction::simplify()]. +//! +//! The pass works as follows: +//! - Re-insert each instruction in order to apply the instruction simplification performed +//! by the [`DataFlowGraph`] automatically as new instructions are pushed. +//! - Check whether any input values have been constrained to be equal to a value of a simpler form +//! by a [constrain instruction][Instruction::Constrain]. If so, replace the input value with the simpler form. +//! - Check whether the instruction is [pure][Instruction::is_pure()] +//! and there exists a duplicate instruction earlier in the same block. +//! If so, the instruction can be replaced with the results of this previous instruction. +//! +//! These operations are done in parallel so that they can each benefit from each other +//! without the need for multiple passes. +//! +//! Other passes perform a certain amount of constant folding automatically as they insert instructions +//! into the [`DataFlowGraph`] but this pass can become needed if [`DataFlowGraph::set_value`] or +//! [`DataFlowGraph::set_value_from_id`] are used on a value which enables instructions dependent on the value to +//! now be simplified. +//! +//! This is the only pass which removes duplicated pure [`Instruction`]s however and so is needed when +//! different blocks are merged, i.e. after the [`flatten_cfg`][super::flatten_cfg] pass. +use std::collections::HashSet; + +use iter_extended::vecmap; + +use crate::ssa::{ + ir::{ + basic_block::BasicBlockId, + dfg::{DataFlowGraph, InsertInstructionResult}, + function::Function, + instruction::{Instruction, InstructionId}, + value::{Value, ValueId}, + }, + ssa_gen::Ssa, +}; +use fxhash::FxHashMap as HashMap; + +impl Ssa { + /// Performs constant folding on each instruction. + /// + /// See [`constant_folding`][self] module for more information. + pub(crate) fn fold_constants(mut self) -> Ssa { + for function in self.functions.values_mut() { + constant_fold(function); + } + self + } +} + +/// The structure of this pass is simple: +/// Go through each block and re-insert all instructions. +fn constant_fold(function: &mut Function) { + let mut context = Context::default(); + context.block_queue.push(function.entry_block()); + + while let Some(block) = context.block_queue.pop() { + if context.visited_blocks.contains(&block) { + continue; + } + + context.visited_blocks.insert(block); + context.fold_constants_in_block(function, block); + } +} + +#[derive(Default)] +struct Context { + /// Maps pre-folded ValueIds to the new ValueIds obtained by re-inserting the instruction. + visited_blocks: HashSet, + block_queue: Vec, +} + +impl Context { + fn fold_constants_in_block(&mut self, function: &mut Function, block: BasicBlockId) { + let instructions = function.dfg[block].take_instructions(); + + // Cache of instructions without any side-effects along with their outputs. + let mut cached_instruction_results: HashMap> = HashMap::default(); + let mut constrained_values: HashMap = HashMap::default(); + + for instruction_id in instructions { + Self::fold_constants_into_instruction( + &mut function.dfg, + block, + instruction_id, + &mut cached_instruction_results, + &mut constrained_values, + ); + } + self.block_queue.extend(function.dfg[block].successors()); + } + + fn fold_constants_into_instruction( + dfg: &mut DataFlowGraph, + block: BasicBlockId, + id: InstructionId, + instruction_result_cache: &mut HashMap>, + constrained_values: &mut HashMap, + ) { + let instruction = Self::resolve_instruction(id, dfg, constrained_values); + let old_results = dfg.instruction_results(id).to_vec(); + + // If a copy of this instruction exists earlier in the block, then reuse the previous results. + if let Some(cached_results) = instruction_result_cache.get(&instruction) { + Self::replace_result_ids(dfg, &old_results, cached_results); + return; + } + + // Otherwise, try inserting the instruction again to apply any optimizations using the newly resolved inputs. + let new_results = Self::push_instruction(id, instruction.clone(), &old_results, block, dfg); + + Self::replace_result_ids(dfg, &old_results, &new_results); + + Self::cache_instruction( + instruction, + new_results, + dfg, + instruction_result_cache, + constrained_values, + ); + } + + /// Fetches an [`Instruction`] by its [`InstructionId`] and fully resolves its inputs. + fn resolve_instruction( + instruction_id: InstructionId, + dfg: &DataFlowGraph, + constrained_values: &mut HashMap, + ) -> Instruction { + let instruction = dfg[instruction_id].clone(); + + // Alternate between resolving `value_id` in the `dfg` and checking to see if the resolved value + // has been constrained to be equal to some simpler value in the current block. + // + // This allows us to reach a stable final `ValueId` for each instruction input as we add more + // constraints to the cache. + fn resolve_cache( + dfg: &DataFlowGraph, + cache: &HashMap, + value_id: ValueId, + ) -> ValueId { + let resolved_id = dfg.resolve(value_id); + match cache.get(&resolved_id) { + Some(cached_value) => resolve_cache(dfg, cache, *cached_value), + None => resolved_id, + } + } + + // Resolve any inputs to ensure that we're comparing like-for-like instructions. + instruction.map_values(|value_id| resolve_cache(dfg, constrained_values, value_id)) + } + + /// Pushes a new [`Instruction`] into the [`DataFlowGraph`] which applies any optimizations + /// based on newly resolved values for its inputs. + /// + /// This may result in the [`Instruction`] being optimized away or replaced with a constant value. + fn push_instruction( + id: InstructionId, + instruction: Instruction, + old_results: &[ValueId], + block: BasicBlockId, + dfg: &mut DataFlowGraph, + ) -> Vec { + let ctrl_typevars = instruction + .requires_ctrl_typevars() + .then(|| vecmap(old_results, |result| dfg.type_of_value(*result))); + + let call_stack = dfg.get_call_stack(id); + let new_results = + match dfg.insert_instruction_and_results(instruction, block, ctrl_typevars, call_stack) + { + InsertInstructionResult::SimplifiedTo(new_result) => vec![new_result], + InsertInstructionResult::SimplifiedToMultiple(new_results) => new_results, + InsertInstructionResult::Results(_, new_results) => new_results.to_vec(), + InsertInstructionResult::InstructionRemoved => vec![], + }; + // Optimizations while inserting the instruction should not change the number of results. + assert_eq!(old_results.len(), new_results.len()); + + new_results + } + + fn cache_instruction( + instruction: Instruction, + instruction_results: Vec, + dfg: &DataFlowGraph, + instruction_result_cache: &mut HashMap>, + constraint_cache: &mut HashMap, + ) { + // If the instruction was a constraint, then create a link between the two `ValueId`s + // to map from the more complex to the simpler value. + if let Instruction::Constrain(lhs, rhs, _) = instruction { + // These `ValueId`s should be fully resolved now. + match (&dfg[lhs], &dfg[rhs]) { + // Ignore trivial constraints + (Value::NumericConstant { .. }, Value::NumericConstant { .. }) => (), + + // Prefer replacing with constants where possible. + (Value::NumericConstant { .. }, _) => { + constraint_cache.insert(rhs, lhs); + } + (_, Value::NumericConstant { .. }) => { + constraint_cache.insert(lhs, rhs); + } + // Otherwise prefer block parameters over instruction results. + // This is as block parameters are more likely to be a single witness rather than a full expression. + (Value::Param { .. }, Value::Instruction { .. }) => { + constraint_cache.insert(rhs, lhs); + } + (Value::Instruction { .. }, Value::Param { .. }) => { + constraint_cache.insert(lhs, rhs); + } + (_, _) => (), + } + } + + // If the instruction doesn't have side-effects, cache the results so we can reuse them if + // the same instruction appears again later in the block. + if instruction.is_pure(dfg) { + instruction_result_cache.insert(instruction, instruction_results); + } + } + + /// Replaces a set of [`ValueId`]s inside the [`DataFlowGraph`] with another. + fn replace_result_ids( + dfg: &mut DataFlowGraph, + old_results: &[ValueId], + new_results: &[ValueId], + ) { + for (old_result, new_result) in old_results.iter().zip(new_results) { + dfg.set_value_from_id(*old_result, *new_result); + } + } +} + +#[cfg(test)] +mod test { + use std::rc::Rc; + + use crate::ssa::{ + function_builder::FunctionBuilder, + ir::{ + function::RuntimeType, + instruction::{BinaryOp, Instruction, TerminatorInstruction}, + map::Id, + types::Type, + value::{Value, ValueId}, + }, + }; + + #[test] + fn simple_constant_fold() { + // fn main f0 { + // b0(v0: Field): + // v1 = add v0, Field 1 + // v2 = mul v1, Field 3 + // return v2 + // } + // + // After constructing this IR, we set the value of v0 to 2. + // The expected return afterwards should be 9. + let main_id = Id::test_new(0); + + // Compiling main + let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); + let v0 = builder.add_parameter(Type::field()); + + let one = builder.field_constant(1u128); + let two = builder.field_constant(2u128); + let three = builder.field_constant(3u128); + + let v1 = builder.insert_binary(v0, BinaryOp::Add, one); + let v2 = builder.insert_binary(v1, BinaryOp::Mul, three); + builder.terminate_with_return(vec![v2]); + + let mut ssa = builder.finish(); + let main = ssa.main_mut(); + let instructions = main.dfg[main.entry_block()].instructions(); + assert_eq!(instructions.len(), 2); // The final return is not counted + + // Expected output: + // + // fn main f0 { + // b0(Field 2: Field): + // return Field 9 + // } + main.dfg.set_value_from_id(v0, two); + + let ssa = ssa.fold_constants(); + let main = ssa.main(); + let block = &main.dfg[main.entry_block()]; + assert_eq!(block.instructions().len(), 0); + + match block.terminator() { + Some(TerminatorInstruction::Return { return_values }) => { + let value = main + .dfg + .get_numeric_constant(return_values[0]) + .expect("Expected constant 9") + .to_u128(); + assert_eq!(value, 9); + } + _ => unreachable!("b0 should have a return terminator"), + } + } + + #[test] + fn arrays_elements_are_updated() { + // fn main f0 { + // b0(v0: Field): + // v1 = add v0, Field 1 + // return [v1] + // } + // + // After constructing this IR, we run constant folding with no expected benefit, but to + // ensure that all new values ids are correctly propagated. + let main_id = Id::test_new(0); + + // Compiling main + let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); + let v0 = builder.add_parameter(Type::field()); + let one = builder.field_constant(1u128); + let v1 = builder.insert_binary(v0, BinaryOp::Add, one); + + let array_type = Type::Array(Rc::new(vec![Type::field()]), 1); + let arr = builder.current_function.dfg.make_array(vec![v1].into(), array_type); + builder.terminate_with_return(vec![arr]); + + let ssa = builder.finish().fold_constants(); + let main = ssa.main(); + let entry_block_id = main.entry_block(); + let entry_block = &main.dfg[entry_block_id]; + assert_eq!(entry_block.instructions().len(), 1); + let new_add_instr = entry_block.instructions().first().unwrap(); + let new_add_instr_result = main.dfg.instruction_results(*new_add_instr)[0]; + assert_ne!(new_add_instr_result, v1); + + let return_value_id = match entry_block.unwrap_terminator() { + TerminatorInstruction::Return { return_values } => return_values[0], + _ => unreachable!(), + }; + let return_element = match &main.dfg[return_value_id] { + Value::Array { array, .. } => array[0], + _ => unreachable!(), + }; + // The return element is expected to refer to the new add instruction result. + assert_eq!(main.dfg.resolve(new_add_instr_result), main.dfg.resolve(return_element)); + } + + #[test] + fn instruction_deduplication() { + // fn main f0 { + // b0(v0: Field): + // v1 = cast v0 as u32 + // v2 = cast v0 as u32 + // constrain v1 v2 + // } + // + // After constructing this IR, we run constant folding which should replace the second cast + // with a reference to the results to the first. This then allows us to optimize away + // the constrain instruction as both inputs are known to be equal. + // + // The first cast instruction is retained and will be removed in the dead instruction elimination pass. + let main_id = Id::test_new(0); + + // Compiling main + let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); + let v0 = builder.add_parameter(Type::field()); + + let v1 = builder.insert_cast(v0, Type::unsigned(32)); + let v2 = builder.insert_cast(v0, Type::unsigned(32)); + builder.insert_constrain(v1, v2, None); + + let mut ssa = builder.finish(); + let main = ssa.main_mut(); + let instructions = main.dfg[main.entry_block()].instructions(); + assert_eq!(instructions.len(), 3); + + // Expected output: + // + // fn main f0 { + // b0(v0: Field): + // v1 = cast v0 as u32 + // } + let ssa = ssa.fold_constants(); + let main = ssa.main(); + let instructions = main.dfg[main.entry_block()].instructions(); + + assert_eq!(instructions.len(), 1); + let instruction = &main.dfg[instructions[0]]; + + assert_eq!(instruction, &Instruction::Cast(ValueId::test_new(0), Type::unsigned(32))); + } + + #[test] + fn constrained_value_replacement() { + // fn main f0 { + // b0(v0: Field): + // constrain v0 == Field 10 + // v1 = add v0, Field 1 + // constrain v1 == Field 11 + // } + // + // After constructing this IR, we run constant folding which should replace references to `v0` + // with the constant `10`. This then allows us to optimize away the rest of the circuit. + + let main_id = Id::test_new(0); + + // Compiling main + let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); + let v0 = builder.add_parameter(Type::field()); + + let field_10 = builder.field_constant(10u128); + builder.insert_constrain(v0, field_10, None); + + let field_1 = builder.field_constant(1u128); + let v1 = builder.insert_binary(v0, BinaryOp::Add, field_1); + + let field_11 = builder.field_constant(11u128); + builder.insert_constrain(v1, field_11, None); + + let mut ssa = builder.finish(); + let main = ssa.main_mut(); + let instructions = main.dfg[main.entry_block()].instructions(); + assert_eq!(instructions.len(), 3); + + // Expected output: + // + // fn main f0 { + // b0(v0: Field): + // constrain v0 == Field 10 + // } + let ssa = ssa.fold_constants(); + let main = ssa.main(); + let instructions = main.dfg[main.entry_block()].instructions(); + + assert_eq!(instructions.len(), 1); + let instruction = &main.dfg[instructions[0]]; + + assert_eq!( + instruction, + &Instruction::Constrain(ValueId::test_new(0), ValueId::test_new(1), None) + ); + } +} diff --git a/crates/noirc_evaluator/src/ssa/opt/defunctionalize.rs b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs similarity index 97% rename from crates/noirc_evaluator/src/ssa/opt/defunctionalize.rs rename to compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs index 10561bf731f..62b335be1e2 100644 --- a/crates/noirc_evaluator/src/ssa/opt/defunctionalize.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs @@ -4,12 +4,13 @@ //! with a non-literal target can be replaced with a call to an apply function. //! The apply function is a dispatch function that takes the function id as a parameter //! and dispatches to the correct target. -use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet, HashSet}; use acvm::FieldElement; use iter_extended::vecmap; use crate::ssa::{ + function_builder::FunctionBuilder, ir::{ basic_block::BasicBlockId, function::{Function, FunctionId, RuntimeType, Signature}, @@ -17,9 +18,9 @@ use crate::ssa::{ types::{NumericType, Type}, value::{Value, ValueId}, }, - ssa_builder::FunctionBuilder, ssa_gen::Ssa, }; +use fxhash::FxHashMap as HashMap; /// Represents an 'apply' function created by this pass to dispatch higher order functions to. /// Pseudocode of an `apply` function is given below: @@ -245,12 +246,11 @@ fn create_apply_functions( ssa: &mut Ssa, variants_map: BTreeMap>, ) -> HashMap { - let mut apply_functions = HashMap::new(); + let mut apply_functions = HashMap::default(); for (signature, variants) in variants_map.into_iter() { assert!( !variants.is_empty(), - "ICE: at least one variant should exist for a dynamic call {:?}", - signature + "ICE: at least one variant should exist for a dynamic call {signature:?}" ); let dispatches_to_multiple_functions = variants.len() > 1; @@ -289,14 +289,14 @@ fn create_apply_function( function_id_to_field(*function_id), Type::Numeric(NumericType::NativeField), ); - let condition = - function_builder.insert_binary(target_id, BinaryOp::Eq, function_id_constant); // If it's not the last function to dispatch, create an if statement if !is_last { next_function_block = Some(function_builder.insert_block()); let executor_block = function_builder.insert_block(); + let condition = + function_builder.insert_binary(target_id, BinaryOp::Eq, function_id_constant); function_builder.terminate_with_jmpif( condition, executor_block, @@ -305,7 +305,7 @@ fn create_apply_function( function_builder.switch_to_block(executor_block); } else { // Else just constrain the condition - function_builder.insert_constrain(condition); + function_builder.insert_constrain(target_id, function_id_constant, None); } // Find the target block or build it if necessary let current_block = function_builder.current_block(); diff --git a/crates/noirc_evaluator/src/ssa/opt/die.rs b/compiler/noirc_evaluator/src/ssa/opt/die.rs similarity index 99% rename from crates/noirc_evaluator/src/ssa/opt/die.rs rename to compiler/noirc_evaluator/src/ssa/opt/die.rs index 47b94741266..3db95f6ad99 100644 --- a/crates/noirc_evaluator/src/ssa/opt/die.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/die.rs @@ -129,13 +129,13 @@ impl Context { #[cfg(test)] mod test { use crate::ssa::{ + function_builder::FunctionBuilder, ir::{ function::RuntimeType, instruction::{BinaryOp, Intrinsic}, map::Id, types::Type, }, - ssa_builder::FunctionBuilder, }; #[test] diff --git a/crates/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs similarity index 89% rename from crates/noirc_evaluator/src/ssa/opt/flatten_cfg.rs rename to compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index 7eb266aaf75..d57c2cc7933 100644 --- a/crates/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -131,7 +131,8 @@ //! v11 = mul v4, Field 12 //! v12 = add v10, v11 //! store v12 at v5 (new store) -use std::collections::{BTreeMap, HashMap, HashSet}; +use fxhash::FxHashMap as HashMap; +use std::collections::{BTreeMap, HashSet}; use acvm::FieldElement; use iter_extended::vecmap; @@ -143,7 +144,7 @@ use crate::ssa::{ dfg::{CallStack, InsertInstructionResult}, function::Function, function_inserter::FunctionInserter, - instruction::{BinaryOp, Instruction, InstructionId, TerminatorInstruction}, + instruction::{BinaryOp, Instruction, InstructionId, Intrinsic, TerminatorInstruction}, types::Type, value::{Value, ValueId}, }, @@ -175,8 +176,21 @@ struct Context<'f> { branch_ends: HashMap, /// Maps an address to the old and new value of the element at that address + /// These only hold stores for one block at a time and is cleared + /// between inlining of branches. store_values: HashMap, + /// Maps an address to the old and new value of the element at that address + /// The difference between this map and store_values is that this stores + /// the old and new value of an element from the outer block whose jmpif + /// terminator is being flattened. + /// + /// This map persists throughout the flattening process, where addresses + /// are overwritten as new stores are found. This overwriting is the desired behavior, + /// as we want the most update to date value to be stored at a given address as + /// we walk through blocks to flatten. + outer_block_stores: HashMap, + /// Stores all allocations local to the current branch. /// Since these branches are local to the current branch (ie. only defined within one branch of /// an if expression), they should not be merged with their previous value or stored value in @@ -206,12 +220,9 @@ struct Branch { } fn flatten_function_cfg(function: &mut Function) { - // TODO This pass will run forever on a brillig function. - // TODO In particular, analyze will check if the predecessors - // TODO have been processed and push the block to the back of the queue - // TODO This loops forever, if the predecessors are not then processed - // TODO Because it will visit the same block again, pop it out of the queue - // TODO then back into the queue again. + // This pass may run forever on a brillig function. + // Analyze will check if the predecessors have been processed and push the block to the back of + // the queue. This loops forever if there are still any loops present in the program. if let crate::ssa::ir::function::RuntimeType::Brillig = function.runtime() { return; } @@ -221,10 +232,11 @@ fn flatten_function_cfg(function: &mut Function) { let mut context = Context { inserter: FunctionInserter::new(function), cfg, - store_values: HashMap::new(), + store_values: HashMap::default(), local_allocations: HashSet::new(), branch_ends, conditions: Vec::new(), + outer_block_stores: HashMap::default(), }; context.flatten(); } @@ -247,6 +259,26 @@ impl<'f> Context<'f> { /// Returns the last block to be inlined. This is either the return block of the function or, /// if self.conditions is not empty, the end block of the most recent condition. fn handle_terminator(&mut self, block: BasicBlockId) -> BasicBlockId { + if let TerminatorInstruction::JmpIf { .. } = + self.inserter.function.dfg[block].unwrap_terminator() + { + // Find stores in the outer block and insert into the `outer_block_stores` map. + // Not using this map can lead to issues when attempting to merge slices. + // When inlining a branch end, only the then branch and the else branch are checked for stores. + // However, there are cases where we want to load a value that comes from the outer block + // that we are handling the terminator for here. + let instructions = self.inserter.function.dfg[block].instructions().to_vec(); + for instruction in instructions { + let (instruction, _) = self.inserter.map_instruction(instruction); + if let Instruction::Store { address, value } = instruction { + let load = Instruction::Load { address }; + let load_type = Some(vec![self.inserter.function.dfg.type_of_value(value)]); + let old_value = self.insert_instruction_with_typevars(load, load_type).first(); + self.outer_block_stores.insert(address, Store { old_value, new_value: value }); + } + } + } + match self.inserter.function.dfg[block].unwrap_terminator() { TerminatorInstruction::JmpIf { condition, then_destination, else_destination } => { let old_condition = *condition; @@ -414,20 +446,10 @@ impl<'f> Context<'f> { _ => panic!("Expected slice type"), }; - let then_value = self.inserter.function.dfg[then_value_id].clone(); - let else_value = self.inserter.function.dfg[else_value_id].clone(); - - let len = match then_value { - Value::Array { array, .. } => array.len(), - _ => panic!("Expected array value"), - }; - - let else_len = match else_value { - Value::Array { array, .. } => array.len(), - _ => panic!("Expected array value"), - }; + let then_len = self.get_slice_length(then_value_id); + let else_len = self.get_slice_length(else_value_id); - let len = len.max(else_len); + let len = then_len.max(else_len); for i in 0..len { for (element_index, element_type) in element_types.iter().enumerate() { @@ -448,7 +470,7 @@ impl<'f> Context<'f> { } }; - let then_element = get_element(then_value_id, typevars.clone(), len); + let then_element = get_element(then_value_id, typevars.clone(), then_len); let else_element = get_element(else_value_id, typevars, else_len); merged.push_back(self.merge_values( @@ -463,6 +485,54 @@ impl<'f> Context<'f> { self.inserter.function.dfg.make_array(merged, typ) } + fn get_slice_length(&mut self, value_id: ValueId) -> usize { + let value = &self.inserter.function.dfg[value_id]; + match value { + Value::Array { array, .. } => array.len(), + Value::Instruction { instruction: instruction_id, .. } => { + let instruction = &self.inserter.function.dfg[*instruction_id]; + match instruction { + Instruction::ArraySet { array, .. } => self.get_slice_length(*array), + Instruction::Load { address } => { + let context_store = if let Some(store) = self.store_values.get(address) { + store + } else { + self.outer_block_stores + .get(address) + .expect("ICE: load in merger should have store from outer block") + }; + + self.get_slice_length(context_store.new_value) + } + Instruction::Call { func, arguments } => { + let func = &self.inserter.function.dfg[*func]; + let slice_contents = arguments[1]; + match func { + Value::Intrinsic(intrinsic) => match intrinsic { + Intrinsic::SlicePushBack + | Intrinsic::SlicePushFront + | Intrinsic::SliceInsert => { + self.get_slice_length(slice_contents) + 1 + } + Intrinsic::SlicePopBack + | Intrinsic::SlicePopFront + | Intrinsic::SliceRemove => { + self.get_slice_length(slice_contents) - 1 + } + _ => { + unreachable!("ICE: Intrinsic not supported, got {intrinsic:?}") + } + }, + _ => unreachable!("ICE: Expected intrinsic value but got {func:?}"), + } + } + _ => unreachable!("ICE: Got unexpected instruction: {instruction:?}"), + } + } + _ => unreachable!("ICE: Got unexpected value when resolving slice length {value:?}"), + } + } + /// Given an if expression that returns an array: `if c { array1 } else { array2 }`, /// this function will recursively merge array1 and array2 into a single resulting array /// by creating a new array containing the result of self.merge_values for each element. @@ -590,7 +660,7 @@ impl<'f> Context<'f> { // args that will be merged by inline_branch_end. Since jmpifs don't have // block arguments, it is safe to use the jmpif block here. last_block: jmpif_block, - store_values: HashMap::new(), + store_values: HashMap::default(), local_allocations: HashSet::new(), } } else { @@ -769,16 +839,25 @@ impl<'f> Context<'f> { ) -> Instruction { if let Some((_, condition)) = self.conditions.last().copied() { match instruction { - Instruction::Constrain(value) => { - let mul = self.insert_instruction( - Instruction::binary(BinaryOp::Mul, value, condition), + Instruction::Constrain(lhs, rhs, message) => { + // Replace constraint `lhs == rhs` with `condition * lhs == condition * rhs`. + + // Condition needs to be cast to argument type in order to multiply them together. + let argument_type = self.inserter.function.dfg.type_of_value(lhs); + let casted_condition = self.insert_instruction( + Instruction::Cast(condition, argument_type), + call_stack.clone(), + ); + + let lhs = self.insert_instruction( + Instruction::binary(BinaryOp::Mul, lhs, casted_condition), call_stack.clone(), ); - let eq = self.insert_instruction( - Instruction::binary(BinaryOp::Eq, mul, condition), + let rhs = self.insert_instruction( + Instruction::binary(BinaryOp::Mul, rhs, casted_condition), call_stack, ); - Instruction::Constrain(eq) + Instruction::Constrain(lhs, rhs, message) } Instruction::Store { address, value } => { self.remember_store(address, value); @@ -805,6 +884,7 @@ mod test { use std::rc::Rc; use crate::ssa::{ + function_builder::FunctionBuilder, ir::{ dfg::DataFlowGraph, function::{Function, RuntimeType}, @@ -813,7 +893,6 @@ mod test { types::Type, value::{Value, ValueId}, }, - ssa_builder::FunctionBuilder, }; #[test] @@ -890,11 +969,12 @@ mod test { let v0 = builder.add_parameter(Type::bool()); let v1 = builder.add_parameter(Type::bool()); + let v_true = builder.numeric_constant(true, Type::bool()); builder.terminate_with_jmpif(v0, b1, b2); builder.switch_to_block(b1); - builder.insert_constrain(v1); + builder.insert_constrain(v1, v_true, None); builder.terminate_with_jmp(b2, vec![]); builder.switch_to_block(b2); @@ -1345,14 +1425,15 @@ mod test { let b1 = builder.insert_block(); let b2 = builder.insert_block(); - let v_false = builder.numeric_constant(0_u128, Type::bool()); + let v_true = builder.numeric_constant(true, Type::bool()); + let v_false = builder.numeric_constant(false, Type::bool()); builder.terminate_with_jmpif(v_false, b1, b2); builder.switch_to_block(b1); builder.terminate_with_jmp(b2, vec![]); builder.switch_to_block(b2); - builder.insert_constrain(v_false); // should not be removed + builder.insert_constrain(v_false, v_true, None); // should not be removed builder.terminate_with_return(vec![]); let ssa = builder.finish().flatten_cfg(); @@ -1360,7 +1441,7 @@ mod test { // Assert we have not incorrectly removed a constraint: use Instruction::Constrain; - let constrain_count = count_instruction(main, |ins| matches!(ins, Constrain(_))); + let constrain_count = count_instruction(main, |ins| matches!(ins, Constrain(..))); assert_eq!(constrain_count, 1); } @@ -1433,9 +1514,9 @@ mod test { builder.terminate_with_jmp(b3, vec![]); builder.switch_to_block(b3); - let b_true = builder.numeric_constant(1_u128, Type::unsigned(1)); - let v12 = builder.insert_binary(v9, BinaryOp::Eq, b_true); - builder.insert_constrain(v12); + let v_true = builder.numeric_constant(true, Type::bool()); + let v12 = builder.insert_binary(v9, BinaryOp::Eq, v_true); + builder.insert_constrain(v12, v_true, None); builder.terminate_with_return(vec![]); let ssa = builder.finish().flatten_cfg(); @@ -1444,9 +1525,11 @@ mod test { // Now assert that there is not an always-false constraint after flattening: let mut constrain_count = 0; for instruction in main.dfg[main.entry_block()].instructions() { - if let Instruction::Constrain(value) = main.dfg[*instruction] { - if let Some(constant) = main.dfg.get_numeric_constant(value) { - assert!(constant.is_one()); + if let Instruction::Constrain(lhs, rhs, ..) = main.dfg[*instruction] { + if let (Some(lhs), Some(rhs)) = + (main.dfg.get_numeric_constant(lhs), main.dfg.get_numeric_constant(rhs)) + { + assert_eq!(lhs, rhs); } constrain_count += 1; } diff --git a/crates/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs similarity index 98% rename from crates/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs rename to compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs index 1203d03f562..59bee00936a 100644 --- a/crates/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs @@ -19,9 +19,9 @@ //! //! This algorithm will remember each join point found in `find_join_point_of_branches` and //! the resulting map from each split block to each join block is returned. -use std::collections::HashMap; use crate::ssa::ir::{basic_block::BasicBlockId, cfg::ControlFlowGraph, function::Function}; +use fxhash::FxHashMap as HashMap; /// Returns a `HashMap` mapping blocks that start a branch (i.e. blocks terminated with jmpif) to /// their corresponding blocks that end the branch. @@ -61,7 +61,7 @@ struct Context<'cfg> { impl<'cfg> Context<'cfg> { fn new(cfg: &'cfg ControlFlowGraph) -> Self { - Self { cfg, branch_ends: HashMap::new() } + Self { cfg, branch_ends: HashMap::default() } } fn find_join_point_of_branches( @@ -113,9 +113,9 @@ impl<'cfg> Context<'cfg> { mod test { use crate::ssa::{ + function_builder::FunctionBuilder, ir::{cfg::ControlFlowGraph, function::RuntimeType, map::Id, types::Type}, opt::flatten_cfg::branch_analysis::find_branch_ends, - ssa_builder::FunctionBuilder, }; #[test] diff --git a/crates/noirc_evaluator/src/ssa/opt/inlining.rs b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs similarity index 91% rename from crates/noirc_evaluator/src/ssa/opt/inlining.rs rename to compiler/noirc_evaluator/src/ssa/opt/inlining.rs index 55424f8f32f..07b524ebc96 100644 --- a/crates/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -2,11 +2,12 @@ //! The purpose of this pass is to inline the instructions of each function call //! within the function caller. If all function calls are known, there will only //! be a single function remaining when the pass finishes. -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeSet, HashSet}; -use iter_extended::vecmap; +use iter_extended::{btree_map, vecmap}; use crate::ssa::{ + function_builder::FunctionBuilder, ir::{ basic_block::BasicBlockId, dfg::{CallStack, InsertInstructionResult}, @@ -14,9 +15,9 @@ use crate::ssa::{ instruction::{Instruction, InstructionId, TerminatorInstruction}, value::{Value, ValueId}, }, - ssa_builder::FunctionBuilder, ssa_gen::Ssa, }; +use fxhash::FxHashMap as HashMap; /// An arbitrary limit to the maximum number of recursive call /// frames at any point in time. @@ -35,8 +36,13 @@ impl Ssa { /// changes. This is because if the function's id later becomes known by a later /// pass, we would need to re-run all of inlining anyway to inline it, so we might /// as well save the work for later instead of performing it twice. - pub(crate) fn inline_functions(self) -> Ssa { - InlineContext::new(&self).inline_all(self) + pub(crate) fn inline_functions(mut self) -> Ssa { + self.functions = btree_map(get_entry_point_functions(&self), |entry_point| { + let new_function = InlineContext::new(&self, entry_point).inline_all(&self); + (entry_point, new_function) + }); + + self } } @@ -51,10 +57,8 @@ struct InlineContext { call_stack: CallStack, - /// True if we failed to inline at least one call. If this is still false when finishing - /// inlining we can remove all other functions from the resulting Ssa struct and keep only - /// the function that was inlined into. - failed_to_inline_a_call: bool, + // The FunctionId of the entry point function we're inlining into in the old, unmodified Ssa. + entry_point: FunctionId, } /// The per-function inlining context contains information that is only valid for one function. @@ -87,8 +91,22 @@ struct PerFunctionContext<'function> { /// Maps InstructionIds from the function being inlined to the function being inlined into. instructions: HashMap, - /// True if we're currently working on the main function. - inlining_main: bool, + /// True if we're currently working on the entry point function. + inlining_entry: bool, +} + +/// The entry point functions are each function we should inline into - and each function that +/// should be left in the final program. This is usually just `main` but also includes any +/// brillig functions used. +fn get_entry_point_functions(ssa: &Ssa) -> BTreeSet { + let functions = ssa.functions.iter(); + let mut entry_points = functions + .filter(|(_, function)| function.runtime() == RuntimeType::Brillig) + .map(|(id, _)| *id) + .collect::>(); + + entry_points.insert(ssa.main_id); + entry_points } impl InlineContext { @@ -97,24 +115,20 @@ impl InlineContext { /// The function being inlined into will always be the main function, although it is /// actually a copy that is created in case the original main is still needed from a function /// that could not be inlined calling it. - fn new(ssa: &Ssa) -> InlineContext { - let main_name = ssa.main().name().to_owned(); - let builder = FunctionBuilder::new(main_name, ssa.next_id.next(), RuntimeType::Acir); - Self { - builder, - recursion_level: 0, - call_stack: CallStack::new(), - failed_to_inline_a_call: false, - } + fn new(ssa: &Ssa, entry_point: FunctionId) -> InlineContext { + let source = &ssa.functions[&entry_point]; + let builder = FunctionBuilder::new(source.name().to_owned(), entry_point, source.runtime()); + Self { builder, recursion_level: 0, entry_point, call_stack: CallStack::new() } } - /// Start inlining the main function and all functions reachable from it. - fn inline_all(mut self, ssa: Ssa) -> Ssa { - let main = ssa.main(); - let mut context = PerFunctionContext::new(&mut self, main); - context.inlining_main = true; + /// Start inlining the entry point function and all functions reachable from it. + fn inline_all(mut self, ssa: &Ssa) -> Function { + let entry_point = &ssa.functions[&self.entry_point]; + + let mut context = PerFunctionContext::new(&mut self, entry_point); + context.inlining_entry = true; - // The main block is already inserted so we have to add it to context.blocks and add + // The entry block is already inserted so we have to add it to context.blocks and add // its parameters here. Failing to do so would cause context.translate_block() to add // a fresh block for the entry block rather than use the existing one. let entry_block = context.context.builder.current_function.entry_block(); @@ -127,8 +141,12 @@ impl InlineContext { } context.blocks.insert(context.source_function.entry_block(), entry_block); - context.inline_blocks(&ssa); - self.finish(ssa) + context.inline_blocks(ssa); + + // Finally, we should have 1 function left representing the inlined version of the target function. + let mut new_ssa = self.builder.finish(); + assert_eq!(new_ssa.functions.len(), 1); + new_ssa.functions.pop_first().unwrap().1 } /// Inlines a function into the current function and returns the translated return values @@ -161,26 +179,6 @@ impl InlineContext { self.recursion_level -= 1; return_values } - - /// Finish inlining and return the new Ssa struct with the inlined version of main. - /// If any functions failed to inline, they are not removed from the final Ssa struct. - fn finish(self, mut ssa: Ssa) -> Ssa { - let mut new_ssa = self.builder.finish(); - assert_eq!(new_ssa.functions.len(), 1); - - // If we failed to inline any call, any function may still be reachable so we - // don't remove any from the final program. We could be more precise here and - // do a reachability analysis but it should be fine to keep the extra functions - // around longer if they are not called. - if self.failed_to_inline_a_call { - let new_main = new_ssa.functions.pop_first().unwrap().1; - ssa.main_id = new_main.id(); - ssa.functions.insert(new_main.id(), new_main); - ssa - } else { - new_ssa - } - } } impl<'function> PerFunctionContext<'function> { @@ -192,10 +190,10 @@ impl<'function> PerFunctionContext<'function> { Self { context, source_function, - blocks: HashMap::new(), - instructions: HashMap::new(), - values: HashMap::new(), - inlining_main: false, + blocks: HashMap::default(), + instructions: HashMap::default(), + values: HashMap::default(), + inlining_entry: false, } } @@ -279,10 +277,7 @@ impl<'function> PerFunctionContext<'function> { // don't correspond to actual functions in the SSA program that would // need to be removed afterward. Value::Intrinsic(_) => None, - _ => { - self.context.failed_to_inline_a_call = true; - None - } + _ => None, } } @@ -355,10 +350,7 @@ impl<'function> PerFunctionContext<'function> { Instruction::Call { func, arguments } => match self.get_function(*func) { Some(function) => match ssa.functions[&function].runtime() { RuntimeType::Acir => self.inline_function(ssa, *id, function, arguments), - RuntimeType::Brillig => { - self.context.failed_to_inline_a_call = true; - self.push_instruction(*id); - } + RuntimeType::Brillig => self.push_instruction(*id), }, None => self.push_instruction(*id), }, @@ -392,7 +384,7 @@ impl<'function> PerFunctionContext<'function> { self.context.call_stack.pop_back(); } - let new_results = InsertInstructionResult::Results(&new_results); + let new_results = InsertInstructionResult::Results(call_id, &new_results); Self::insert_new_instruction_results(&mut self.values, old_results, new_results); } @@ -435,7 +427,7 @@ impl<'function> PerFunctionContext<'function> { values.insert(*old_result, new_result); } } - InsertInstructionResult::Results(new_results) => { + InsertInstructionResult::Results(_, new_results) => { for (old_result, new_result) in old_results.iter().zip(new_results) { values.insert(*old_result, *new_result); } @@ -494,7 +486,7 @@ impl<'function> PerFunctionContext<'function> { } TerminatorInstruction::Return { return_values } => { let return_values = vecmap(return_values, |value| self.translate_value(*value)); - if self.inlining_main { + if self.inlining_entry { self.context.builder.terminate_with_return(return_values.clone()); } // Note that `translate_block` would take us back to the point at which the @@ -513,6 +505,7 @@ mod test { use acvm::FieldElement; use crate::ssa::{ + function_builder::FunctionBuilder, ir::{ basic_block::BasicBlockId, function::RuntimeType, @@ -520,7 +513,6 @@ mod test { map::Id, types::Type, }, - ssa_builder::FunctionBuilder, }; #[test] diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs new file mode 100644 index 00000000000..71524ab9736 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -0,0 +1,709 @@ +//! The goal of the mem2reg SSA optimization pass is to replace any `Load` instructions to known +//! addresses with the value stored at that address, if it is also known. This pass will also remove +//! any `Store` instructions within a block that are no longer needed because no more loads occur in +//! between the Store in question and the next Store. +//! +//! The pass works as follows: +//! - Each block in each function is iterated in forward-order. +//! - The starting value of each reference in the block is the unification of the same references +//! at the end of each direct predecessor block to the current block. +//! - At each step, the value of each reference is either Known(ValueId) or Unknown. +//! - Two reference values unify to each other if they are exactly equal, or to Unknown otherwise. +//! - If a block has no predecessors, the starting value of each reference is Unknown. +//! - Throughout this pass, aliases of each reference are also tracked. +//! - References typically have 1 alias - themselves. +//! - A reference with multiple aliases means we will not be able to optimize out loads if the +//! reference is stored to. Note that this means we can still optimize out loads if these +//! aliased references are never stored to, or the store occurs after a load. +//! - A reference with 0 aliases means we were unable to find which reference this reference +//! refers to. If such a reference is stored to, we must conservatively invalidate every +//! reference in the current block. +//! +//! From there, to figure out the value of each reference at the end of block, iterate each instruction: +//! - On `Instruction::Allocate`: +//! - Register a new reference was made with itself as its only alias +//! - On `Instruction::Load { address }`: +//! - If `address` is known to only have a single alias (including itself) and if the value of +//! that alias is known, replace the value of the load with the known value. +//! - Furthermore, if the result of the load is a reference, mark the result as an alias +//! of the reference it dereferences to (if known). +//! - If which reference it dereferences to is not known, this load result has no aliases. +//! - On `Instruction::Store { address, value }`: +//! - If the address of the store is known: +//! - If the address has exactly 1 alias: +//! - Set the value of the address to `Known(value)`. +//! - If the address has more than 1 alias: +//! - Set the value of every possible alias to `Unknown`. +//! - If the address has 0 aliases: +//! - Conservatively mark every alias in the block to `Unknown`. +//! - If the address of the store is not known: +//! - Conservatively mark every alias in the block to `Unknown`. +//! - Additionally, if there were no Loads to any alias of the address between this Store and +//! the previous Store to the same address, the previous store can be removed. +//! - On `Instruction::Call { arguments }`: +//! - If any argument of the call is a reference, set the value of each alias of that +//! reference to `Unknown` +//! - Any builtin functions that may return aliases if their input also contains a +//! reference should be tracked. Examples: `slice_push_back`, `slice_insert`, `slice_remove`, etc. +//! +//! On a terminator instruction: +//! - If the terminator is a `Jmp`: +//! - For each reference argument of the jmp, mark the corresponding block parameter it is passed +//! to as an alias for the jmp argument. +//! +//! Finally, if this is the only block in the function, we can remove any Stores that were not +//! referenced by the terminator instruction. +//! +//! Repeating this algorithm for each block in the function in program order should result in +//! optimizing out most known loads. However, identifying all aliases correctly has been proven +//! undecidable in general (Landi, 1992). So this pass will not always optimize out all loads +//! that could theoretically be optimized out. This pass can be performed at any time in the +//! SSA optimization pipeline, although it will be more successful the simpler the program's CFG is. +//! This pass is currently performed several times to enable other passes - most notably being +//! performed before loop unrolling to try to allow for mutable variables used for loop indices. +mod alias_set; +mod block; + +use std::collections::{BTreeMap, BTreeSet}; + +use crate::ssa::{ + ir::{ + basic_block::BasicBlockId, + cfg::ControlFlowGraph, + dom::DominatorTree, + function::Function, + function_inserter::FunctionInserter, + instruction::{Instruction, InstructionId, TerminatorInstruction}, + post_order::PostOrder, + types::Type, + value::ValueId, + }, + ssa_gen::Ssa, +}; + +use self::alias_set::AliasSet; +use self::block::{Block, Expression}; + +impl Ssa { + /// Attempts to remove any load instructions that recover values that are already available in + /// scope, and attempts to remove stores that are subsequently redundant. + pub(crate) fn mem2reg(mut self) -> Ssa { + for function in self.functions.values_mut() { + let mut context = PerFunctionContext::new(function); + context.mem2reg(); + context.remove_instructions(); + } + self + } +} + +struct PerFunctionContext<'f> { + cfg: ControlFlowGraph, + post_order: PostOrder, + dom_tree: DominatorTree, + + blocks: BTreeMap, + + inserter: FunctionInserter<'f>, + + /// Load and Store instructions that should be removed at the end of the pass. + /// + /// We avoid removing individual instructions as we go since removing elements + /// from the middle of Vecs many times will be slower than a single call to `retain`. + instructions_to_remove: BTreeSet, +} + +impl<'f> PerFunctionContext<'f> { + fn new(function: &'f mut Function) -> Self { + let cfg = ControlFlowGraph::with_function(function); + let post_order = PostOrder::with_function(function); + let dom_tree = DominatorTree::with_cfg_and_post_order(&cfg, &post_order); + + PerFunctionContext { + cfg, + post_order, + dom_tree, + inserter: FunctionInserter::new(function), + blocks: BTreeMap::new(), + instructions_to_remove: BTreeSet::new(), + } + } + + /// Apply the mem2reg pass to the given function. + /// + /// This function is expected to be the same one that the internal cfg, post_order, and + /// dom_tree were created from. + fn mem2reg(&mut self) { + // Iterate each block in reverse post order = forward order + let mut block_order = PostOrder::with_function(self.inserter.function).into_vec(); + block_order.reverse(); + + for block in block_order { + let references = self.find_starting_references(block); + self.analyze_block(block, references); + } + } + + /// The value of each reference at the start of the given block is the unification + /// of the value of the same reference at the end of its predecessor blocks. + fn find_starting_references(&mut self, block: BasicBlockId) -> Block { + let mut predecessors = self.cfg.predecessors(block); + + if let Some(first_predecessor) = predecessors.next() { + let mut first = self.blocks.get(&first_predecessor).cloned().unwrap_or_default(); + first.last_stores.clear(); + + // Note that we have to start folding with the first block as the accumulator. + // If we started with an empty block, an empty block union'd with any other block + // is always also empty so we'd never be able to track any references across blocks. + predecessors.fold(first, |block, predecessor| { + let predecessor = self.blocks.entry(predecessor).or_default(); + block.unify(predecessor) + }) + } else { + Block::default() + } + } + + /// Analyze a block with the given starting reference values. + /// + /// This will remove any known loads in the block and track the value of references + /// as they are stored to. When this function is finished, the value of each reference + /// at the end of this block will be remembered in `self.blocks`. + fn analyze_block(&mut self, block: BasicBlockId, mut references: Block) { + let instructions = self.inserter.function.dfg[block].take_instructions(); + + for instruction in instructions { + self.analyze_instruction(block, &mut references, instruction); + } + + self.handle_terminator(block, &mut references); + + // If there's only 1 block in the function total, we can remove any remaining last stores + // as well. We can't do this if there are multiple blocks since subsequent blocks may + // reference these stores. + if self.post_order.as_slice().len() == 1 { + self.remove_stores_that_do_not_alias_parameters(&references); + } + + self.blocks.insert(block, references); + } + + /// Add all instructions in `last_stores` to `self.instructions_to_remove` which do not + /// possibly alias any parameters of the given function. + fn remove_stores_that_do_not_alias_parameters(&mut self, references: &Block) { + let parameters = self.inserter.function.parameters().iter(); + let reference_parameters = parameters + .filter(|param| self.inserter.function.dfg.value_is_reference(**param)) + .collect::>(); + + for (allocation, instruction) in &references.last_stores { + if let Some(expression) = references.expressions.get(allocation) { + if let Some(aliases) = references.aliases.get(expression) { + let allocation_aliases_parameter = + aliases.any(|alias| reference_parameters.contains(&alias)); + + // If `allocation_aliases_parameter` is known to be false + if allocation_aliases_parameter == Some(false) { + self.instructions_to_remove.insert(*instruction); + } + } + } + } + } + + fn analyze_instruction( + &mut self, + block_id: BasicBlockId, + references: &mut Block, + mut instruction: InstructionId, + ) { + // If the instruction was simplified and optimized out of the program we shouldn't analyze + // it. Analyzing it could make tracking aliases less accurate if it is e.g. an ArrayGet + // call that used to hold references but has since been optimized out to a known result. + if let Some(new_id) = self.inserter.push_instruction(instruction, block_id) { + instruction = new_id; + } else { + return; + } + + match &self.inserter.function.dfg[instruction] { + Instruction::Load { address } => { + let address = self.inserter.function.dfg.resolve(*address); + + let result = self.inserter.function.dfg.instruction_results(instruction)[0]; + references.remember_dereference(self.inserter.function, address, result); + + // If the load is known, replace it with the known value and remove the load + if let Some(value) = references.get_known_value(address) { + let result = self.inserter.function.dfg.instruction_results(instruction)[0]; + self.inserter.map_value(result, value); + self.instructions_to_remove.insert(instruction); + } else { + references.mark_value_used(address, self.inserter.function); + } + } + Instruction::Store { address, value } => { + let address = self.inserter.function.dfg.resolve(*address); + let value = self.inserter.function.dfg.resolve(*value); + + self.check_array_aliasing(references, value); + + // If there was another store to this instruction without any (unremoved) loads or + // function calls in-between, we can remove the previous store. + if let Some(last_store) = references.last_stores.get(&address) { + self.instructions_to_remove.insert(*last_store); + } + + references.set_known_value(address, value); + references.last_stores.insert(address, instruction); + } + Instruction::Allocate => { + // Register the new reference + let result = self.inserter.function.dfg.instruction_results(instruction)[0]; + references.expressions.insert(result, Expression::Other(result)); + references.aliases.insert(Expression::Other(result), AliasSet::known(result)); + } + Instruction::ArrayGet { array, .. } => { + let result = self.inserter.function.dfg.instruction_results(instruction)[0]; + references.mark_value_used(*array, self.inserter.function); + + if self.inserter.function.dfg.value_is_reference(result) { + let array = self.inserter.function.dfg.resolve(*array); + let expression = Expression::ArrayElement(Box::new(Expression::Other(array))); + + if let Some(aliases) = references.aliases.get_mut(&expression) { + aliases.insert(result); + } + } + } + Instruction::ArraySet { array, value, .. } => { + references.mark_value_used(*array, self.inserter.function); + let element_type = self.inserter.function.dfg.type_of_value(*value); + + if Self::contains_references(&element_type) { + let result = self.inserter.function.dfg.instruction_results(instruction)[0]; + let array = self.inserter.function.dfg.resolve(*array); + + let expression = Expression::ArrayElement(Box::new(Expression::Other(array))); + + let mut aliases = if let Some(aliases) = references.aliases.get_mut(&expression) + { + aliases.clone() + } else if let Some((elements, _)) = + self.inserter.function.dfg.get_array_constant(array) + { + let aliases = references.collect_all_aliases(elements); + self.set_aliases(references, array, aliases.clone()); + aliases + } else { + AliasSet::unknown() + }; + + aliases.unify(&references.get_aliases_for_value(*value)); + + references.expressions.insert(result, expression.clone()); + references.aliases.insert(expression, aliases); + } + } + Instruction::Call { arguments, .. } => self.mark_all_unknown(arguments, references), + _ => (), + } + } + + fn check_array_aliasing(&self, references: &mut Block, array: ValueId) { + if let Some((elements, typ)) = self.inserter.function.dfg.get_array_constant(array) { + if Self::contains_references(&typ) { + // TODO: Check if type directly holds references or holds arrays that hold references + let expr = Expression::ArrayElement(Box::new(Expression::Other(array))); + references.expressions.insert(array, expr.clone()); + let aliases = references.aliases.entry(expr).or_default(); + + for element in elements { + aliases.insert(element); + } + } + } + } + + fn contains_references(typ: &Type) -> bool { + match typ { + Type::Numeric(_) => false, + Type::Function => false, + Type::Reference => true, + Type::Array(elements, _) | Type::Slice(elements) => { + elements.iter().any(Self::contains_references) + } + } + } + + fn set_aliases(&self, references: &mut Block, address: ValueId, new_aliases: AliasSet) { + let expression = + references.expressions.entry(address).or_insert(Expression::Other(address)); + let aliases = references.aliases.entry(expression.clone()).or_default(); + *aliases = new_aliases; + } + + fn mark_all_unknown(&self, values: &[ValueId], references: &mut Block) { + for value in values { + if self.inserter.function.dfg.value_is_reference(*value) { + let value = self.inserter.function.dfg.resolve(*value); + references.set_unknown(value); + references.mark_value_used(value, self.inserter.function); + } + } + } + + /// Remove any instructions in `self.instructions_to_remove` from the current function. + /// This is expected to contain any loads which were replaced and any stores which are + /// no longer needed. + fn remove_instructions(&mut self) { + // The order we iterate blocks in is not important + for block in self.post_order.as_slice() { + self.inserter.function.dfg[*block] + .instructions_mut() + .retain(|instruction| !self.instructions_to_remove.contains(instruction)); + } + } + + fn handle_terminator(&mut self, block: BasicBlockId, references: &mut Block) { + self.inserter.map_terminator_in_place(block); + + match self.inserter.function.dfg[block].unwrap_terminator() { + TerminatorInstruction::JmpIf { .. } => (), // Nothing to do + TerminatorInstruction::Jmp { destination, arguments, .. } => { + let destination_parameters = self.inserter.function.dfg[*destination].parameters(); + assert_eq!(destination_parameters.len(), arguments.len()); + + // Add an alias for each reference parameter + for (parameter, argument) in destination_parameters.iter().zip(arguments) { + if self.inserter.function.dfg.value_is_reference(*parameter) { + let argument = self.inserter.function.dfg.resolve(*argument); + + if let Some(expression) = references.expressions.get(&argument) { + if let Some(aliases) = references.aliases.get_mut(expression) { + // The argument reference is possibly aliased by this block parameter + aliases.insert(*parameter); + } + } + } + } + } + TerminatorInstruction::Return { return_values } => { + // Removing all `last_stores` for each returned reference is more important here + // than setting them all to ReferenceValue::Unknown since no other block should + // have a block with a Return terminator as a predecessor anyway. + self.mark_all_unknown(return_values, references); + } + } + } +} + +#[cfg(test)] +mod tests { + use std::rc::Rc; + + use acvm::FieldElement; + use im::vector; + + use crate::ssa::{ + function_builder::FunctionBuilder, + ir::{ + basic_block::BasicBlockId, + dfg::DataFlowGraph, + function::RuntimeType, + instruction::{BinaryOp, Instruction, Intrinsic, TerminatorInstruction}, + map::Id, + types::Type, + }, + }; + + #[test] + fn test_simple() { + // fn func() { + // b0(): + // v0 = allocate + // store [Field 1, Field 2] in v0 + // v1 = load v0 + // v2 = array_get v1, index 1 + // return v2 + // } + + let func_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); + let v0 = builder.insert_allocate(); + let one = builder.field_constant(FieldElement::one()); + let two = builder.field_constant(FieldElement::one()); + + let element_type = Rc::new(vec![Type::field()]); + let array_type = Type::Array(element_type, 2); + let array = builder.array_constant(vector![one, two], array_type.clone()); + + builder.insert_store(v0, array); + let v1 = builder.insert_load(v0, array_type); + let v2 = builder.insert_array_get(v1, one, Type::field()); + builder.terminate_with_return(vec![v2]); + + let ssa = builder.finish().mem2reg().fold_constants(); + + let func = ssa.main(); + let block_id = func.entry_block(); + + assert_eq!(count_loads(block_id, &func.dfg), 0); + assert_eq!(count_stores(block_id, &func.dfg), 0); + + let ret_val_id = match func.dfg[block_id].terminator().unwrap() { + TerminatorInstruction::Return { return_values } => return_values.first().unwrap(), + _ => unreachable!(), + }; + assert_eq!(func.dfg[*ret_val_id], func.dfg[two]); + } + + #[test] + fn test_simple_with_call() { + // fn func { + // b0(): + // v0 = allocate + // store v0, Field 1 + // v1 = load v0 + // call f0(v0) + // return v1 + // } + + let func_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); + let v0 = builder.insert_allocate(); + let one = builder.field_constant(FieldElement::one()); + builder.insert_store(v0, one); + let v1 = builder.insert_load(v0, Type::field()); + let f0 = builder.import_intrinsic_id(Intrinsic::AssertConstant); + builder.insert_call(f0, vec![v0], vec![]); + builder.terminate_with_return(vec![v1]); + + let ssa = builder.finish().mem2reg(); + + let func = ssa.main(); + let block_id = func.entry_block(); + + assert_eq!(count_loads(block_id, &func.dfg), 0); + assert_eq!(count_stores(block_id, &func.dfg), 1); + + let ret_val_id = match func.dfg[block_id].terminator().unwrap() { + TerminatorInstruction::Return { return_values } => return_values.first().unwrap(), + _ => unreachable!(), + }; + assert_eq!(func.dfg[*ret_val_id], func.dfg[one]); + } + + #[test] + fn test_simple_with_return() { + // fn func { + // b0(): + // v0 = allocate + // store v0, Field 1 + // return v0 + // } + + let func_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); + let v0 = builder.insert_allocate(); + let const_one = builder.field_constant(FieldElement::one()); + builder.insert_store(v0, const_one); + builder.terminate_with_return(vec![v0]); + + let ssa = builder.finish().mem2reg(); + + let func = ssa.main(); + let block_id = func.entry_block(); + + // Store is needed by the return value, and can't be removed + assert_eq!(count_stores(block_id, &func.dfg), 1); + let instructions = func.dfg[block_id].instructions(); + assert_eq!(instructions.len(), 2); + + let ret_val_id = match func.dfg[block_id].terminator().unwrap() { + TerminatorInstruction::Return { return_values } => *return_values.first().unwrap(), + _ => unreachable!(), + }; + + // Since the mem2reg pass simplifies as it goes, the id of the allocate instruction result + // is most likely no longer v0. We have to retrieve the new id here. + let alloca_id = func.dfg.instruction_results(instructions[0])[0]; + assert_eq!(ret_val_id, alloca_id); + } + + fn count_stores(block: BasicBlockId, dfg: &DataFlowGraph) -> usize { + dfg[block] + .instructions() + .iter() + .filter(|instruction_id| matches!(dfg[**instruction_id], Instruction::Store { .. })) + .count() + } + + fn count_loads(block: BasicBlockId, dfg: &DataFlowGraph) -> usize { + dfg[block] + .instructions() + .iter() + .filter(|instruction_id| matches!(dfg[**instruction_id], Instruction::Load { .. })) + .count() + } + + // Test that loads across multiple blocks are removed + #[test] + fn multiple_blocks() { + // fn main { + // b0(): + // v0 = allocate + // store Field 5 in v0 + // v1 = load v0 + // jmp b1(v1): + // b1(v2: Field): + // v3 = load v0 + // store Field 6 in v0 + // v4 = load v0 + // return v2, v3, v4 + // } + let main_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); + + let v0 = builder.insert_allocate(); + + let five = builder.field_constant(5u128); + builder.insert_store(v0, five); + + let v1 = builder.insert_load(v0, Type::field()); + let b1 = builder.insert_block(); + builder.terminate_with_jmp(b1, vec![v1]); + + builder.switch_to_block(b1); + let v2 = builder.add_block_parameter(b1, Type::field()); + let v3 = builder.insert_load(v0, Type::field()); + + let six = builder.field_constant(6u128); + builder.insert_store(v0, six); + let v4 = builder.insert_load(v0, Type::field()); + + builder.terminate_with_return(vec![v2, v3, v4]); + + let ssa = builder.finish(); + assert_eq!(ssa.main().reachable_blocks().len(), 2); + + // Expected result: + // acir fn main f0 { + // b0(): + // v7 = allocate + // store Field 5 at v7 + // jmp b1(Field 5) + // b1(v3: Field): + // store Field 6 at v7 + // return v3, Field 5, Field 6 + // } + let ssa = ssa.mem2reg(); + + let main = ssa.main(); + assert_eq!(main.reachable_blocks().len(), 2); + + // The loads should be removed + assert_eq!(count_loads(main.entry_block(), &main.dfg), 0); + assert_eq!(count_loads(b1, &main.dfg), 0); + + // Neither store is removed since they are each the last in the block and there are multiple blocks + assert_eq!(count_stores(main.entry_block(), &main.dfg), 1); + assert_eq!(count_stores(b1, &main.dfg), 1); + + // The jmp to b1 should also be a constant 5 now + match main.dfg[main.entry_block()].terminator() { + Some(TerminatorInstruction::Jmp { arguments, .. }) => { + assert_eq!(arguments.len(), 1); + let argument = + main.dfg.get_numeric_constant(arguments[0]).expect("Expected constant value"); + assert_eq!(argument.to_u128(), 5); + } + _ => unreachable!(), + }; + } + + // Test that a load in a predecessor block has been removed if the value + // is later stored in a successor block + #[test] + fn load_aliases_in_predecessor_block() { + // fn main { + // b0(): + // v0 = allocate + // store Field 0 at v0 + // v2 = allocate + // store v0 at v2 + // v3 = load v2 + // v4 = load v2 + // jmp b1() + // b1(): + // store Field 1 at v3 + // store Field 2 at v4 + // v8 = load v3 + // v9 = eq v8, Field 2 + // return + // } + let main_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); + + let v0 = builder.insert_allocate(); + + let zero = builder.field_constant(0u128); + builder.insert_store(v0, zero); + + let v2 = builder.insert_allocate(); + builder.insert_store(v2, v0); + + let v3 = builder.insert_load(v2, Type::field()); + let v4 = builder.insert_load(v2, Type::field()); + let b1 = builder.insert_block(); + builder.terminate_with_jmp(b1, vec![]); + + builder.switch_to_block(b1); + + let one = builder.field_constant(1u128); + builder.insert_store(v3, one); + + let two = builder.field_constant(2u128); + builder.insert_store(v4, two); + + let v8 = builder.insert_load(v3, Type::field()); + let _ = builder.insert_binary(v8, BinaryOp::Eq, two); + + builder.terminate_with_return(vec![]); + + let ssa = builder.finish(); + assert_eq!(ssa.main().reachable_blocks().len(), 2); + + // Expected result: + // acir fn main f0 { + // b0(): + // v9 = allocate + // store Field 0 at v9 + // v10 = allocate + // store v9 at v10 + // jmp b1() + // b1(): + // store Field 2 at v9 + // return + // } + let ssa = ssa.mem2reg(); + + let main = ssa.main(); + assert_eq!(main.reachable_blocks().len(), 2); + + // All loads should be removed + assert_eq!(count_loads(main.entry_block(), &main.dfg), 0); + assert_eq!(count_loads(b1, &main.dfg), 0); + + // Only the first store in b1 is removed since there is another store to the same reference + // in the same block, and the store is not needed before the later store. + assert_eq!(count_stores(main.entry_block(), &main.dfg), 2); + assert_eq!(count_stores(b1, &main.dfg), 1); + + let b1_instructions = main.dfg[b1].instructions(); + + // We expect the last eq to be optimized out + assert_eq!(b1_instructions.len(), 1); + } +} diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs new file mode 100644 index 00000000000..5477025e429 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs @@ -0,0 +1,76 @@ +use std::collections::BTreeSet; + +use crate::ssa::ir::value::ValueId; + +/// A set of possible aliases. Each ValueId in this set represents one possible value the reference +/// holding this AliasSet may be aliased to. This struct wrapper is provided so that when we take +/// the union of multiple alias sets, the result should be empty if any individual set is empty. +/// +/// Note that we distinguish between "definitely has no aliases" - `Some(BTreeSet::new())`, and +/// "unknown which aliases this may refer to" - `None`. +#[derive(Debug, Default, Clone)] +pub(super) struct AliasSet { + aliases: Option>, +} + +impl AliasSet { + pub(super) fn unknown() -> AliasSet { + Self { aliases: None } + } + + pub(super) fn known(value: ValueId) -> AliasSet { + let mut aliases = BTreeSet::new(); + aliases.insert(value); + Self { aliases: Some(aliases) } + } + + /// In rare cases, such as when creating an empty array of references, the set of aliases for a + /// particular value will be known to be zero, which is distinct from being unknown and + /// possibly referring to any alias. + pub(super) fn known_empty() -> AliasSet { + Self { aliases: Some(BTreeSet::new()) } + } + + pub(super) fn is_unknown(&self) -> bool { + self.aliases.is_none() + } + + /// Return the single known alias if there is exactly one. + /// Otherwise, return None. + pub(super) fn single_alias(&self) -> Option { + self.aliases + .as_ref() + .and_then(|aliases| (aliases.len() == 1).then(|| *aliases.first().unwrap())) + } + + /// Unify this alias set with another. The result of this set is empty if either set is empty. + /// Otherwise, it is the union of both alias sets. + pub(super) fn unify(&mut self, other: &Self) { + if let (Some(self_aliases), Some(other_aliases)) = (&mut self.aliases, &other.aliases) { + self_aliases.extend(other_aliases); + } else { + self.aliases = None; + } + } + + /// Inserts a new alias into this set if it is not unknown + pub(super) fn insert(&mut self, new_alias: ValueId) { + if let Some(aliases) = &mut self.aliases { + aliases.insert(new_alias); + } + } + + /// Returns `Some(true)` if `f` returns true for any known alias in this set. + /// If this alias set is unknown, None is returned. + pub(super) fn any(&self, f: impl FnMut(ValueId) -> bool) -> Option { + self.aliases.as_ref().map(|aliases| aliases.iter().copied().any(f)) + } + + pub(super) fn for_each(&self, mut f: impl FnMut(ValueId)) { + if let Some(aliases) = &self.aliases { + for alias in aliases { + f(*alias); + } + } + } +} diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg/block.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg/block.rs new file mode 100644 index 00000000000..22c5705b723 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg/block.rs @@ -0,0 +1,243 @@ +use std::{borrow::Cow, collections::BTreeMap}; + +use crate::ssa::ir::{ + function::Function, + instruction::{Instruction, InstructionId}, + value::ValueId, +}; + +use super::alias_set::AliasSet; + +/// A `Block` acts as a per-block context for the mem2reg pass. +/// Most notably, it contains the current alias set thought to track each +/// reference value if known, and it contains the expected ReferenceValue +/// for each ValueId. When a block is finished, the final values of these +/// are expected to match the values held by each ValueId at the very end +/// of a block. +#[derive(Debug, Default, Clone)] +pub(super) struct Block { + /// Maps a ValueId to the Expression it represents. + /// Multiple ValueIds can map to the same Expression, e.g. + /// dereferences to the same allocation. + pub(super) expressions: BTreeMap, + + /// Each expression is tracked as to how many aliases it + /// may have. If there is only 1, we can attempt to optimize + /// out any known loads to that alias. Note that "alias" here + /// includes the original reference as well. + pub(super) aliases: BTreeMap, + + /// Each allocate instruction result (and some reference block parameters) + /// will map to a Reference value which tracks whether the last value stored + /// to the reference is known. + pub(super) references: BTreeMap, + + /// The last instance of a `Store` instruction to each address in this block + pub(super) last_stores: BTreeMap, +} + +/// An `Expression` here is used to represent a canonical key +/// into the aliases map since otherwise two dereferences of the +/// same address will be given different ValueIds. +#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)] +pub(super) enum Expression { + Dereference(Box), + ArrayElement(Box), + Other(ValueId), +} + +/// Every reference's value is either Known and can be optimized away, or Unknown. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(super) enum ReferenceValue { + Unknown, + Known(ValueId), +} + +impl ReferenceValue { + fn unify(self, other: Self) -> Self { + if self == other { + self + } else { + ReferenceValue::Unknown + } + } +} + +impl Block { + /// If the given reference id points to a known value, return the value + pub(super) fn get_known_value(&self, address: ValueId) -> Option { + if let Some(expression) = self.expressions.get(&address) { + if let Some(aliases) = self.aliases.get(expression) { + // We could allow multiple aliases if we check that the reference + // value in each is equal. + if let Some(alias) = aliases.single_alias() { + if let Some(ReferenceValue::Known(value)) = self.references.get(&alias) { + return Some(*value); + } + } + } + } + None + } + + /// If the given address is known, set its value to `ReferenceValue::Known(value)`. + pub(super) fn set_known_value(&mut self, address: ValueId, value: ValueId) { + self.set_value(address, ReferenceValue::Known(value)); + } + + pub(super) fn set_unknown(&mut self, address: ValueId) { + self.set_value(address, ReferenceValue::Unknown); + } + + fn set_value(&mut self, address: ValueId, value: ReferenceValue) { + let expression = self.expressions.entry(address).or_insert(Expression::Other(address)); + let aliases = self.aliases.entry(expression.clone()).or_default(); + + if aliases.is_unknown() { + // uh-oh, we don't know at all what this reference refers to, could be anything. + // Now we have to invalidate every reference we know of + self.invalidate_all_references(); + } else if let Some(alias) = aliases.single_alias() { + self.references.insert(alias, value); + } else { + // More than one alias. We're not sure which it refers to so we have to + // conservatively invalidate all references it may refer to. + aliases.for_each(|alias| { + if let Some(reference_value) = self.references.get_mut(&alias) { + *reference_value = ReferenceValue::Unknown; + } + }); + } + } + + fn invalidate_all_references(&mut self) { + for reference_value in self.references.values_mut() { + *reference_value = ReferenceValue::Unknown; + } + + self.last_stores.clear(); + } + + pub(super) fn unify(mut self, other: &Self) -> Self { + for (value_id, expression) in &other.expressions { + if let Some(existing) = self.expressions.get(value_id) { + assert_eq!(existing, expression, "Expected expressions for {value_id} to be equal"); + } else { + self.expressions.insert(*value_id, expression.clone()); + } + } + + for (expression, new_aliases) in &other.aliases { + let expression = expression.clone(); + + self.aliases + .entry(expression) + .and_modify(|aliases| aliases.unify(new_aliases)) + .or_insert_with(|| new_aliases.clone()); + } + + // Keep only the references present in both maps. + let mut intersection = BTreeMap::new(); + for (value_id, reference) in &other.references { + if let Some(existing) = self.references.get(value_id) { + intersection.insert(*value_id, existing.unify(*reference)); + } + } + self.references = intersection; + + self + } + + /// Remember that `result` is the result of dereferencing `address`. This is important to + /// track aliasing when references are stored within other references. + pub(super) fn remember_dereference( + &mut self, + function: &Function, + address: ValueId, + result: ValueId, + ) { + if function.dfg.value_is_reference(result) { + if let Some(known_address) = self.get_known_value(address) { + self.expressions.insert(result, Expression::Other(known_address)); + } else { + let expression = Expression::Dereference(Box::new(Expression::Other(address))); + self.expressions.insert(result, expression); + // No known aliases to insert for this expression... can we find an alias + // even if we don't have a known address? If not we'll have to invalidate all + // known references if this reference is ever stored to. + } + } + } + + /// Iterate through each known alias of the given address and apply the function `f` to each. + fn for_each_alias_of( + &mut self, + address: ValueId, + mut f: impl FnMut(&mut Self, ValueId) -> T, + ) { + if let Some(expr) = self.expressions.get(&address) { + if let Some(aliases) = self.aliases.get(expr).cloned() { + aliases.for_each(|alias| { + f(self, alias); + }); + } + } + } + + fn keep_last_stores_for(&mut self, address: ValueId, function: &Function) { + let address = function.dfg.resolve(address); + self.keep_last_store(address, function); + self.for_each_alias_of(address, |t, alias| t.keep_last_store(alias, function)); + } + + fn keep_last_store(&mut self, address: ValueId, function: &Function) { + let address = function.dfg.resolve(address); + + if let Some(instruction) = self.last_stores.remove(&address) { + // Whenever we decide we want to keep a store instruction, we also need + // to go through its stored value and mark that used as well. + match &function.dfg[instruction] { + Instruction::Store { value, .. } => { + self.mark_value_used(*value, function); + } + other => { + unreachable!("last_store held an id of a non-store instruction: {other:?}") + } + } + } + } + + pub(super) fn mark_value_used(&mut self, value: ValueId, function: &Function) { + self.keep_last_stores_for(value, function); + + // We must do a recursive check for arrays since they're the only Values which may contain + // other ValueIds. + if let Some((array, _)) = function.dfg.get_array_constant(value) { + for value in array { + self.mark_value_used(value, function); + } + } + } + + /// Collect all aliases used by the given value list + pub(super) fn collect_all_aliases( + &self, + values: impl IntoIterator, + ) -> AliasSet { + let mut aliases = AliasSet::known_empty(); + for value in values { + aliases.unify(&self.get_aliases_for_value(value)); + } + aliases + } + + pub(super) fn get_aliases_for_value(&self, value: ValueId) -> Cow { + if let Some(expression) = self.expressions.get(&value) { + if let Some(aliases) = self.aliases.get(expression) { + return Cow::Borrowed(aliases); + } + } + + Cow::Owned(AliasSet::unknown()) + } +} diff --git a/crates/noirc_evaluator/src/ssa/opt/mod.rs b/compiler/noirc_evaluator/src/ssa/opt/mod.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/opt/mod.rs rename to compiler/noirc_evaluator/src/ssa/opt/mod.rs diff --git a/crates/noirc_evaluator/src/ssa/opt/simplify_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs similarity index 99% rename from crates/noirc_evaluator/src/ssa/opt/simplify_cfg.rs rename to compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs index ad257362da5..da6f0af2484 100644 --- a/crates/noirc_evaluator/src/ssa/opt/simplify_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs @@ -151,13 +151,13 @@ fn try_inline_into_predecessor( #[cfg(test)] mod test { use crate::ssa::{ + function_builder::FunctionBuilder, ir::{ function::RuntimeType, instruction::{BinaryOp, TerminatorInstruction}, map::Id, types::Type, }, - ssa_builder::FunctionBuilder, }; #[test] diff --git a/crates/noirc_evaluator/src/ssa/opt/unrolling.rs b/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs similarity index 96% rename from crates/noirc_evaluator/src/ssa/opt/unrolling.rs rename to compiler/noirc_evaluator/src/ssa/opt/unrolling.rs index 9bf62bda1cb..552d9ef6f4b 100644 --- a/crates/noirc_evaluator/src/ssa/opt/unrolling.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs @@ -12,7 +12,7 @@ //! //! Note that this pass also often creates superfluous jmp instructions in the //! program that will need to be removed by a later simplify cfg pass. -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use crate::{ errors::RuntimeError, @@ -31,12 +31,22 @@ use crate::{ ssa_gen::Ssa, }, }; +use fxhash::FxHashMap as HashMap; impl Ssa { /// Unroll all loops in each SSA function. /// If any loop cannot be unrolled, it is left as-is or in a partially unrolled state. pub(crate) fn unroll_loops(mut self) -> Result { for function in self.functions.values_mut() { + // Loop unrolling in brillig can lead to a code explosion currently. This can + // also be true for ACIR, but we have no alternative to unrolling in ACIR. + // Brillig also generally prefers smaller code rather than faster code. + if function.runtime() == RuntimeType::Brillig { + continue; + } + + // This check is always true with the addition of the above guard, but I'm + // keeping it in case the guard on brillig functions is ever removed. let abort_on_error = function.runtime() == RuntimeType::Acir; find_all_loops(function).unroll_each_loop(function, abort_on_error)?; } @@ -44,7 +54,7 @@ impl Ssa { } } -pub(crate) struct Loop { +struct Loop { /// The header block of a loop is the block which dominates all the /// other blocks in the loop. header: BasicBlockId, @@ -57,12 +67,12 @@ pub(crate) struct Loop { pub(crate) blocks: HashSet, } -pub(crate) struct Loops { +struct Loops { /// The loops that failed to be unrolled so that we do not try to unroll them again. /// Each loop is identified by its header block id. failed_to_unroll: HashSet, - pub(crate) yet_to_unroll: Vec, + yet_to_unroll: Vec, modified_blocks: HashSet, cfg: ControlFlowGraph, dom_tree: DominatorTree, @@ -70,7 +80,7 @@ pub(crate) struct Loops { /// Find a loop in the program by finding a node that dominates any predecessor node. /// The edge where this happens will be the back-edge of the loop. -pub(crate) fn find_all_loops(function: &Function) -> Loops { +fn find_all_loops(function: &Function) -> Loops { let cfg = ControlFlowGraph::with_function(function); let post_order = PostOrder::with_function(function); let mut dom_tree = DominatorTree::with_cfg_and_post_order(&cfg, &post_order); @@ -307,9 +317,9 @@ impl<'f> LoopIteration<'f> { loop_, insert_block, source_block, - blocks: HashMap::new(), - original_blocks: HashMap::new(), - visited_blocks: HashSet::new(), + blocks: HashMap::default(), + original_blocks: HashMap::default(), + visited_blocks: HashSet::default(), induction_value: None, } } @@ -454,8 +464,8 @@ impl<'f> LoopIteration<'f> { #[cfg(test)] mod tests { use crate::ssa::{ + function_builder::FunctionBuilder, ir::{function::RuntimeType, instruction::BinaryOp, map::Id, types::Type}, - ssa_builder::FunctionBuilder, }; #[test] @@ -536,7 +546,7 @@ mod tests { builder.switch_to_block(b5); let v4 = builder.insert_binary(v0, BinaryOp::Add, v2); let v5 = builder.insert_binary(ten, BinaryOp::Lt, v4); - builder.insert_constrain(v5); + builder.insert_constrain(v5, one, None); let v6 = builder.insert_binary(v2, BinaryOp::Add, one); builder.terminate_with_jmp(b4, vec![v6]); diff --git a/crates/noirc_evaluator/src/ssa/ssa_gen/context.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs similarity index 98% rename from crates/noirc_evaluator/src/ssa/ssa_gen/context.rs rename to compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs index 0b3ee5b9acf..e7f8131bc35 100644 --- a/crates/noirc_evaluator/src/ssa/ssa_gen/context.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::rc::Rc; use std::sync::{Mutex, RwLock}; @@ -9,6 +8,7 @@ use noirc_frontend::monomorphization::ast::{self, LocalId, Parameters}; use noirc_frontend::monomorphization::ast::{FuncId, Program}; use noirc_frontend::{BinaryOpKind, Signedness}; +use crate::ssa::function_builder::FunctionBuilder; use crate::ssa::ir::dfg::DataFlowGraph; use crate::ssa::ir::function::FunctionId as IrFunctionId; use crate::ssa::ir::function::{Function, RuntimeType}; @@ -16,9 +16,9 @@ use crate::ssa::ir::instruction::{BinaryOp, Endian, Intrinsic}; use crate::ssa::ir::map::AtomicCounter; use crate::ssa::ir::types::{NumericType, Type}; use crate::ssa::ir::value::ValueId; -use crate::ssa::ssa_builder::FunctionBuilder; use super::value::{Tree, Value, Values}; +use fxhash::FxHashMap as HashMap; /// The FunctionContext is the main context object for translating a /// function into SSA form during the SSA-gen pass. @@ -94,7 +94,7 @@ impl<'a> FunctionContext<'a> { .1; let builder = FunctionBuilder::new(function_name, function_id, runtime); - let mut this = Self { definitions: HashMap::new(), builder, shared_context }; + let mut this = Self { definitions: HashMap::default(), builder, shared_context }; this.add_parameters_to_scope(parameters); this } @@ -247,7 +247,7 @@ impl<'a> FunctionContext<'a> { self.builder.insert_binary(lhs, BinaryOp::Mul, pow) } - /// Insert ssa instructions which computes lhs << rhs by doing lhs/2^rhs + /// Insert ssa instructions which computes lhs >> rhs by doing lhs/2^rhs fn insert_shift_right(&mut self, lhs: ValueId, rhs: ValueId) -> ValueId { let base = self.builder.field_constant(FieldElement::from(2_u128)); let pow = self.pow(base, rhs); @@ -306,6 +306,7 @@ impl<'a> FunctionContext<'a> { if operator_requires_swapped_operands(operator) { std::mem::swap(&mut lhs, &mut rhs); } + self.builder.set_location(location).insert_binary(lhs, op, rhs) } }; @@ -658,14 +659,19 @@ impl<'a> FunctionContext<'a> { match lvalue { LValue::Ident => unreachable!("Cannot assign to a variable without a reference"), LValue::Index { old_array: mut array, index, array_lvalue, location } => { - array = self.assign_lvalue_index(new_value, array, index, location); + array = self.assign_lvalue_index(new_value, array, index, None, location); self.assign_new_value(*array_lvalue, array.into()); } LValue::SliceIndex { old_slice: slice, index, slice_lvalue, location } => { let mut slice_values = slice.into_value_list(self); - slice_values[1] = - self.assign_lvalue_index(new_value, slice_values[1], index, location); + slice_values[1] = self.assign_lvalue_index( + new_value, + slice_values[1], + index, + Some(slice_values[0]), + location, + ); // The size of the slice does not change in a slice index assignment so we can reuse the same length value let new_slice = Tree::Branch(vec![slice_values[0].into(), slice_values[1].into()]); @@ -686,6 +692,7 @@ impl<'a> FunctionContext<'a> { new_value: Values, mut array: ValueId, index: ValueId, + length: Option, location: Location, ) -> ValueId { let element_size = self.builder.field_constant(self.element_size(array)); @@ -697,7 +704,7 @@ impl<'a> FunctionContext<'a> { new_value.for_each(|value| { let value = value.eval(self); - array = self.builder.insert_array_set(array, index, value); + array = self.builder.insert_array_set(array, index, value, length); index = self.builder.insert_binary(index, BinaryOp::Add, one); }); array diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs new file mode 100644 index 00000000000..652869bdc9d --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs @@ -0,0 +1,563 @@ +mod context; +mod program; +mod value; + +pub(crate) use program::Ssa; + +use context::SharedContext; +use iter_extended::vecmap; +use noirc_errors::Location; +use noirc_frontend::{ + monomorphization::ast::{self, Binary, Expression, Program}, + BinaryOpKind, +}; + +use crate::ssa::ir::types::NumericType; + +use self::{ + context::FunctionContext, + value::{Tree, Values}, +}; + +use super::ir::{function::RuntimeType, instruction::BinaryOp, types::Type, value::ValueId}; + +/// Generates SSA for the given monomorphized program. +/// +/// This function will generate the SSA but does not perform any optimizations on it. +pub(crate) fn generate_ssa(program: Program) -> Ssa { + let context = SharedContext::new(program); + + let main_id = Program::main_id(); + let main = context.program.main(); + + // Queue the main function for compilation + context.get_or_queue_function(main_id); + + let mut function_context = FunctionContext::new( + main.name.clone(), + &main.parameters, + if main.unconstrained { RuntimeType::Brillig } else { RuntimeType::Acir }, + &context, + ); + function_context.codegen_function_body(&main.body); + + // Main has now been compiled and any other functions referenced within have been added to the + // function queue as they were found in codegen_ident. This queueing will happen each time a + // previously-unseen function is found so we need now only continue popping from this queue + // to generate SSA for each function used within the program. + while let Some((src_function_id, dest_id)) = context.pop_next_function_in_queue() { + let function = &context.program[src_function_id]; + function_context.new_function(dest_id, function); + function_context.codegen_function_body(&function.body); + } + + function_context.builder.finish() +} + +impl<'a> FunctionContext<'a> { + /// Codegen a function's body and set its return value to that of its last parameter. + /// For functions returning nothing, this will be an empty list. + fn codegen_function_body(&mut self, body: &Expression) { + let return_value = self.codegen_expression(body); + let results = return_value.into_value_list(self); + self.builder.terminate_with_return(results); + } + + fn codegen_expression(&mut self, expr: &Expression) -> Values { + match expr { + Expression::Ident(ident) => self.codegen_ident(ident), + Expression::Literal(literal) => self.codegen_literal(literal), + Expression::Block(block) => self.codegen_block(block), + Expression::Unary(unary) => self.codegen_unary(unary), + Expression::Binary(binary) => self.codegen_binary(binary), + Expression::Index(index) => self.codegen_index(index), + Expression::Cast(cast) => self.codegen_cast(cast), + Expression::For(for_expr) => self.codegen_for(for_expr), + Expression::If(if_expr) => self.codegen_if(if_expr), + Expression::Tuple(tuple) => self.codegen_tuple(tuple), + Expression::ExtractTupleField(tuple, index) => { + self.codegen_extract_tuple_field(tuple, *index) + } + Expression::Call(call) => self.codegen_call(call), + Expression::Let(let_expr) => self.codegen_let(let_expr), + Expression::Constrain(expr, location, assert_message) => { + self.codegen_constrain(expr, *location, assert_message.clone()) + } + Expression::Assign(assign) => self.codegen_assign(assign), + Expression::Semi(semi) => self.codegen_semi(semi), + } + } + + /// Codegen any non-tuple expression so that we can unwrap the Values + /// tree to return a single value for use with most SSA instructions. + fn codegen_non_tuple_expression(&mut self, expr: &Expression) -> ValueId { + self.codegen_expression(expr).into_leaf().eval(self) + } + + /// Codegen a reference to an ident. + /// The only difference between this and codegen_ident is that if the variable is mutable + /// as in `let mut var = ...;` the `Value::Mutable` will be returned directly instead of + /// being automatically loaded from. This is needed when taking the reference of a variable + /// to reassign to it. Note that mutable references `let x = &mut ...;` do not require this + /// since they are not automatically loaded from and must be explicitly dereferenced. + fn codegen_ident_reference(&mut self, ident: &ast::Ident) -> Values { + match &ident.definition { + ast::Definition::Local(id) => self.lookup(*id), + ast::Definition::Function(id) => self.get_or_queue_function(*id), + ast::Definition::Oracle(name) => self.builder.import_foreign_function(name).into(), + ast::Definition::Builtin(name) | ast::Definition::LowLevel(name) => { + match self.builder.import_intrinsic(name) { + Some(builtin) => builtin.into(), + None => panic!("No builtin function named '{name}' found"), + } + } + } + } + + /// Codegen an identifier, automatically loading its value if it is mutable. + fn codegen_ident(&mut self, ident: &ast::Ident) -> Values { + self.codegen_ident_reference(ident).map(|value| value.eval(self).into()) + } + + fn codegen_literal(&mut self, literal: &ast::Literal) -> Values { + match literal { + ast::Literal::Array(array) => { + let elements = vecmap(&array.contents, |element| self.codegen_expression(element)); + + let typ = Self::convert_type(&array.typ).flatten(); + match array.typ { + ast::Type::Array(_, _) => self.codegen_array(elements, typ[0].clone()), + ast::Type::Slice(_) => { + let slice_length = + self.builder.field_constant(array.contents.len() as u128); + let slice_contents = self.codegen_array(elements, typ[1].clone()); + Tree::Branch(vec![slice_length.into(), slice_contents]) + } + _ => unreachable!( + "ICE: array literal type must be an array or a slice, but got {}", + array.typ + ), + } + } + ast::Literal::Integer(value, typ) => { + let typ = Self::convert_non_tuple_type(typ); + self.builder.numeric_constant(*value, typ).into() + } + ast::Literal::Bool(value) => { + self.builder.numeric_constant(*value as u128, Type::bool()).into() + } + ast::Literal::Str(string) => { + let elements = vecmap(string.as_bytes(), |byte| { + self.builder.numeric_constant(*byte as u128, Type::field()).into() + }); + let typ = Self::convert_non_tuple_type(&ast::Type::String(elements.len() as u64)); + self.codegen_array(elements, typ) + } + ast::Literal::FmtStr(string, number_of_fields, fields) => { + // A caller needs multiple pieces of information to make use of a format string + // The message string, the number of fields to be formatted, and the fields themselves + let string = Expression::Literal(ast::Literal::Str(string.clone())); + let number_of_fields = Expression::Literal(ast::Literal::Integer( + (*number_of_fields as u128).into(), + ast::Type::Field, + )); + let fields = *fields.clone(); + let fmt_str_tuple = &[string, number_of_fields, fields]; + self.codegen_tuple(fmt_str_tuple) + } + } + } + + /// Codegen an array by allocating enough space for each element and inserting separate + /// store instructions until each element is stored. The store instructions will be separated + /// by add instructions to calculate the new offset address to store to next. + /// + /// In the case of arrays of structs, the structs are flattened such that each field will be + /// stored next to the other fields in memory. So an array such as [(1, 2), (3, 4)] is + /// stored the same as the array [1, 2, 3, 4]. + /// + /// The value returned from this function is always that of the allocate instruction. + fn codegen_array(&mut self, elements: Vec, typ: Type) -> Values { + let mut array = im::Vector::new(); + + for element in elements { + element.for_each(|element| { + let element = element.eval(self); + array.push_back(element); + }); + } + + self.builder.array_constant(array, typ).into() + } + + fn codegen_block(&mut self, block: &[Expression]) -> Values { + let mut result = Self::unit_value(); + for expr in block { + result = self.codegen_expression(expr); + } + result + } + + fn codegen_unary(&mut self, unary: &ast::Unary) -> Values { + match unary.operator { + noirc_frontend::UnaryOp::Not => { + let rhs = self.codegen_expression(&unary.rhs); + let rhs = rhs.into_leaf().eval(self); + self.builder.insert_not(rhs).into() + } + noirc_frontend::UnaryOp::Minus => { + let rhs = self.codegen_expression(&unary.rhs); + let rhs = rhs.into_leaf().eval(self); + let typ = self.builder.type_of_value(rhs); + let zero = self.builder.numeric_constant(0u128, typ); + self.insert_binary( + zero, + noirc_frontend::BinaryOpKind::Subtract, + rhs, + unary.location, + ) + } + noirc_frontend::UnaryOp::MutableReference => { + self.codegen_reference(&unary.rhs).map(|rhs| { + match rhs { + value::Value::Normal(value) => { + let alloc = self.builder.insert_allocate(); + self.builder.insert_store(alloc, value); + Tree::Leaf(value::Value::Normal(alloc)) + } + // NOTE: The `.into()` here converts the Value::Mutable into + // a Value::Normal so it is no longer automatically dereferenced. + value::Value::Mutable(reference, _) => reference.into(), + } + }) + } + noirc_frontend::UnaryOp::Dereference { .. } => { + let rhs = self.codegen_expression(&unary.rhs); + self.dereference(&rhs, &unary.result_type) + } + } + } + + fn dereference(&mut self, values: &Values, element_type: &ast::Type) -> Values { + let element_types = Self::convert_type(element_type); + values.map_both(element_types, |value, element_type| { + let reference = value.eval(self); + self.builder.insert_load(reference, element_type).into() + }) + } + + fn codegen_reference(&mut self, expr: &Expression) -> Values { + match expr { + Expression::Ident(ident) => self.codegen_ident_reference(ident), + Expression::ExtractTupleField(tuple, index) => { + let tuple = self.codegen_reference(tuple); + Self::get_field(tuple, *index) + } + other => self.codegen_expression(other), + } + } + + fn codegen_binary(&mut self, binary: &ast::Binary) -> Values { + let lhs = self.codegen_non_tuple_expression(&binary.lhs); + let rhs = self.codegen_non_tuple_expression(&binary.rhs); + self.insert_binary(lhs, binary.operator, rhs, binary.location) + } + + fn codegen_index(&mut self, index: &ast::Index) -> Values { + let array_or_slice = self.codegen_expression(&index.collection).into_value_list(self); + let index_value = self.codegen_non_tuple_expression(&index.index); + // Slices are represented as a tuple in the form: (length, slice contents). + // Thus, slices require two value ids for their representation. + let (array, slice_length) = if array_or_slice.len() > 1 { + (array_or_slice[1], Some(array_or_slice[0])) + } else { + (array_or_slice[0], None) + }; + self.codegen_array_index( + array, + index_value, + &index.element_type, + index.location, + slice_length, + ) + } + + /// This is broken off from codegen_index so that it can also be + /// used to codegen a LValue::Index. + /// + /// Set load_result to true to load from each relevant index of the array + /// (it may be multiple in the case of tuples). Set it to false to instead + /// return a reference to each element, for use with the store instruction. + fn codegen_array_index( + &mut self, + array: super::ir::value::ValueId, + index: super::ir::value::ValueId, + element_type: &ast::Type, + location: Location, + length: Option, + ) -> Values { + // base_index = index * type_size + let type_size = Self::convert_type(element_type).size_of_type(); + let type_size = self.builder.field_constant(type_size as u128); + let base_index = + self.builder.set_location(location).insert_binary(index, BinaryOp::Mul, type_size); + + let mut field_index = 0u128; + Self::map_type(element_type, |typ| { + let offset = self.make_offset(base_index, field_index); + field_index += 1; + + let array_type = &self.builder.type_of_value(array); + match array_type { + Type::Slice(_) => { + self.codegen_slice_access_check(index, length); + } + Type::Array(..) => { + // Nothing needs to done to prepare an array access on an array + } + _ => unreachable!("must have array or slice but got {array_type}"), + } + self.builder.insert_array_get(array, offset, typ).into() + }) + } + + /// Prepare a slice access. + /// Check that the index being used to access a slice element + /// is less than the dynamic slice length. + fn codegen_slice_access_check( + &mut self, + index: super::ir::value::ValueId, + length: Option, + ) { + let array_len = length.expect("ICE: a length must be supplied for indexing slices"); + // Check the type of the index value for valid comparisons + let array_len = match self.builder.type_of_value(index) { + Type::Numeric(numeric_type) => match numeric_type { + // If the index itself is an integer, keep the array length as a Field + NumericType::Unsigned { .. } | NumericType::Signed { .. } => array_len, + // If the index and the array length are both Fields we will not be able to perform a less than comparison on them. + // Thus, we cast the array length to a u64 before performing the less than comparison + NumericType::NativeField => self + .builder + .insert_cast(array_len, Type::Numeric(NumericType::Unsigned { bit_size: 64 })), + }, + _ => unreachable!("ICE: array index must be a numeric type"), + }; + + let is_offset_out_of_bounds = self.builder.insert_binary(index, BinaryOp::Lt, array_len); + let true_const = self.builder.numeric_constant(true, Type::bool()); + self.builder.insert_constrain(is_offset_out_of_bounds, true_const, None); + } + + fn codegen_cast(&mut self, cast: &ast::Cast) -> Values { + let lhs = self.codegen_non_tuple_expression(&cast.lhs); + let typ = Self::convert_non_tuple_type(&cast.r#type); + self.builder.set_location(cast.location); + self.builder.insert_cast(lhs, typ).into() + } + + /// Codegens a for loop, creating three new blocks in the process. + /// The return value of a for loop is always a unit literal. + /// + /// For example, the loop `for i in start .. end { body }` is codegen'd as: + /// + /// v0 = ... codegen start ... + /// v1 = ... codegen end ... + /// br loop_entry(v0) + /// loop_entry(i: Field): + /// v2 = lt i v1 + /// brif v2, then: loop_body, else: loop_end + /// loop_body(): + /// v3 = ... codegen body ... + /// v4 = add 1, i + /// br loop_entry(v4) + /// loop_end(): + /// ... This is the current insert point after codegen_for finishes ... + fn codegen_for(&mut self, for_expr: &ast::For) -> Values { + let loop_entry = self.builder.insert_block(); + let loop_body = self.builder.insert_block(); + let loop_end = self.builder.insert_block(); + + // this is the 'i' in `for i in start .. end { block }` + let index_type = Self::convert_non_tuple_type(&for_expr.index_type); + let loop_index = self.builder.add_block_parameter(loop_entry, index_type); + + self.builder.set_location(for_expr.start_range_location); + let start_index = self.codegen_non_tuple_expression(&for_expr.start_range); + + self.builder.set_location(for_expr.end_range_location); + let end_index = self.codegen_non_tuple_expression(&for_expr.end_range); + + // Set the location of the initial jmp instruction to the start range. This is the location + // used to issue an error if the start range cannot be determined at compile-time. + self.builder.set_location(for_expr.start_range_location); + self.builder.terminate_with_jmp(loop_entry, vec![start_index]); + + // Compile the loop entry block + self.builder.switch_to_block(loop_entry); + + // Set the location of the ending Lt instruction and the jmpif back-edge of the loop to the + // end range. These are the instructions used to issue an error if the end of the range + // cannot be determined at compile-time. + self.builder.set_location(for_expr.end_range_location); + let jump_condition = self.builder.insert_binary(loop_index, BinaryOp::Lt, end_index); + self.builder.terminate_with_jmpif(jump_condition, loop_body, loop_end); + + // Compile the loop body + self.builder.switch_to_block(loop_body); + self.define(for_expr.index_variable, loop_index.into()); + self.codegen_expression(&for_expr.block); + let new_loop_index = self.make_offset(loop_index, 1); + self.builder.terminate_with_jmp(loop_entry, vec![new_loop_index]); + + // Finish by switching back to the end of the loop + self.builder.switch_to_block(loop_end); + Self::unit_value() + } + + /// Codegens an if expression, handling the case of what to do if there is no 'else'. + /// + /// For example, the expression `if cond { a } else { b }` is codegen'd as: + /// + /// v0 = ... codegen cond ... + /// brif v0, then: then_block, else: else_block + /// then_block(): + /// v1 = ... codegen a ... + /// br end_if(v1) + /// else_block(): + /// v2 = ... codegen b ... + /// br end_if(v2) + /// end_if(v3: ?): // Type of v3 matches the type of a and b + /// ... This is the current insert point after codegen_if finishes ... + /// + /// As another example, the expression `if cond { a }` is codegen'd as: + /// + /// v0 = ... codegen cond ... + /// brif v0, then: then_block, else: end_block + /// then_block: + /// v1 = ... codegen a ... + /// br end_if() + /// end_if: // No block parameter is needed. Without an else, the unit value is always returned. + /// ... This is the current insert point after codegen_if finishes ... + fn codegen_if(&mut self, if_expr: &ast::If) -> Values { + let condition = self.codegen_non_tuple_expression(&if_expr.condition); + + let then_block = self.builder.insert_block(); + let else_block = self.builder.insert_block(); + + self.builder.terminate_with_jmpif(condition, then_block, else_block); + + self.builder.switch_to_block(then_block); + let then_value = self.codegen_expression(&if_expr.consequence); + + let mut result = Self::unit_value(); + + if let Some(alternative) = &if_expr.alternative { + let end_block = self.builder.insert_block(); + let then_values = then_value.into_value_list(self); + self.builder.terminate_with_jmp(end_block, then_values); + + self.builder.switch_to_block(else_block); + let else_value = self.codegen_expression(alternative); + let else_values = else_value.into_value_list(self); + self.builder.terminate_with_jmp(end_block, else_values); + + // Create block arguments for the end block as needed to branch to + // with our then and else value. + result = Self::map_type(&if_expr.typ, |typ| { + self.builder.add_block_parameter(end_block, typ).into() + }); + + // Must also set the then block to jmp to the end now + self.builder.switch_to_block(end_block); + } else { + // In the case we have no 'else', the 'else' block is actually the end block. + self.builder.terminate_with_jmp(else_block, vec![]); + self.builder.switch_to_block(else_block); + } + + result + } + + fn codegen_tuple(&mut self, tuple: &[Expression]) -> Values { + Tree::Branch(vecmap(tuple, |expr| self.codegen_expression(expr))) + } + + fn codegen_extract_tuple_field(&mut self, tuple: &Expression, field_index: usize) -> Values { + let tuple = self.codegen_expression(tuple); + Self::get_field(tuple, field_index) + } + + /// Generate SSA for a function call. Note that calls to built-in functions + /// and intrinsics are also represented by the function call instruction. + fn codegen_call(&mut self, call: &ast::Call) -> Values { + let function = self.codegen_non_tuple_expression(&call.func); + let arguments = call + .arguments + .iter() + .flat_map(|argument| self.codegen_expression(argument).into_value_list(self)) + .collect(); + + self.insert_call(function, arguments, &call.return_type, call.location) + } + + /// Generate SSA for the given variable. + /// If the variable is immutable, no special handling is necessary and we can return the given + /// ValueId directly. If it is mutable, we'll need to allocate space for the value and store + /// the initial value before returning the allocate instruction. + fn codegen_let(&mut self, let_expr: &ast::Let) -> Values { + let mut values = self.codegen_expression(&let_expr.expression); + + if let_expr.mutable { + values = values.map(|value| { + let value = value.eval(self); + Tree::Leaf(self.new_mutable_variable(value)) + }); + } + + self.define(let_expr.id, values); + Self::unit_value() + } + + fn codegen_constrain( + &mut self, + expr: &Expression, + location: Location, + assert_message: Option, + ) -> Values { + match expr { + // If we're constraining an equality to be true then constrain the two sides directly. + Expression::Binary(Binary { lhs, operator, rhs, .. }) + if operator == &BinaryOpKind::Equal => + { + let lhs = self.codegen_non_tuple_expression(lhs); + let rhs = self.codegen_non_tuple_expression(rhs); + self.builder.set_location(location).insert_constrain(lhs, rhs, assert_message); + } + + _ => { + let expr = self.codegen_non_tuple_expression(expr); + let true_literal = self.builder.numeric_constant(true, Type::bool()); + self.builder.set_location(location).insert_constrain( + expr, + true_literal, + assert_message, + ); + } + } + Self::unit_value() + } + + fn codegen_assign(&mut self, assign: &ast::Assign) -> Values { + let lhs = self.extract_current_value(&assign.lvalue); + let rhs = self.codegen_expression(&assign.expression); + + self.assign_new_value(lhs, rhs); + Self::unit_value() + } + + fn codegen_semi(&mut self, expr: &Expression) -> Values { + self.codegen_expression(expr); + Self::unit_value() + } +} diff --git a/crates/noirc_evaluator/src/ssa/ssa_gen/program.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/ssa_gen/program.rs rename to compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs diff --git a/crates/noirc_evaluator/src/ssa/ssa_gen/value.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/value.rs similarity index 100% rename from crates/noirc_evaluator/src/ssa/ssa_gen/value.rs rename to compiler/noirc_evaluator/src/ssa/ssa_gen/value.rs diff --git a/compiler/noirc_frontend/Cargo.toml b/compiler/noirc_frontend/Cargo.toml new file mode 100644 index 00000000000..1cb6e0c5c51 --- /dev/null +++ b/compiler/noirc_frontend/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "noirc_frontend" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +acvm.workspace = true +noirc_errors.workspace = true +noirc_printable_type.workspace = true +fm.workspace = true +arena.workspace = true +iter-extended.workspace = true +chumsky.workspace = true +thiserror.workspace = true +smol_str.workspace = true +serde_json.workspace = true +rustc-hash = "1.1.0" +small-ord-set = "0.1.3" +regex = "1.9.1" + +[dev-dependencies] +strum = "0.24" +strum_macros = "0.24" + +[features] +aztec = [] \ No newline at end of file diff --git a/crates/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs similarity index 90% rename from crates/noirc_frontend/src/ast/expression.rs rename to compiler/noirc_frontend/src/ast/expression.rs index 8b15f6e3b9d..9b695eb3e59 100644 --- a/crates/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -1,9 +1,9 @@ use std::fmt::Display; -use crate::token::{Attribute, Token}; +use crate::token::{Attributes, Token}; use crate::{ Distinctness, Ident, Path, Pattern, Recoverable, Statement, TraitConstraint, UnresolvedType, - Visibility, + UnresolvedTypeData, Visibility, }; use acvm::FieldElement; use iter_extended::vecmap; @@ -351,8 +351,9 @@ pub struct Lambda { pub struct FunctionDefinition { pub name: Ident, - // XXX: Currently we only have one attribute defined. If more attributes are needed per function, we can make this a vector and make attribute definition more expressive - pub attribute: Option, + // The `Attributes` container holds both `primary` (ones that change the function kind) + // and `secondary` attributes (ones that do not change the function kind) + pub attributes: Attributes, /// True if this function was defined with the 'open' keyword pub is_open: bool, @@ -377,7 +378,7 @@ pub enum FunctionReturnType { /// Returns type is not specified. Default(Span), /// Everything else. - Ty(UnresolvedType, Span), + Ty(UnresolvedType), } /// Describes the types of smart contract functions that are allowed. @@ -626,32 +627,80 @@ impl Display for Lambda { } } +impl FunctionDefinition { + pub fn normal( + name: &Ident, + generics: &UnresolvedGenerics, + parameters: &[(Ident, UnresolvedType)], + body: &BlockExpression, + where_clause: &[TraitConstraint], + return_type: &FunctionReturnType, + ) -> FunctionDefinition { + let p = parameters + .iter() + .map(|(ident, unresolved_type)| { + (Pattern::Identifier(ident.clone()), unresolved_type.clone(), Visibility::Private) + }) + .collect(); + FunctionDefinition { + name: name.clone(), + attributes: Attributes::empty(), + is_open: false, + is_internal: false, + is_unconstrained: false, + generics: generics.clone(), + parameters: p, + body: body.clone(), + span: name.span(), + where_clause: where_clause.to_vec(), + return_type: return_type.clone(), + return_visibility: Visibility::Private, + return_distinctness: Distinctness::DuplicationAllowed, + } + } +} + impl Display for FunctionDefinition { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(attribute) = &self.attribute { - writeln!(f, "{attribute}")?; - } + writeln!(f, "{:?}", self.attributes)?; let parameters = vecmap(&self.parameters, |(name, r#type, visibility)| { format!("{name}: {visibility} {type}") }); + let where_clause = vecmap(&self.where_clause, ToString::to_string); + let where_clause_str = if !where_clause.is_empty() { + format!("where {}", where_clause.join(", ")) + } else { + "".to_string() + }; + write!( f, - "fn {}({}) -> {} {}", + "fn {}({}) -> {} {} {}", self.name, parameters.join(", "), self.return_type, + where_clause_str, self.body ) } } +impl FunctionReturnType { + pub fn get_type(&self) -> &UnresolvedTypeData { + match self { + FunctionReturnType::Default(_span) => &UnresolvedTypeData::Unit, + FunctionReturnType::Ty(typ) => &typ.typ, + } + } +} + impl Display for FunctionReturnType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { FunctionReturnType::Default(_) => f.write_str(""), - FunctionReturnType::Ty(ty, _) => write!(f, "{ty}"), + FunctionReturnType::Ty(ty) => write!(f, "{ty}"), } } } diff --git a/compiler/noirc_frontend/src/ast/function.rs b/compiler/noirc_frontend/src/ast/function.rs new file mode 100644 index 00000000000..72ed1db6e3b --- /dev/null +++ b/compiler/noirc_frontend/src/ast/function.rs @@ -0,0 +1,116 @@ +use std::fmt::Display; + +use noirc_errors::Span; + +use crate::{ + token::{Attributes, PrimaryAttribute, SecondaryAttribute}, + FunctionReturnType, Ident, Pattern, Visibility, +}; + +use super::{FunctionDefinition, UnresolvedType, UnresolvedTypeData}; + +// A NoirFunction can be either a foreign low level function or a function definition +// A closure / function definition will be stored under a name, so we do not differentiate between their variants +// The name for function literal will be the variable it is bound to, and the name for a function definition will +// be the function name itself. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct NoirFunction { + pub kind: FunctionKind, + pub def: FunctionDefinition, +} + +/// Currently, we support three types of functions: +/// - Normal functions +/// - LowLevel/Foreign which link to an OPCODE in ACIR +/// - BuiltIn which are provided by the runtime +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum FunctionKind { + LowLevel, + Builtin, + Normal, + Oracle, +} + +impl NoirFunction { + pub fn normal(def: FunctionDefinition) -> NoirFunction { + NoirFunction { kind: FunctionKind::Normal, def } + } + pub fn builtin(def: FunctionDefinition) -> NoirFunction { + NoirFunction { kind: FunctionKind::Builtin, def } + } + pub fn low_level(def: FunctionDefinition) -> NoirFunction { + NoirFunction { kind: FunctionKind::LowLevel, def } + } + pub fn oracle(def: FunctionDefinition) -> NoirFunction { + NoirFunction { kind: FunctionKind::Oracle, def } + } + + pub fn return_type(&self) -> UnresolvedType { + match &self.def.return_type { + FunctionReturnType::Default(_) => { + UnresolvedType::without_span(UnresolvedTypeData::Unit) + } + FunctionReturnType::Ty(ty) => ty.clone(), + } + } + pub fn name(&self) -> &str { + &self.name_ident().0.contents + } + pub fn name_ident(&self) -> &Ident { + &self.def.name + } + pub fn parameters(&self) -> &Vec<(Pattern, UnresolvedType, Visibility)> { + &self.def.parameters + } + pub fn attributes(&self) -> &Attributes { + &self.def.attributes + } + pub fn primary_attribute(&self) -> Option<&PrimaryAttribute> { + self.def.attributes.primary.as_ref() + } + pub fn secondary_attributes(&self) -> &Vec { + self.def.attributes.secondary.as_ref() + } + pub fn def(&self) -> &FunctionDefinition { + &self.def + } + pub fn def_mut(&mut self) -> &mut FunctionDefinition { + &mut self.def + } + pub fn number_of_statements(&self) -> usize { + self.def.body.0.len() + } + pub fn span(&self) -> Span { + self.def.span + } + + pub fn foreign(&self) -> Option<&FunctionDefinition> { + match &self.kind { + FunctionKind::LowLevel => {} + _ => return None, + } + assert!(self.primary_attribute().unwrap().is_foreign()); + Some(&self.def) + } +} + +impl From for NoirFunction { + fn from(fd: FunctionDefinition) -> Self { + // The function type is determined by the existence of a primary attribute + let kind = match fd.attributes.primary { + Some(PrimaryAttribute::Builtin(_)) => FunctionKind::Builtin, + Some(PrimaryAttribute::Foreign(_)) => FunctionKind::LowLevel, + Some(PrimaryAttribute::Test { .. }) => FunctionKind::Normal, + Some(PrimaryAttribute::Oracle(_)) => FunctionKind::Oracle, + None => FunctionKind::Normal, + }; + + NoirFunction { def: fd, kind } + } +} + +impl Display for NoirFunction { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.def.fmt(f) + } +} diff --git a/compiler/noirc_frontend/src/ast/mod.rs b/compiler/noirc_frontend/src/ast/mod.rs new file mode 100644 index 00000000000..aa79929fdd7 --- /dev/null +++ b/compiler/noirc_frontend/src/ast/mod.rs @@ -0,0 +1,301 @@ +//! The submodules of this module define the various data types required to +//! represent Noir's Ast. Of particular importance are ExpressionKind and Statement +//! which can be found in expression.rs and statement.rs respectively. +//! +//! Noir's Ast is produced by the parser and taken as input to name resolution, +//! where it is converted into the Hir (defined in the hir_def module). +mod expression; +mod function; +mod statement; +mod structure; +mod traits; +mod type_alias; + +pub use expression::*; +pub use function::*; + +use noirc_errors::Span; +pub use statement::*; +pub use structure::*; +pub use traits::*; +pub use type_alias::*; + +use crate::{ + parser::{ParserError, ParserErrorReason}, + token::IntType, + BinaryTypeOperator, +}; +use iter_extended::vecmap; + +/// The parser parses types as 'UnresolvedType's which +/// require name resolution to resolve any type names used +/// for structs within, but are otherwise identical to Types. +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +pub enum UnresolvedTypeData { + FieldElement, + Array(Option, Box), // [4]Witness = Array(4, Witness) + Integer(Signedness, u32), // u32 = Integer(unsigned, 32) + Bool, + Expression(UnresolvedTypeExpression), + String(Option), + FormatString(UnresolvedTypeExpression, Box), + Unit, + + /// A Named UnresolvedType can be a struct type or a type variable + Named(Path, Vec), + + /// &mut T + MutableReference(Box), + + // Note: Tuples have no visibility, instead each of their elements may have one. + Tuple(Vec), + + Function( + /*args:*/ Vec, + /*ret:*/ Box, + /*env:*/ Box, + ), + + Unspecified, // This is for when the user declares a variable without specifying it's type + Error, +} + +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +pub struct UnresolvedType { + pub typ: UnresolvedTypeData, + + // The span is None in the cases where the User omitted a type: + // fn Foo() {} --- return type is UnresolvedType::Unit without a span + // let x = 100; --- type is UnresolvedType::Unspecified without a span + pub span: Option, +} + +/// The precursor to TypeExpression, this is the type that the parser allows +/// to be used in the length position of an array type. Only constants, variables, +/// and numeric binary operators are allowed here. +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +pub enum UnresolvedTypeExpression { + Variable(Path), + Constant(u64, Span), + BinaryOperation( + Box, + BinaryTypeOperator, + Box, + Span, + ), +} + +impl Recoverable for UnresolvedType { + fn error(span: Span) -> Self { + UnresolvedType { typ: UnresolvedTypeData::Error, span: Some(span) } + } +} + +impl std::fmt::Display for UnresolvedTypeData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use UnresolvedTypeData::*; + match self { + FieldElement => write!(f, "Field"), + Array(len, typ) => match len { + None => write!(f, "[{typ}]"), + Some(len) => write!(f, "[{typ}; {len}]"), + }, + Integer(sign, num_bits) => match sign { + Signedness::Signed => write!(f, "i{num_bits}"), + Signedness::Unsigned => write!(f, "u{num_bits}"), + }, + Named(s, args) => { + let args = vecmap(args, |arg| ToString::to_string(&arg.typ)); + if args.is_empty() { + write!(f, "{s}") + } else { + write!(f, "{}<{}>", s, args.join(", ")) + } + } + Tuple(elements) => { + let elements = vecmap(elements, ToString::to_string); + write!(f, "({})", elements.join(", ")) + } + Expression(expression) => expression.fmt(f), + Bool => write!(f, "bool"), + String(len) => match len { + None => write!(f, "str<_>"), + Some(len) => write!(f, "str<{len}>"), + }, + FormatString(len, elements) => write!(f, "fmt<{len}, {elements}"), + Function(args, ret, env) => { + let args = vecmap(args, ToString::to_string).join(", "); + + match &env.as_ref().typ { + UnresolvedTypeData::Unit => { + write!(f, "fn({args}) -> {ret}") + } + UnresolvedTypeData::Tuple(env_types) => { + let env_types = vecmap(env_types, |arg| arg.typ.to_string()).join(", "); + write!(f, "fn[{env_types}]({args}) -> {ret}") + } + other => write!(f, "fn[{other}]({args}) -> {ret}"), + } + } + MutableReference(element) => write!(f, "&mut {element}"), + Unit => write!(f, "()"), + Error => write!(f, "error"), + Unspecified => write!(f, "unspecified"), + } + } +} + +impl std::fmt::Display for UnresolvedType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.typ.fmt(f) + } +} + +impl std::fmt::Display for UnresolvedTypeExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + UnresolvedTypeExpression::Variable(name) => name.fmt(f), + UnresolvedTypeExpression::Constant(x, _) => x.fmt(f), + UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, _) => { + write!(f, "({lhs} {op} {rhs})") + } + } + } +} + +impl UnresolvedType { + pub fn without_span(typ: UnresolvedTypeData) -> UnresolvedType { + UnresolvedType { typ, span: None } + } + + pub fn unspecified() -> UnresolvedType { + UnresolvedType { typ: UnresolvedTypeData::Unspecified, span: None } + } +} + +impl UnresolvedTypeData { + pub fn from_int_token(token: IntType) -> UnresolvedTypeData { + use {IntType::*, UnresolvedTypeData::Integer}; + match token { + Signed(num_bits) => Integer(Signedness::Signed, num_bits), + Unsigned(num_bits) => Integer(Signedness::Unsigned, num_bits), + } + } + + pub fn with_span(&self, span: Span) -> UnresolvedType { + UnresolvedType { typ: self.clone(), span: Some(span) } + } +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] +pub enum Signedness { + Unsigned, + Signed, +} + +impl UnresolvedTypeExpression { + // This large error size is justified because it improves parsing speeds by around 40% in + // release mode. See `ParserError` definition for further explanation. + #[allow(clippy::result_large_err)] + pub fn from_expr( + expr: Expression, + span: Span, + ) -> Result { + Self::from_expr_helper(expr).map_err(|err_expr| { + ParserError::with_reason( + ParserErrorReason::InvalidArrayLengthExpression(err_expr), + span, + ) + }) + } + + pub fn span(&self) -> Span { + match self { + UnresolvedTypeExpression::Variable(path) => path.span(), + UnresolvedTypeExpression::Constant(_, span) => *span, + UnresolvedTypeExpression::BinaryOperation(_, _, _, span) => *span, + } + } + + fn from_expr_helper(expr: Expression) -> Result { + match expr.kind { + ExpressionKind::Literal(Literal::Integer(int)) => match int.try_to_u64() { + Some(int) => Ok(UnresolvedTypeExpression::Constant(int, expr.span)), + None => Err(expr), + }, + ExpressionKind::Variable(path) => Ok(UnresolvedTypeExpression::Variable(path)), + ExpressionKind::Prefix(prefix) if prefix.operator == UnaryOp::Minus => { + let lhs = Box::new(UnresolvedTypeExpression::Constant(0, expr.span)); + let rhs = Box::new(UnresolvedTypeExpression::from_expr_helper(prefix.rhs)?); + let op = BinaryTypeOperator::Subtraction; + Ok(UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, expr.span)) + } + ExpressionKind::Infix(infix) if Self::operator_allowed(infix.operator.contents) => { + let lhs = Box::new(UnresolvedTypeExpression::from_expr_helper(infix.lhs)?); + let rhs = Box::new(UnresolvedTypeExpression::from_expr_helper(infix.rhs)?); + let op = match infix.operator.contents { + BinaryOpKind::Add => BinaryTypeOperator::Addition, + BinaryOpKind::Subtract => BinaryTypeOperator::Subtraction, + BinaryOpKind::Multiply => BinaryTypeOperator::Multiplication, + BinaryOpKind::Divide => BinaryTypeOperator::Division, + BinaryOpKind::Modulo => BinaryTypeOperator::Modulo, + _ => unreachable!(), // impossible via operator_allowed check + }; + Ok(UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, expr.span)) + } + _ => Err(expr), + } + } + + fn operator_allowed(op: BinaryOpKind) -> bool { + matches!( + op, + BinaryOpKind::Add + | BinaryOpKind::Subtract + | BinaryOpKind::Multiply + | BinaryOpKind::Divide + | BinaryOpKind::Modulo + ) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +/// Represents whether the parameter is public or known only to the prover. +pub enum Visibility { + Public, + // Constants are not allowed in the ABI for main at the moment. + // Constant, + Private, +} + +impl std::fmt::Display for Visibility { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Public => write!(f, "pub"), + Self::Private => write!(f, "priv"), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +/// Represents whether the return value should compromise of unique witness indices such that no +/// index occurs within the program's abi more than once. +/// +/// This is useful for application stacks that require an uniform abi across across multiple +/// circuits. When index duplication is allowed, the compiler may identify that a public input +/// reaches the output unaltered and is thus referenced directly, causing the input and output +/// witness indices to overlap. Similarly, repetitions of copied values in the output may be +/// optimized away. +pub enum Distinctness { + Distinct, + DuplicationAllowed, +} + +impl std::fmt::Display for Distinctness { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Distinct => write!(f, "distinct"), + Self::DuplicationAllowed => write!(f, "duplication-allowed"), + } + } +} diff --git a/crates/noirc_frontend/src/ast/statement.rs b/compiler/noirc_frontend/src/ast/statement.rs similarity index 99% rename from crates/noirc_frontend/src/ast/statement.rs rename to compiler/noirc_frontend/src/ast/statement.rs index 7d51ed60b46..51afa688082 100644 --- a/crates/noirc_frontend/src/ast/statement.rs +++ b/compiler/noirc_frontend/src/ast/statement.rs @@ -247,7 +247,7 @@ impl Display for UseTree { write!(f, "{name}")?; while let Some(alias) = alias { - write!(f, " as {}", alias)?; + write!(f, " as {alias}")?; } Ok(()) @@ -401,7 +401,7 @@ pub enum LValue { } #[derive(Debug, PartialEq, Eq, Clone)] -pub struct ConstrainStatement(pub Expression); +pub struct ConstrainStatement(pub Expression, pub Option); #[derive(Debug, PartialEq, Eq, Clone)] pub enum Pattern { diff --git a/crates/noirc_frontend/src/ast/structure.rs b/compiler/noirc_frontend/src/ast/structure.rs similarity index 100% rename from crates/noirc_frontend/src/ast/structure.rs rename to compiler/noirc_frontend/src/ast/structure.rs diff --git a/crates/noirc_frontend/src/ast/traits.rs b/compiler/noirc_frontend/src/ast/traits.rs similarity index 83% rename from crates/noirc_frontend/src/ast/traits.rs rename to compiler/noirc_frontend/src/ast/traits.rs index 4a649a64cc6..0120b70e5e8 100644 --- a/crates/noirc_frontend/src/ast/traits.rs +++ b/compiler/noirc_frontend/src/ast/traits.rs @@ -68,10 +68,21 @@ pub struct TraitImpl { pub items: Vec, } -/// Represents a trait constraint such as `where Foo: Display` +/// Represents a simple trait constraint such as `where Foo: TraitY` +/// Complex trait constraints such as `where Foo: Display + TraitX + TraitY` are converted +/// in the parser to a series of simple constraints: +/// `Foo: Display` +/// `Foo: TraitX` +/// `Foo: TraitY` #[derive(Clone, Debug, PartialEq, Eq)] pub struct TraitConstraint { pub typ: UnresolvedType, + pub trait_bound: TraitBound, +} + +/// Represents a single trait bound, such as `TraitX` or `TraitY` +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TraitBound { pub trait_name: Ident, pub trait_generics: Vec, } @@ -133,21 +144,20 @@ impl Display for TraitItem { write!( f, - "fn {name}<{}>({}) -> {} where {}", - generics, parameters, return_type, where_clause + "fn {name}<{generics}>({parameters}) -> {return_type} where {where_clause}" )?; if let Some(body) = body { - write!(f, "{}", body) + write!(f, "{body}") } else { write!(f, ";") } } TraitItem::Constant { name, typ, default_value } => { - write!(f, "let {}: {}", name, typ)?; + write!(f, "let {name}: {typ}")?; if let Some(default_value) = default_value { - write!(f, "{};", default_value) + write!(f, "{default_value};") } else { write!(f, ";") } @@ -158,9 +168,19 @@ impl Display for TraitItem { } impl Display for TraitConstraint { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}: {}", self.typ, self.trait_bound) + } +} + +impl Display for TraitBound { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let generics = vecmap(&self.trait_generics, |generic| generic.to_string()); - write!(f, "{}: {}<{}>", self.typ, self.trait_name, generics.join(", ")) + if !generics.is_empty() { + write!(f, "{}<{}>", self.trait_name, generics.join(", ")) + } else { + write!(f, "{}", self.trait_name) + } } } @@ -188,7 +208,7 @@ impl Display for TraitImplItem { TraitImplItem::Function(function) => function.fmt(f), TraitImplItem::Type { name, alias } => write!(f, "type {name} = {alias};"), TraitImplItem::Constant(name, typ, value) => { - write!(f, "let {}: {} = {};", name, typ, value) + write!(f, "let {name}: {typ} = {value};") } } } diff --git a/crates/noirc_frontend/src/ast/type_alias.rs b/compiler/noirc_frontend/src/ast/type_alias.rs similarity index 100% rename from crates/noirc_frontend/src/ast/type_alias.rs rename to compiler/noirc_frontend/src/ast/type_alias.rs diff --git a/compiler/noirc_frontend/src/graph/mod.rs b/compiler/noirc_frontend/src/graph/mod.rs new file mode 100644 index 00000000000..d8c539038df --- /dev/null +++ b/compiler/noirc_frontend/src/graph/mod.rs @@ -0,0 +1,422 @@ +// This has been taken and modified from the rust-analyzer codebase +// For the most part, everything is the same, the differences are quite subtle +// but still present. Moreover, since RA is uses incremental compilation, the usage of this component may differ. +// This version is also simpler due to not having macro_defs or proc_macros +// XXX: Edition may be reintroduced or some sort of versioning + +use std::{fmt::Display, str::FromStr}; + +use fm::FileId; +use rustc_hash::{FxHashMap, FxHashSet}; +use smol_str::SmolStr; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum CrateId { + Root(usize), + Crate(usize), + Stdlib(usize), + Dummy, +} + +impl CrateId { + pub fn dummy_id() -> CrateId { + CrateId::Dummy + } + + pub fn is_stdlib(&self) -> bool { + matches!(self, CrateId::Stdlib(_)) + } + + pub fn is_root(&self) -> bool { + matches!(self, CrateId::Root(_)) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct CrateName(SmolStr); + +impl CrateName { + fn is_valid_name(name: &str) -> bool { + !name.is_empty() && name.chars().all(|n| !CHARACTER_BLACK_LIST.contains(&n)) + } +} + +impl Display for CrateName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl From for String { + fn from(crate_name: CrateName) -> Self { + crate_name.0.into() + } +} +impl From<&CrateName> for String { + fn from(crate_name: &CrateName) -> Self { + crate_name.0.clone().into() + } +} + +/// Creates a new CrateName rejecting any crate name that +/// has a character on the blacklist. +/// The difference between RA and this implementation is that +/// characters on the blacklist are never allowed; there is no normalization. +impl FromStr for CrateName { + type Err = String; + + fn from_str(name: &str) -> Result { + if Self::is_valid_name(name) { + Ok(Self(SmolStr::new(name))) + } else { + Err("Package names must be non-empty and cannot contain hyphens".into()) + } + } +} + +#[cfg(test)] +mod crate_name { + use super::{CrateName, CHARACTER_BLACK_LIST}; + + #[test] + fn it_rejects_empty_string() { + assert!(!CrateName::is_valid_name("")); + } + + #[test] + fn it_rejects_blacklisted_chars() { + for bad_char in CHARACTER_BLACK_LIST { + let bad_char_string = bad_char.to_string(); + assert!(!CrateName::is_valid_name(&bad_char_string)); + } + } +} + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct CrateGraph { + arena: FxHashMap, +} + +/// List of characters that are not allowed in a crate name +/// For example, Hyphen(-) is disallowed as it is similar to underscore(_) +/// and we do not want names that differ by a hyphen +pub const CHARACTER_BLACK_LIST: [char; 1] = ['-']; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CrateData { + pub root_file_id: FileId, + pub dependencies: Vec, +} + +/// A dependency is a crate name and a crate_id +/// This means that the same crate can be compiled once under different names +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Dependency { + pub crate_id: CrateId, + pub name: CrateName, +} + +impl Dependency { + pub fn as_name(&self) -> String { + self.name.clone().into() + } +} + +impl CrateGraph { + pub fn root_crate_id(&self) -> &CrateId { + self.arena + .keys() + .find(|crate_id| crate_id.is_root()) + .expect("ICE: A root crate should exist in the CrateGraph") + } + + pub fn stdlib_crate_id(&self) -> &CrateId { + self.arena + .keys() + .find(|crate_id| crate_id.is_stdlib()) + .expect("ICE: The stdlib should exist in the CrateGraph") + } + + pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId { + for (crate_id, crate_data) in self.arena.iter() { + if crate_id.is_root() { + panic!("ICE: Cannot add two crate roots to a graph - use `add_crate` instead"); + } + + if crate_data.root_file_id == file_id { + panic!("ICE: This FileId was already added to the CrateGraph") + } + } + + let data = CrateData { root_file_id: file_id, dependencies: Vec::new() }; + let crate_id = CrateId::Root(self.arena.len()); + let prev = self.arena.insert(crate_id, data); + assert!(prev.is_none()); + crate_id + } + + pub fn add_crate(&mut self, file_id: FileId) -> CrateId { + let mut crates_with_file_id = self + .arena + .iter() + .filter(|(_, crate_data)| crate_data.root_file_id == file_id) + .peekable(); + + let matching_id = crates_with_file_id.next(); + if crates_with_file_id.peek().is_some() { + panic!("ICE: Found multiple crates with the same FileId"); + } + + match matching_id { + Some((crate_id @ CrateId::Crate(_), _)) => *crate_id, + Some((CrateId::Root(_), _)) => { + panic!("ICE: Tried to re-add the root crate as a regular crate") + } + Some((CrateId::Stdlib(_), _)) => { + panic!("ICE: Tried to re-add the stdlib crate as a regular crate") + } + Some((CrateId::Dummy, _)) => { + panic!("ICE: A dummy CrateId should not exist in the CrateGraph") + } + None => { + let data = CrateData { root_file_id: file_id, dependencies: Vec::new() }; + let crate_id = CrateId::Crate(self.arena.len()); + let prev = self.arena.insert(crate_id, data); + assert!(prev.is_none()); + crate_id + } + } + } + + pub fn add_stdlib(&mut self, file_id: FileId) -> CrateId { + for (crate_id, crate_data) in self.arena.iter() { + if crate_id.is_stdlib() { + panic!("ICE: Cannot add two stdlib crates to a graph - use `add_crate` instead"); + } + + if crate_data.root_file_id == file_id { + panic!("ICE: This FileId was already added to the CrateGraph") + } + } + + let data = CrateData { root_file_id: file_id, dependencies: Vec::new() }; + let crate_id = CrateId::Stdlib(self.arena.len()); + let prev = self.arena.insert(crate_id, data); + assert!(prev.is_none()); + crate_id + } + + pub fn iter_keys(&self) -> impl Iterator + '_ { + self.arena.keys().copied() + } + + pub fn crates_in_topological_order(&self) -> Vec { + let mut res = Vec::new(); + let mut visited = FxHashSet::default(); + + for krate in self.arena.keys().copied() { + go(self, &mut visited, &mut res, krate); + } + + return res; + + fn go( + graph: &CrateGraph, + visited: &mut FxHashSet, + res: &mut Vec, + source: CrateId, + ) { + if !visited.insert(source) { + return; + } + for dep in graph[source].dependencies.iter() { + go(graph, visited, res, dep.crate_id); + } + res.push(source); + } + } + + pub fn add_dep( + &mut self, + from: CrateId, + name: CrateName, + to: CrateId, + ) -> Result<(), CyclicDependenciesError> { + if self.dfs_find(from, to, &mut FxHashSet::default()) { + return Err(CyclicDependenciesError { from, to }); + } + self.arena.get_mut(&from).unwrap().add_dep(name, to); + Ok(()) + } + + fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet) -> bool { + if !visited.insert(from) { + return false; + } + + if target == from { + return true; + } + + for dep in &self[from].dependencies { + let crate_id = dep.crate_id; + if self.dfs_find(target, crate_id, visited) { + return true; + } + } + false + } + + pub fn number_of_crates(&self) -> usize { + self.arena.len() + } +} +impl CrateData { + fn add_dep(&mut self, name: CrateName, crate_id: CrateId) { + self.dependencies.push(Dependency { crate_id, name }); + } +} +impl std::ops::Index for CrateGraph { + type Output = CrateData; + fn index(&self, crate_id: CrateId) -> &CrateData { + &self.arena[&crate_id] + } +} +impl std::ops::Index<&CrateId> for CrateGraph { + type Output = CrateData; + fn index(&self, crate_id: &CrateId) -> &CrateData { + &self.arena[crate_id] + } +} + +/// XXX: This is bare-bone for two reasons: +// There are no display names currently +// The error would be better if it showed the full cyclic dependency, including transitives. +#[allow(dead_code)] +#[derive(Debug)] +pub struct CyclicDependenciesError { + from: CrateId, + to: CrateId, +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use super::{CrateGraph, FileId}; + + fn dummy_file_ids(n: usize) -> Vec { + use fm::{FileMap, FILE_EXTENSION}; + let mut fm = FileMap::default(); + + let mut vec_ids = Vec::with_capacity(n); + for i in 0..n { + let mut pth = PathBuf::new(); + pth.push(format!("{}", i)); + pth.set_extension(FILE_EXTENSION); + vec_ids.push(fm.add_file(pth.into(), String::new())); + } + + vec_ids + } + + #[test] + fn detect_cyclic_dependency_indirect() { + let file_ids = dummy_file_ids(3); + + let mut graph = CrateGraph::default(); + let crate1 = graph.add_crate_root(file_ids[0]); + let crate2 = graph.add_crate(file_ids[1]); + let crate3 = graph.add_crate(file_ids[2]); + + assert!(graph.add_dep(crate1, "crate2".parse().unwrap(), crate2).is_ok()); + assert!(graph.add_dep(crate2, "crate3".parse().unwrap(), crate3).is_ok()); + assert!(graph.add_dep(crate3, "crate1".parse().unwrap(), crate1).is_err()); + } + + #[test] + fn it_works() { + let file_ids = dummy_file_ids(3); + let file_id_0 = file_ids[0]; + let file_id_1 = file_ids[1]; + let file_id_2 = file_ids[2]; + let mut graph = CrateGraph::default(); + let crate1 = graph.add_crate_root(file_id_0); + let crate2 = graph.add_crate(file_id_1); + let crate3 = graph.add_crate(file_id_2); + assert!(graph.add_dep(crate1, "crate2".parse().unwrap(), crate2).is_ok()); + assert!(graph.add_dep(crate2, "crate3".parse().unwrap(), crate3).is_ok()); + } + #[test] + fn it_works2() { + let file_ids = dummy_file_ids(3); + let file_id_0 = file_ids[0]; + let file_id_1 = file_ids[1]; + let file_id_2 = file_ids[2]; + let mut graph = CrateGraph::default(); + let _crate1 = graph.add_crate_root(file_id_0); + let _crate2 = graph.add_crate(file_id_1); + + // Adding the same file, so the crate should be the same. + let crate3 = graph.add_crate(file_id_2); + let crate3_2 = graph.add_crate(file_id_2); + assert_eq!(crate3, crate3_2); + } + + #[test] + #[should_panic = "ICE: Cannot add two crate roots to a graph - use `add_crate` instead"] + fn panics_if_adding_two_roots() { + let file_ids = dummy_file_ids(2); + let mut graph = CrateGraph::default(); + let _ = graph.add_crate_root(file_ids[0]); + let _ = graph.add_crate_root(file_ids[1]); + } + + #[test] + #[should_panic = "ICE: This FileId was already added to the CrateGraph"] + fn panics_if_adding_existing_file_as_root() { + let file_ids = dummy_file_ids(1); + let mut graph = CrateGraph::default(); + let file_id_0 = file_ids[0]; + let _ = graph.add_crate(file_id_0); + let _ = graph.add_crate_root(file_id_0); + } + + #[test] + #[should_panic = "ICE: Cannot add two stdlib crates to a graph - use `add_crate` instead"] + fn panics_if_adding_two_stdlib() { + let file_ids = dummy_file_ids(2); + let mut graph = CrateGraph::default(); + let _ = graph.add_stdlib(file_ids[0]); + let _ = graph.add_stdlib(file_ids[1]); + } + + #[test] + #[should_panic = "ICE: This FileId was already added to the CrateGraph"] + fn panics_if_adding_existing_file_as_stdlib() { + let file_ids = dummy_file_ids(1); + let mut graph = CrateGraph::default(); + let file_id_0 = file_ids[0]; + let _ = graph.add_crate(file_id_0); + let _ = graph.add_stdlib(file_id_0); + } + + #[test] + #[should_panic = "ICE: Tried to re-add the root crate as a regular crate"] + fn panics_if_adding_root_as_regular() { + let file_ids = dummy_file_ids(1); + let mut graph = CrateGraph::default(); + let file_id_0 = file_ids[0]; + let _ = graph.add_crate_root(file_id_0); + let _ = graph.add_crate(file_id_0); + } + #[test] + #[should_panic = "ICE: Tried to re-add the stdlib crate as a regular crate"] + fn panics_if_adding_stdlib_as_regular() { + let file_ids = dummy_file_ids(1); + let mut graph = CrateGraph::default(); + let file_id_0 = file_ids[0]; + let _ = graph.add_stdlib(file_id_0); + let _ = graph.add_crate(file_id_0); + } +} diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs new file mode 100644 index 00000000000..c55335e4443 --- /dev/null +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -0,0 +1,776 @@ +use super::dc_mod::collect_defs; +use super::errors::{DefCollectorErrorKind, DuplicateType}; +use crate::graph::CrateId; +use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleId}; +use crate::hir::resolution::errors::ResolverError; +use crate::hir::resolution::import::PathResolutionError; +use crate::hir::resolution::resolver::Resolver; +use crate::hir::resolution::{ + import::{resolve_imports, ImportDirective}, + path_resolver::StandardPathResolver, +}; +use crate::hir::type_check::{type_check_func, TypeChecker}; +use crate::hir::Context; +use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, TypeAliasId}; +use crate::{ + ExpressionKind, FunctionReturnType, Generics, Ident, LetStatement, Literal, NoirFunction, + NoirStruct, NoirTrait, NoirTypeAlias, ParsedModule, Shared, StructType, TraitItem, + TraitItemType, Type, TypeBinding, UnresolvedGenerics, UnresolvedType, +}; +use fm::FileId; +use iter_extended::vecmap; +use noirc_errors::Span; +use noirc_errors::{CustomDiagnostic, FileDiagnostic}; +use std::collections::{BTreeMap, HashMap}; +use std::rc::Rc; +use std::vec; + +/// Stores all of the unresolved functions in a particular file/mod +#[derive(Clone)] +pub struct UnresolvedFunctions { + pub file_id: FileId, + pub functions: Vec<(LocalModuleId, FuncId, NoirFunction)>, +} + +impl UnresolvedFunctions { + pub fn push_fn(&mut self, mod_id: LocalModuleId, func_id: FuncId, func: NoirFunction) { + self.functions.push((mod_id, func_id, func)); + } +} + +pub struct UnresolvedStruct { + pub file_id: FileId, + pub module_id: LocalModuleId, + pub struct_def: NoirStruct, +} + +#[derive(Clone)] +pub struct UnresolvedTrait { + pub file_id: FileId, + pub module_id: LocalModuleId, + pub trait_def: NoirTrait, +} + +pub struct UnresolvedTraitImpl { + pub file_id: FileId, + pub module_id: LocalModuleId, + pub the_trait: UnresolvedTrait, + pub methods: UnresolvedFunctions, + pub trait_impl_ident: Ident, // for error reporting +} + +#[derive(Clone)] +pub struct UnresolvedTypeAlias { + pub file_id: FileId, + pub module_id: LocalModuleId, + pub type_alias_def: NoirTypeAlias, +} + +#[derive(Clone)] +pub struct UnresolvedGlobal { + pub file_id: FileId, + pub module_id: LocalModuleId, + pub stmt_id: StmtId, + pub stmt_def: LetStatement, +} + +/// Given a Crate root, collect all definitions in that crate +pub struct DefCollector { + pub(crate) def_map: CrateDefMap, + pub(crate) collected_imports: Vec, + pub(crate) collected_functions: Vec, + pub(crate) collected_types: BTreeMap, + pub(crate) collected_type_aliases: BTreeMap, + pub(crate) collected_traits: BTreeMap, + pub(crate) collected_globals: Vec, + pub(crate) collected_impls: ImplMap, + pub(crate) collected_traits_impls: TraitImplMap, +} + +/// Maps the type and the module id in which the impl is defined to the functions contained in that +/// impl along with the generics declared on the impl itself. This also contains the Span +/// of the object_type of the impl, used to issue an error if the object type fails to resolve. +/// +/// Note that because these are keyed by unresolved types, the impl map is one of the few instances +/// of HashMap rather than BTreeMap. For this reason, we should be careful not to iterate over it +/// since it would be non-deterministic. +type ImplMap = + HashMap<(UnresolvedType, LocalModuleId), Vec<(UnresolvedGenerics, Span, UnresolvedFunctions)>>; + +type TraitImplMap = HashMap<(UnresolvedType, LocalModuleId, TraitId), UnresolvedTraitImpl>; + +impl DefCollector { + fn new(def_map: CrateDefMap) -> DefCollector { + DefCollector { + def_map, + collected_imports: vec![], + collected_functions: vec![], + collected_types: BTreeMap::new(), + collected_type_aliases: BTreeMap::new(), + collected_traits: BTreeMap::new(), + collected_impls: HashMap::new(), + collected_globals: vec![], + collected_traits_impls: HashMap::new(), + } + } + + /// Collect all of the definitions in a given crate into a CrateDefMap + /// Modules which are not a part of the module hierarchy starting with + /// the root module, will be ignored. + pub fn collect( + mut def_map: CrateDefMap, + context: &mut Context, + ast: ParsedModule, + root_file_id: FileId, + errors: &mut Vec, + ) { + let crate_id = def_map.krate; + + // Recursively resolve the dependencies + // + // Dependencies are fetched from the crate graph + // Then added these to the context of DefMaps once they are resolved + // + let crate_graph = &context.crate_graph[crate_id]; + + for dep in crate_graph.dependencies.clone() { + CrateDefMap::collect_defs(dep.crate_id, context, errors); + + let dep_def_root = + context.def_map(&dep.crate_id).expect("ice: def map was just created").root; + let module_id = ModuleId { krate: dep.crate_id, local_id: dep_def_root }; + // Add this crate as a dependency by linking it's root module + def_map.extern_prelude.insert(dep.as_name(), module_id); + } + + // At this point, all dependencies are resolved and type checked. + // + // It is now possible to collect all of the definitions of this crate. + let crate_root = def_map.root; + let mut def_collector = DefCollector::new(def_map); + + // Collecting module declarations with ModCollector + // and lowering the functions + // i.e. Use a mod collector to collect the nodes at the root module + // and process them + collect_defs(&mut def_collector, ast, root_file_id, crate_root, crate_id, context, errors); + + // Add the current crate to the collection of DefMaps + context.def_maps.insert(crate_id, def_collector.def_map); + + // Resolve unresolved imports collected from the crate + let (resolved, unresolved_imports) = + resolve_imports(crate_id, def_collector.collected_imports, &context.def_maps); + + let current_def_map = context.def_maps.get(&crate_id).unwrap(); + + errors.extend(vecmap(unresolved_imports, |(error, module_id)| { + let file_id = current_def_map.file_id(module_id); + let error = DefCollectorErrorKind::PathResolutionError(error); + error.into_file_diagnostic(file_id) + })); + + // Populate module namespaces according to the imports used + let current_def_map = context.def_maps.get_mut(&crate_id).unwrap(); + for resolved_import in resolved { + let name = resolved_import.name; + for ns in resolved_import.resolved_namespace.iter_defs() { + let result = current_def_map.modules[resolved_import.module_scope.0] + .import(name.clone(), ns); + + if let Err((first_def, second_def)) = result { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Import, + first_def, + second_def, + }; + errors.push(err.into_file_diagnostic(root_file_id)); + } + } + } + + // We must first resolve and intern the globals before we can resolve any stmts inside each function. + // Each function uses its own resolver with a newly created ScopeForest, and must be resolved again to be within a function's scope + // + // Additionally, we must resolve integer globals before structs since structs may refer to + // the values of integer globals as numeric generics. + let (literal_globals, other_globals) = + filter_literal_globals(def_collector.collected_globals); + + let mut file_global_ids = resolve_globals(context, literal_globals, crate_id, errors); + + resolve_type_aliases(context, def_collector.collected_type_aliases, crate_id, errors); + + resolve_traits(context, def_collector.collected_traits, crate_id, errors); + // Must resolve structs before we resolve globals. + resolve_structs(context, def_collector.collected_types, crate_id, errors); + + // We must wait to resolve non-integer globals until after we resolve structs since structs + // globals will need to reference the struct type they're initialized to to ensure they are valid. + let mut more_global_ids = resolve_globals(context, other_globals, crate_id, errors); + + file_global_ids.append(&mut more_global_ids); + + // Before we resolve any function symbols we must go through our impls and + // re-collect the methods within into their proper module. This cannot be + // done before resolution since we need to be able to resolve the type of the + // impl since that determines the module we should collect into. + collect_impls(context, crate_id, &def_collector.collected_impls, errors); + + collect_trait_impls(context, crate_id, &def_collector.collected_traits_impls, errors); + + // Lower each function in the crate. This is now possible since imports have been resolved + let file_func_ids = resolve_free_functions( + &mut context.def_interner, + crate_id, + &context.def_maps, + def_collector.collected_functions, + None, + errors, + ); + + let file_method_ids = resolve_impls( + &mut context.def_interner, + crate_id, + &context.def_maps, + def_collector.collected_impls, + errors, + ); + + let file_trait_impls_ids = + resolve_trait_impls(context, def_collector.collected_traits_impls, crate_id, errors); + + type_check_globals(&mut context.def_interner, file_global_ids, errors); + + // Type check all of the functions in the crate + type_check_functions(&mut context.def_interner, file_func_ids, errors); + type_check_functions(&mut context.def_interner, file_trait_impls_ids, errors); + type_check_functions(&mut context.def_interner, file_method_ids, errors); + } +} + +/// Go through the list of impls and add each function within to the scope +/// of the module defined by its type. +fn collect_impls( + context: &mut Context, + crate_id: CrateId, + collected_impls: &ImplMap, + errors: &mut Vec, +) { + let interner = &mut context.def_interner; + let def_maps = &mut context.def_maps; + + for ((unresolved_type, module_id), methods) in collected_impls { + let path_resolver = + StandardPathResolver::new(ModuleId { local_id: *module_id, krate: crate_id }); + + let file = def_maps[&crate_id].file_id(*module_id); + + for (generics, span, unresolved) in methods { + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + resolver.add_generics(generics); + let typ = resolver.resolve_type(unresolved_type.clone()); + + extend_errors(errors, unresolved.file_id, resolver.take_errors()); + + if let Some(struct_type) = get_struct_type(&typ) { + let struct_type = struct_type.borrow(); + let type_module = struct_type.id.local_module_id(); + + // `impl`s are only allowed on types defined within the current crate + if struct_type.id.krate() != crate_id { + let span = *span; + let type_name = struct_type.name.to_string(); + let error = DefCollectorErrorKind::ForeignImpl { span, type_name }; + errors.push(error.into_file_diagnostic(unresolved.file_id)); + continue; + } + + // Grab the module defined by the struct type. Note that impls are a case + // where the module the methods are added to is not the same as the module + // they are resolved in. + let module = &mut def_maps.get_mut(&crate_id).unwrap().modules[type_module.0]; + + for (_, method_id, method) in &unresolved.functions { + let result = module.declare_function(method.name_ident().clone(), *method_id); + + if let Err((first_def, second_def)) = result { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Function, + first_def, + second_def, + }; + errors.push(err.into_file_diagnostic(unresolved.file_id)); + } + } + // Prohibit defining impls for primitive types if we're not in the stdlib + } else if typ != Type::Error && !crate_id.is_stdlib() { + let span = *span; + let error = DefCollectorErrorKind::NonStructTypeInImpl { span }; + errors.push(error.into_file_diagnostic(unresolved.file_id)); + } + } + } +} + +fn collect_trait_impls( + context: &mut Context, + crate_id: CrateId, + collected_impls: &TraitImplMap, + errors: &mut Vec, +) { + let interner = &mut context.def_interner; + let def_maps = &mut context.def_maps; + + // TODO: To follow the semantics of Rust, we must allow the impl if either + // 1. The type is a struct and it's defined in the current crate + // 2. The trait is defined in the current crate + for ((unresolved_type, module_id, _), trait_impl) in collected_impls { + let path_resolver = + StandardPathResolver::new(ModuleId { local_id: *module_id, krate: crate_id }); + + for (_, func_id, ast) in &trait_impl.methods.functions { + let file = def_maps[&crate_id].file_id(*module_id); + + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + resolver.add_generics(&ast.def.generics); + let typ = resolver.resolve_type(unresolved_type.clone()); + + // Add the method to the struct's namespace + if let Some(struct_type) = get_struct_type(&typ) { + extend_errors(errors, trait_impl.file_id, resolver.take_errors()); + + let struct_type = struct_type.borrow(); + let type_module = struct_type.id.local_module_id(); + + let module = &mut def_maps.get_mut(&crate_id).unwrap().modules[type_module.0]; + + let result = module.declare_function(ast.name_ident().clone(), *func_id); + + if let Err((first_def, second_def)) = result { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Function, + first_def, + second_def, + }; + errors.push(err.into_file_diagnostic(trait_impl.file_id)); + } + } else { + let span = trait_impl.trait_impl_ident.span(); + let trait_ident = trait_impl.the_trait.trait_def.name.clone(); + let error = DefCollectorErrorKind::NonStructTraitImpl { trait_ident, span }; + errors.push(error.into_file_diagnostic(trait_impl.file_id)); + } + } + } +} + +fn get_struct_type(typ: &Type) -> Option<&Shared> { + match typ { + Type::Struct(definition, _) => Some(definition), + _ => None, + } +} + +fn extend_errors(errors: &mut Vec, file: fm::FileId, new_errors: Errs) +where + Errs: IntoIterator, + Err: Into, +{ + errors.extend(new_errors.into_iter().map(|err| err.into().in_file(file))); +} + +/// Separate the globals Vec into two. The first element in the tuple will be the +/// literal globals, except for arrays, and the second will be all other globals. +/// We exclude array literals as they can contain complex types +fn filter_literal_globals( + globals: Vec, +) -> (Vec, Vec) { + globals.into_iter().partition(|global| match &global.stmt_def.expression.kind { + ExpressionKind::Literal(literal) => !matches!(literal, Literal::Array(_)), + _ => false, + }) +} + +fn resolve_globals( + context: &mut Context, + globals: Vec, + crate_id: CrateId, + errors: &mut Vec, +) -> Vec<(FileId, StmtId)> { + vecmap(globals, |global| { + let module_id = ModuleId { local_id: global.module_id, krate: crate_id }; + let path_resolver = StandardPathResolver::new(module_id); + let storage_slot = context.next_storage_slot(module_id); + + let mut resolver = Resolver::new( + &mut context.def_interner, + &path_resolver, + &context.def_maps, + global.file_id, + ); + + let name = global.stmt_def.pattern.name_ident().clone(); + + let hir_stmt = resolver.resolve_global_let(global.stmt_def); + extend_errors(errors, global.file_id, resolver.take_errors()); + + context.def_interner.update_global(global.stmt_id, hir_stmt); + + context.def_interner.push_global(global.stmt_id, name, global.module_id, storage_slot); + + (global.file_id, global.stmt_id) + }) +} + +fn type_check_globals( + interner: &mut NodeInterner, + global_ids: Vec<(FileId, StmtId)>, + all_errors: &mut Vec, +) { + for (file_id, stmt_id) in global_ids { + let errors = TypeChecker::check_global(&stmt_id, interner); + extend_errors(all_errors, file_id, errors); + } +} + +/// Create the mappings from TypeId -> StructType +/// so that expressions can access the fields of structs +fn resolve_structs( + context: &mut Context, + structs: BTreeMap, + crate_id: CrateId, + errors: &mut Vec, +) { + // Resolve each field in each struct. + // Each struct should already be present in the NodeInterner after def collection. + for (type_id, typ) in structs { + let (generics, fields) = resolve_struct_fields(context, crate_id, typ, errors); + context.def_interner.update_struct(type_id, |struct_def| { + struct_def.set_fields(fields); + struct_def.generics = generics; + }); + } +} + +fn resolve_trait_types( + _context: &mut Context, + _crate_id: CrateId, + _unresolved_trait: &UnresolvedTrait, + _errors: &mut [FileDiagnostic], +) -> Vec { + // TODO + vec![] +} +fn resolve_trait_constants( + _context: &mut Context, + _crate_id: CrateId, + _unresolved_trait: &UnresolvedTrait, + _errors: &mut [FileDiagnostic], +) -> Vec { + // TODO + vec![] +} + +fn resolve_trait_methods( + context: &mut Context, + crate_id: CrateId, + unresolved_trait: &UnresolvedTrait, + errors: &mut Vec, +) -> Vec { + let interner = &mut context.def_interner; + let def_maps = &mut context.def_maps; + + let path_resolver = StandardPathResolver::new(ModuleId { + local_id: unresolved_trait.module_id, + krate: crate_id, + }); + let file = def_maps[&crate_id].file_id(unresolved_trait.module_id); + + let mut res = vec![]; + + for item in &unresolved_trait.trait_def.items { + if let TraitItem::Function { + name, + generics: _, + parameters, + return_type, + where_clause: _, + body: _, + } = item + { + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + let arguments = vecmap(parameters, |param| resolver.resolve_type(param.1.clone())); + let resolved_return_type = match return_type { + FunctionReturnType::Default(_) => None, + FunctionReturnType::Ty(unresolved_type) => { + Some(resolver.resolve_type(unresolved_type.clone())) + } + }; + let name = name.clone(); + // TODO + let generics: Generics = vec![]; + let span: Span = name.span(); + let f = TraitItemType::Function { + name, + generics, + arguments, + return_type: resolved_return_type, + span, + }; + res.push(f); + let new_errors = take_errors_filter_self_not_resolved(resolver); + extend_errors(errors, file, new_errors); + } + } + res +} + +fn take_errors_filter_self_not_resolved(resolver: Resolver<'_>) -> Vec { + resolver + .take_errors() + .iter() + .cloned() + .filter(|resolution_error| match resolution_error { + ResolverError::PathResolutionError(PathResolutionError::Unresolved(ident)) => { + &ident.0.contents != "Self" + } + _ => true, + }) + .collect() +} + +/// Create the mappings from TypeId -> TraitType +/// so that expressions can access the elements of traits +fn resolve_traits( + context: &mut Context, + traits: BTreeMap, + crate_id: CrateId, + errors: &mut Vec, +) { + for (trait_id, unresolved_trait) in &traits { + context.def_interner.push_empty_trait(*trait_id, unresolved_trait); + } + for (trait_id, unresolved_trait) in traits { + let mut items: Vec = vec![]; + // Resolve order + // 1. Trait Types ( Trait contants can have a trait type, therefore types before constants) + items.append(&mut resolve_trait_types(context, crate_id, &unresolved_trait, errors)); + // 2. Trait Constants ( Trait's methods can use trait types & constants, threfore they should be after) + items.append(&mut resolve_trait_constants(context, crate_id, &unresolved_trait, errors)); + // 3. Trait Methods + items.append(&mut resolve_trait_methods(context, crate_id, &unresolved_trait, errors)); + context.def_interner.update_trait(trait_id, |trait_def| { + trait_def.set_items(items); + }); + } +} + +fn resolve_struct_fields( + context: &mut Context, + krate: CrateId, + unresolved: UnresolvedStruct, + all_errors: &mut Vec, +) -> (Generics, Vec<(Ident, Type)>) { + let path_resolver = + StandardPathResolver::new(ModuleId { local_id: unresolved.module_id, krate }); + + let file = unresolved.file_id; + + let (generics, fields, errors) = + Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) + .resolve_struct_fields(unresolved.struct_def); + + extend_errors(all_errors, unresolved.file_id, errors); + (generics, fields) +} + +fn resolve_type_aliases( + context: &mut Context, + type_aliases: BTreeMap, + crate_id: CrateId, + all_errors: &mut Vec, +) { + for (type_id, unresolved_typ) in type_aliases { + let path_resolver = StandardPathResolver::new(ModuleId { + local_id: unresolved_typ.module_id, + krate: crate_id, + }); + let file = unresolved_typ.file_id; + let (typ, generics, errors) = + Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) + .resolve_type_aliases(unresolved_typ.type_alias_def); + extend_errors(all_errors, file, errors); + + context.def_interner.set_type_alias(type_id, typ, generics); + } +} + +fn resolve_impls( + interner: &mut NodeInterner, + crate_id: CrateId, + def_maps: &BTreeMap, + collected_impls: ImplMap, + errors: &mut Vec, +) -> Vec<(FileId, FuncId)> { + let mut file_method_ids = Vec::new(); + + for ((unresolved_type, module_id), methods) in collected_impls { + let path_resolver = + StandardPathResolver::new(ModuleId { local_id: module_id, krate: crate_id }); + + let file = def_maps[&crate_id].file_id(module_id); + + for (generics, _, functions) in methods { + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + resolver.add_generics(&generics); + let generics = resolver.get_generics().to_vec(); + let self_type = resolver.resolve_type(unresolved_type.clone()); + + let mut file_func_ids = resolve_function_set( + interner, + crate_id, + def_maps, + functions, + Some(self_type.clone()), + generics, + errors, + ); + if self_type != Type::Error { + for (file_id, method_id) in &file_func_ids { + let method_name = interner.function_name(method_id).to_owned(); + + if let Some(first_fn) = + interner.add_method(&self_type, method_name.clone(), *method_id) + { + let error = ResolverError::DuplicateDefinition { + name: method_name, + first_span: interner.function_ident(&first_fn).span(), + second_span: interner.function_ident(method_id).span(), + }; + + errors.push(error.into_file_diagnostic(*file_id)); + } + } + } + file_method_ids.append(&mut file_func_ids); + } + } + + file_method_ids +} + +fn resolve_trait_impls( + context: &mut Context, + traits: TraitImplMap, + crate_id: CrateId, + errors: &mut Vec, +) -> Vec<(FileId, FuncId)> { + let interner = &mut context.def_interner; + let mut methods = Vec::<(FileId, FuncId)>::new(); + + for ((unresolved_type, _, trait_id), trait_impl) in traits { + let local_mod_id = trait_impl.module_id; + let module_id = ModuleId { krate: crate_id, local_id: local_mod_id }; + let path_resolver = StandardPathResolver::new(module_id); + + let self_type = { + let mut resolver = + Resolver::new(interner, &path_resolver, &context.def_maps, trait_impl.file_id); + resolver.resolve_type(unresolved_type.clone()) + }; + + let mut impl_methods = resolve_function_set( + interner, + crate_id, + &context.def_maps, + trait_impl.methods.clone(), + Some(self_type.clone()), + vec![], // TODO + errors, + ); + + let trait_definition_ident = &trait_impl.trait_impl_ident; + let key = (self_type.clone(), trait_id); + if let Some(prev_trait_impl_ident) = interner.get_previous_trait_implementation(&key) { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::TraitImplementation, + first_def: prev_trait_impl_ident.clone(), + second_def: trait_definition_ident.clone(), + }; + errors.push(err.into_file_diagnostic(trait_impl.methods.file_id)); + } else { + let _func_ids = + interner.add_trait_implementaion(&key, trait_definition_ident, &trait_impl.methods); + } + + methods.append(&mut impl_methods); + } + + methods +} +fn resolve_free_functions( + interner: &mut NodeInterner, + crate_id: CrateId, + def_maps: &BTreeMap, + collected_functions: Vec, + self_type: Option, + errors: &mut Vec, +) -> Vec<(FileId, FuncId)> { + // Lower each function in the crate. This is now possible since imports have been resolved + collected_functions + .into_iter() + .flat_map(|unresolved_functions| { + resolve_function_set( + interner, + crate_id, + def_maps, + unresolved_functions, + self_type.clone(), + vec![], // no impl generics + errors, + ) + }) + .collect() +} + +fn resolve_function_set( + interner: &mut NodeInterner, + crate_id: CrateId, + def_maps: &BTreeMap, + unresolved_functions: UnresolvedFunctions, + self_type: Option, + impl_generics: Vec<(Rc, Shared, Span)>, + errors: &mut Vec, +) -> Vec<(FileId, FuncId)> { + let file_id = unresolved_functions.file_id; + + vecmap(unresolved_functions.functions, |(mod_id, func_id, func)| { + let module_id = ModuleId { krate: crate_id, local_id: mod_id }; + let path_resolver = + StandardPathResolver::new(ModuleId { local_id: mod_id, krate: crate_id }); + + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file_id); + // Must use set_generics here to ensure we re-use the same generics from when + // the impl was originally collected. Otherwise the function will be using different + // TypeVariables for the same generic, causing it to instantiate incorrectly. + resolver.set_generics(impl_generics.clone()); + resolver.set_self_type(self_type.clone()); + + let (hir_func, func_meta, errs) = resolver.resolve_function(func, func_id, module_id); + interner.push_fn_meta(func_meta, func_id); + interner.update_fn(func_id, hir_func); + extend_errors(errors, file_id, errs); + (file_id, func_id) + }) +} + +fn type_check_functions( + interner: &mut NodeInterner, + file_func_ids: Vec<(FileId, FuncId)>, + errors: &mut Vec, +) { + for (file, func) in file_func_ids { + extend_errors(errors, file, type_check_func(interner, func)); + } +} diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs new file mode 100644 index 00000000000..2679059cebd --- /dev/null +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -0,0 +1,539 @@ +use fm::FileId; +use noirc_errors::{FileDiagnostic, Location}; + +use crate::{ + graph::CrateId, + hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, + node_interner::TraitId, + parser::SubModule, + FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, + ParsedModule, TraitImpl, TraitImplItem, TraitItem, TypeImpl, +}; + +use super::{ + dc_crate::{ + DefCollector, UnresolvedFunctions, UnresolvedGlobal, UnresolvedTraitImpl, + UnresolvedTypeAlias, + }, + errors::{DefCollectorErrorKind, DuplicateType}, +}; +use crate::hir::def_map::{parse_file, LocalModuleId, ModuleData, ModuleDefId, ModuleId}; +use crate::hir::resolution::import::ImportDirective; +use crate::hir::Context; + +/// Given a module collect all definitions into ModuleData +struct ModCollector<'a> { + pub(crate) def_collector: &'a mut DefCollector, + pub(crate) file_id: FileId, + pub(crate) module_id: LocalModuleId, +} + +/// Walk a module and collect its definitions. +/// +/// This performs the entirety of the definition collection phase of the name resolution pass. +pub fn collect_defs( + def_collector: &mut DefCollector, + ast: ParsedModule, + file_id: FileId, + module_id: LocalModuleId, + crate_id: CrateId, + context: &mut Context, + errors: &mut Vec, +) { + let mut collector = ModCollector { def_collector, file_id, module_id }; + + // First resolve the module declarations + for decl in ast.module_decls { + collector.parse_module_declaration(context, &decl, crate_id, errors); + } + + collector.collect_submodules(context, crate_id, ast.submodules, file_id, errors); + + // Then add the imports to defCollector to resolve once all modules in the hierarchy have been resolved + for import in ast.imports { + collector.def_collector.collected_imports.push(ImportDirective { + module_id: collector.module_id, + path: import.path, + alias: import.alias, + }); + } + + collector.collect_globals(context, ast.globals, errors); + + collector.collect_traits(ast.traits, crate_id, errors); + + collector.collect_structs(context, ast.types, crate_id, errors); + + collector.collect_type_aliases(context, ast.type_aliases, errors); + + collector.collect_functions(context, ast.functions, errors); + + collector.collect_trait_impls(context, ast.trait_impls, errors); + + collector.collect_impls(context, ast.impls); +} + +impl<'a> ModCollector<'a> { + fn collect_globals( + &mut self, + context: &mut Context, + globals: Vec, + errors: &mut Vec, + ) { + for global in globals { + let name = global.pattern.name_ident().clone(); + + // First create dummy function in the DefInterner + // So that we can get a StmtId + let stmt_id = context.def_interner.push_empty_global(); + + // Add the statement to the scope so its path can be looked up later + let result = + self.def_collector.def_map.modules[self.module_id.0].declare_global(name, stmt_id); + + if let Err((first_def, second_def)) = result { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Global, + first_def, + second_def, + }; + errors.push(err.into_file_diagnostic(self.file_id)); + } + + self.def_collector.collected_globals.push(UnresolvedGlobal { + file_id: self.file_id, + module_id: self.module_id, + stmt_id, + stmt_def: global, + }); + } + } + + fn collect_impls(&mut self, context: &mut Context, impls: Vec) { + for r#impl in impls { + let mut unresolved_functions = + UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; + + for method in r#impl.methods { + let func_id = context.def_interner.push_empty_fn(); + context.def_interner.push_function_definition(method.name().to_owned(), func_id); + unresolved_functions.push_fn(self.module_id, func_id, method); + } + + let key = (r#impl.object_type, self.module_id); + let methods = self.def_collector.collected_impls.entry(key).or_default(); + methods.push((r#impl.generics, r#impl.type_span, unresolved_functions)); + } + } + + fn collect_trait_impls( + &mut self, + context: &mut Context, + impls: Vec, + errors: &mut Vec, + ) { + for trait_impl in impls { + let trait_name = trait_impl.trait_name.clone(); + let module = &self.def_collector.def_map.modules[self.module_id.0]; + match module.find_name(&trait_name).types { + Some((module_def_id, _visibility)) => { + if let Some(collected_trait) = self.get_unresolved_trait(module_def_id) { + let unresolved_functions = self.collect_trait_implementations( + context, + &trait_impl, + &collected_trait.trait_def, + errors, + ); + + for (_, func_id, noir_function) in &unresolved_functions.functions { + let name = noir_function.name().to_owned(); + + context.def_interner.push_function_definition(name, *func_id); + } + + let unresolved_trait_impl = UnresolvedTraitImpl { + file_id: self.file_id, + module_id: self.module_id, + the_trait: collected_trait, + methods: unresolved_functions, + trait_impl_ident: trait_impl.trait_name.clone(), + }; + + let trait_id = match module_def_id { + ModuleDefId::TraitId(trait_id) => trait_id, + _ => unreachable!(), + }; + + let key = (trait_impl.object_type, self.module_id, trait_id); + self.def_collector + .collected_traits_impls + .insert(key, unresolved_trait_impl); + } else { + let error = DefCollectorErrorKind::NotATrait { + not_a_trait_name: trait_name.clone(), + }; + errors.push(error.into_file_diagnostic(self.file_id)); + } + } + None => { + let error = DefCollectorErrorKind::TraitNotFound { trait_ident: trait_name }; + errors.push(error.into_file_diagnostic(self.file_id)); + } + } + } + } + + fn get_unresolved_trait(&self, module_def_id: ModuleDefId) -> Option { + match module_def_id { + ModuleDefId::TraitId(trait_id) => { + self.def_collector.collected_traits.get(&trait_id).cloned() + } + _ => None, + } + } + + fn collect_trait_implementations( + &mut self, + context: &mut Context, + trait_impl: &TraitImpl, + trait_def: &NoirTrait, + errors: &mut Vec, + ) -> UnresolvedFunctions { + let mut unresolved_functions = + UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; + + for item in &trait_impl.items { + if let TraitImplItem::Function(impl_method) = item { + let func_id = context.def_interner.push_empty_fn(); + context + .def_interner + .push_function_definition(impl_method.name().to_owned(), func_id); + unresolved_functions.push_fn(self.module_id, func_id, impl_method.clone()); + } + } + + for item in &trait_def.items { + // TODO(Maddiaa): Investigate trait implementations with attributes see: https://github.com/noir-lang/noir/issues/2629 + if let TraitItem::Function { + name, + generics, + parameters, + return_type, + where_clause, + body, + } = item + { + let is_implemented = unresolved_functions + .functions + .iter() + .any(|(_, _, func_impl)| func_impl.name() == name.0.contents); + if !is_implemented { + match body { + Some(body) => { + let method_name = name.0.contents.clone(); + let func_id = context.def_interner.push_empty_fn(); + context.def_interner.push_function_definition(method_name, func_id); + let impl_method = NoirFunction::normal(FunctionDefinition::normal( + name, + generics, + parameters, + body, + where_clause, + return_type, + )); + unresolved_functions.push_fn(self.module_id, func_id, impl_method); + } + None => { + let error = DefCollectorErrorKind::TraitMissedMethodImplementation { + trait_name: trait_def.name.clone(), + method_name: name.clone(), + trait_impl_span: trait_impl.object_type_span, + }; + errors.push(error.into_file_diagnostic(self.file_id)); + } + } + } + } + } + unresolved_functions + } + + fn collect_functions( + &mut self, + context: &mut Context, + functions: Vec, + errors: &mut Vec, + ) { + let mut unresolved_functions = + UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; + + for function in functions { + let name = function.name_ident().clone(); + + // First create dummy function in the DefInterner + // So that we can get a FuncId + let func_id = context.def_interner.push_empty_fn(); + context.def_interner.push_function_definition(name.0.contents.clone(), func_id); + + // Now link this func_id to a crate level map with the noir function and the module id + // Encountering a NoirFunction, we retrieve it's module_data to get the namespace + // Once we have lowered it to a HirFunction, we retrieve it's Id from the DefInterner + // and replace it + // With this method we iterate each function in the Crate and not each module + // This may not be great because we have to pull the module_data for each function + unresolved_functions.push_fn(self.module_id, func_id, function); + + // Add function to scope/ns of the module + let result = self.def_collector.def_map.modules[self.module_id.0] + .declare_function(name, func_id); + + if let Err((first_def, second_def)) = result { + let error = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Function, + first_def, + second_def, + }; + errors.push(error.into_file_diagnostic(self.file_id)); + } + } + + self.def_collector.collected_functions.push(unresolved_functions); + } + + /// Collect any struct definitions declared within the ast. + /// Returns a vector of errors if any structs were already defined. + fn collect_structs( + &mut self, + context: &mut Context, + types: Vec, + krate: CrateId, + errors: &mut Vec, + ) { + for struct_definition in types { + let name = struct_definition.name.clone(); + + let unresolved = UnresolvedStruct { + file_id: self.file_id, + module_id: self.module_id, + struct_def: struct_definition, + }; + + // Create the corresponding module for the struct namespace + let id = match self.push_child_module(&name, self.file_id, false, false, errors) { + Some(local_id) => context.def_interner.new_struct(&unresolved, krate, local_id), + None => continue, + }; + + // Add the struct to scope so its path can be looked up later + let result = + self.def_collector.def_map.modules[self.module_id.0].declare_struct(name, id); + + if let Err((first_def, second_def)) = result { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::TypeDefinition, + first_def, + second_def, + }; + errors.push(err.into_file_diagnostic(self.file_id)); + } + + // And store the TypeId -> StructType mapping somewhere it is reachable + self.def_collector.collected_types.insert(id, unresolved); + } + } + + /// Collect any type aliases definitions declared within the ast. + /// Returns a vector of errors if any type aliases were already defined. + fn collect_type_aliases( + &mut self, + context: &mut Context, + type_aliases: Vec, + errors: &mut Vec, + ) { + for type_alias in type_aliases { + let name = type_alias.name.clone(); + + // And store the TypeId -> TypeAlias mapping somewhere it is reachable + let unresolved = UnresolvedTypeAlias { + file_id: self.file_id, + module_id: self.module_id, + type_alias_def: type_alias, + }; + + let type_alias_id = context.def_interner.push_type_alias(&unresolved); + + // Add the type alias to scope so its path can be looked up later + let result = self.def_collector.def_map.modules[self.module_id.0] + .declare_type_alias(name, type_alias_id); + + if let Err((first_def, second_def)) = result { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Function, + first_def, + second_def, + }; + errors.push(err.into_file_diagnostic(self.file_id)); + } + + self.def_collector.collected_type_aliases.insert(type_alias_id, unresolved); + } + } + + /// Collect any traits definitions declared within the ast. + /// Returns a vector of errors if any traits were already defined. + fn collect_traits( + &mut self, + traits: Vec, + krate: CrateId, + errors: &mut Vec, + ) { + for trait_definition in traits { + let name = trait_definition.name.clone(); + + // Create the corresponding module for the trait namespace + let id = match self.push_child_module(&name, self.file_id, false, false, errors) { + Some(local_id) => TraitId(ModuleId { krate, local_id }), + None => continue, + }; + + // Add the trait to scope so its path can be looked up later + let result = + self.def_collector.def_map.modules[self.module_id.0].declare_trait(name, id); + + if let Err((first_def, second_def)) = result { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Trait, + first_def, + second_def, + }; + errors.push(err.into_file_diagnostic(self.file_id)); + } + + // And store the TraitId -> TraitType mapping somewhere it is reachable + let unresolved = UnresolvedTrait { + file_id: self.file_id, + module_id: self.module_id, + trait_def: trait_definition, + }; + self.def_collector.collected_traits.insert(id, unresolved); + } + } + + fn collect_submodules( + &mut self, + context: &mut Context, + crate_id: CrateId, + submodules: Vec, + file_id: FileId, + errors: &mut Vec, + ) { + for submodule in submodules { + if let Some(child) = self.push_child_module( + &submodule.name, + file_id, + true, + submodule.is_contract, + errors, + ) { + collect_defs( + self.def_collector, + submodule.contents, + file_id, + child, + crate_id, + context, + errors, + ); + } + } + } + + /// Search for a module named `mod_name` + /// Parse it, add it as a child to the parent module in which it was declared + /// and then collect all definitions of the child module + fn parse_module_declaration( + &mut self, + context: &mut Context, + mod_name: &Ident, + crate_id: CrateId, + errors: &mut Vec, + ) { + let child_file_id = + match context.file_manager.find_module(self.file_id, &mod_name.0.contents) { + Ok(child_file_id) => child_file_id, + Err(_) => { + let err = + DefCollectorErrorKind::UnresolvedModuleDecl { mod_name: mod_name.clone() }; + errors.push(err.into_file_diagnostic(self.file_id)); + return; + } + }; + + // Parse the AST for the module we just found and then recursively look for it's defs + let ast = parse_file(&mut context.file_manager, child_file_id, errors); + + // Add module into def collector and get a ModuleId + if let Some(child_mod_id) = + self.push_child_module(mod_name, child_file_id, true, false, errors) + { + collect_defs( + self.def_collector, + ast, + child_file_id, + child_mod_id, + crate_id, + context, + errors, + ); + } + } + + /// Add a child module to the current def_map. + /// On error this returns None and pushes to `errors` + fn push_child_module( + &mut self, + mod_name: &Ident, + file_id: FileId, + add_to_parent_scope: bool, + is_contract: bool, + errors: &mut Vec, + ) -> Option { + let parent = Some(self.module_id); + let location = Location::new(mod_name.span(), file_id); + let new_module = ModuleData::new(parent, location, is_contract); + let module_id = self.def_collector.def_map.modules.insert(new_module); + + let modules = &mut self.def_collector.def_map.modules; + + // Update the parent module to reference the child + modules[self.module_id.0].children.insert(mod_name.clone(), LocalModuleId(module_id)); + + // Add this child module into the scope of the parent module as a module definition + // module definitions are definitions which can only exist at the module level. + // ModuleDefinitionIds can be used across crates since they contain the CrateId + // + // We do not want to do this in the case of struct modules (each struct type corresponds + // to a child module containing its methods) since the module name should not shadow + // the struct name. + if add_to_parent_scope { + let mod_id = ModuleId { + krate: self.def_collector.def_map.krate, + local_id: LocalModuleId(module_id), + }; + + if let Err((first_def, second_def)) = + modules[self.module_id.0].declare_child_module(mod_name.to_owned(), mod_id) + { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Module, + first_def, + second_def, + }; + errors.push(err.into_file_diagnostic(self.file_id)); + return None; + } + } + + Some(LocalModuleId(module_id)) + } +} diff --git a/compiler/noirc_frontend/src/hir/def_collector/errors.rs b/compiler/noirc_frontend/src/hir/def_collector/errors.rs new file mode 100644 index 00000000000..ec5de088574 --- /dev/null +++ b/compiler/noirc_frontend/src/hir/def_collector/errors.rs @@ -0,0 +1,207 @@ +use crate::hir::resolution::import::PathResolutionError; +use crate::Ident; +use crate::UnresolvedType; + +use noirc_errors::CustomDiagnostic as Diagnostic; +use noirc_errors::FileDiagnostic; +use noirc_errors::Span; +use thiserror::Error; + +use std::fmt; + +#[derive(Debug)] +pub enum DuplicateType { + Function, + Module, + Global, + TypeDefinition, + Import, + Trait, + TraitImplementation, +} + +#[derive(Error, Debug)] +pub enum DefCollectorErrorKind { + #[error("duplicate {typ} found in namespace")] + Duplicate { typ: DuplicateType, first_def: Ident, second_def: Ident }, + #[error("unresolved import")] + UnresolvedModuleDecl { mod_name: Ident }, + #[error("path resolution error")] + PathResolutionError(PathResolutionError), + #[error("Non-struct type used in impl")] + NonStructTypeInImpl { span: Span }, + #[error("Non-struct type used in trait impl")] + NonStructTraitImpl { trait_ident: Ident, span: Span }, + #[error("Cannot `impl` a type defined outside the current crate")] + ForeignImpl { span: Span, type_name: String }, + #[error("Mismatch signature of trait")] + MismatchTraitImlementationParameter { + trait_name: String, + impl_method: String, + parameter: Ident, + expected_type: UnresolvedType, + }, + #[error("Mismatch return type of trait implementation")] + MismatchTraitImplementationReturnType { trait_name: String, impl_ident: Ident }, + #[error("Mismatch number of parameters in of trait implementation")] + MismatchTraitImplementationNumParameters { + actual_num_parameters: usize, + expected_num_parameters: usize, + trait_name: String, + impl_ident: Ident, + }, + #[error("Method is not defined in trait")] + MethodNotInTrait { trait_name: Ident, impl_method: Ident }, + #[error("Only traits can be implemented")] + NotATrait { not_a_trait_name: Ident }, + #[error("Trait not found")] + TraitNotFound { trait_ident: Ident }, + #[error("Missing Trait method implementation")] + TraitMissedMethodImplementation { trait_name: Ident, method_name: Ident, trait_impl_span: Span }, +} + +impl DefCollectorErrorKind { + pub fn into_file_diagnostic(self, file: fm::FileId) -> FileDiagnostic { + Diagnostic::from(self).in_file(file) + } +} + +impl fmt::Display for DuplicateType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + DuplicateType::Function => write!(f, "function"), + DuplicateType::Module => write!(f, "module"), + DuplicateType::Global => write!(f, "global"), + DuplicateType::TypeDefinition => write!(f, "type definition"), + DuplicateType::Trait => write!(f, "trait definition"), + DuplicateType::TraitImplementation => write!(f, "trait implementation"), + DuplicateType::Import => write!(f, "import"), + } + } +} + +impl From for Diagnostic { + fn from(error: DefCollectorErrorKind) -> Diagnostic { + match error { + DefCollectorErrorKind::Duplicate { typ, first_def, second_def } => { + let primary_message = format!( + "duplicate definitions of {} with name {} found", + &typ, &first_def.0.contents + ); + { + let first_span = first_def.0.span(); + let second_span = second_def.0.span(); + let mut diag = Diagnostic::simple_error( + primary_message, + format!("first {} found here", &typ), + first_span, + ); + diag.add_secondary(format!("second {} found here", &typ), second_span); + diag + } + } + DefCollectorErrorKind::UnresolvedModuleDecl { mod_name } => { + let span = mod_name.0.span(); + let mod_name = &mod_name.0.contents; + + Diagnostic::simple_error( + format!("could not resolve module `{mod_name}` "), + String::new(), + span, + ) + } + DefCollectorErrorKind::PathResolutionError(error) => error.into(), + DefCollectorErrorKind::NonStructTypeInImpl { span } => Diagnostic::simple_error( + "Non-struct type used in impl".into(), + "Only struct types may have implementation methods".into(), + span, + ), + DefCollectorErrorKind::NonStructTraitImpl { trait_ident, span } => { + Diagnostic::simple_error( + format!("Only struct types may implement trait `{trait_ident}`"), + "Only struct types may implement traits".into(), + span, + ) + } + DefCollectorErrorKind::ForeignImpl { span, type_name } => Diagnostic::simple_error( + "Cannot `impl` a type that was defined outside the current crate".into(), + format!("{type_name} was defined outside the current crate"), + span, + ), + DefCollectorErrorKind::TraitNotFound { trait_ident } => Diagnostic::simple_error( + format!("Trait {trait_ident} not found"), + "".to_string(), + trait_ident.span(), + ), + DefCollectorErrorKind::MismatchTraitImplementationReturnType { + trait_name, + impl_ident, + } => { + let span = impl_ident.span(); + let method_name = impl_ident.0.contents; + Diagnostic::simple_error( + format!("Mismatch return type of method with name {method_name} that implements trait {trait_name}"), + "".to_string(), + span, + ) + } + DefCollectorErrorKind::MismatchTraitImplementationNumParameters { + expected_num_parameters, + actual_num_parameters, + trait_name, + impl_ident, + } => { + let method_name = impl_ident.0.contents.clone(); + let primary_message = format!( + "Mismatch - expected {expected_num_parameters} arguments, but got {actual_num_parameters} of trait `{trait_name}` implementation `{method_name}`"); + Diagnostic::simple_error(primary_message, "".to_string(), impl_ident.span()) + } + DefCollectorErrorKind::MismatchTraitImlementationParameter { + trait_name, + impl_method, + parameter, + expected_type, + } => { + let primary_message = format!( + "Mismatch signature of method {impl_method} that implements trait {trait_name}" + ); + let secondary_message = + format!("`{}: {}` expected", parameter.0.contents, expected_type,); + let span = parameter.span(); + Diagnostic::simple_error(primary_message, secondary_message, span) + } + DefCollectorErrorKind::MethodNotInTrait { trait_name, impl_method } => { + let trait_name = trait_name.0.contents; + let impl_method_span = impl_method.span(); + let impl_method_name = impl_method.0.contents; + let primary_message = format!("method with name {impl_method_name} is not part of trait {trait_name}, therefore it can't be implemented"); + Diagnostic::simple_error(primary_message, "".to_owned(), impl_method_span) + } + DefCollectorErrorKind::TraitMissedMethodImplementation { + trait_name, + method_name, + trait_impl_span, + } => { + let trait_name = trait_name.0.contents; + let impl_method_name = method_name.0.contents; + let primary_message = format!( + "method `{impl_method_name}` from trait `{trait_name}` is not implemented" + ); + Diagnostic::simple_error( + primary_message, + format!("Please implement {impl_method_name} here"), + trait_impl_span, + ) + } + DefCollectorErrorKind::NotATrait { not_a_trait_name } => { + let span = not_a_trait_name.0.span(); + let name = ¬_a_trait_name.0.contents; + Diagnostic::simple_error( + format!("{name} is not a trait, therefore it can't be implemented"), + String::new(), + span, + ) + } + } + } +} diff --git a/crates/noirc_frontend/src/hir/def_collector/mod.rs b/compiler/noirc_frontend/src/hir/def_collector/mod.rs similarity index 100% rename from crates/noirc_frontend/src/hir/def_collector/mod.rs rename to compiler/noirc_frontend/src/hir/def_collector/mod.rs diff --git a/compiler/noirc_frontend/src/hir/def_map/aztec_library.rs b/compiler/noirc_frontend/src/hir/def_map/aztec_library.rs new file mode 100644 index 00000000000..9d7dfc458eb --- /dev/null +++ b/compiler/noirc_frontend/src/hir/def_map/aztec_library.rs @@ -0,0 +1,632 @@ +use acvm::FieldElement; +use noirc_errors::{CustomDiagnostic, Span}; + +use crate::graph::CrateId; +use crate::token::SecondaryAttribute; +use crate::{ + hir::Context, BlockExpression, CallExpression, CastExpression, Distinctness, Expression, + ExpressionKind, ForExpression, FunctionReturnType, Ident, ImportStatement, IndexExpression, + LetStatement, Literal, MemberAccessExpression, MethodCallExpression, NoirFunction, + ParsedModule, Path, PathKind, Pattern, Statement, UnresolvedType, UnresolvedTypeData, + Visibility, +}; +use noirc_errors::FileDiagnostic; + +// +// Helper macros for creating noir ast nodes +// +fn ident(name: &str) -> Ident { + Ident::new(name.to_string(), Span::default()) +} + +fn ident_path(name: &str) -> Path { + Path::from_ident(ident(name)) +} + +fn path(ident: Ident) -> Path { + Path::from_ident(ident) +} + +fn expression(kind: ExpressionKind) -> Expression { + Expression::new(kind, Span::default()) +} + +fn variable(name: &str) -> Expression { + expression(ExpressionKind::Variable(ident_path(name))) +} + +fn variable_ident(identifier: Ident) -> Expression { + expression(ExpressionKind::Variable(path(identifier))) +} + +fn variable_path(path: Path) -> Expression { + expression(ExpressionKind::Variable(path)) +} + +fn method_call(object: Expression, method_name: &str, arguments: Vec) -> Expression { + expression(ExpressionKind::MethodCall(Box::new(MethodCallExpression { + object, + method_name: ident(method_name), + arguments, + }))) +} + +fn call(func: Expression, arguments: Vec) -> Expression { + expression(ExpressionKind::Call(Box::new(CallExpression { func: Box::new(func), arguments }))) +} + +fn mutable(pattern: &str) -> Pattern { + Pattern::Mutable(Box::new(Pattern::Identifier(ident(pattern))), Span::default()) +} + +fn mutable_assignment(name: &str, assigned_to: Expression) -> Statement { + Statement::Let(LetStatement { + pattern: mutable(name), + r#type: make_type(UnresolvedTypeData::Unspecified), + expression: assigned_to, + }) +} + +fn member_access(lhs: &str, rhs: &str) -> Expression { + expression(ExpressionKind::MemberAccess(Box::new(MemberAccessExpression { + lhs: variable(lhs), + rhs: ident(rhs), + }))) +} + +macro_rules! chained_path { + ( $base:expr $(, $tail:expr)* ) => { + { + let mut base_path = ident_path($base); + $( + base_path.segments.push(ident($tail)); + )* + base_path + } + } +} + +macro_rules! chained_dep { + ( $base:expr $(, $tail:expr)* ) => { + { + let mut base_path = ident_path($base); + base_path.kind = PathKind::Dep; + $( + base_path.segments.push(ident($tail)); + )* + base_path + } + } +} + +fn cast(lhs: Expression, ty: UnresolvedTypeData) -> Expression { + expression(ExpressionKind::Cast(Box::new(CastExpression { lhs, r#type: make_type(ty) }))) +} + +fn make_type(typ: UnresolvedTypeData) -> UnresolvedType { + UnresolvedType { typ, span: None } +} + +fn index_array(array: Ident, index: &str) -> Expression { + expression(ExpressionKind::Index(Box::new(IndexExpression { + collection: variable_path(path(array)), + index: variable(index), + }))) +} + +fn index_array_variable(array: Expression, index: &str) -> Expression { + expression(ExpressionKind::Index(Box::new(IndexExpression { + collection: array, + index: variable(index), + }))) +} + +fn import(path: Path) -> ImportStatement { + ImportStatement { path, alias: None } +} + +// +// Create AST Nodes for Aztec +// + +/// Traverses every function in the ast, calling `transform_function` which +/// determines if further processing is required +pub(crate) fn transform( + mut ast: ParsedModule, + crate_id: &CrateId, + context: &Context, + errors: &mut Vec, +) -> ParsedModule { + // Usage -> mut ast -> aztec_library::transform(&mut ast) + + // Covers all functions in the ast + for submodule in ast.submodules.iter_mut().filter(|submodule| submodule.is_contract) { + if transform_module(&mut submodule.contents.functions) { + check_for_aztec_dependency(crate_id, context, errors); + include_relevant_imports(&mut submodule.contents); + } + } + ast +} + +/// Includes an import to the aztec library if it has not been included yet +fn include_relevant_imports(ast: &mut ParsedModule) { + // Create the aztec import path using the assumed chained_dep! macro + let aztec_import_path = import(chained_dep!("aztec")); + + // Check if the aztec import already exists + let is_aztec_imported = + ast.imports.iter().any(|existing_import| existing_import.path == aztec_import_path.path); + + // If aztec is not imported, add the import at the beginning + if !is_aztec_imported { + ast.imports.insert(0, aztec_import_path); + } +} + +/// Creates an error alerting the user that they have not downloaded the Aztec-noir library +fn check_for_aztec_dependency( + crate_id: &CrateId, + context: &Context, + errors: &mut Vec, +) { + let crate_graph = &context.crate_graph[crate_id]; + let has_aztec_dependency = crate_graph.dependencies.iter().any(|dep| dep.as_name() == "aztec"); + + if !has_aztec_dependency { + errors.push(FileDiagnostic::new( + crate_graph.root_file_id, + CustomDiagnostic::from_message( + "Aztec dependency not found. Please add aztec as a dependency in your Cargo.toml", + ), + )); + } +} + +/// Determines if the function is annotated with `aztec(private)` or `aztec(public)` +/// If it is, it calls the `transform` function which will perform the required transformations. +/// Returns true if an annotated function is found, false otherwise +fn transform_module(functions: &mut [NoirFunction]) -> bool { + let mut has_annotated_functions = false; + for func in functions.iter_mut() { + for secondary_attribute in func.def.attributes.secondary.clone() { + if let SecondaryAttribute::Custom(custom_attribute) = secondary_attribute { + match custom_attribute.as_str() { + "aztec(private)" => { + transform_function("Private", func); + has_annotated_functions = true; + } + "aztec(public)" => { + transform_function("Public", func); + has_annotated_functions = true; + } + _ => continue, + } + } + } + } + has_annotated_functions +} + +/// If it does, it will insert the following things: +/// - A new Input that is provided for a kernel app circuit, named: {Public/Private}ContextInputs +/// - Hashes all of the function input variables +/// - This instantiates a helper function +fn transform_function(ty: &str, func: &mut NoirFunction) { + let context_name = format!("{}Context", ty); + let inputs_name = format!("{}ContextInputs", ty); + let return_type_name = format!("{}CircuitPublicInputs", ty); + + // Insert the context creation as the first action + let create_context = create_context(&context_name, &func.def.parameters); + func.def.body.0.splice(0..0, (create_context).iter().cloned()); + + // Add the inputs to the params + let input = create_inputs(&inputs_name); + func.def.parameters.insert(0, input); + + // Abstract return types such that they get added to the kernel's return_values + if let Some(return_values) = abstract_return_values(func) { + func.def.body.0.push(return_values); + } + + // Push the finish method call to the end of the function + let finish_def = create_context_finish(); + func.def.body.0.push(finish_def); + + let return_type = create_return_type(&return_type_name); + func.def.return_type = return_type; + func.def.return_visibility = Visibility::Public; + + // Distinct return types are only required for private functions + // Public functions should have open auto-inferred + match ty { + "Private" => func.def.return_distinctness = Distinctness::Distinct, + "Public" => func.def.is_open = true, + _ => (), + } +} + +/// Helper function that returns what the private context would look like in the ast +/// This should make it available to be consumed within aztec private annotated functions. +/// +/// The replaced code: +/// ```noir +/// /// Before +/// fn foo(inputs: PrivateContextInputs) { +/// // ... +/// } +/// +/// /// After +/// #[aztec(private)] +/// fn foo() { +/// // ... +/// } +pub(crate) fn create_inputs(ty: &str) -> (Pattern, UnresolvedType, Visibility) { + let context_ident = ident("inputs"); + let context_pattern = Pattern::Identifier(context_ident); + let type_path = chained_path!("aztec", "abi", ty); + let context_type = make_type(UnresolvedTypeData::Named(type_path, vec![])); + let visibility = Visibility::Private; + + (context_pattern, context_type, visibility) +} + +/// Creates the private context object to be accessed within the function, the parameters need to be extracted to be +/// appended into the args hash object. +/// +/// The replaced code: +/// ```noir +/// #[aztec(private)] +/// fn foo(structInput: SomeStruct, arrayInput: [u8; 10], fieldInput: Field) -> Field { +/// // Create the hasher object +/// let mut hasher = Hasher::new(); +/// +/// // struct inputs call serialize on them to add an array of fields +/// hasher.add_multiple(structInput.serialize()); +/// +/// // Array inputs are iterated over and each element is added to the hasher (as a field) +/// for i in 0..arrayInput.len() { +/// hasher.add(arrayInput[i] as Field); +/// } +/// // Field inputs are added to the hasher +/// hasher.add({ident}); +/// +/// // Create the context +/// // The inputs (injected by this `create_inputs`) and completed hash object are passed to the context +/// let mut context = PrivateContext::new(inputs, hasher.hash()); +/// } +/// ``` +fn create_context(ty: &str, params: &[(Pattern, UnresolvedType, Visibility)]) -> Vec { + let mut injected_expressions: Vec = vec![]; + + // `let mut hasher = Hasher::new();` + let let_hasher = mutable_assignment( + "hasher", // Assigned to + call( + variable_path(chained_path!("aztec", "abi", "Hasher", "new")), // Path + vec![], // args + ), + ); + + // Completes: `let mut hasher = Hasher::new();` + injected_expressions.push(let_hasher); + + // Iterate over each of the function parameters, adding to them to the hasher + params.iter().for_each(|(pattern, typ, _vis)| { + match pattern { + Pattern::Identifier(identifier) => { + // Match the type to determine the padding to do + let unresolved_type = &typ.typ; + let expression = match unresolved_type { + // `hasher.add_multiple({ident}.serialize())` + UnresolvedTypeData::Named(..) => add_struct_to_hasher(identifier), + // TODO: if this is an array of structs, we should call serialize on each of them (no methods currently do this yet) + UnresolvedTypeData::Array(..) => add_array_to_hasher(identifier), + // `hasher.add({ident})` + UnresolvedTypeData::FieldElement => add_field_to_hasher(identifier), + // Add the integer to the hasher, casted to a field + // `hasher.add({ident} as Field)` + UnresolvedTypeData::Integer(..) | UnresolvedTypeData::Bool => { + add_cast_to_hasher(identifier) + } + _ => unreachable!("[Aztec Noir] Provided parameter type is not supported"), + }; + injected_expressions.push(expression); + } + _ => todo!(), // Maybe unreachable? + } + }); + + // Create the inputs to the context + let inputs_expression = variable("inputs"); + // `hasher.hash()` + let hash_call = method_call( + variable("hasher"), // variable + "hash", // method name + vec![], // args + ); + + // let mut context = {ty}::new(inputs, hash); + let let_context = mutable_assignment( + "context", // Assigned to + call( + variable_path(chained_path!("aztec", "context", ty, "new")), // Path + vec![inputs_expression, hash_call], // args + ), + ); + injected_expressions.push(let_context); + + // Return all expressions that will be injected by the hasher + injected_expressions +} + +/// Abstract Return Type +/// +/// This function intercepts the function's current return type and replaces it with pushes +/// To the kernel +/// +/// The replaced code: +/// ```noir +/// /// Before +/// #[aztec(private)] +/// fn foo() -> abi::PrivateCircuitPublicInputs { +/// // ... +/// let my_return_value: Field = 10; +/// context.return_values.push(my_return_value); +/// } +/// +/// /// After +/// #[aztec(private)] +/// fn foo() -> Field { +/// // ... +/// let my_return_value: Field = 10; +/// my_return_value +/// } +/// ``` +/// Similarly; Structs will be pushed to the context, after serialize() is called on them. +/// Arrays will be iterated over and each element will be pushed to the context. +/// Any primitive type that can be cast will be casted to a field and pushed to the context. +fn abstract_return_values(func: &NoirFunction) -> Option { + let current_return_type = func.return_type().typ; + let len = func.def.body.len(); + let last_statement = &func.def.body.0[len - 1]; + + // TODO: (length, type) => We can limit the size of the array returned to be limited by kernel size + // Doesnt need done until we have settled on a kernel size + // TODO: support tuples here and in inputs -> convert into an issue + + // Check if the return type is an expression, if it is, we can handle it + match last_statement { + Statement::Expression(expression) => match current_return_type { + // Call serialize on structs, push the whole array, calling push_array + UnresolvedTypeData::Named(..) => Some(make_struct_return_type(expression.clone())), + UnresolvedTypeData::Array(..) => Some(make_array_return_type(expression.clone())), + // Cast these types to a field before pushing + UnresolvedTypeData::Bool | UnresolvedTypeData::Integer(..) => { + Some(make_castable_return_type(expression.clone())) + } + UnresolvedTypeData::FieldElement => Some(make_return_push(expression.clone())), + _ => None, + }, + _ => None, + } +} + +/// Context Return Values +/// +/// Creates an instance to the context return values +/// ```noir +/// `context.return_values` +/// ``` +fn context_return_values() -> Expression { + member_access("context", "return_values") +} + +/// Make return Push +/// +/// Translates to: +/// `context.return_values.push({push_value})` +fn make_return_push(push_value: Expression) -> Statement { + Statement::Semi(method_call(context_return_values(), "push", vec![push_value])) +} + +/// Make Return push array +/// +/// Translates to: +/// `context.return_values.push_array({push_value})` +fn make_return_push_array(push_value: Expression) -> Statement { + Statement::Semi(method_call(context_return_values(), "push_array", vec![push_value])) +} + +/// Make struct return type +/// +/// Translates to: +/// ```noir +/// `context.return_values.push_array({push_value}.serialize())` +fn make_struct_return_type(expression: Expression) -> Statement { + let serialized_call = method_call( + expression.clone(), // variable + "serialize", // method name + vec![], // args + ); + make_return_push_array(serialized_call) +} + +/// Make array return type +/// +/// Translates to: +/// ```noir +/// for i in 0..{ident}.len() { +/// context.return_values.push({ident}[i] as Field) +/// } +/// ``` +fn make_array_return_type(expression: Expression) -> Statement { + let inner_cast_expression = + cast(index_array_variable(expression.clone(), "i"), UnresolvedTypeData::FieldElement); + let assignment = Statement::Semi(method_call( + context_return_values(), // variable + "push", // method name + vec![inner_cast_expression], + )); + + create_loop_over(expression.clone(), vec![assignment]) +} + +/// Castable return type +/// +/// Translates to: +/// ```noir +/// context.return_values.push({ident} as Field) +/// ``` +fn make_castable_return_type(expression: Expression) -> Statement { + // Cast these types to a field before pushing + let cast_expression = cast(expression.clone(), UnresolvedTypeData::FieldElement); + make_return_push(cast_expression) +} + +/// Create Return Type +/// +/// Public functions return abi::PublicCircuitPublicInputs while +/// private functions return abi::PrivateCircuitPublicInputs +/// +/// This call constructs an ast token referencing the above types +/// The name is set in the function above `transform`, hence the +/// whole token name is passed in +/// +/// The replaced code: +/// ```noir +/// +/// /// Before +/// fn foo() -> abi::PrivateCircuitPublicInputs { +/// // ... +/// } +/// +/// /// After +/// #[aztec(private)] +/// fn foo() { +/// // ... +/// } +pub(crate) fn create_return_type(ty: &str) -> FunctionReturnType { + let return_path = chained_path!("aztec", "abi", ty); + + let ty = make_type(UnresolvedTypeData::Named(return_path, vec![])); + FunctionReturnType::Ty(ty) +} + +/// Create Context Finish +/// +/// Each aztec function calls `context.finish()` at the end of a function +/// to return values required by the kernel. +/// +/// The replaced code: +/// ```noir +/// /// Before +/// fn foo() -> abi::PrivateCircuitPublicInputs { +/// // ... +/// context.finish() +/// } +/// +/// /// After +/// #[aztec(private)] +/// fn foo() { +/// // ... +/// } +pub(crate) fn create_context_finish() -> Statement { + let method_call = method_call( + variable("context"), // variable + "finish", // method name + vec![], // args + ); + Statement::Expression(method_call) +} + +// +// Methods to create hasher inputs +// + +fn add_struct_to_hasher(identifier: &Ident) -> Statement { + // If this is a struct, we call serialize and add the array to the hasher + let serialized_call = method_call( + variable_path(path(identifier.clone())), // variable + "serialize", // method name + vec![], // args + ); + + Statement::Semi(method_call( + variable("hasher"), // variable + "add_multiple", // method name + vec![serialized_call], // args + )) +} + +fn create_loop_over(var: Expression, loop_body: Vec) -> Statement { + // If this is an array of primitive types (integers / fields) we can add them each to the hasher + // casted to a field + + // `array.len()` + let end_range_expression = method_call( + var.clone(), // variable + "len", // method name + vec![], // args + ); + + // What will be looped over + // - `hasher.add({ident}[i] as Field)` + let for_loop_block = expression(ExpressionKind::Block(BlockExpression(loop_body))); + + // `for i in 0..{ident}.len()` + Statement::Expression(expression(ExpressionKind::For(Box::new(ForExpression { + identifier: ident("i"), + start_range: expression(ExpressionKind::Literal(Literal::Integer(FieldElement::from( + i128::from(0), + )))), + end_range: end_range_expression, + block: for_loop_block, + })))) +} + +fn add_array_to_hasher(identifier: &Ident) -> Statement { + // If this is an array of primitive types (integers / fields) we can add them each to the hasher + // casted to a field + + // Wrap in the semi thing - does that mean ended with semi colon? + // `hasher.add({ident}[i] as Field)` + let cast_expression = cast( + index_array(identifier.clone(), "i"), // lhs - `ident[i]` + UnresolvedTypeData::FieldElement, // cast to - `as Field` + ); + let block_statement = Statement::Semi(method_call( + variable("hasher"), // variable + "add", // method name + vec![cast_expression], + )); + + create_loop_over(variable_ident(identifier.clone()), vec![block_statement]) +} + +fn add_field_to_hasher(identifier: &Ident) -> Statement { + // `hasher.add({ident})` + let iden = variable_path(path(identifier.clone())); + Statement::Semi(method_call( + variable("hasher"), // variable + "add", // method name + vec![iden], // args + )) +} + +fn add_cast_to_hasher(identifier: &Ident) -> Statement { + // `hasher.add({ident} as Field)` + // `{ident} as Field` + let cast_operation = cast( + variable_path(path(identifier.clone())), // lhs + UnresolvedTypeData::FieldElement, // rhs + ); + + // `hasher.add({ident} as Field)` + Statement::Semi(method_call( + variable("hasher"), // variable + "add", // method name + vec![cast_operation], // args + )) +} diff --git a/crates/noirc_frontend/src/hir/def_map/item_scope.rs b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs similarity index 100% rename from crates/noirc_frontend/src/hir/def_map/item_scope.rs rename to compiler/noirc_frontend/src/hir/def_map/item_scope.rs diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs new file mode 100644 index 00000000000..2d5f7f38191 --- /dev/null +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -0,0 +1,278 @@ +use crate::graph::CrateId; +use crate::hir::def_collector::dc_crate::DefCollector; +use crate::hir::Context; +use crate::node_interner::{FuncId, NodeInterner}; +use crate::parser::{parse_program, ParsedModule}; +use crate::token::{PrimaryAttribute, TestScope}; +use arena::{Arena, Index}; +use fm::{FileId, FileManager}; +use noirc_errors::{FileDiagnostic, Location}; +use std::collections::BTreeMap; + +mod module_def; +pub use module_def::*; +mod item_scope; +pub use item_scope::*; +mod module_data; +pub use module_data::*; +mod namespace; +pub use namespace::*; + +#[cfg(feature = "aztec")] +mod aztec_library; + +/// The name that is used for a non-contract program's entry-point function. +pub const MAIN_FUNCTION: &str = "main"; + +// XXX: Ultimately, we want to constrain an index to be of a certain type just like in RA +/// Lets first check if this is offered by any external crate +/// XXX: RA has made this a crate on crates.io +#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)] +pub struct LocalModuleId(pub Index); + +impl LocalModuleId { + pub fn dummy_id() -> LocalModuleId { + LocalModuleId(Index::from_raw_parts(std::usize::MAX, std::u64::MAX)) + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct ModuleId { + pub krate: CrateId, + pub local_id: LocalModuleId, +} + +impl ModuleId { + pub fn dummy_id() -> ModuleId { + ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() } + } +} + +impl ModuleId { + pub fn module(self, def_maps: &BTreeMap) -> &ModuleData { + &def_maps[&self.krate].modules()[self.local_id.0] + } +} + +/// Map of all modules and scopes defined within a crate. +/// +/// The definitions of the crate are accessible indirectly via the scopes of each module. +#[derive(Debug)] +pub struct CrateDefMap { + pub(crate) root: LocalModuleId, + + pub(crate) modules: Arena, + + pub(crate) krate: CrateId, + + pub(crate) extern_prelude: BTreeMap, +} + +impl CrateDefMap { + /// Collect all definitions in the crate + pub fn collect_defs( + crate_id: CrateId, + context: &mut Context, + errors: &mut Vec, + ) { + // Check if this Crate has already been compiled + // XXX: There is probably a better alternative for this. + // Without this check, the compiler will panic as it does not + // expect the same crate to be processed twice. It would not + // make the implementation wrong, if the same crate was processed twice, it just makes it slow. + if context.def_map(&crate_id).is_some() { + return; + } + + // First parse the root file. + let root_file_id = context.crate_graph[crate_id].root_file_id; + let ast = parse_file(&mut context.file_manager, root_file_id, errors); + + #[cfg(feature = "aztec")] + let ast = aztec_library::transform(ast, &crate_id, context, errors); + + // Allocate a default Module for the root, giving it a ModuleId + let mut modules: Arena = Arena::default(); + let location = Location::new(Default::default(), root_file_id); + let root = modules.insert(ModuleData::new(None, location, false)); + + let def_map = CrateDefMap { + root: LocalModuleId(root), + modules, + krate: crate_id, + extern_prelude: BTreeMap::new(), + }; + + // Now we want to populate the CrateDefMap using the DefCollector + DefCollector::collect(def_map, context, ast, root_file_id, errors); + } + + pub fn root(&self) -> LocalModuleId { + self.root + } + pub fn modules(&self) -> &Arena { + &self.modules + } + pub fn krate(&self) -> CrateId { + self.krate + } + + /// Find the main function for this crate + pub fn main_function(&self) -> Option { + let root_module = &self.modules()[self.root.0]; + + // This function accepts an Ident, so we attach a dummy span to + // "main". Equality is implemented only on the contents. + root_module.find_func_with_name(&MAIN_FUNCTION.into()) + } + + pub fn file_id(&self, module_id: LocalModuleId) -> FileId { + self.modules[module_id.0].location.file + } + + /// Go through all modules in this crate, and find all functions in + /// each module with the #[test] attribute + pub fn get_all_test_functions<'a>( + &'a self, + interner: &'a NodeInterner, + ) -> impl Iterator + 'a { + self.modules.iter().flat_map(|(_, module)| { + module.value_definitions().filter_map(|id| { + if let Some(func_id) = id.as_function() { + let func_meta = interner.function_meta(&func_id); + match func_meta.attributes.primary { + Some(PrimaryAttribute::Test(scope)) => { + Some(TestFunction::new(func_id, scope, func_meta.name.location)) + } + _ => None, + } + } else { + None + } + }) + }) + } + + /// Go through all modules in this crate, find all `contract ... { ... }` declarations, + /// and collect them all into a Vec. + pub fn get_all_contracts(&self) -> Vec { + self.modules + .iter() + .filter_map(|(id, module)| { + if module.is_contract { + let functions = + module.value_definitions().filter_map(|id| id.as_function()).collect(); + let name = self.get_module_path(id, module.parent); + Some(Contract { name, location: module.location, functions }) + } else { + None + } + }) + .collect() + } + + /// Find a child module's name by inspecting its parent. + /// Currently required as modules do not store their own names. + pub fn get_module_path(&self, child_id: Index, parent: Option) -> String { + self.get_module_path_with_separator(child_id, parent, ".") + } + + pub fn get_module_path_with_separator( + &self, + child_id: Index, + parent: Option, + separator: &str, + ) -> String { + if let Some(id) = parent { + let parent = &self.modules[id.0]; + let name = parent + .children + .iter() + .find(|(_, id)| id.0 == child_id) + .map(|(name, _)| &name.0.contents) + .expect("Child module was not a child of the given parent module"); + + let parent_name = self.get_module_path_with_separator(id.0, parent.parent, separator); + if parent_name.is_empty() { + name.to_string() + } else { + format!("{parent_name}{separator}{name}") + } + } else { + String::new() + } + } +} + +/// A 'contract' in Noir source code with the given name and functions. +/// This is not an AST node, it is just a convenient form to return for CrateDefMap::get_all_contracts. +pub struct Contract { + /// To keep `name` semi-unique, it is prefixed with the names of parent modules via CrateDefMap::get_module_path + pub name: String, + pub location: Location, + pub functions: Vec, +} + +/// Given a FileId, fetch the File, from the FileManager and parse it's content +pub fn parse_file( + fm: &mut FileManager, + file_id: FileId, + all_errors: &mut Vec, +) -> ParsedModule { + let file = fm.fetch_file(file_id); + let (program, errors) = parse_program(file.source()); + all_errors.extend(errors.into_iter().map(|error| error.in_file(file_id))); + program +} + +impl std::ops::Index for CrateDefMap { + type Output = ModuleData; + fn index(&self, local_module_id: LocalModuleId) -> &ModuleData { + &self.modules[local_module_id.0] + } +} +impl std::ops::IndexMut for CrateDefMap { + fn index_mut(&mut self, local_module_id: LocalModuleId) -> &mut ModuleData { + &mut self.modules[local_module_id.0] + } +} + +pub struct TestFunction { + id: FuncId, + scope: TestScope, + location: Location, +} + +impl TestFunction { + fn new(id: FuncId, scope: TestScope, location: Location) -> Self { + TestFunction { id, scope, location } + } + + /// Returns the function id of the test function + pub fn get_id(&self) -> FuncId { + self.id + } + + pub fn file_id(&self) -> FileId { + self.location.file + } + + /// Returns true if the test function has been specified to fail + /// This is done by annotating the function with `#[test(should_fail)]` + /// or `#[test(should_fail_with = "reason")]` + pub fn should_fail(&self) -> bool { + match self.scope { + TestScope::ShouldFailWith { .. } => true, + TestScope::None => false, + } + } + + /// Returns the reason for the test function to fail if specified + /// by the user. + pub fn failure_reason(&self) -> Option<&str> { + match &self.scope { + TestScope::None => None, + TestScope::ShouldFailWith { reason } => reason.as_deref(), + } + } +} diff --git a/crates/noirc_frontend/src/hir/def_map/module_data.rs b/compiler/noirc_frontend/src/hir/def_map/module_data.rs similarity index 100% rename from crates/noirc_frontend/src/hir/def_map/module_data.rs rename to compiler/noirc_frontend/src/hir/def_map/module_data.rs diff --git a/crates/noirc_frontend/src/hir/def_map/module_def.rs b/compiler/noirc_frontend/src/hir/def_map/module_def.rs similarity index 100% rename from crates/noirc_frontend/src/hir/def_map/module_def.rs rename to compiler/noirc_frontend/src/hir/def_map/module_def.rs diff --git a/crates/noirc_frontend/src/hir/def_map/namespace.rs b/compiler/noirc_frontend/src/hir/def_map/namespace.rs similarity index 91% rename from crates/noirc_frontend/src/hir/def_map/namespace.rs rename to compiler/noirc_frontend/src/hir/def_map/namespace.rs index f0d0f154661..9221b389d84 100644 --- a/crates/noirc_frontend/src/hir/def_map/namespace.rs +++ b/compiler/noirc_frontend/src/hir/def_map/namespace.rs @@ -21,11 +21,11 @@ impl PerNs { } pub fn iter_defs(self) -> impl Iterator { - self.types.map(|it| it.0).into_iter().chain(self.values.map(|it| it.0).into_iter()) + self.types.map(|it| it.0).into_iter().chain(self.values.map(|it| it.0)) } pub fn iter_items(self) -> impl Iterator { - self.types.into_iter().chain(self.values.into_iter()) + self.types.into_iter().chain(self.values) } pub fn is_none(&self) -> bool { diff --git a/compiler/noirc_frontend/src/hir/mod.rs b/compiler/noirc_frontend/src/hir/mod.rs new file mode 100644 index 00000000000..1bdd3a62b72 --- /dev/null +++ b/compiler/noirc_frontend/src/hir/mod.rs @@ -0,0 +1,189 @@ +pub mod def_collector; +pub mod def_map; +pub mod resolution; +pub mod scope; +pub mod type_check; + +use crate::graph::{CrateGraph, CrateId, Dependency}; +use crate::hir_def::function::FuncMeta; +use crate::node_interner::{FuncId, NodeInterner, StructId}; +use def_map::{Contract, CrateDefMap}; +use fm::FileManager; +use std::collections::BTreeMap; + +use self::def_map::TestFunction; + +/// Helper object which groups together several useful context objects used +/// during name resolution. Once name resolution is finished, only the +/// def_interner is required for type inference and monomorphization. +pub struct Context { + pub def_interner: NodeInterner, + pub crate_graph: CrateGraph, + pub(crate) def_maps: BTreeMap, + pub file_manager: FileManager, + + /// Maps a given (contract) module id to the next available storage slot + /// for that contract. + pub storage_slots: BTreeMap, +} + +#[derive(Debug, Copy, Clone)] +pub enum FunctionNameMatch<'a> { + Anything, + Exact(&'a str), + Contains(&'a str), +} + +pub type StorageSlot = u32; + +impl Context { + pub fn new(file_manager: FileManager, crate_graph: CrateGraph) -> Context { + Context { + def_interner: NodeInterner::default(), + def_maps: BTreeMap::new(), + crate_graph, + file_manager, + storage_slots: BTreeMap::new(), + } + } + + /// Returns the CrateDefMap for a given CrateId. + /// It is perfectly valid for the compiler to look + /// up a CrateDefMap and it is not available. + /// This is how the compiler knows to compile a Crate. + pub fn def_map(&self, crate_id: &CrateId) -> Option<&CrateDefMap> { + self.def_maps.get(crate_id) + } + + /// Return the CrateId for each crate that has been compiled + /// successfully + pub fn crates(&self) -> impl Iterator + '_ { + self.crate_graph.iter_keys() + } + + pub fn root_crate_id(&self) -> &CrateId { + self.crate_graph.root_crate_id() + } + + pub fn stdlib_crate_id(&self) -> &CrateId { + self.crate_graph.stdlib_crate_id() + } + + // TODO: Decide if we actually need `function_name` and `fully_qualified_function_name` + pub fn function_name(&self, id: &FuncId) -> &str { + self.def_interner.function_name(id) + } + + pub fn fully_qualified_function_name(&self, crate_id: &CrateId, id: &FuncId) -> String { + let def_map = self.def_map(crate_id).expect("The local crate should be analyzed already"); + + let name = self.def_interner.function_name(id); + + let meta = self.def_interner.function_meta(id); + let module = self.module(meta.module_id); + + let parent = + def_map.get_module_path_with_separator(meta.module_id.local_id.0, module.parent, "::"); + + if parent.is_empty() { + name.into() + } else { + format!("{parent}::{name}") + } + } + + /// Returns a fully-qualified path to the given [StructId] from the given [CrateId]. This function also + /// account for the crate names of dependencies. + /// + /// For example, if you project contains a `main.nr` and `foo.nr` and you provide the `main_crate_id` and the + /// `bar_struct_id` where the `Bar` struct is inside `foo.nr`, this function would return `foo::Bar` as a [String]. + pub fn fully_qualified_struct_path(&self, crate_id: &CrateId, id: StructId) -> String { + let module_id = id.module_id(); + let child_id = module_id.local_id.0; + let def_map = + self.def_map(&module_id.krate).expect("The local crate should be analyzed already"); + + let module = self.module(module_id); + + let module_path = def_map.get_module_path_with_separator(child_id, module.parent, "::"); + + if &module_id.krate == crate_id { + module_path + } else { + let crate_name = &self.crate_graph[crate_id] + .dependencies + .iter() + .find_map(|dep| match dep { + Dependency { name, crate_id } if crate_id == &module_id.krate => Some(name), + _ => None, + }) + .expect("The Struct was supposed to be defined in a dependency"); + format!("{crate_name}::{module_path}") + } + } + + pub fn function_meta(&self, func_id: &FuncId) -> FuncMeta { + self.def_interner.function_meta(func_id) + } + + /// Returns the FuncId of the 'main' function in a crate. + /// - Expects check_crate to be called beforehand + /// - Panics if no main function is found + pub fn get_main_function(&self, crate_id: &CrateId) -> Option { + // Find the local crate, one should always be present + let local_crate = self.def_map(crate_id).unwrap(); + + local_crate.main_function() + } + + /// Returns a list of all functions in the current crate marked with #[test] + /// whose names contain the given pattern string. An empty pattern string + /// will return all functions marked with #[test]. + pub fn get_all_test_functions_in_crate_matching( + &self, + crate_id: &CrateId, + pattern: FunctionNameMatch, + ) -> Vec<(String, TestFunction)> { + let interner = &self.def_interner; + let def_map = self.def_map(crate_id).expect("The local crate should be analyzed already"); + + def_map + .get_all_test_functions(interner) + .filter_map(|test_function| { + let fully_qualified_name = + self.fully_qualified_function_name(crate_id, &test_function.get_id()); + match &pattern { + FunctionNameMatch::Anything => Some((fully_qualified_name, test_function)), + FunctionNameMatch::Exact(pattern) => (&fully_qualified_name == pattern) + .then_some((fully_qualified_name, test_function)), + FunctionNameMatch::Contains(pattern) => fully_qualified_name + .contains(pattern) + .then_some((fully_qualified_name, test_function)), + } + }) + .collect() + } + + /// Return a Vec of all `contract` declarations in the source code and the functions they contain + pub fn get_all_contracts(&self, crate_id: &CrateId) -> Vec { + self.def_map(crate_id) + .expect("The local crate should be analyzed already") + .get_all_contracts() + } + + fn module(&self, module_id: def_map::ModuleId) -> &def_map::ModuleData { + module_id.module(&self.def_maps) + } + + /// Returns the next available storage slot in the given module. + /// Returns None if the given module is not a contract module. + fn next_storage_slot(&mut self, module_id: def_map::ModuleId) -> Option { + let module = self.module(module_id); + + module.is_contract.then(|| { + let next_slot = self.storage_slots.entry(module_id).or_insert(0); + *next_slot += 1; + *next_slot + }) + } +} diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs new file mode 100644 index 00000000000..93304ac151c --- /dev/null +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -0,0 +1,293 @@ +pub use noirc_errors::Span; +use noirc_errors::{CustomDiagnostic as Diagnostic, FileDiagnostic}; +use thiserror::Error; + +use crate::{parser::ParserError, Ident, Type}; + +use super::import::PathResolutionError; + +#[derive(Error, Debug, Clone, PartialEq, Eq)] +pub enum PubPosition { + #[error("parameter")] + Parameter, + #[error("return type")] + ReturnType, +} + +#[derive(Error, Debug, Clone, PartialEq, Eq)] +pub enum ResolverError { + #[error("Duplicate definition")] + DuplicateDefinition { name: String, first_span: Span, second_span: Span }, + #[error("Unused variable")] + UnusedVariable { ident: Ident }, + #[error("Could not find variable in this scope")] + VariableNotDeclared { name: String, span: Span }, + #[error("path is not an identifier")] + PathIsNotIdent { span: Span }, + #[error("could not resolve path")] + PathResolutionError(PathResolutionError), + #[error("Expected")] + Expected { span: Span, expected: String, got: String }, + #[error("Duplicate field in constructor")] + DuplicateField { field: Ident }, + #[error("No such field in struct")] + NoSuchField { field: Ident, struct_definition: Ident }, + #[error("Missing fields from struct")] + MissingFields { span: Span, missing_fields: Vec, struct_definition: Ident }, + #[error("Unneeded 'mut', pattern is already marked as mutable")] + UnnecessaryMut { first_mut: Span, second_mut: Span }, + #[error("Unneeded 'pub', function is not the main method")] + UnnecessaryPub { ident: Ident, position: PubPosition }, + #[error("Required 'pub', main function must return public value")] + NecessaryPub { ident: Ident }, + #[error("'distinct' keyword can only be used with main method")] + DistinctNotAllowed { ident: Ident }, + #[error("Missing expression for declared constant")] + MissingRhsExpr { name: String, span: Span }, + #[error("Expression invalid in an array length context")] + InvalidArrayLengthExpr { span: Span }, + #[error("Integer too large to be evaluated in an array length context")] + IntegerTooLarge { span: Span }, + #[error("No global or generic type parameter found with the given name")] + NoSuchNumericTypeVariable { path: crate::Path }, + #[error("Closures cannot capture mutable variables")] + CapturedMutableVariable { span: Span }, + #[error("Test functions are not allowed to have any parameters")] + TestFunctionHasParameters { span: Span }, + #[error("Only struct types can be used in constructor expressions")] + NonStructUsedInConstructor { typ: Type, span: Span }, + #[error("Only struct types can have generics")] + NonStructWithGenerics { span: Span }, + #[error("Cannot apply generics on Self type")] + GenericsOnSelfType { span: Span }, + #[error("Incorrect amount of arguments to generic type constructor")] + IncorrectGenericCount { span: Span, struct_type: String, actual: usize, expected: usize }, + #[error("{0}")] + ParserError(Box), + #[error("Function is not defined in a contract yet sets its contract visibility")] + ContractFunctionTypeInNormalFunction { span: Span }, + #[error("Cannot create a mutable reference to {variable}, it was declared to be immutable")] + MutableReferenceToImmutableVariable { variable: String, span: Span }, + #[error("Mutable references to array indices are unsupported")] + MutableReferenceToArrayElement { span: Span }, + #[error("Function is not defined in a contract yet sets is_internal")] + ContractFunctionInternalInNormalFunction { span: Span }, + #[error("Numeric constants should be printed without formatting braces")] + NumericConstantInFormatString { name: String, span: Span }, + #[error("Closure environment must be a tuple or unit type")] + InvalidClosureEnvironment { typ: Type, span: Span }, +} + +impl ResolverError { + pub fn into_file_diagnostic(self, file: fm::FileId) -> FileDiagnostic { + Diagnostic::from(self).in_file(file) + } +} + +impl From for Diagnostic { + /// Only user errors can be transformed into a Diagnostic + /// ICEs will make the compiler panic, as they could affect the + /// soundness of the generated program + fn from(error: ResolverError) -> Diagnostic { + match error { + ResolverError::DuplicateDefinition { name, first_span, second_span } => { + let mut diag = Diagnostic::simple_error( + format!("duplicate definitions of {name} found"), + "first definition found here".to_string(), + first_span, + ); + diag.add_secondary("second definition found here".to_string(), second_span); + diag + } + ResolverError::UnusedVariable { ident } => { + let name = &ident.0.contents; + + Diagnostic::simple_warning( + format!("unused variable {name}"), + "unused variable ".to_string(), + ident.span(), + ) + } + ResolverError::VariableNotDeclared { name, span } => Diagnostic::simple_error( + format!("cannot find `{name}` in this scope "), + "not found in this scope".to_string(), + span, + ), + ResolverError::PathIsNotIdent { span } => Diagnostic::simple_error( + "cannot use path as an identifier".to_string(), + String::new(), + span, + ), + ResolverError::PathResolutionError(error) => error.into(), + ResolverError::Expected { span, expected, got } => Diagnostic::simple_error( + format!("expected {expected} got {got}"), + String::new(), + span, + ), + ResolverError::DuplicateField { field } => Diagnostic::simple_error( + format!("duplicate field {field}"), + String::new(), + field.span(), + ), + ResolverError::NoSuchField { field, struct_definition } => { + let mut error = Diagnostic::simple_error( + format!("no such field {field} defined in struct {struct_definition}"), + String::new(), + field.span(), + ); + + error.add_secondary( + format!("{struct_definition} defined here with no {field} field"), + struct_definition.span(), + ); + error + } + ResolverError::MissingFields { span, missing_fields, struct_definition } => { + let plural = if missing_fields.len() != 1 { "s" } else { "" }; + let missing_fields = missing_fields.join(", "); + + let mut error = Diagnostic::simple_error( + format!("missing field{plural}: {missing_fields}"), + String::new(), + span, + ); + + error.add_secondary( + format!("{struct_definition} defined here"), + struct_definition.span(), + ); + error + } + ResolverError::UnnecessaryMut { first_mut, second_mut } => { + let mut error = Diagnostic::simple_error( + "'mut' here is not necessary".to_owned(), + "".to_owned(), + second_mut, + ); + error.add_secondary( + "Pattern was already made mutable from this 'mut'".to_owned(), + first_mut, + ); + error + } + ResolverError::UnnecessaryPub { ident, position } => { + let name = &ident.0.contents; + + let mut diag = Diagnostic::simple_warning( + format!("unnecessary pub keyword on {position} for function {name}"), + format!("unnecessary pub {position}"), + ident.0.span(), + ); + + diag.add_note("The `pub` keyword only has effects on arguments to the entry-point function of a program. Thus, adding it to other function parameters can be deceiving and should be removed".to_owned()); + diag + } + ResolverError::NecessaryPub { ident } => { + let name = &ident.0.contents; + + let mut diag = Diagnostic::simple_error( + format!("missing pub keyword on return type of function {name}"), + "missing pub on return type".to_string(), + ident.0.span(), + ); + + diag.add_note("The `pub` keyword is mandatory for the entry-point function return type because the verifier cannot retrieve private witness and thus the function will not be able to return a 'priv' value".to_owned()); + diag + } + ResolverError::DistinctNotAllowed { ident } => { + let name = &ident.0.contents; + + let mut diag = Diagnostic::simple_error( + format!("Invalid `distinct` keyword on return type of function {name}"), + "Invalid distinct on return type".to_string(), + ident.0.span(), + ); + + diag.add_note("The `distinct` keyword is only valid when used on the main function of a program, as its only purpose is to ensure that all witness indices that occur in the abi are unique".to_owned()); + diag + } + ResolverError::MissingRhsExpr { name, span } => Diagnostic::simple_error( + format!( + "no expression specifying the value stored by the constant variable {name}" + ), + "expected expression to be stored for let statement".to_string(), + span, + ), + ResolverError::InvalidArrayLengthExpr { span } => Diagnostic::simple_error( + "Expression invalid in an array-length context".into(), + "Array-length expressions can only have simple integer operations and any variables used must be global constants".into(), + span, + ), + ResolverError::IntegerTooLarge { span } => Diagnostic::simple_error( + "Integer too large to be evaluated to an array-length".into(), + "Array-lengths may be a maximum size of usize::MAX, including intermediate calculations".into(), + span, + ), + ResolverError::NoSuchNumericTypeVariable { path } => Diagnostic::simple_error( + format!("Cannot find a global or generic type parameter named `{path}`"), + "Only globals or generic type parameters are allowed to be used as an array type's length".to_string(), + path.span(), + ), + ResolverError::CapturedMutableVariable { span } => Diagnostic::simple_error( + "Closures cannot capture mutable variables".into(), + "Mutable variable".into(), + span, + ), + ResolverError::TestFunctionHasParameters { span } => Diagnostic::simple_error( + "Test functions cannot have any parameters".into(), + "Try removing the parameters or moving the test into a wrapper function".into(), + span, + ), + ResolverError::NonStructUsedInConstructor { typ, span } => Diagnostic::simple_error( + "Only struct types can be used in constructor expressions".into(), + format!("{typ} has no fields to construct it with"), + span, + ), + ResolverError::NonStructWithGenerics { span } => Diagnostic::simple_error( + "Only struct types can have generic arguments".into(), + "Try removing the generic arguments".into(), + span, + ), + ResolverError::GenericsOnSelfType { span } => Diagnostic::simple_error( + "Cannot apply generics to Self type".into(), + "Use an explicit type name or apply the generics at the start of the impl instead".into(), + span, + ), + ResolverError::IncorrectGenericCount { span, struct_type, actual, expected } => { + let expected_plural = if expected == 1 { "" } else { "s" }; + let actual_plural = if actual == 1 { "is" } else { "are" }; + + Diagnostic::simple_error( + format!("The struct type {struct_type} has {expected} generic{expected_plural} but {actual} {actual_plural} given here"), + "Incorrect number of generic arguments".into(), + span, + ) + } + ResolverError::ParserError(error) => (*error).into(), + ResolverError::ContractFunctionTypeInNormalFunction { span } => Diagnostic::simple_error( + "Only functions defined within contracts can set their contract function type".into(), + "Non-contract functions cannot be 'open'".into(), + span, + ), + ResolverError::MutableReferenceToImmutableVariable { variable, span } => { + Diagnostic::simple_error(format!("Cannot mutably reference the immutable variable {variable}"), format!("{variable} is immutable"), span) + }, + ResolverError::MutableReferenceToArrayElement { span } => { + Diagnostic::simple_error("Mutable references to array elements are currently unsupported".into(), "Try storing the element in a fresh variable first".into(), span) + }, + ResolverError::ContractFunctionInternalInNormalFunction { span } => Diagnostic::simple_error( + "Only functions defined within contracts can set their functions to be internal".into(), + "Non-contract functions cannot be 'internal'".into(), + span, + ), + ResolverError::NumericConstantInFormatString { name, span } => Diagnostic::simple_error( + format!("cannot find `{name}` in this scope "), + "Numeric constants should be printed without formatting braces".to_string(), + span, + ), + ResolverError::InvalidClosureEnvironment { span, typ } => Diagnostic::simple_error( + format!("{typ} is not a valid closure environment type"), + "Closure environment must be a tuple or unit type".to_string(), span), + } + } +} diff --git a/crates/noirc_frontend/src/hir/resolution/import.rs b/compiler/noirc_frontend/src/hir/resolution/import.rs similarity index 95% rename from crates/noirc_frontend/src/hir/resolution/import.rs rename to compiler/noirc_frontend/src/hir/resolution/import.rs index 68796cf26bd..6f3140a65d4 100644 --- a/crates/noirc_frontend/src/hir/resolution/import.rs +++ b/compiler/noirc_frontend/src/hir/resolution/import.rs @@ -2,7 +2,7 @@ use iter_extended::partition_results; use noirc_errors::CustomDiagnostic; use crate::graph::CrateId; -use std::collections::HashMap; +use std::collections::BTreeMap; use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleDefId, ModuleId, PerNs}; use crate::{Ident, Path, PathKind}; @@ -52,7 +52,7 @@ impl From for CustomDiagnostic { pub fn resolve_imports( crate_id: CrateId, imports_to_resolve: Vec, - def_maps: &HashMap, + def_maps: &BTreeMap, ) -> (Vec, Vec<(PathResolutionError, LocalModuleId)>) { let def_map = &def_maps[&crate_id]; @@ -71,7 +71,7 @@ pub fn resolve_imports( } pub(super) fn allow_referencing_contracts( - def_maps: &HashMap, + def_maps: &BTreeMap, krate: CrateId, local_id: LocalModuleId, ) -> bool { @@ -81,7 +81,7 @@ pub(super) fn allow_referencing_contracts( pub fn resolve_path_to_ns( import_directive: &ImportDirective, def_map: &CrateDefMap, - def_maps: &HashMap, + def_maps: &BTreeMap, allow_contracts: bool, ) -> PathResolution { let import_path = &import_directive.path.segments; @@ -111,7 +111,7 @@ pub fn resolve_path_to_ns( fn resolve_path_from_crate_root( def_map: &CrateDefMap, import_path: &[Ident], - def_maps: &HashMap, + def_maps: &BTreeMap, allow_contracts: bool, ) -> PathResolution { resolve_name_in_module(def_map, import_path, def_map.root, def_maps, allow_contracts) @@ -121,7 +121,7 @@ fn resolve_name_in_module( def_map: &CrateDefMap, import_path: &[Ident], starting_mod: LocalModuleId, - def_maps: &HashMap, + def_maps: &BTreeMap, allow_contracts: bool, ) -> PathResolution { let mut current_mod = &def_map.modules[starting_mod.0]; @@ -151,7 +151,7 @@ fn resolve_name_in_module( ModuleDefId::ModuleId(id) => id, ModuleDefId::FunctionId(_) => panic!("functions cannot be in the type namespace"), // TODO: If impls are ever implemented, types can be used in a path - ModuleDefId::TypeId(id) => id.0, + ModuleDefId::TypeId(id) => id.module_id(), ModuleDefId::TypeAliasId(_) => panic!("type aliases cannot be used in type namespace"), ModuleDefId::TraitId(id) => id.0, ModuleDefId::GlobalId(_) => panic!("globals cannot be in the type namespace"), @@ -185,7 +185,7 @@ fn resolve_path_name(import_directive: &ImportDirective) -> Ident { fn resolve_external_dep( current_def_map: &CrateDefMap, directive: &ImportDirective, - def_maps: &HashMap, + def_maps: &BTreeMap, allow_contracts: bool, ) -> PathResolution { // Use extern_prelude to get the dep diff --git a/crates/noirc_frontend/src/hir/resolution/mod.rs b/compiler/noirc_frontend/src/hir/resolution/mod.rs similarity index 100% rename from crates/noirc_frontend/src/hir/resolution/mod.rs rename to compiler/noirc_frontend/src/hir/resolution/mod.rs diff --git a/crates/noirc_frontend/src/hir/resolution/path_resolver.rs b/compiler/noirc_frontend/src/hir/resolution/path_resolver.rs similarity index 91% rename from crates/noirc_frontend/src/hir/resolution/path_resolver.rs rename to compiler/noirc_frontend/src/hir/resolution/path_resolver.rs index eb0483fbf54..4c16edd56f1 100644 --- a/crates/noirc_frontend/src/hir/resolution/path_resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/path_resolver.rs @@ -2,7 +2,7 @@ use super::import::{ allow_referencing_contracts, resolve_path_to_ns, ImportDirective, PathResolutionError, }; use crate::Path; -use std::collections::HashMap; +use std::collections::BTreeMap; use crate::graph::CrateId; use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleDefId, ModuleId}; @@ -11,7 +11,7 @@ pub trait PathResolver { /// Resolve the given path returning the resolved ModuleDefId. fn resolve( &self, - def_maps: &HashMap, + def_maps: &BTreeMap, path: Path, ) -> Result; @@ -34,7 +34,7 @@ impl StandardPathResolver { impl PathResolver for StandardPathResolver { fn resolve( &self, - def_maps: &HashMap, + def_maps: &BTreeMap, path: Path, ) -> Result { resolve_path(def_maps, self.module_id, path) @@ -52,7 +52,7 @@ impl PathResolver for StandardPathResolver { /// Resolve the given path to a function or a type. /// In the case of a conflict, functions are given priority pub fn resolve_path( - def_maps: &HashMap, + def_maps: &BTreeMap, module_id: ModuleId, path: Path, ) -> Result { diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs similarity index 95% rename from crates/noirc_frontend/src/hir/resolution/resolver.rs rename to compiler/noirc_frontend/src/hir/resolution/resolver.rs index 6ce06d4a1ae..411e91f2cf4 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -17,9 +17,9 @@ use crate::hir_def::expr::{ HirIfExpression, HirIndexExpression, HirInfixExpression, HirLambda, HirLiteral, HirMemberAccess, HirMethodCallExpression, HirPrefixExpression, }; -use crate::token::Attribute; +use crate::token::PrimaryAttribute; use regex::Regex; -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, HashSet}; use std::rc::Rc; use crate::graph::CrateId; @@ -36,7 +36,8 @@ use crate::{ use crate::{ ArrayLiteral, ContractFunctionType, Distinctness, Generics, LValue, NoirStruct, NoirTypeAlias, Path, Pattern, Shared, StructType, Trait, Type, TypeAliasType, TypeBinding, TypeVariable, - UnaryOp, UnresolvedGenerics, UnresolvedType, UnresolvedTypeExpression, Visibility, ERROR_IDENT, + UnaryOp, UnresolvedGenerics, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression, + Visibility, ERROR_IDENT, }; use fm::FileId; use iter_extended::vecmap; @@ -74,7 +75,7 @@ pub struct LambdaContext { pub struct Resolver<'a> { scopes: ScopeForest, path_resolver: &'a dyn PathResolver, - def_maps: &'a HashMap, + def_maps: &'a BTreeMap, interner: &'a mut NodeInterner, errors: Vec, file: FileId, @@ -106,7 +107,7 @@ impl<'a> Resolver<'a> { pub fn new( interner: &'a mut NodeInterner, path_resolver: &'a dyn PathResolver, - def_maps: &'a HashMap, + def_maps: &'a BTreeMap, file: FileId, ) -> Resolver<'a> { Self { @@ -331,9 +332,11 @@ impl<'a> Resolver<'a> { /// Translates an UnresolvedType into a Type and appends any /// freshly created TypeVariables created to new_variables. fn resolve_type_inner(&mut self, typ: UnresolvedType, new_variables: &mut Generics) -> Type { - match typ { - UnresolvedType::FieldElement => Type::FieldElement, - UnresolvedType::Array(size, elem) => { + use UnresolvedTypeData::*; + + match typ.typ { + FieldElement => Type::FieldElement, + Array(size, elem) => { let elem = Box::new(self.resolve_type_inner(*elem, new_variables)); let size = if size.is_none() { Type::NotConstant @@ -342,32 +345,51 @@ impl<'a> Resolver<'a> { }; Type::Array(Box::new(size), elem) } - UnresolvedType::Expression(expr) => self.convert_expression_type(expr), - UnresolvedType::Integer(sign, bits) => Type::Integer(sign, bits), - UnresolvedType::Bool => Type::Bool, - UnresolvedType::String(size) => { + Expression(expr) => self.convert_expression_type(expr), + Integer(sign, bits) => Type::Integer(sign, bits), + Bool => Type::Bool, + String(size) => { let resolved_size = self.resolve_array_size(size, new_variables); Type::String(Box::new(resolved_size)) } - UnresolvedType::FormatString(size, fields) => { + FormatString(size, fields) => { let resolved_size = self.convert_expression_type(size); let fields = self.resolve_type_inner(*fields, new_variables); Type::FmtString(Box::new(resolved_size), Box::new(fields)) } - UnresolvedType::Unit => Type::Unit, - UnresolvedType::Unspecified => Type::Error, - UnresolvedType::Error => Type::Error, - UnresolvedType::Named(path, args) => self.resolve_named_type(path, args, new_variables), - UnresolvedType::Tuple(fields) => { + Unit => Type::Unit, + Unspecified => Type::Error, + Error => Type::Error, + Named(path, args) => self.resolve_named_type(path, args, new_variables), + Tuple(fields) => { Type::Tuple(vecmap(fields, |field| self.resolve_type_inner(field, new_variables))) } - UnresolvedType::Function(args, ret, env) => { + Function(args, ret, env) => { let args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); let ret = Box::new(self.resolve_type_inner(*ret, new_variables)); + + // expect() here is valid, because the only places we don't have a span are omitted types + // e.g. a function without return type implicitly has a spanless UnresolvedType::Unit return type + // To get an invalid env type, the user must explicitly specify the type, which will have a span + let env_span = + env.span.expect("Unexpected missing span for closure environment type"); + let env = Box::new(self.resolve_type_inner(*env, new_variables)); - Type::Function(args, ret, env) + + match *env { + Type::Unit | Type::Tuple(_) | Type::NamedGeneric(_, _) => { + Type::Function(args, ret, env) + } + _ => { + self.push_err(ResolverError::InvalidClosureEnvironment { + typ: *env, + span: env_span, + }); + Type::Error + } + } } - UnresolvedType::MutableReference(element) => { + MutableReference(element) => { Type::MutableReference(Box::new(self.resolve_type_inner(*element, new_variables))) } } @@ -416,7 +438,16 @@ impl<'a> Resolver<'a> { type_alias_string }); - return self.interner.get_type_alias(id).get_type(&args); + let result = self.interner.get_type_alias(id).get_type(&args); + + // Because there is no ordering to when type aliases (and other globals) are resolved, + // it is possible for one to refer to an Error type and issue no error if it is set + // equal to another type alias. Fixing this fully requires an analysis to create a DFG + // of definition ordering, but for now we have an explicit check here so that we at + // least issue an error that the type was not found instead of silently passing. + if result != Type::Error { + return result; + } } match self.lookup_struct_or_error(path) { @@ -576,9 +607,9 @@ impl<'a> Resolver<'a> { /// Translates a (possibly Unspecified) UnresolvedType to a Type. /// Any UnresolvedType::Unspecified encountered are replaced with fresh type variables. fn resolve_inferred_type(&mut self, typ: UnresolvedType) -> Type { - match typ { - UnresolvedType::Unspecified => self.interner.next_type_variable(), - other => self.resolve_type_inner(other, &mut vec![]), + match &typ.typ { + UnresolvedTypeData::Unspecified => self.interner.next_type_variable(), + _ => self.resolve_type_inner(typ, &mut vec![]), } } @@ -647,7 +678,7 @@ impl<'a> Resolver<'a> { let id = self.interner.function_definition_id(func_id); let name_ident = HirIdent { id, location }; - let attributes = func.attribute().cloned(); + let attributes = func.attributes().clone(); let mut generics = vecmap(self.generics.clone(), |(name, typevar, _)| match &*typevar.borrow() { @@ -700,7 +731,9 @@ impl<'a> Resolver<'a> { self.push_err(ResolverError::DistinctNotAllowed { ident: func.name_ident().clone() }); } - if attributes == Some(Attribute::Test) && !parameters.is_empty() { + if matches!(attributes.primary, Some(PrimaryAttribute::Test { .. })) + && !parameters.is_empty() + { self.push_err(ResolverError::TestFunctionHasParameters { span: func.name_ident().span(), }); @@ -806,7 +839,7 @@ impl<'a> Resolver<'a> { parameters: &[Type], return_type: &Type, ) -> Vec<(String, TypeVariable)> { - let mut found = HashMap::new(); + let mut found = BTreeMap::new(); for parameter in parameters { Self::find_numeric_generics_in_type(parameter, &mut found); } @@ -814,7 +847,10 @@ impl<'a> Resolver<'a> { found.into_iter().collect() } - fn find_numeric_generics_in_type(typ: &Type, found: &mut HashMap>) { + fn find_numeric_generics_in_type( + typ: &Type, + found: &mut BTreeMap>, + ) { match typ { Type::FieldElement | Type::Integer(_, _) @@ -897,7 +933,8 @@ impl<'a> Resolver<'a> { } Statement::Constrain(constrain_stmt) => { let expr_id = self.resolve_expression(constrain_stmt.0); - HirStatement::Constrain(HirConstrainStatement(expr_id, self.file)) + let assert_message = constrain_stmt.1; + HirStatement::Constrain(HirConstrainStatement(expr_id, self.file, assert_message)) } Statement::Expression(expr) => HirStatement::Expression(self.resolve_expression(expr)), Statement::Semi(expr) => HirStatement::Semi(self.resolve_expression(expr)), @@ -1485,7 +1522,7 @@ pub fn verify_mutable_reference(interner: &NodeInterner, rhs: ExprId) -> Result< mod test { use core::panic; - use std::collections::HashMap; + use std::collections::BTreeMap; use fm::FileId; use iter_extended::vecmap; @@ -1513,22 +1550,23 @@ mod test { // and functions can be forward declared fn init_src_code_resolution( src: &str, - ) -> (ParsedModule, NodeInterner, HashMap, FileId, TestPathResolver) { + ) -> (ParsedModule, NodeInterner, BTreeMap, FileId, TestPathResolver) + { let (program, errors) = parse_program(src); - if !errors.is_empty() { + if errors.iter().any(|e| e.is_error()) { panic!("Unexpected parse errors in test code: {:?}", errors); } let interner: NodeInterner = NodeInterner::default(); - let mut def_maps: HashMap = HashMap::new(); + let mut def_maps: BTreeMap = BTreeMap::new(); let file = FileId::default(); let mut modules = arena::Arena::new(); let location = Location::new(Default::default(), file); modules.insert(ModuleData::new(None, location, false)); - let path_resolver = TestPathResolver(HashMap::new()); + let path_resolver = TestPathResolver(BTreeMap::new()); def_maps.insert( CrateId::dummy_id(), @@ -1536,7 +1574,7 @@ mod test { root: path_resolver.local_module_id(), modules, krate: CrateId::dummy_id(), - extern_prelude: HashMap::new(), + extern_prelude: BTreeMap::new(), }, ); @@ -1969,12 +2007,12 @@ mod test { } } - struct TestPathResolver(HashMap); + struct TestPathResolver(BTreeMap); impl PathResolver for TestPathResolver { fn resolve( &self, - _def_maps: &HashMap, + _def_maps: &BTreeMap, path: Path, ) -> Result { // Not here that foo::bar and hello::foo::bar would fetch the same thing diff --git a/crates/noirc_frontend/src/hir/scope/mod.rs b/compiler/noirc_frontend/src/hir/scope/mod.rs similarity index 100% rename from crates/noirc_frontend/src/hir/scope/mod.rs rename to compiler/noirc_frontend/src/hir/scope/mod.rs diff --git a/compiler/noirc_frontend/src/hir/type_check/errors.rs b/compiler/noirc_frontend/src/hir/type_check/errors.rs new file mode 100644 index 00000000000..3190c7a24a2 --- /dev/null +++ b/compiler/noirc_frontend/src/hir/type_check/errors.rs @@ -0,0 +1,242 @@ +use acvm::FieldElement; +use noirc_errors::CustomDiagnostic as Diagnostic; +use noirc_errors::Span; +use thiserror::Error; + +use crate::hir::resolution::errors::ResolverError; +use crate::hir_def::expr::HirBinaryOp; +use crate::hir_def::types::Type; +use crate::FunctionReturnType; +use crate::Signedness; + +#[derive(Error, Debug, Clone, PartialEq, Eq)] +pub enum Source { + #[error("Binary")] + Binary, + #[error("Assignment")] + Assignment, + #[error("ArrayElements")] + ArrayElements, + #[error("ArrayLen")] + ArrayLen, + #[error("StringLen")] + StringLen, + #[error("Comparison")] + Comparison, + #[error("BinOp")] + BinOp, + #[error("Return")] + Return(FunctionReturnType, Span), +} + +#[derive(Error, Debug, Clone, PartialEq, Eq)] +pub enum TypeCheckError { + #[error("Operator {op:?} cannot be used in a {place:?}")] + OpCannotBeUsed { op: HirBinaryOp, place: &'static str, span: Span }, + #[error("The literal `{expr:?}` cannot fit into `{ty}` which has range `{range}`")] + OverflowingAssignment { expr: FieldElement, ty: Type, range: String, span: Span }, + #[error("Type {typ:?} cannot be used in a {place:?}")] + TypeCannotBeUsed { typ: Type, place: &'static str, span: Span }, + #[error("Expected type {expected_typ:?} is not the same as {expr_typ:?}")] + TypeMismatch { expected_typ: String, expr_typ: String, expr_span: Span }, + #[error("Expected type {expected} is not the same as {actual}")] + TypeMismatchWithSource { expected: Type, actual: Type, span: Span, source: Source }, + #[error("Expected {expected:?} found {found:?}")] + ArityMisMatch { expected: u16, found: u16, span: Span }, + #[error("Return type in a function cannot be public")] + PublicReturnType { typ: Type, span: Span }, + #[error("Cannot cast type {from}, 'as' is only for primitive field or integer types")] + InvalidCast { from: Type, span: Span }, + #[error("Expected a function, but found a(n) {found}")] + ExpectedFunction { found: Type, span: Span }, + #[error("Type {lhs_type} has no member named {field_name}")] + AccessUnknownMember { lhs_type: Type, field_name: String, span: Span }, + #[error("Function expects {expected} parameters but {found} given")] + ParameterCountMismatch { expected: usize, found: usize, span: Span }, + #[error("Only integer and Field types may be casted to")] + UnsupportedCast { span: Span }, + #[error("Index {index} is out of bounds for this tuple {lhs_type} of length {length}")] + TupleIndexOutOfBounds { index: usize, lhs_type: Type, length: usize, span: Span }, + #[error("Variable {name} must be mutable to be assigned to")] + VariableMustBeMutable { name: String, span: Span }, + #[error("No method named '{method_name}' found for type '{object_type}'")] + UnresolvedMethodCall { method_name: String, object_type: Type, span: Span }, + #[error("Comparisons are invalid on Field types. Try casting the operands to a sized integer type first")] + InvalidComparisonOnField { span: Span }, + #[error("Integers must have the same signedness LHS is {sign_x:?}, RHS is {sign_y:?}")] + IntegerSignedness { sign_x: Signedness, sign_y: Signedness, span: Span }, + #[error("Integers must have the same bit width LHS is {bit_width_x}, RHS is {bit_width_y}")] + IntegerBitWidth { bit_width_x: u32, bit_width_y: u32, span: Span }, + #[error("{kind} cannot be used in an infix operation")] + InvalidInfixOp { kind: &'static str, span: Span }, + #[error("{kind} cannot be used in a unary operation")] + InvalidUnaryOp { kind: String, span: Span }, + #[error("Bitwise operations are invalid on Field types. Try casting the operands to a sized integer type first.")] + InvalidBitwiseOperationOnField { span: Span }, + #[error("Integer cannot be used with type {typ}")] + IntegerTypeMismatch { typ: Type, span: Span }, + #[error("Cannot use an integer and a Field in a binary operation, try converting the Field into an integer first")] + IntegerAndFieldBinaryOperation { span: Span }, + #[error("Fields cannot be compared, try casting to an integer first")] + FieldComparison { span: Span }, + #[error("The number of bits to use for this bitwise operation is ambiguous. Either the operand's type or return type should be specified")] + AmbiguousBitWidth { span: Span }, + #[error("Error with additional context")] + Context { err: Box, ctx: &'static str }, + #[error("Array is not homogeneous")] + NonHomogeneousArray { + first_span: Span, + first_type: String, + first_index: usize, + second_span: Span, + second_type: String, + second_index: usize, + }, + #[error("Cannot infer type of expression, type annotations needed before this point")] + TypeAnnotationsNeeded { span: Span }, + #[error("use of deprecated function {name}")] + CallDeprecated { name: String, note: Option, span: Span }, + #[error("{0}")] + ResolverError(ResolverError), + #[error("Unused expression result of type {expr_type}")] + UnusedResultError { expr_type: Type, expr_span: Span }, +} + +impl TypeCheckError { + pub fn add_context(self, ctx: &'static str) -> Self { + TypeCheckError::Context { err: Box::new(self), ctx } + } +} + +impl From for Diagnostic { + fn from(error: TypeCheckError) -> Diagnostic { + match error { + TypeCheckError::TypeCannotBeUsed { typ, place, span } => Diagnostic::simple_error( + format!("The type {} cannot be used in a {}", &typ, place), + String::new(), + span, + ), + TypeCheckError::Context { err, ctx } => { + let mut diag = Diagnostic::from(*err); + diag.add_note(ctx.to_owned()); + diag + } + TypeCheckError::OpCannotBeUsed { op, place, span } => Diagnostic::simple_error( + format!("The operator {op:?} cannot be used in a {place}"), + String::new(), + span, + ), + TypeCheckError::TypeMismatch { expected_typ, expr_typ, expr_span } => { + Diagnostic::simple_error( + format!("Expected type {expected_typ}, found type {expr_typ}"), + String::new(), + expr_span, + ) + } + TypeCheckError::NonHomogeneousArray { + first_span, + first_type, + first_index, + second_span, + second_type, + second_index, + } => { + let mut diag = Diagnostic::simple_error( + format!( + "Non homogeneous array, different element types found at indices ({first_index},{second_index})" + ), + format!("Found type {first_type}"), + first_span, + ); + diag.add_secondary(format!("but then found type {second_type}"), second_span); + diag + } + TypeCheckError::ArityMisMatch { expected, found, span } => { + let plural = if expected == 1 { "" } else { "s" }; + let msg = format!("Expected {expected} argument{plural}, but found {found}"); + Diagnostic::simple_error(msg, String::new(), span) + } + TypeCheckError::ParameterCountMismatch { expected, found, span } => { + let empty_or_s = if expected == 1 { "" } else { "s" }; + let was_or_were = if found == 1 { "was" } else { "were" }; + let msg = format!("Function expects {expected} parameter{empty_or_s} but {found} {was_or_were} given"); + Diagnostic::simple_error(msg, String::new(), span) + } + TypeCheckError::InvalidCast { span, .. } + | TypeCheckError::ExpectedFunction { span, .. } + | TypeCheckError::AccessUnknownMember { span, .. } + | TypeCheckError::UnsupportedCast { span } + | TypeCheckError::TupleIndexOutOfBounds { span, .. } + | TypeCheckError::VariableMustBeMutable { span, .. } + | TypeCheckError::UnresolvedMethodCall { span, .. } + | TypeCheckError::InvalidComparisonOnField { span } + | TypeCheckError::IntegerSignedness { span, .. } + | TypeCheckError::IntegerBitWidth { span, .. } + | TypeCheckError::InvalidInfixOp { span, .. } + | TypeCheckError::InvalidUnaryOp { span, .. } + | TypeCheckError::InvalidBitwiseOperationOnField { span, .. } + | TypeCheckError::IntegerTypeMismatch { span, .. } + | TypeCheckError::FieldComparison { span, .. } + | TypeCheckError::AmbiguousBitWidth { span, .. } + | TypeCheckError::IntegerAndFieldBinaryOperation { span } + | TypeCheckError::OverflowingAssignment { span, .. } => { + Diagnostic::simple_error(error.to_string(), String::new(), span) + } + TypeCheckError::PublicReturnType { typ, span } => Diagnostic::simple_error( + "Functions cannot declare a public return type".to_string(), + format!("return type is {typ}"), + span, + ), + TypeCheckError::TypeAnnotationsNeeded { span } => Diagnostic::simple_error( + "Expression type is ambiguous".to_string(), + "Type must be known at this point".to_string(), + span, + ), + TypeCheckError::ResolverError(error) => error.into(), + TypeCheckError::TypeMismatchWithSource { expected, actual, span, source } => { + let message = match source { + Source::Binary => format!("Types in a binary operation should match, but found {expected} and {actual}"), + Source::Assignment => { + format!("Cannot assign an expression of type {actual} to a value of type {expected}") + } + Source::ArrayElements => format!("Cannot compare {expected} and {actual}, the array element types differ"), + Source::ArrayLen => format!("Can only compare arrays of the same length. Here LHS is of length {expected}, and RHS is {actual}"), + Source::StringLen => format!("Can only compare strings of the same length. Here LHS is of length {expected}, and RHS is {actual}"), + Source::Comparison => format!("Unsupported types for comparison: {expected} and {actual}"), + Source::BinOp => format!("Unsupported types for binary operation: {expected} and {actual}"), + Source::Return(ret_ty, expr_span) => { + let ret_ty_span = match ret_ty.clone() { + FunctionReturnType::Default(span) => span, + FunctionReturnType::Ty(ty) => ty.span.unwrap(), + }; + + let mut diagnostic = Diagnostic::simple_error(format!("expected type {expected}, found type {actual}"), format!("expected {expected} because of return type"), ret_ty_span); + + if let FunctionReturnType::Default(_) = ret_ty { + diagnostic.add_note(format!("help: try adding a return type: `-> {actual}`")); + } + + diagnostic.add_secondary(format!("{actual} returned here"), expr_span); + + return diagnostic + }, + }; + + Diagnostic::simple_error(message, String::new(), span) + } + TypeCheckError::CallDeprecated { span, ref note, .. } => { + let primary_message = error.to_string(); + let secondary_message = note.clone().unwrap_or_default(); + + Diagnostic::simple_warning(primary_message, secondary_message, span) + } + TypeCheckError::UnusedResultError { expr_type, expr_span } => { + Diagnostic::simple_warning( + format!("Unused expression result of type {expr_type}"), + String::new(), + expr_span, + ) + } + } + } +} diff --git a/crates/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs similarity index 95% rename from crates/noirc_frontend/src/hir/type_check/expr.rs rename to compiler/noirc_frontend/src/hir/type_check/expr.rs index 9f00f4b61da..3b5d3758c4b 100644 --- a/crates/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -11,7 +11,6 @@ use crate::{ types::Type, }, node_interner::{DefinitionKind, ExprId, FuncId}, - token::Attribute::Deprecated, Shared, Signedness, TypeBinding, TypeVariableKind, UnaryOp, }; @@ -26,7 +25,7 @@ impl<'interner> TypeChecker<'interner> { self.interner.try_definition(id).map(|def| &def.kind) { let meta = self.interner.function_meta(func_id); - if let Some(Deprecated(note)) = meta.attributes { + if let Some(note) = meta.attributes.get_deprecated_note() { self.errors.push(TypeCheckError::CallDeprecated { name: self.interner.definition_name(id).to_string(), note, @@ -319,9 +318,9 @@ impl<'interner> TypeChecker<'interner> { }; if let Some(expected_object_type) = expected_object_type { - if matches!(expected_object_type.follow_bindings(), Type::MutableReference(_)) { - let actual_type = argument_types[0].0.follow_bindings(); + let actual_type = argument_types[0].0.follow_bindings(); + if matches!(expected_object_type.follow_bindings(), Type::MutableReference(_)) { if !matches!(actual_type, Type::MutableReference(_)) { if let Err(error) = verify_mutable_reference(self.interner, method_call.object) { @@ -335,18 +334,52 @@ impl<'interner> TypeChecker<'interner> { // inserted by a field access expression `foo.bar` on a mutable reference `foo`. if self.try_remove_implicit_dereference(method_call.object).is_none() { // If that didn't work, then wrap the whole expression in an `&mut` + let location = self.interner.id_location(method_call.object); + method_call.object = self.interner.push_expr(HirExpression::Prefix(HirPrefixExpression { operator: UnaryOp::MutableReference, rhs: method_call.object, })); self.interner.push_expr_type(&method_call.object, new_type); + self.interner.push_expr_location( + method_call.object, + location.span, + location.file, + ); } } + // Otherwise if the object type is a mutable reference and the method is not, insert as + // many dereferences as needed. + } else if matches!(actual_type, Type::MutableReference(_)) { + let (object, new_type) = + self.insert_auto_dereferences(method_call.object, actual_type); + method_call.object = object; + argument_types[0].0 = new_type; } } } + /// Insert as many dereference operations as necessary to automatically dereference a method + /// call object to its base value type T. + fn insert_auto_dereferences(&mut self, object: ExprId, typ: Type) -> (ExprId, Type) { + if let Type::MutableReference(element) = typ { + let location = self.interner.id_location(object); + + let object = self.interner.push_expr(HirExpression::Prefix(HirPrefixExpression { + operator: UnaryOp::Dereference { implicitly_added: true }, + rhs: object, + })); + self.interner.push_expr_type(&object, element.as_ref().clone()); + self.interner.push_expr_location(object, location.span, location.file); + + // Recursively dereference to allow for converting &mut &mut T to T + self.insert_auto_dereferences(object, *element) + } else { + (object, typ) + } + } + /// Given a method object: `(*foo).bar` of a method call `(*foo).bar.baz()`, remove the /// implicitly added dereference operator if one is found. /// @@ -567,6 +600,9 @@ impl<'interner> TypeChecker<'interner> { })); this.interner.push_expr_type(&old_lhs, lhs_type); this.interner.push_expr_type(access_lhs, element); + + let old_location = this.interner.id_location(old_lhs); + this.interner.push_expr_location(*access_lhs, span, old_location.file); }; match self.check_field_access(&lhs_type, &access.rhs.0.contents, span, dereference_lhs) { diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs new file mode 100644 index 00000000000..ea1793b7e76 --- /dev/null +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -0,0 +1,453 @@ +//! This file contains type_check_func, the entry point to the type checking pass (for each function). +//! +//! The pass structure of type checking is relatively straightforward. It is a single pass through +//! the HIR of each function and outputs the inferred type of each HIR node into the NodeInterner, +//! keyed by the ID of the node. +//! +//! Although this algorithm features inference via TypeVariables, there is no generalization step +//! as all functions are required to give their full signatures. Closures are inferred but are +//! never generalized and thus cannot be used polymorphically. +mod errors; +mod expr; +mod stmt; + +pub use errors::TypeCheckError; + +use crate::{ + hir_def::{expr::HirExpression, stmt::HirStatement}, + node_interner::{ExprId, FuncId, NodeInterner, StmtId}, + Type, +}; + +use self::errors::Source; + +type TypeCheckFn = Box Result<(), TypeCheckError>>; + +pub struct TypeChecker<'interner> { + delayed_type_checks: Vec, + interner: &'interner mut NodeInterner, + errors: Vec, +} + +/// Type checks a function and assigns the +/// appropriate types to expressions in a side table +pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec { + let meta = interner.function_meta(&func_id); + let declared_return_type = meta.return_type().clone(); + let can_ignore_ret = meta.can_ignore_return_type(); + + let function_body = interner.function(&func_id); + let function_body_id = function_body.as_expr(); + + let mut type_checker = TypeChecker::new(interner); + + // Bind each parameter to its annotated type. + // This is locally obvious, but it must be bound here so that the + // Definition object of the parameter in the NodeInterner is given the correct type. + for param in meta.parameters.into_iter() { + type_checker.bind_pattern(¶m.0, param.1); + } + + let (function_last_type, delayed_type_check_functions, mut errors) = + type_checker.check_function_body(function_body_id); + + // Go through any delayed type checking errors to see if they are resolved, or error otherwise. + for type_check_fn in delayed_type_check_functions { + if let Err(error) = type_check_fn() { + errors.push(error); + } + } + + // Check declared return type and actual return type + if !can_ignore_ret { + let (expr_span, empty_function) = function_info(interner, function_body_id); + + let func_span = interner.expr_span(function_body_id); // XXX: We could be more specific and return the span of the last stmt, however stmts do not have spans yet + function_last_type.unify_with_coercions( + &declared_return_type, + *function_body_id, + interner, + &mut errors, + || { + let mut error = TypeCheckError::TypeMismatchWithSource { + expected: declared_return_type.clone(), + actual: function_last_type.clone(), + span: func_span, + source: Source::Return(meta.return_type, expr_span), + }; + + if empty_function { + error = error.add_context( + "implicitly returns `()` as its body has no tail or `return` expression", + ); + } + + error + }, + ); + } + + errors +} + +fn function_info( + interner: &mut NodeInterner, + function_body_id: &ExprId, +) -> (noirc_errors::Span, bool) { + let (expr_span, empty_function) = + if let HirExpression::Block(block) = interner.expression(function_body_id) { + let last_stmt = block.statements().last(); + let mut span = interner.expr_span(function_body_id); + + if let Some(last_stmt) = last_stmt { + if let HirStatement::Expression(expr) = interner.statement(last_stmt) { + span = interner.expr_span(&expr); + } + } + + (span, last_stmt.is_none()) + } else { + (interner.expr_span(function_body_id), false) + }; + (expr_span, empty_function) +} + +impl<'interner> TypeChecker<'interner> { + fn new(interner: &'interner mut NodeInterner) -> Self { + Self { delayed_type_checks: Vec::new(), interner, errors: vec![] } + } + + pub fn push_delayed_type_check(&mut self, f: TypeCheckFn) { + self.delayed_type_checks.push(f); + } + + fn check_function_body( + mut self, + body: &ExprId, + ) -> (Type, Vec, Vec) { + let body_type = self.check_expression(body); + (body_type, self.delayed_type_checks, self.errors) + } + + pub fn check_global(id: &StmtId, interner: &'interner mut NodeInterner) -> Vec { + let mut this = Self { delayed_type_checks: Vec::new(), interner, errors: vec![] }; + this.check_statement(id); + this.errors + } + + /// Wrapper of Type::unify using self.errors + fn unify( + &mut self, + actual: &Type, + expected: &Type, + make_error: impl FnOnce() -> TypeCheckError, + ) { + actual.unify(expected, &mut self.errors, make_error); + } + + /// Wrapper of Type::unify_with_coercions using self.errors + fn unify_with_coercions( + &mut self, + actual: &Type, + expected: &Type, + expression: ExprId, + make_error: impl FnOnce() -> TypeCheckError, + ) { + actual.unify_with_coercions( + expected, + expression, + self.interner, + &mut self.errors, + make_error, + ); + } +} + +// XXX: These tests are all manual currently. +/// We can either build a test apparatus or pass raw code through the resolver +#[cfg(test)] +mod test { + use std::collections::{BTreeMap, HashMap}; + use std::vec; + + use fm::FileId; + use iter_extended::vecmap; + use noirc_errors::{Location, Span}; + + use crate::graph::CrateId; + use crate::hir::def_map::{ModuleData, ModuleId}; + use crate::hir::resolution::import::PathResolutionError; + use crate::hir_def::expr::HirIdent; + use crate::hir_def::stmt::HirLetStatement; + use crate::hir_def::stmt::HirPattern::Identifier; + use crate::hir_def::types::Type; + use crate::hir_def::{ + expr::{HirBinaryOp, HirBlockExpression, HirExpression, HirInfixExpression}, + function::{FuncMeta, HirFunction}, + stmt::HirStatement, + }; + use crate::node_interner::{DefinitionKind, FuncId, NodeInterner}; + use crate::token::Attributes; + use crate::{ + hir::{ + def_map::{CrateDefMap, LocalModuleId, ModuleDefId}, + resolution::{path_resolver::PathResolver, resolver::Resolver}, + }, + parse_program, FunctionKind, Path, + }; + use crate::{BinaryOpKind, Distinctness, FunctionReturnType, Visibility}; + + #[test] + fn basic_let() { + let mut interner = NodeInterner::default(); + + // Add a simple let Statement into the interner + // let z = x + y; + // + // Push x variable + let x_id = interner.push_definition("x".into(), false, DefinitionKind::Local(None)); + + // Safety: The FileId in a location isn't used for tests + let file = FileId::default(); + let location = Location::new(Span::default(), file); + + let x = HirIdent { id: x_id, location }; + + // Push y variable + let y_id = interner.push_definition("y".into(), false, DefinitionKind::Local(None)); + let y = HirIdent { id: y_id, location }; + + // Push z variable + let z_id = interner.push_definition("z".into(), false, DefinitionKind::Local(None)); + let z = HirIdent { id: z_id, location }; + + // Push x and y as expressions + let x_expr_id = interner.push_expr(HirExpression::Ident(x)); + let y_expr_id = interner.push_expr(HirExpression::Ident(y)); + + // Create Infix + let operator = HirBinaryOp { location, kind: BinaryOpKind::Add }; + let expr = HirInfixExpression { lhs: x_expr_id, operator, rhs: y_expr_id }; + let expr_id = interner.push_expr(HirExpression::Infix(expr)); + interner.push_expr_location(expr_id, Span::single_char(0), file); + + interner.push_expr_location(x_expr_id, Span::single_char(0), file); + interner.push_expr_location(y_expr_id, Span::single_char(0), file); + + // Create let statement + let let_stmt = HirLetStatement { + pattern: Identifier(z), + r#type: Type::FieldElement, + expression: expr_id, + }; + let stmt_id = interner.push_stmt(HirStatement::Let(let_stmt)); + let expr_id = interner.push_expr(HirExpression::Block(HirBlockExpression(vec![stmt_id]))); + interner.push_expr_location(expr_id, Span::single_char(0), file); + + // Create function to enclose the let statement + let func = HirFunction::unchecked_from_expr(expr_id); + let func_id = interner.push_fn(func); + + let name = HirIdent { + location, + id: interner.push_definition("test_func".into(), false, DefinitionKind::Local(None)), + }; + + // Add function meta + let func_meta = FuncMeta { + name, + kind: FunctionKind::Normal, + module_id: ModuleId::dummy_id(), + attributes: Attributes::empty(), + location, + contract_function_type: None, + is_internal: None, + is_unconstrained: false, + typ: Type::Function( + vec![Type::FieldElement, Type::FieldElement], + Box::new(Type::Unit), + Box::new(Type::Unit), + ), + parameters: vec![ + (Identifier(x), Type::FieldElement, Visibility::Private), + (Identifier(y), Type::FieldElement, Visibility::Private), + ] + .into(), + return_visibility: Visibility::Private, + return_distinctness: Distinctness::DuplicationAllowed, + has_body: true, + return_type: FunctionReturnType::Default(Span::default()), + }; + interner.push_fn_meta(func_meta, func_id); + + let errors = super::type_check_func(&mut interner, func_id); + assert!(errors.is_empty()); + } + + #[test] + #[should_panic] + fn basic_let_stmt() { + let src = r#" + fn main(x : Field) { + let k = [x,x]; + let _z = x + k; + } + "#; + + type_check_src_code(src, vec![String::from("main")]); + } + + #[test] + fn basic_index_expr() { + let src = r#" + fn main(x : Field) { + let k = [x,x]; + let _z = x + k[0]; + } + "#; + + type_check_src_code(src, vec![String::from("main")]); + } + #[test] + fn basic_call_expr() { + let src = r#" + fn main(x : Field) { + let _z = x + foo(x); + } + + fn foo(x : Field) -> Field { + x + } + "#; + + type_check_src_code(src, vec![String::from("main"), String::from("foo")]); + } + #[test] + fn basic_for_expr() { + let src = r#" + fn main(_x : Field) { + let _j = for _i in 0..10 { + for _k in 0..100 { + + } + }; + } + + "#; + + type_check_src_code(src, vec![String::from("main"), String::from("foo")]); + } + #[test] + fn basic_closure() { + let src = r#" + fn main(x : Field) -> pub Field { + let closure = |y| y + x; + closure(x) + } + "#; + + type_check_src_code(src, vec![String::from("main"), String::from("foo")]); + } + + #[test] + fn closure_with_no_args() { + let src = r#" + fn main(x : Field) -> pub Field { + let closure = || x; + closure() + } + "#; + + type_check_src_code(src, vec![String::from("main")]); + } + // This is the same Stub that is in the resolver, maybe we can pull this out into a test module and re-use? + struct TestPathResolver(HashMap); + + impl PathResolver for TestPathResolver { + fn resolve( + &self, + _def_maps: &BTreeMap, + path: Path, + ) -> Result { + // Not here that foo::bar and hello::foo::bar would fetch the same thing + let name = path.segments.last().unwrap(); + self.0 + .get(&name.0.contents) + .cloned() + .ok_or_else(move || PathResolutionError::Unresolved(name.clone())) + } + + fn local_module_id(&self) -> LocalModuleId { + LocalModuleId(arena::Index::from_raw_parts(0, 0)) + } + + fn module_id(&self) -> ModuleId { + ModuleId { krate: CrateId::dummy_id(), local_id: self.local_module_id() } + } + } + + impl TestPathResolver { + fn insert_func(&mut self, name: String, func_id: FuncId) { + self.0.insert(name, func_id.into()); + } + } + + // This function assumes that there is only one function and this is the + // func id that is returned + fn type_check_src_code(src: &str, func_namespace: Vec) { + let (program, errors) = parse_program(src); + let mut interner = NodeInterner::default(); + + // Using assert_eq here instead of assert(errors.is_empty()) displays + // the whole vec if the assert fails rather than just two booleans + assert_eq!(errors, vec![]); + + let main_id = interner.push_fn(HirFunction::empty()); + interner.push_function_definition("main".into(), main_id); + + let func_ids = vecmap(&func_namespace, |name| { + let id = interner.push_fn(HirFunction::empty()); + interner.push_function_definition(name.into(), id); + id + }); + + let mut path_resolver = TestPathResolver(HashMap::new()); + for (name, id) in func_namespace.into_iter().zip(func_ids.clone()) { + path_resolver.insert_func(name.to_owned(), id); + } + + let mut def_maps = BTreeMap::new(); + let file = FileId::default(); + + let mut modules = arena::Arena::new(); + let location = Location::new(Default::default(), file); + modules.insert(ModuleData::new(None, location, false)); + + def_maps.insert( + CrateId::dummy_id(), + CrateDefMap { + root: path_resolver.local_module_id(), + modules, + krate: CrateId::dummy_id(), + extern_prelude: BTreeMap::new(), + }, + ); + + let func_meta = vecmap(program.functions, |nf| { + let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); + let (hir_func, func_meta, resolver_errors) = + resolver.resolve_function(nf, main_id, ModuleId::dummy_id()); + assert_eq!(resolver_errors, vec![]); + (hir_func, func_meta) + }); + + for ((hir_func, meta), func_id) in func_meta.into_iter().zip(func_ids.clone()) { + interner.update_fn(func_id, hir_func); + interner.push_fn_meta(meta, func_id); + } + + // Type check section + let errors = super::type_check_func(&mut interner, func_ids.first().cloned().unwrap()); + assert_eq!(errors, vec![]); + } +} diff --git a/crates/noirc_frontend/src/hir/type_check/stmt.rs b/compiler/noirc_frontend/src/hir/type_check/stmt.rs similarity index 100% rename from crates/noirc_frontend/src/hir/type_check/stmt.rs rename to compiler/noirc_frontend/src/hir/type_check/stmt.rs diff --git a/crates/noirc_frontend/src/hir_def/expr.rs b/compiler/noirc_frontend/src/hir_def/expr.rs similarity index 100% rename from crates/noirc_frontend/src/hir_def/expr.rs rename to compiler/noirc_frontend/src/hir_def/expr.rs diff --git a/compiler/noirc_frontend/src/hir_def/function.rs b/compiler/noirc_frontend/src/hir_def/function.rs new file mode 100644 index 00000000000..c552100c919 --- /dev/null +++ b/compiler/noirc_frontend/src/hir_def/function.rs @@ -0,0 +1,176 @@ +use iter_extended::vecmap; +use noirc_errors::{Location, Span}; + +use super::expr::{HirBlockExpression, HirExpression, HirIdent}; +use super::stmt::HirPattern; +use crate::hir::def_map::ModuleId; +use crate::node_interner::{ExprId, NodeInterner}; +use crate::{token::Attributes, FunctionKind}; +use crate::{ContractFunctionType, Distinctness, FunctionReturnType, Type, Visibility}; + +/// A Hir function is a block expression +/// with a list of statements +#[derive(Debug, Clone)] +pub struct HirFunction(ExprId); + +impl HirFunction { + pub fn empty() -> HirFunction { + HirFunction(ExprId::empty_block_id()) + } + + pub const fn unchecked_from_expr(expr_id: ExprId) -> HirFunction { + HirFunction(expr_id) + } + + pub const fn as_expr(&self) -> &ExprId { + &self.0 + } + + pub fn block(&self, interner: &NodeInterner) -> HirBlockExpression { + match interner.expression(&self.0) { + HirExpression::Block(block_expr) => block_expr, + _ => unreachable!("ice: functions can only be block expressions"), + } + } +} + +/// An interned function parameter from a function definition +pub type Param = (HirPattern, Type, Visibility); + +#[derive(Debug, Clone)] +pub struct Parameters(pub Vec); + +impl Parameters { + pub fn span(&self) -> Span { + assert!(!self.is_empty()); + let mut spans = vecmap(&self.0, |param| match ¶m.0 { + HirPattern::Identifier(ident) => ident.location.span, + HirPattern::Mutable(_, span) => *span, + HirPattern::Tuple(_, span) => *span, + HirPattern::Struct(_, _, span) => *span, + }); + + let merged_span = spans.pop().unwrap(); + for span in spans { + let _ = merged_span.merge(span); + } + + merged_span + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn iter(&self) -> impl Iterator { + self.0.iter() + } +} + +impl IntoIterator for Parameters { + type Item = Param; + type IntoIter = as IntoIterator>::IntoIter; + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl From> for Parameters { + fn from(vec: Vec) -> Parameters { + Parameters(vec) + } +} + +pub type FunctionSignature = (Vec, Option); + +/// A FuncMeta contains the signature of the function and any associated meta data like +/// the function's Location, FunctionKind, and attributes. If the function's body is +/// needed, it can be retrieved separately via `NodeInterner::function(&self, &FuncId)`. +#[derive(Debug, Clone)] +pub struct FuncMeta { + pub name: HirIdent, + + pub kind: FunctionKind, + + pub module_id: ModuleId, + + /// A function's attributes are the `#[...]` items above the function + /// definition. + /// Primary Attributes will alter the function kind, secondary attributes do not + pub attributes: Attributes, + + /// This function's type in its contract. + /// If this function is not in a contract, this is always 'Secret'. + pub contract_function_type: Option, + + /// This function's visibility. + /// If this function is internal can only be called by itself. + /// Will be None if not in contract. + pub is_internal: Option, + + pub is_unconstrained: bool, + + pub parameters: Parameters, + + pub return_type: FunctionReturnType, + + pub return_visibility: Visibility, + + pub return_distinctness: Distinctness, + + /// The type of this function. Either a Type::Function + /// or a Type::Forall for generic functions. + pub typ: Type, + + pub location: Location, + + // This flag is needed for the attribute check pass + pub has_body: bool, +} + +impl FuncMeta { + /// Builtin, LowLevel and Oracle functions usually have the return type + /// declared, however their function bodies will be empty + /// So this method tells the type checker to ignore the return + /// of the empty function, which is unit + pub fn can_ignore_return_type(&self) -> bool { + match self.kind { + FunctionKind::LowLevel | FunctionKind::Builtin | FunctionKind::Oracle => true, + FunctionKind::Normal => false, + } + } + + pub fn into_function_signature(self) -> FunctionSignature { + // Doesn't use `self.return_type()` so we aren't working with references and don't need a `clone()` + let return_type = match self.typ { + Type::Function(_, ret, _env) => *ret, + Type::Forall(_, typ) => match *typ { + Type::Function(_, ret, _env) => *ret, + _ => unreachable!(), + }, + _ => unreachable!(), + }; + let return_type = match return_type { + Type::Unit => None, + typ => Some(typ), + }; + + (self.parameters.0, return_type) + } + + /// Gives the (uninstantiated) return type of this function. + pub fn return_type(&self) -> &Type { + match &self.typ { + Type::Function(_, ret, _env) => ret, + Type::Forall(_, typ) => match typ.as_ref() { + Type::Function(_, ret, _env) => ret, + _ => unreachable!(), + }, + _ => unreachable!(), + } + } +} diff --git a/crates/noirc_frontend/src/hir_def/mod.rs b/compiler/noirc_frontend/src/hir_def/mod.rs similarity index 100% rename from crates/noirc_frontend/src/hir_def/mod.rs rename to compiler/noirc_frontend/src/hir_def/mod.rs diff --git a/crates/noirc_frontend/src/hir_def/stmt.rs b/compiler/noirc_frontend/src/hir_def/stmt.rs similarity index 97% rename from crates/noirc_frontend/src/hir_def/stmt.rs rename to compiler/noirc_frontend/src/hir_def/stmt.rs index 8cf9d82f580..0dcb7192be2 100644 --- a/crates/noirc_frontend/src/hir_def/stmt.rs +++ b/compiler/noirc_frontend/src/hir_def/stmt.rs @@ -46,7 +46,7 @@ pub struct HirAssignStatement { /// originates from. This is used later in the SSA pass to issue /// an error if a constrain is found to be always false. #[derive(Debug, Clone)] -pub struct HirConstrainStatement(pub ExprId, pub FileId); +pub struct HirConstrainStatement(pub ExprId, pub FileId, pub Option); #[derive(Debug, Clone)] pub enum HirPattern { diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs new file mode 100644 index 00000000000..8372f7a0355 --- /dev/null +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -0,0 +1,1341 @@ +use std::{ + cell::RefCell, + collections::{BTreeSet, HashMap}, + rc::Rc, +}; + +use crate::{ + hir::type_check::TypeCheckError, + node_interner::{ExprId, NodeInterner, TypeAliasId}, +}; +use iter_extended::vecmap; +use noirc_errors::Span; +use noirc_printable_type::PrintableType; + +use crate::{node_interner::StructId, node_interner::TraitId, Ident, Signedness}; + +use super::expr::{HirCallExpression, HirExpression, HirIdent}; + +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +pub enum Type { + /// A primitive Field type + FieldElement, + + /// Array(N, E) is an array of N elements of type E. It is expected that N + /// is either a type variable of some kind or a Type::Constant. + Array(Box, Box), + + /// A primitive integer type with the given sign and bit count. + /// E.g. `u32` would be `Integer(Unsigned, 32)` + Integer(Signedness, u32), + + /// The primitive `bool` type. + Bool, + + /// String(N) is an array of characters of length N. It is expected that N + /// is either a type variable of some kind or a Type::Constant. + String(Box), + + /// FmtString(N, Vec) is an array of characters of length N that contains + /// a list of fields specified inside the string by the following regular expression r"\{([\S]+)\}" + FmtString(Box, Box), + + /// The unit type `()`. + Unit, + + /// A user-defined struct type. The `Shared` field here refers to + /// the shared definition for each instance of this struct type. The `Vec` + /// represents the generic arguments (if any) to this struct type. + Struct(Shared, Vec), + + /// A tuple type with the given list of fields in the order they appear in source code. + Tuple(Vec), + + /// TypeVariables are stand-in variables for some type which is not yet known. + /// They are not to be confused with NamedGenerics. While the later mostly works + /// as with normal types (ie. for two NamedGenerics T and U, T != U), TypeVariables + /// will be automatically rebound as necessary to satisfy any calls to unify. + /// + /// TypeVariables are often created when a generic function is instantiated. This + /// is a process that replaces each NamedGeneric in a generic function with a TypeVariable. + /// Doing this at each call site of a generic function is how they can be called with + /// different argument types each time. + TypeVariable(TypeVariable, TypeVariableKind), + + /// NamedGenerics are the 'T' or 'U' in a user-defined generic function + /// like `fn foo(...) {}`. Unlike TypeVariables, they cannot be bound over. + NamedGeneric(TypeVariable, Rc), + + /// A functions with arguments, a return type and environment. + /// the environment should be `Unit` by default, + /// for closures it should contain a `Tuple` type with the captured + /// variable types. + Function(Vec, Box, Box), + + /// &mut T + MutableReference(Box), + + /// A type generic over the given type variables. + /// Storing both the TypeVariableId and TypeVariable isn't necessary + /// but it makes handling them both easier. The TypeVariableId should + /// never be bound over during type checking, but during monomorphization it + /// will be and thus needs the full TypeVariable link. + Forall(Generics, Box), + + /// A type-level integer. Included to let an Array's size type variable + /// bind to an integer without special checks to bind it to a non-type. + Constant(u64), + + /// The type of a slice is an array of size NotConstant. + /// The size of an array literal is resolved to this if it ever uses operations + /// involving slices. + NotConstant, + + /// The result of some type error. Remembering type errors as their own type variant lets + /// us avoid issuing repeat type errors for the same item. For example, a lambda with + /// an invalid type would otherwise issue a new error each time it is called + /// if not for this variant. + Error, +} + +/// A list of TypeVariableIds to bind to a type. Storing the +/// TypeVariable in addition to the matching TypeVariableId allows +/// the binding to later be undone if needed. +pub type TypeBindings = HashMap; + +/// Represents a struct type in the type system. Each instance of this +/// rust struct will be shared across all Type::Struct variants that represent +/// the same struct type. +#[derive(Debug, Eq)] +pub struct StructType { + /// A unique id representing this struct type. Used to check if two + /// struct types are equal. + pub id: StructId, + + pub name: Ident, + + /// Fields are ordered and private, they should only + /// be accessed through get_field(), get_fields(), or instantiate() + /// since these will handle applying generic arguments to fields as well. + fields: Vec<(Ident, Type)>, + + pub generics: Generics, + pub span: Span, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum TraitItemType { + /// A function declaration in a trait. + Function { + name: Ident, + generics: Generics, + arguments: Vec, + return_type: Option, + span: Span, + }, + + /// A constant declaration in a trait. + Constant { name: Ident, ty: Type, span: Span }, + + /// A type declaration in a trait. + Type { name: Ident, ty: Type, span: Span }, +} +/// Represents a trait type in the type system. Each instance of this +/// rust struct will be shared across all Type::Trait variants that represent +/// the same trait type. +#[derive(Debug, Eq)] +pub struct Trait { + /// A unique id representing this trait type. Used to check if two + /// struct traits are equal. + pub id: TraitId, + + pub items: Vec, + + pub name: Ident, + pub generics: Generics, + pub span: Span, +} + +/// Corresponds to generic lists such as `` in the source +/// program. The `TypeVariableId` portion is used to match two +/// type variables to check for equality, while the `TypeVariable` is +/// the actual part that can be mutated to bind it to another type. +pub type Generics = Vec<(TypeVariableId, TypeVariable)>; + +impl std::hash::Hash for StructType { + fn hash(&self, state: &mut H) { + self.id.hash(state); + } +} + +impl PartialEq for StructType { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl std::hash::Hash for Trait { + fn hash(&self, state: &mut H) { + self.id.hash(state); + } +} + +impl PartialEq for Trait { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl Trait { + pub fn new( + id: TraitId, + name: Ident, + span: Span, + items: Vec, + generics: Generics, + ) -> Trait { + Trait { id, name, span, items, generics } + } + + pub fn set_items(&mut self, items: Vec) { + self.items = items; + } +} + +impl std::fmt::Display for Trait { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name) + } +} + +impl StructType { + pub fn new( + id: StructId, + name: Ident, + span: Span, + fields: Vec<(Ident, Type)>, + generics: Generics, + ) -> StructType { + StructType { id, fields, name, span, generics } + } + + /// To account for cyclic references between structs, a struct's + /// fields are resolved strictly after the struct itself is initially + /// created. Therefore, this method is used to set the fields once they + /// become known. + pub fn set_fields(&mut self, fields: Vec<(Ident, Type)>) { + assert!(self.fields.is_empty()); + self.fields = fields; + } + + pub fn num_fields(&self) -> usize { + self.fields.len() + } + + /// Returns the field matching the given field name, as well as its field index. + pub fn get_field(&self, field_name: &str, generic_args: &[Type]) -> Option<(Type, usize)> { + assert_eq!(self.generics.len(), generic_args.len()); + + self.fields.iter().enumerate().find(|(_, (name, _))| name.0.contents == field_name).map( + |(i, (_, typ))| { + let substitutions = self + .generics + .iter() + .zip(generic_args) + .map(|((old_id, old_var), new)| (*old_id, (old_var.clone(), new.clone()))) + .collect(); + + (typ.substitute(&substitutions), i) + }, + ) + } + + /// Returns all the fields of this type, after being applied to the given generic arguments. + pub fn get_fields(&self, generic_args: &[Type]) -> Vec<(String, Type)> { + assert_eq!(self.generics.len(), generic_args.len()); + + let substitutions = self + .generics + .iter() + .zip(generic_args) + .map(|((old_id, old_var), new)| (*old_id, (old_var.clone(), new.clone()))) + .collect(); + + vecmap(&self.fields, |(name, typ)| { + let name = name.0.contents.clone(); + (name, typ.substitute(&substitutions)) + }) + } + + pub fn field_names(&self) -> BTreeSet { + self.fields.iter().map(|(name, _)| name.clone()).collect() + } + + /// True if the given index is the same index as a generic type of this struct + /// which is expected to be a numeric generic. + /// This is needed because we infer type kinds in Noir and don't have extensive kind checking. + pub fn generic_is_numeric(&self, index_of_generic: usize) -> bool { + let target_id = self.generics[index_of_generic].0; + self.fields.iter().any(|(_, field)| field.contains_numeric_typevar(target_id)) + } + + /// Instantiate this struct type, returning a Vec of the new generic args (in + /// the same order as self.generics) + pub fn instantiate(&self, interner: &mut NodeInterner) -> Vec { + vecmap(&self.generics, |_| interner.next_type_variable()) + } +} + +impl std::fmt::Display for StructType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name) + } +} + +/// Wrap around an unsolved type +#[derive(Debug, Clone, Eq)] +pub struct TypeAliasType { + pub name: Ident, + pub id: TypeAliasId, + pub typ: Type, + pub generics: Generics, + pub span: Span, +} + +impl std::hash::Hash for TypeAliasType { + fn hash(&self, state: &mut H) { + self.id.hash(state); + } +} + +impl PartialEq for TypeAliasType { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl std::fmt::Display for TypeAliasType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name)?; + + if !self.generics.is_empty() { + let generics = vecmap(&self.generics, |(_, binding)| binding.borrow().to_string()); + write!(f, "{}", generics.join(", "))?; + } + + Ok(()) + } +} + +impl TypeAliasType { + pub fn new( + id: TypeAliasId, + name: Ident, + span: Span, + typ: Type, + generics: Generics, + ) -> TypeAliasType { + TypeAliasType { id, typ, name, span, generics } + } + + pub fn set_type_and_generics(&mut self, new_typ: Type, new_generics: Generics) { + assert_eq!(self.typ, Type::Error); + self.typ = new_typ; + self.generics = new_generics; + } + + pub fn get_type(&self, generic_args: &[Type]) -> Type { + assert_eq!(self.generics.len(), generic_args.len()); + + let substitutions = self + .generics + .iter() + .zip(generic_args) + .map(|((old_id, old_var), new)| (*old_id, (old_var.clone(), new.clone()))) + .collect(); + + self.typ.substitute(&substitutions) + } +} + +/// A shared, mutable reference to some T. +/// Wrapper is required for Hash impl of RefCell. +#[derive(Debug, Eq, PartialOrd, Ord)] +pub struct Shared(Rc>); + +impl std::hash::Hash for Shared { + fn hash(&self, state: &mut H) { + self.0.borrow().hash(state); + } +} + +impl PartialEq for Shared { + fn eq(&self, other: &Self) -> bool { + let ref1 = self.0.borrow(); + let ref2 = other.0.borrow(); + *ref1 == *ref2 + } +} + +impl Clone for Shared { + fn clone(&self) -> Self { + Shared(self.0.clone()) + } +} + +impl From for Shared { + fn from(thing: T) -> Shared { + Shared::new(thing) + } +} + +impl Shared { + pub fn new(thing: T) -> Shared { + Shared(Rc::new(RefCell::new(thing))) + } + + pub fn borrow(&self) -> std::cell::Ref { + self.0.borrow() + } + + pub fn borrow_mut(&self) -> std::cell::RefMut { + self.0.borrow_mut() + } +} + +/// A restricted subset of binary operators useable on +/// type level integers for use in the array length positions of types. +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum BinaryTypeOperator { + Addition, + Subtraction, + Multiplication, + Division, + Modulo, +} + +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +pub enum TypeVariableKind { + /// Can bind to any type + Normal, + + /// A generic integer or field type. This is a more specific kind of TypeVariable + /// that can only be bound to Type::Field, Type::Integer, or other polymorphic integers. + /// This is the type of undecorated integer literals like `46`. Typing them in this way + /// allows them to be polymorphic over the actual integer/field type used without requiring + /// type annotations on each integer literal. + IntegerOrField, + + /// A potentially constant array size. This will only bind to itself, Type::NotConstant, or + /// Type::Constant(n) with a matching size. This defaults to Type::Constant(n) if still unbound + /// during monomorphization. + Constant(u64), +} + +/// A TypeVariable is a mutable reference that is either +/// bound to some type, or unbound with a given TypeVariableId. +pub type TypeVariable = Shared; + +/// TypeBindings are the mutable insides of a TypeVariable. +/// They are either bound to some type, or are unbound. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum TypeBinding { + Bound(Type), + Unbound(TypeVariableId), +} + +impl TypeBinding { + pub fn is_unbound(&self) -> bool { + matches!(self, TypeBinding::Unbound(_)) + } + + pub fn bind_to(&mut self, binding: Type, span: Span) -> Result<(), TypeCheckError> { + match self { + TypeBinding::Bound(_) => panic!("Tried to bind an already bound type variable!"), + TypeBinding::Unbound(id) => { + if binding.occurs(*id) { + Err(TypeCheckError::TypeAnnotationsNeeded { span }) + } else { + *self = TypeBinding::Bound(binding); + Ok(()) + } + } + } + } +} + +/// A unique ID used to differentiate different type variables +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct TypeVariableId(pub usize); + +impl Type { + pub fn default_int_type() -> Type { + Type::FieldElement + } + + pub fn type_variable(id: TypeVariableId) -> Type { + Type::TypeVariable(Shared::new(TypeBinding::Unbound(id)), TypeVariableKind::Normal) + } + + /// Returns a TypeVariable(_, TypeVariableKind::Constant(length)) to bind to + /// a constant integer for e.g. an array length. + pub fn constant_variable(length: u64, interner: &mut NodeInterner) -> Type { + let id = interner.next_type_variable_id(); + let kind = TypeVariableKind::Constant(length); + Type::TypeVariable(Shared::new(TypeBinding::Unbound(id)), kind) + } + + pub fn polymorphic_integer(interner: &mut NodeInterner) -> Type { + let id = interner.next_type_variable_id(); + let kind = TypeVariableKind::IntegerOrField; + Type::TypeVariable(Shared::new(TypeBinding::Unbound(id)), kind) + } + + /// A bit of an awkward name for this function - this function returns + /// true for type variables or polymorphic integers which are unbound. + /// NamedGenerics will always be false as although they are bindable, + /// they shouldn't be bound over until monomorphization. + pub fn is_bindable(&self) -> bool { + match self { + Type::TypeVariable(binding, _) => match &*binding.borrow() { + TypeBinding::Bound(binding) => binding.is_bindable(), + TypeBinding::Unbound(_) => true, + }, + _ => false, + } + } + + pub fn is_field(&self) -> bool { + matches!(self.follow_bindings(), Type::FieldElement) + } + + pub fn is_signed(&self) -> bool { + matches!(self.follow_bindings(), Type::Integer(Signedness::Signed, _)) + } + + pub fn is_unsigned(&self) -> bool { + matches!(self.follow_bindings(), Type::Integer(Signedness::Unsigned, _)) + } + + fn contains_numeric_typevar(&self, target_id: TypeVariableId) -> bool { + // True if the given type is a NamedGeneric with the target_id + let named_generic_id_matches_target = |typ: &Type| { + if let Type::NamedGeneric(type_variable, _) = typ { + match &*type_variable.borrow() { + TypeBinding::Bound(_) => { + unreachable!("Named generics should not be bound until monomorphization") + } + TypeBinding::Unbound(id) => target_id == *id, + } + } else { + false + } + }; + + match self { + Type::FieldElement + | Type::Integer(_, _) + | Type::Bool + | Type::Unit + | Type::Error + | Type::TypeVariable(_, _) + | Type::Constant(_) + | Type::NamedGeneric(_, _) + | Type::NotConstant + | Type::Forall(_, _) => false, + + Type::Array(length, elem) => { + elem.contains_numeric_typevar(target_id) || named_generic_id_matches_target(length) + } + + Type::Tuple(fields) => { + fields.iter().any(|field| field.contains_numeric_typevar(target_id)) + } + Type::Function(parameters, return_type, env) => { + parameters.iter().any(|parameter| parameter.contains_numeric_typevar(target_id)) + || return_type.contains_numeric_typevar(target_id) + || env.contains_numeric_typevar(target_id) + } + Type::Struct(struct_type, generics) => { + generics.iter().enumerate().any(|(i, generic)| { + if named_generic_id_matches_target(generic) { + struct_type.borrow().generic_is_numeric(i) + } else { + generic.contains_numeric_typevar(target_id) + } + }) + } + Type::MutableReference(element) => element.contains_numeric_typevar(target_id), + Type::String(length) => named_generic_id_matches_target(length), + Type::FmtString(length, elements) => { + elements.contains_numeric_typevar(target_id) + || named_generic_id_matches_target(length) + } + } + } +} + +impl std::fmt::Display for Type { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Type::FieldElement => { + write!(f, "Field") + } + Type::Array(len, typ) => { + if matches!(len.follow_bindings(), Type::NotConstant) { + write!(f, "[{typ}]") + } else { + write!(f, "[{typ}; {len}]") + } + } + Type::Integer(sign, num_bits) => match sign { + Signedness::Signed => write!(f, "i{num_bits}"), + Signedness::Unsigned => write!(f, "u{num_bits}"), + }, + Type::TypeVariable(id, TypeVariableKind::Normal) => write!(f, "{}", id.borrow()), + Type::TypeVariable(binding, TypeVariableKind::IntegerOrField) => { + if let TypeBinding::Unbound(_) = &*binding.borrow() { + // Show a Field by default if this TypeVariableKind::IntegerOrField is unbound, since that is + // what they bind to by default anyway. It is less confusing than displaying it + // as a generic. + write!(f, "Field") + } else { + write!(f, "{}", binding.borrow()) + } + } + Type::TypeVariable(binding, TypeVariableKind::Constant(n)) => { + if let TypeBinding::Unbound(_) = &*binding.borrow() { + // TypeVariableKind::Constant(n) binds to Type::Constant(n) by default, so just show that. + write!(f, "{n}") + } else { + write!(f, "{}", binding.borrow()) + } + } + Type::Struct(s, args) => { + let args = vecmap(args, |arg| arg.to_string()); + if args.is_empty() { + write!(f, "{}", s.borrow()) + } else { + write!(f, "{}<{}>", s.borrow(), args.join(", ")) + } + } + Type::Tuple(elements) => { + let elements = vecmap(elements, ToString::to_string); + write!(f, "({})", elements.join(", ")) + } + Type::Bool => write!(f, "bool"), + Type::String(len) => write!(f, "str<{len}>"), + Type::FmtString(len, elements) => { + write!(f, "fmtstr<{len}, {elements}>") + } + Type::Unit => write!(f, "()"), + Type::Error => write!(f, "error"), + Type::NamedGeneric(binding, name) => match &*binding.borrow() { + TypeBinding::Bound(binding) => binding.fmt(f), + TypeBinding::Unbound(_) if name.is_empty() => write!(f, "_"), + TypeBinding::Unbound(_) => write!(f, "{name}"), + }, + Type::Constant(x) => x.fmt(f), + Type::Forall(typevars, typ) => { + let typevars = vecmap(typevars, |(var, _)| var.to_string()); + write!(f, "forall {}. {}", typevars.join(" "), typ) + } + Type::Function(args, ret, env) => { + let closure_env_text = match **env { + Type::Unit => "".to_string(), + _ => format!(" with closure environment {env}"), + }; + + let args = vecmap(args.iter(), ToString::to_string); + + write!(f, "fn({}) -> {ret}{closure_env_text}", args.join(", ")) + } + Type::MutableReference(element) => { + write!(f, "&mut {element}") + } + Type::NotConstant => write!(f, "_"), + } + } +} + +impl std::fmt::Display for BinaryTypeOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BinaryTypeOperator::Addition => write!(f, "+"), + BinaryTypeOperator::Subtraction => write!(f, "-"), + BinaryTypeOperator::Multiplication => write!(f, "*"), + BinaryTypeOperator::Division => write!(f, "/"), + BinaryTypeOperator::Modulo => write!(f, "%"), + } + } +} + +impl std::fmt::Display for TypeVariableId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "_") + } +} + +impl std::fmt::Display for TypeBinding { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeBinding::Bound(typ) => typ.fmt(f), + TypeBinding::Unbound(id) => id.fmt(f), + } + } +} + +pub struct UnificationError; + +impl Type { + /// Try to bind a MaybeConstant variable to self, succeeding if self is a Constant, + /// MaybeConstant, or type variable. + pub fn try_bind_to_maybe_constant( + &self, + var: &TypeVariable, + target_length: u64, + ) -> Result<(), UnificationError> { + let target_id = match &*var.borrow() { + TypeBinding::Bound(_) => unreachable!(), + TypeBinding::Unbound(id) => *id, + }; + + match self { + Type::Constant(length) if *length == target_length => { + *var.borrow_mut() = TypeBinding::Bound(self.clone()); + Ok(()) + } + Type::NotConstant => { + *var.borrow_mut() = TypeBinding::Bound(Type::NotConstant); + Ok(()) + } + Type::TypeVariable(binding, kind) => { + let borrow = binding.borrow(); + match &*borrow { + TypeBinding::Bound(typ) => typ.try_bind_to_maybe_constant(var, target_length), + // Avoid infinitely recursive bindings + TypeBinding::Unbound(id) if *id == target_id => Ok(()), + TypeBinding::Unbound(_) => match kind { + TypeVariableKind::Normal => { + drop(borrow); + let clone = Type::TypeVariable( + var.clone(), + TypeVariableKind::Constant(target_length), + ); + *binding.borrow_mut() = TypeBinding::Bound(clone); + Ok(()) + } + TypeVariableKind::Constant(length) if *length == target_length => { + drop(borrow); + let clone = Type::TypeVariable( + var.clone(), + TypeVariableKind::Constant(target_length), + ); + *binding.borrow_mut() = TypeBinding::Bound(clone); + Ok(()) + } + TypeVariableKind::Constant(_) | TypeVariableKind::IntegerOrField => { + Err(UnificationError) + } + }, + } + } + _ => Err(UnificationError), + } + } + + /// Try to bind a PolymorphicInt variable to self, succeeding if self is an integer, field, + /// other PolymorphicInt type, or type variable. + pub fn try_bind_to_polymorphic_int(&self, var: &TypeVariable) -> Result<(), UnificationError> { + let target_id = match &*var.borrow() { + TypeBinding::Bound(_) => unreachable!(), + TypeBinding::Unbound(id) => *id, + }; + + match self { + Type::FieldElement | Type::Integer(..) => { + *var.borrow_mut() = TypeBinding::Bound(self.clone()); + Ok(()) + } + Type::TypeVariable(self_var, TypeVariableKind::IntegerOrField) => { + let borrow = self_var.borrow(); + match &*borrow { + TypeBinding::Bound(typ) => typ.try_bind_to_polymorphic_int(var), + // Avoid infinitely recursive bindings + TypeBinding::Unbound(id) if *id == target_id => Ok(()), + TypeBinding::Unbound(_) => { + drop(borrow); + *var.borrow_mut() = TypeBinding::Bound(self.clone()); + Ok(()) + } + } + } + Type::TypeVariable(binding, TypeVariableKind::Normal) => { + let borrow = binding.borrow(); + match &*borrow { + TypeBinding::Bound(typ) => typ.try_bind_to_polymorphic_int(var), + // Avoid infinitely recursive bindings + TypeBinding::Unbound(id) if *id == target_id => Ok(()), + TypeBinding::Unbound(_) => { + drop(borrow); + // PolymorphicInt is more specific than TypeVariable so we bind the type + // variable to PolymorphicInt instead. + let clone = + Type::TypeVariable(var.clone(), TypeVariableKind::IntegerOrField); + *binding.borrow_mut() = TypeBinding::Bound(clone); + Ok(()) + } + } + } + _ => Err(UnificationError), + } + } + + pub fn try_bind_to(&self, var: &TypeVariable) -> Result<(), UnificationError> { + let target_id = match &*var.borrow() { + TypeBinding::Bound(_) => unreachable!(), + TypeBinding::Unbound(id) => *id, + }; + + if let Some(binding) = self.get_inner_type_variable() { + match &*binding.borrow() { + TypeBinding::Bound(typ) => return typ.try_bind_to(var), + // Don't recursively bind the same id to itself + TypeBinding::Unbound(id) if *id == target_id => return Ok(()), + _ => (), + } + } + + // Check if the target id occurs within self before binding. Otherwise this could + // cause infinitely recursive types + if self.occurs(target_id) { + Err(UnificationError) + } else { + *var.borrow_mut() = TypeBinding::Bound(self.clone()); + Ok(()) + } + } + + fn get_inner_type_variable(&self) -> Option> { + match self { + Type::TypeVariable(var, _) | Type::NamedGeneric(var, _) => Some(var.clone()), + _ => None, + } + } + + /// Try to unify this type with another, setting any type variables found + /// equal to the other type in the process. Unification is more strict + /// than sub-typing but less strict than Eq. Returns true if the unification + /// succeeded. Note that any bindings performed in a failed unification are + /// not undone. This may cause further type errors later on. + pub fn unify( + &self, + expected: &Type, + errors: &mut Vec, + make_error: impl FnOnce() -> TypeCheckError, + ) { + if let Err(UnificationError) = self.try_unify(expected) { + errors.push(make_error()); + } + } + + /// `try_unify` is a bit of a misnomer since although errors are not committed, + /// any unified bindings are on success. + fn try_unify(&self, other: &Type) -> Result<(), UnificationError> { + use Type::*; + use TypeVariableKind as Kind; + + match (self, other) { + (Error, _) | (_, Error) => Ok(()), + + (TypeVariable(binding, Kind::IntegerOrField), other) + | (other, TypeVariable(binding, Kind::IntegerOrField)) => { + // If it is already bound, unify against what it is bound to + if let TypeBinding::Bound(link) = &*binding.borrow() { + return link.try_unify(other); + } + + // Otherwise, check it is unified against an integer and bind it + other.try_bind_to_polymorphic_int(binding) + } + + (TypeVariable(binding, Kind::Normal), other) + | (other, TypeVariable(binding, Kind::Normal)) => { + if let TypeBinding::Bound(link) = &*binding.borrow() { + return link.try_unify(other); + } + + other.try_bind_to(binding) + } + + (TypeVariable(binding, Kind::Constant(length)), other) + | (other, TypeVariable(binding, Kind::Constant(length))) => { + if let TypeBinding::Bound(link) = &*binding.borrow() { + return link.try_unify(other); + } + + other.try_bind_to_maybe_constant(binding, *length) + } + + (Array(len_a, elem_a), Array(len_b, elem_b)) => { + len_a.try_unify(len_b)?; + elem_a.try_unify(elem_b) + } + + (String(len_a), String(len_b)) => len_a.try_unify(len_b), + + (FmtString(len_a, elements_a), FmtString(len_b, elements_b)) => { + len_a.try_unify(len_b)?; + elements_a.try_unify(elements_b) + } + + (Tuple(elements_a), Tuple(elements_b)) => { + if elements_a.len() != elements_b.len() { + Err(UnificationError) + } else { + for (a, b) in elements_a.iter().zip(elements_b) { + a.try_unify(b)?; + } + Ok(()) + } + } + + // No recursive try_unify call for struct fields. Don't want + // to mutate shared type variables within struct definitions. + // This isn't possible currently but will be once noir gets generic types + (Struct(fields_a, args_a), Struct(fields_b, args_b)) => { + if fields_a == fields_b { + for (a, b) in args_a.iter().zip(args_b) { + a.try_unify(b)?; + } + Ok(()) + } else { + Err(UnificationError) + } + } + + (NamedGeneric(binding_a, name_a), NamedGeneric(binding_b, name_b)) => { + // Ensure NamedGenerics are never bound during type checking + assert!(binding_a.borrow().is_unbound()); + assert!(binding_b.borrow().is_unbound()); + + if name_a == name_b { + Ok(()) + } else { + Err(UnificationError) + } + } + + (Function(params_a, ret_a, env_a), Function(params_b, ret_b, env_b)) => { + if params_a.len() == params_b.len() { + for (a, b) in params_a.iter().zip(params_b.iter()) { + a.try_unify(b)?; + } + + env_a.try_unify(env_b)?; + ret_b.try_unify(ret_a) + } else { + Err(UnificationError) + } + } + + (MutableReference(elem_a), MutableReference(elem_b)) => elem_a.try_unify(elem_b), + + (other_a, other_b) => { + if other_a == other_b { + Ok(()) + } else { + Err(UnificationError) + } + } + } + } + + /// Similar to `unify` but if the check fails this will attempt to coerce the + /// argument to the target type. When this happens, the given expression is wrapped in + /// a new expression to convert its type. E.g. `array` -> `array.as_slice()` + /// + /// Currently the only type coercion in Noir is `[T; N]` into `[T]` via `.as_slice()`. + pub fn unify_with_coercions( + &self, + expected: &Type, + expression: ExprId, + interner: &mut NodeInterner, + errors: &mut Vec, + make_error: impl FnOnce() -> TypeCheckError, + ) { + if let Err(UnificationError) = self.try_unify(expected) { + if !self.try_array_to_slice_coercion(expected, expression, interner) { + errors.push(make_error()); + } + } + } + + /// Try to apply the array to slice coercion to this given type pair and expression. + /// If self can be converted to target this way, do so and return true to indicate success. + fn try_array_to_slice_coercion( + &self, + target: &Type, + expression: ExprId, + interner: &mut NodeInterner, + ) -> bool { + let this = self.follow_bindings(); + let target = target.follow_bindings(); + + if let (Type::Array(size1, element1), Type::Array(size2, element2)) = (&this, &target) { + let size1 = size1.follow_bindings(); + let size2 = size2.follow_bindings(); + + // If we have an array and our target is a slice + if matches!(size1, Type::Constant(_)) && matches!(size2, Type::NotConstant) { + // Still have to ensure the element types match. + // Don't need to issue an error here if not, it will be done in unify_with_coercions + if element1.try_unify(element2).is_ok() { + convert_array_expression_to_slice(expression, this, target, interner); + return true; + } + } + } + false + } + + /// If this type is a Type::Constant (used in array lengths), or is bound + /// to a Type::Constant, return the constant as a u64. + pub fn evaluate_to_u64(&self) -> Option { + if let Some(binding) = self.get_inner_type_variable() { + if let TypeBinding::Bound(binding) = &*binding.borrow() { + return binding.evaluate_to_u64(); + } + } + + match self { + Type::TypeVariable(_, TypeVariableKind::Constant(size)) => Some(*size), + Type::Array(len, _elem) => len.evaluate_to_u64(), + Type::Constant(x) => Some(*x), + _ => None, + } + } + + /// Iterate over the fields of this type. + /// Panics if the type is not a struct or tuple. + pub fn iter_fields(&self) -> impl Iterator { + let fields: Vec<_> = match self { + // Unfortunately the .borrow() here forces us to collect into a Vec + // only to have to call .into_iter again afterward. Trying to elide + // collecting to a Vec leads to us dropping the temporary Ref before + // the iterator is returned + Type::Struct(def, args) => vecmap(&def.borrow().fields, |(name, _)| { + let name = &name.0.contents; + let typ = def.borrow().get_field(name, args).unwrap().0; + (name.clone(), typ) + }), + Type::Tuple(fields) => { + let fields = fields.iter().enumerate(); + vecmap(fields, |(i, field)| (i.to_string(), field.clone())) + } + other => panic!("Tried to iterate over the fields of '{other}', which has none"), + }; + fields.into_iter() + } + + /// Retrieves the type of the given field name + /// Panics if the type is not a struct or tuple. + pub fn get_field_type(&self, field_name: &str) -> Type { + match self { + Type::Struct(def, args) => def.borrow().get_field(field_name, args).unwrap().0, + Type::Tuple(fields) => { + let mut fields = fields.iter().enumerate(); + fields.find(|(i, _)| i.to_string() == *field_name).unwrap().1.clone() + } + other => panic!("Tried to iterate over the fields of '{other}', which has none"), + } + } + + /// Instantiate this type, replacing any type variables it is quantified + /// over with fresh type variables. If this type is not a Type::Forall, + /// it is unchanged. + pub fn instantiate(&self, interner: &mut NodeInterner) -> (Type, TypeBindings) { + match self { + Type::Forall(typevars, typ) => { + let replacements = typevars + .iter() + .map(|(id, var)| { + let new = interner.next_type_variable(); + (*id, (var.clone(), new)) + }) + .collect(); + + let instantiated = typ.substitute(&replacements); + (instantiated, replacements) + } + other => (other.clone(), HashMap::new()), + } + } + + /// Substitute any type variables found within this type with the + /// given bindings if found. If a type variable is not found within + /// the given TypeBindings, it is unchanged. + pub fn substitute(&self, type_bindings: &TypeBindings) -> Type { + if type_bindings.is_empty() { + return self.clone(); + } + + let substitute_binding = |binding: &TypeVariable| match &*binding.borrow() { + TypeBinding::Bound(binding) => binding.substitute(type_bindings), + TypeBinding::Unbound(id) => match type_bindings.get(id) { + Some((_, binding)) => binding.clone(), + None => self.clone(), + }, + }; + + match self { + Type::Array(size, element) => { + let size = Box::new(size.substitute(type_bindings)); + let element = Box::new(element.substitute(type_bindings)); + Type::Array(size, element) + } + Type::String(size) => { + let size = Box::new(size.substitute(type_bindings)); + Type::String(size) + } + Type::FmtString(size, fields) => { + let size = Box::new(size.substitute(type_bindings)); + let fields = Box::new(fields.substitute(type_bindings)); + Type::FmtString(size, fields) + } + Type::NamedGeneric(binding, _) | Type::TypeVariable(binding, _) => { + substitute_binding(binding) + } + // Do not substitute fields, it can lead to infinite recursion + // and we should not match fields when type checking anyway. + Type::Struct(fields, args) => { + let args = vecmap(args, |arg| arg.substitute(type_bindings)); + Type::Struct(fields.clone(), args) + } + Type::Tuple(fields) => { + let fields = vecmap(fields, |field| field.substitute(type_bindings)); + Type::Tuple(fields) + } + Type::Forall(typevars, typ) => { + // Trying to substitute a variable defined within a nested Forall + // is usually impossible and indicative of an error in the type checker somewhere. + for (var, _) in typevars { + assert!(!type_bindings.contains_key(var)); + } + let typ = Box::new(typ.substitute(type_bindings)); + Type::Forall(typevars.clone(), typ) + } + Type::Function(args, ret, env) => { + let args = vecmap(args, |arg| arg.substitute(type_bindings)); + let ret = Box::new(ret.substitute(type_bindings)); + let env = Box::new(env.substitute(type_bindings)); + Type::Function(args, ret, env) + } + Type::MutableReference(element) => { + Type::MutableReference(Box::new(element.substitute(type_bindings))) + } + + Type::FieldElement + | Type::Integer(_, _) + | Type::Bool + | Type::Constant(_) + | Type::Error + | Type::NotConstant + | Type::Unit => self.clone(), + } + } + + /// True if the given TypeVariableId is free anywhere within self + fn occurs(&self, target_id: TypeVariableId) -> bool { + match self { + Type::Array(len, elem) => len.occurs(target_id) || elem.occurs(target_id), + Type::String(len) => len.occurs(target_id), + Type::FmtString(len, fields) => { + let len_occurs = len.occurs(target_id); + let field_occurs = fields.occurs(target_id); + len_occurs || field_occurs + } + Type::Struct(_, generic_args) => generic_args.iter().any(|arg| arg.occurs(target_id)), + Type::Tuple(fields) => fields.iter().any(|field| field.occurs(target_id)), + Type::NamedGeneric(binding, _) | Type::TypeVariable(binding, _) => { + match &*binding.borrow() { + TypeBinding::Bound(binding) => binding.occurs(target_id), + TypeBinding::Unbound(id) => *id == target_id, + } + } + Type::Forall(typevars, typ) => { + !typevars.iter().any(|(id, _)| *id == target_id) && typ.occurs(target_id) + } + Type::Function(args, ret, env) => { + args.iter().any(|arg| arg.occurs(target_id)) + || ret.occurs(target_id) + || env.occurs(target_id) + } + Type::MutableReference(element) => element.occurs(target_id), + + Type::FieldElement + | Type::Integer(_, _) + | Type::Bool + | Type::Constant(_) + | Type::Error + | Type::NotConstant + | Type::Unit => false, + } + } + + /// Follow any TypeVariable bindings within this type. Doing so ensures + /// that if the bindings are rebound or unbound from under the type then the + /// returned type will not change (because it will no longer contain the + /// links that may be unbound). + /// + /// Expected to be called on an instantiated type (with no Type::Foralls) + pub fn follow_bindings(&self) -> Type { + use Type::*; + match self { + Array(size, elem) => { + Array(Box::new(size.follow_bindings()), Box::new(elem.follow_bindings())) + } + String(size) => String(Box::new(size.follow_bindings())), + FmtString(size, args) => { + let size = Box::new(size.follow_bindings()); + let args = Box::new(args.follow_bindings()); + FmtString(size, args) + } + Struct(def, args) => { + let args = vecmap(args, |arg| arg.follow_bindings()); + Struct(def.clone(), args) + } + Tuple(args) => Tuple(vecmap(args, |arg| arg.follow_bindings())), + + TypeVariable(var, _) | NamedGeneric(var, _) => { + if let TypeBinding::Bound(typ) = &*var.borrow() { + return typ.follow_bindings(); + } + self.clone() + } + + Function(args, ret, env) => { + let args = vecmap(args, |arg| arg.follow_bindings()); + let ret = Box::new(ret.follow_bindings()); + let env = Box::new(env.follow_bindings()); + Function(args, ret, env) + } + + MutableReference(element) => MutableReference(Box::new(element.follow_bindings())), + + // Expect that this function should only be called on instantiated types + Forall(..) => unreachable!(), + + FieldElement | Integer(_, _) | Bool | Constant(_) | Unit | Error | NotConstant => { + self.clone() + } + } + } +} + +/// Wraps a given `expression` in `expression.as_slice()` +fn convert_array_expression_to_slice( + expression: ExprId, + array_type: Type, + target_type: Type, + interner: &mut NodeInterner, +) { + let as_slice_method = interner + .lookup_primitive_method(&array_type, "as_slice") + .expect("Expected 'as_slice' method to be present in Noir's stdlib"); + + let as_slice_id = interner.function_definition_id(as_slice_method); + let location = interner.expr_location(&expression); + let as_slice = HirExpression::Ident(HirIdent { location, id: as_slice_id }); + let func = interner.push_expr(as_slice); + + let arguments = vec![expression]; + let call = HirExpression::Call(HirCallExpression { func, arguments, location }); + let call = interner.push_expr(call); + + interner.push_expr_location(call, location.span, location.file); + interner.push_expr_location(func, location.span, location.file); + + interner.push_expr_type(&call, target_type.clone()); + interner.push_expr_type( + &func, + Type::Function(vec![array_type], Box::new(target_type), Box::new(Type::Unit)), + ); +} + +impl BinaryTypeOperator { + /// Return the actual rust numeric function associated with this operator + pub fn function(self) -> fn(u64, u64) -> u64 { + match self { + BinaryTypeOperator::Addition => |a, b| a.wrapping_add(b), + BinaryTypeOperator::Subtraction => |a, b| a.wrapping_sub(b), + BinaryTypeOperator::Multiplication => |a, b| a.wrapping_mul(b), + BinaryTypeOperator::Division => |a, b| a.wrapping_div(b), + BinaryTypeOperator::Modulo => |a, b| a.wrapping_rem(b), // % b, + } + } +} + +impl TypeVariableKind { + /// Returns the default type this type variable should be bound to if it is still unbound + /// during monomorphization. + pub(crate) fn default_type(&self) -> Type { + match self { + TypeVariableKind::IntegerOrField | TypeVariableKind::Normal => Type::default_int_type(), + TypeVariableKind::Constant(length) => Type::Constant(*length), + } + } +} + +impl From for PrintableType { + fn from(value: Type) -> Self { + Self::from(&value) + } +} + +impl From<&Type> for PrintableType { + fn from(value: &Type) -> Self { + // Note; use strict_eq instead of partial_eq when comparing field types + // in this method, you most likely want to distinguish between public and private + match value { + Type::FieldElement => PrintableType::Field, + Type::Array(size, typ) => { + let length = size.evaluate_to_u64().expect("Cannot print variable sized arrays"); + let typ = typ.as_ref(); + PrintableType::Array { length, typ: Box::new(typ.into()) } + } + Type::Integer(sign, bit_width) => match sign { + Signedness::Unsigned => PrintableType::UnsignedInteger { width: *bit_width }, + Signedness::Signed => PrintableType::SignedInteger { width: *bit_width }, + }, + Type::TypeVariable(binding, TypeVariableKind::IntegerOrField) => { + match &*binding.borrow() { + TypeBinding::Bound(typ) => typ.into(), + TypeBinding::Unbound(_) => Type::default_int_type().into(), + } + } + Type::Bool => PrintableType::Boolean, + Type::String(size) => { + let size = size.evaluate_to_u64().expect("Cannot print variable sized strings"); + PrintableType::String { length: size } + } + Type::FmtString(_, _) => unreachable!("format strings cannot be printed"), + Type::Error => unreachable!(), + Type::Unit => unreachable!(), + Type::Constant(_) => unreachable!(), + Type::Struct(def, ref args) => { + let struct_type = def.borrow(); + let fields = struct_type.get_fields(args); + let fields = vecmap(fields, |(name, typ)| (name, typ.into())); + PrintableType::Struct { fields, name: struct_type.name.to_string() } + } + Type::Tuple(_) => todo!("printing tuple types is not yet implemented"), + Type::TypeVariable(_, _) => unreachable!(), + Type::NamedGeneric(..) => unreachable!(), + Type::Forall(..) => unreachable!(), + Type::Function(_, _, _) => unreachable!(), + Type::MutableReference(_) => unreachable!("cannot print &mut"), + Type::NotConstant => unreachable!(), + } + } +} diff --git a/compiler/noirc_frontend/src/lexer/errors.rs b/compiler/noirc_frontend/src/lexer/errors.rs new file mode 100644 index 00000000000..6b382d76f40 --- /dev/null +++ b/compiler/noirc_frontend/src/lexer/errors.rs @@ -0,0 +1,100 @@ +use crate::token::SpannedToken; + +use super::token::Token; +use noirc_errors::CustomDiagnostic as Diagnostic; +use noirc_errors::Span; +use thiserror::Error; + +#[derive(Error, Clone, Debug, PartialEq, Eq)] +pub enum LexerErrorKind { + #[error("An unexpected character {:?} was found.", found)] + UnexpectedCharacter { span: Span, expected: String, found: Option }, + #[error("NotADoubleChar : {:?} is not a double char token", found)] + NotADoubleChar { span: Span, found: Token }, + #[error("InvalidIntegerLiteral : {:?} is not a integer", found)] + InvalidIntegerLiteral { span: Span, found: String }, + #[error("MalformedFuncAttribute : {:?} is not a valid attribute", found)] + MalformedFuncAttribute { span: Span, found: String }, + #[error("TooManyBits")] + TooManyBits { span: Span, max: u32, got: u32 }, + #[error("LogicalAnd used instead of bitwise and")] + LogicalAnd { span: Span }, + #[error("Unterminated block comment")] + UnterminatedBlockComment { span: Span }, +} + +impl LexerErrorKind { + pub fn span(&self) -> Span { + match self { + LexerErrorKind::UnexpectedCharacter { span, .. } => *span, + LexerErrorKind::NotADoubleChar { span, .. } => *span, + LexerErrorKind::InvalidIntegerLiteral { span, .. } => *span, + LexerErrorKind::MalformedFuncAttribute { span, .. } => *span, + LexerErrorKind::TooManyBits { span, .. } => *span, + LexerErrorKind::LogicalAnd { span } => *span, + LexerErrorKind::UnterminatedBlockComment { span } => *span, + } + } + + fn parts(&self) -> (String, String, Span) { + match self { + LexerErrorKind::UnexpectedCharacter { + span, + expected, + found, + } => { + let found: String = found.map(Into::into).unwrap_or_else(|| "".into()); + + ( + "an unexpected character was found".to_string(), + format!(" expected {expected} , but got {found}"), + *span, + ) + }, + LexerErrorKind::NotADoubleChar { span, found } => ( + format!("tried to parse {found} as double char"), + format!( + " {found:?} is not a double char, this is an internal error" + ), + *span, + ), + LexerErrorKind::InvalidIntegerLiteral { span, found } => ( + "invalid integer literal".to_string(), + format!(" {found} is not an integer"), + *span, + ), + LexerErrorKind::MalformedFuncAttribute { span, found } => ( + "malformed function attribute".to_string(), + format!(" {found} is not a valid attribute"), + *span, + ), + LexerErrorKind::TooManyBits { span, max, got } => ( + "integer literal too large".to_string(), + format!( + "The maximum number of bits needed to represent a field is {max}, This integer type needs {got} bits" + ), + *span, + ), + LexerErrorKind::LogicalAnd { span } => ( + "Noir has no logical-and (&&) operator since short-circuiting is much less efficient when compiling to circuits".to_string(), + "Try `&` instead, or use `if` only if you require short-circuiting".to_string(), + *span, + ), + LexerErrorKind::UnterminatedBlockComment { span } => ("unterminated block comment".to_string(), "Unterminated block comment".to_string(), *span), + } + } +} + +impl From for Diagnostic { + fn from(error: LexerErrorKind) -> Diagnostic { + let (primary, secondary, span) = error.parts(); + Diagnostic::simple_error(primary, secondary, span) + } +} + +impl From for chumsky::error::Simple { + fn from(error: LexerErrorKind) -> Self { + let (_, message, span) = error.parts(); + chumsky::error::Simple::custom(span, message) + } +} diff --git a/compiler/noirc_frontend/src/lexer/lexer.rs b/compiler/noirc_frontend/src/lexer/lexer.rs new file mode 100644 index 00000000000..f3fe0b6aefa --- /dev/null +++ b/compiler/noirc_frontend/src/lexer/lexer.rs @@ -0,0 +1,844 @@ +use super::{ + errors::LexerErrorKind, + token::{Attribute, IntType, Keyword, SpannedToken, Token, Tokens}, +}; +use acvm::FieldElement; +use noirc_errors::{Position, Span}; +use std::str::Chars; +use std::{ + iter::{Peekable, Zip}, + ops::RangeFrom, +}; + +/// The job of the lexer is to transform an iterator of characters (`char_iter`) +/// into an iterator of `SpannedToken`. Each `Token` corresponds roughly to 1 word or operator. +/// Tokens are tagged with their location in the source file (a `Span`) for use in error reporting. +pub struct Lexer<'a> { + char_iter: Peekable, RangeFrom>>, + position: Position, + done: bool, +} + +pub type SpannedTokenResult = Result; + +impl<'a> Lexer<'a> { + /// Given a source file of noir code, return all the tokens in the file + /// in order, along with any lexing errors that occurred. + pub fn lex(source: &'a str) -> (Tokens, Vec) { + let lexer = Lexer::new(source); + let mut tokens = vec![]; + let mut errors = vec![]; + for result in lexer { + match result { + Ok(token) => tokens.push(token), + Err(error) => errors.push(error), + } + } + (Tokens(tokens), errors) + } + + fn new(source: &'a str) -> Self { + Lexer { + // We zip with the character index here to ensure the first char has index 0 + char_iter: source.chars().zip(0..).peekable(), + position: 0, + done: false, + } + } + + /// Iterates the cursor and returns the char at the new cursor position + fn next_char(&mut self) -> Option { + let (c, index) = self.char_iter.next()?; + self.position = index; + Some(c) + } + + /// Peeks at the next char. Does not iterate the cursor + fn peek_char(&mut self) -> Option { + self.char_iter.peek().map(|(c, _)| *c) + } + + /// Peeks at the next char and returns true if it is equal to the char argument + fn peek_char_is(&mut self, ch: char) -> bool { + self.peek_char() == Some(ch) + } + + fn ampersand(&mut self) -> SpannedTokenResult { + if self.peek_char_is('&') { + // When we issue this error the first '&' will already be consumed + // and the next token issued will be the next '&'. + let span = Span::inclusive(self.position, self.position + 1); + Err(LexerErrorKind::LogicalAnd { span }) + } else { + self.single_char_token(Token::Ampersand) + } + } + + fn next_token(&mut self) -> SpannedTokenResult { + match self.next_char() { + Some(x) if { x.is_whitespace() } => { + self.eat_whitespace(); + self.next_token() + } + Some('<') => self.glue(Token::Less), + Some('>') => self.glue(Token::Greater), + Some('=') => self.glue(Token::Assign), + Some('/') => self.glue(Token::Slash), + Some('.') => self.glue(Token::Dot), + Some(':') => self.glue(Token::Colon), + Some('!') => self.glue(Token::Bang), + Some('-') => self.glue(Token::Minus), + Some('&') => self.ampersand(), + Some('|') => self.single_char_token(Token::Pipe), + Some('%') => self.single_char_token(Token::Percent), + Some('^') => self.single_char_token(Token::Caret), + Some(';') => self.single_char_token(Token::Semicolon), + Some('*') => self.single_char_token(Token::Star), + Some('(') => self.single_char_token(Token::LeftParen), + Some(')') => self.single_char_token(Token::RightParen), + Some(',') => self.single_char_token(Token::Comma), + Some('+') => self.single_char_token(Token::Plus), + Some('{') => self.single_char_token(Token::LeftBrace), + Some('}') => self.single_char_token(Token::RightBrace), + Some('[') => self.single_char_token(Token::LeftBracket), + Some(']') => self.single_char_token(Token::RightBracket), + Some('"') => self.eat_string_literal(), + Some('f') => self.eat_format_string_or_alpha_numeric(), + Some('#') => self.eat_attribute(), + Some(ch) if ch.is_ascii_alphanumeric() || ch == '_' => self.eat_alpha_numeric(ch), + Some(ch) => { + // We don't report invalid tokens in the source as errors until parsing to + // avoid reporting the error twice. See the note on Token::Invalid's documentation for details. + Ok(Token::Invalid(ch).into_single_span(self.position)) + } + None => { + self.done = true; + Ok(Token::EOF.into_single_span(self.position)) + } + } + } + + fn single_char_token(&self, token: Token) -> SpannedTokenResult { + Ok(token.into_single_span(self.position)) + } + + fn single_double_peek_token( + &mut self, + character: char, + single: Token, + double: Token, + ) -> SpannedTokenResult { + let start = self.position; + + match self.peek_char_is(character) { + false => Ok(single.into_single_span(start)), + true => { + self.next_char(); + Ok(double.into_span(start, start + 1)) + } + } + } + + /// Given that some tokens can contain two characters, such as <= , !=, >= + /// Glue will take the first character of the token and check if it can be glued onto the next character + /// forming a double token + fn glue(&mut self, prev_token: Token) -> SpannedTokenResult { + let spanned_prev_token = prev_token.clone().into_single_span(self.position); + match prev_token { + Token::Dot => self.single_double_peek_token('.', prev_token, Token::DoubleDot), + Token::Less => { + let start = self.position; + if self.peek_char_is('=') { + self.next_char(); + Ok(Token::LessEqual.into_span(start, start + 1)) + } else if self.peek_char_is('<') { + self.next_char(); + Ok(Token::ShiftLeft.into_span(start, start + 1)) + } else { + Ok(prev_token.into_single_span(start)) + } + } + Token::Greater => { + let start = self.position; + if self.peek_char_is('=') { + self.next_char(); + Ok(Token::GreaterEqual.into_span(start, start + 1)) + // Note: There is deliberately no case for RightShift. We always lex >> as + // two separate Greater tokens to help the parser parse nested generic types. + } else { + Ok(prev_token.into_single_span(start)) + } + } + Token::Bang => self.single_double_peek_token('=', prev_token, Token::NotEqual), + Token::Assign => self.single_double_peek_token('=', prev_token, Token::Equal), + Token::Minus => self.single_double_peek_token('>', prev_token, Token::Arrow), + Token::Colon => self.single_double_peek_token(':', prev_token, Token::DoubleColon), + Token::Slash => { + if self.peek_char_is('/') { + self.next_char(); + return self.parse_comment(); + } else if self.peek_char_is('*') { + self.next_char(); + return self.parse_block_comment(); + } + Ok(spanned_prev_token) + } + _ => Err(LexerErrorKind::NotADoubleChar { + span: Span::single_char(self.position), + found: prev_token, + }), + } + } + + /// Keeps consuming tokens as long as the predicate is satisfied + fn eat_while bool>( + &mut self, + initial_char: Option, + predicate: F, + ) -> String { + // This function is only called when we want to continue consuming a character of the same type. + // For example, we see a digit and we want to consume the whole integer + // Therefore, the current character which triggered this function will need to be appended + let mut word = String::new(); + if let Some(init_char) = initial_char { + word.push(init_char); + } + + // Keep checking that we are not at the EOF + while let Some(peek_char) = self.peek_char() { + // Then check for the predicate, if predicate matches append char and increment the cursor + // If not, return word. The next character will be analyzed on the next iteration of next_token, + // Which will increment the cursor + if !predicate(peek_char) { + return word; + } + word.push(peek_char); + + // If we arrive at this point, then the char has been added to the word and we should increment the cursor + self.next_char(); + } + + word + } + + fn eat_alpha_numeric(&mut self, initial_char: char) -> SpannedTokenResult { + match initial_char { + 'A'..='Z' | 'a'..='z' | '_' => Ok(self.eat_word(initial_char)?), + '0'..='9' => self.eat_digit(initial_char), + _ => Err(LexerErrorKind::UnexpectedCharacter { + span: Span::single_char(self.position), + found: initial_char.into(), + expected: "an alpha numeric character".to_owned(), + }), + } + } + + fn eat_attribute(&mut self) -> SpannedTokenResult { + let start = self.position; + + if !self.peek_char_is('[') { + return Err(LexerErrorKind::UnexpectedCharacter { + span: Span::single_char(self.position), + found: self.next_char(), + expected: "[".to_owned(), + }); + } + self.next_char(); + + let word = self.eat_while(None, |ch| ch != ']'); + + if !self.peek_char_is(']') { + return Err(LexerErrorKind::UnexpectedCharacter { + span: Span::single_char(self.position), + expected: "]".to_owned(), + found: self.next_char(), + }); + } + self.next_char(); + + let end = self.position; + + let attribute = Attribute::lookup_attribute(&word, Span::inclusive(start, end))?; + + Ok(attribute.into_span(start, end)) + } + + //XXX(low): Can increase performance if we use iterator semantic and utilize some of the methods on String. See below + // https://doc.rust-lang.org/stable/std/primitive.str.html#method.rsplit + fn eat_word(&mut self, initial_char: char) -> SpannedTokenResult { + let start = self.position; + + let word = self.eat_while(Some(initial_char), |ch| { + ch.is_ascii_alphabetic() || ch.is_numeric() || ch == '_' + }); + + let end = self.position; + + // Check if word either an identifier or a keyword + if let Some(keyword_token) = Keyword::lookup_keyword(&word) { + return Ok(keyword_token.into_span(start, end)); + } + + // Check if word an int type + // if no error occurred, then it is either a valid integer type or it is not an int type + let parsed_token = IntType::lookup_int_type(&word, Span::inclusive(start, end))?; + + // Check if it is an int type + if let Some(int_type_token) = parsed_token { + return Ok(int_type_token.into_span(start, end)); + } + + // Else it is just an identifier + let ident_token = Token::Ident(word); + Ok(ident_token.into_span(start, end)) + } + + fn eat_digit(&mut self, initial_char: char) -> SpannedTokenResult { + let start = self.position; + + let integer_str = self.eat_while(Some(initial_char), |ch| { + ch.is_ascii_digit() | ch.is_ascii_hexdigit() | (ch == 'x') + }); + + let end = self.position; + + let integer = match FieldElement::try_from_str(&integer_str) { + None => { + return Err(LexerErrorKind::InvalidIntegerLiteral { + span: Span::inclusive(start, end), + found: integer_str, + }) + } + Some(integer) => integer, + }; + + let integer_token = Token::Int(integer); + Ok(integer_token.into_span(start, end)) + } + + fn eat_string_literal(&mut self) -> SpannedTokenResult { + let start = self.position; + + let str_literal = self.eat_while(None, |ch| ch != '"'); + + let str_literal_token = Token::Str(str_literal); + + self.next_char(); // Advance past the closing quote + + let end = self.position; + Ok(str_literal_token.into_span(start, end)) + } + + // This differs from `eat_string_literal` in that we want the leading `f` to be captured in the Span + fn eat_fmt_string(&mut self) -> SpannedTokenResult { + let start = self.position; + + self.next_char(); + + let str_literal = self.eat_while(None, |ch| ch != '"'); + + let str_literal_token = Token::FmtStr(str_literal); + + self.next_char(); // Advance past the closing quote + + let end = self.position; + Ok(str_literal_token.into_span(start, end)) + } + + fn eat_format_string_or_alpha_numeric(&mut self) -> SpannedTokenResult { + if self.peek_char_is('"') { + self.eat_fmt_string() + } else { + self.eat_alpha_numeric('f') + } + } + + fn parse_comment(&mut self) -> SpannedTokenResult { + let _ = self.eat_while(None, |ch| ch != '\n'); + self.next_token() + } + + fn parse_block_comment(&mut self) -> SpannedTokenResult { + let start = self.position; + let mut depth = 1usize; + + while let Some(ch) = self.next_char() { + match ch { + '/' if self.peek_char_is('*') => { + self.next_char(); + depth += 1; + } + '*' if self.peek_char_is('/') => { + self.next_char(); + depth -= 1; + + // This block comment is closed, so for a construction like "/* */ */" + // there will be a successfully parsed block comment "/* */" + // and " */" will be processed separately. + if depth == 0 { + break; + } + } + _ => {} + } + } + + if depth == 0 { + self.next_token() + } else { + let span = Span::inclusive(start, self.position); + Err(LexerErrorKind::UnterminatedBlockComment { span }) + } + } + + /// Skips white space. They are not significant in the source language + fn eat_whitespace(&mut self) { + self.eat_while(None, |ch| ch.is_whitespace()); + } +} + +impl<'a> Iterator for Lexer<'a> { + type Item = SpannedTokenResult; + fn next(&mut self) -> Option { + if self.done { + None + } else { + Some(self.next_token()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::token::{Attribute, PrimaryAttribute, SecondaryAttribute, TestScope}; + #[test] + fn test_single_double_char() { + let input = "! != + ( ) { } [ ] | , ; : :: < <= > >= & - -> . .. % / * = == << >>"; + + let expected = vec![ + Token::Bang, + Token::NotEqual, + Token::Plus, + Token::LeftParen, + Token::RightParen, + Token::LeftBrace, + Token::RightBrace, + Token::LeftBracket, + Token::RightBracket, + Token::Pipe, + Token::Comma, + Token::Semicolon, + Token::Colon, + Token::DoubleColon, + Token::Less, + Token::LessEqual, + Token::Greater, + Token::GreaterEqual, + Token::Ampersand, + Token::Minus, + Token::Arrow, + Token::Dot, + Token::DoubleDot, + Token::Percent, + Token::Slash, + Token::Star, + Token::Assign, + Token::Equal, + Token::ShiftLeft, + Token::Greater, + Token::Greater, + Token::EOF, + ]; + + let mut lexer = Lexer::new(input); + + for token in expected.into_iter() { + let got = lexer.next_token().unwrap(); + assert_eq!(got, token); + } + } + + #[test] + fn invalid_attribute() { + let input = "#"; + let mut lexer = Lexer::new(input); + + let token = lexer.next().unwrap(); + assert!(token.is_err()); + } + + #[test] + fn deprecated_attribute() { + let input = r#"#[deprecated]"#; + let mut lexer = Lexer::new(input); + + let token = lexer.next().unwrap().unwrap(); + assert_eq!( + token.token(), + &Token::Attribute(Attribute::Secondary(SecondaryAttribute::Deprecated(None))) + ); + } + + #[test] + fn deprecated_attribute_with_note() { + let input = r#"#[deprecated("hello")]"#; + let mut lexer = Lexer::new(input); + + let token = lexer.next().unwrap().unwrap(); + assert_eq!( + token.token(), + &Token::Attribute(Attribute::Secondary(crate::token::SecondaryAttribute::Deprecated( + "hello".to_string().into() + ))) + ); + } + + #[test] + fn test_custom_gate_syntax() { + let input = "#[foreign(sha256)]#[foreign(blake2s)]#[builtin(sum)]"; + + let expected = vec![ + Token::Attribute(Attribute::Primary(PrimaryAttribute::Foreign("sha256".to_string()))), + Token::Attribute(Attribute::Primary(PrimaryAttribute::Foreign("blake2s".to_string()))), + Token::Attribute(Attribute::Primary(PrimaryAttribute::Builtin("sum".to_string()))), + ]; + + let mut lexer = Lexer::new(input); + for token in expected.into_iter() { + let got = lexer.next_token().unwrap(); + assert_eq!(got, token); + } + } + + #[test] + fn custom_attribute() { + let input = r#"#[custom(hello)]"#; + let mut lexer = Lexer::new(input); + + let token = lexer.next().unwrap().unwrap(); + assert_eq!( + token.token(), + &Token::Attribute(Attribute::Secondary(SecondaryAttribute::Custom( + "custom(hello)".to_string() + ))) + ); + } + + #[test] + fn test_attribute() { + let input = r#"#[test]"#; + let mut lexer = Lexer::new(input); + + let token = lexer.next().unwrap().unwrap(); + assert_eq!( + token.token(), + &Token::Attribute(Attribute::Primary(PrimaryAttribute::Test(TestScope::None))) + ); + } + #[test] + fn test_attribute_with_valid_scope() { + let input = r#"#[test(should_fail)]"#; + let mut lexer = Lexer::new(input); + + let token = lexer.next().unwrap().unwrap(); + assert_eq!( + token.token(), + &Token::Attribute(Attribute::Primary(PrimaryAttribute::Test( + TestScope::ShouldFailWith { reason: None } + ))) + ); + } + + #[test] + fn test_attribute_with_valid_scope_should_fail_with() { + let input = r#"#[test(should_fail_with = "hello")]"#; + let mut lexer = Lexer::new(input); + + let token = lexer.next().unwrap().unwrap(); + assert_eq!( + token.token(), + &Token::Attribute(Attribute::Primary(PrimaryAttribute::Test( + TestScope::ShouldFailWith { reason: Some("hello".to_owned()) } + ))) + ); + } + + #[test] + fn test_attribute_with_invalid_scope() { + let input = r#"#[test(invalid_scope)]"#; + let mut lexer = Lexer::new(input); + + let token = lexer.next().unwrap(); + let err = match token { + Ok(_) => panic!("test has an invalid scope, so expected an error"), + Err(err) => err, + }; + + // Check if error is MalformedFuncAttribute and found is "foo" + let sub_string = match err { + LexerErrorKind::MalformedFuncAttribute { found, .. } => found, + _ => panic!("expected malformed func attribute error"), + }; + + assert_eq!(sub_string, "test(invalid_scope)"); + } + + #[test] + fn test_int_type() { + let input = "u16 i16 i108 u104.5"; + + let expected = vec![ + Token::IntType(IntType::Unsigned(16)), + Token::IntType(IntType::Signed(16)), + Token::IntType(IntType::Signed(108)), + Token::IntType(IntType::Unsigned(104)), + Token::Dot, + Token::Int(5_i128.into()), + ]; + + let mut lexer = Lexer::new(input); + for token in expected.into_iter() { + let got = lexer.next_token().unwrap(); + assert_eq!(got, token); + } + } + + #[test] + fn test_arithmetic_sugar() { + let input = "+= -= *= /= %="; + + let expected = vec![ + Token::Plus, + Token::Assign, + Token::Minus, + Token::Assign, + Token::Star, + Token::Assign, + Token::Slash, + Token::Assign, + Token::Percent, + Token::Assign, + ]; + + let mut lexer = Lexer::new(input); + for token in expected.into_iter() { + let got = lexer.next_token().unwrap(); + assert_eq!(got, token); + } + } + + #[test] + fn unterminated_block_comment() { + let input = "/*/"; + + let mut lexer = Lexer::new(input); + let token = lexer.next().unwrap(); + + assert!(token.is_err()); + } + + #[test] + fn test_comment() { + let input = "// hello + let x = 5 + "; + + let expected = vec![ + Token::Keyword(Keyword::Let), + Token::Ident("x".to_string()), + Token::Assign, + Token::Int(FieldElement::from(5_i128)), + ]; + + let mut lexer = Lexer::new(input); + for token in expected.into_iter() { + let first_lexer_output = lexer.next_token().unwrap(); + assert_eq!(first_lexer_output, token); + } + } + + #[test] + fn test_block_comment() { + let input = " + /* comment */ + let x = 5 + /* comment */ + "; + + let expected = vec![ + Token::Keyword(Keyword::Let), + Token::Ident("x".to_string()), + Token::Assign, + Token::Int(FieldElement::from(5_i128)), + ]; + + let mut lexer = Lexer::new(input); + for token in expected.into_iter() { + let first_lexer_output = lexer.next_token().unwrap(); + assert_eq!(first_lexer_output, token); + } + } + + #[test] + fn test_nested_block_comments() { + let input = " + /* /* */ /** */ /*! */ */ + let x = 5 + /* /* */ /** */ /*! */ */ + "; + + let expected = vec![ + Token::Keyword(Keyword::Let), + Token::Ident("x".to_string()), + Token::Assign, + Token::Int(FieldElement::from(5_i128)), + ]; + + let mut lexer = Lexer::new(input); + for token in expected.into_iter() { + let first_lexer_output = lexer.next_token().unwrap(); + assert_eq!(first_lexer_output, token); + } + } + #[test] + fn test_eat_string_literal() { + let input = "let _word = \"hello\""; + + let expected = vec![ + Token::Keyword(Keyword::Let), + Token::Ident("_word".to_string()), + Token::Assign, + Token::Str("hello".to_string()), + ]; + let mut lexer = Lexer::new(input); + + for token in expected.into_iter() { + let got = lexer.next_token().unwrap(); + assert_eq!(got, token); + } + } + + #[test] + fn test_eat_hex_int() { + let input = "0x05"; + + let expected = vec![Token::Int(5_i128.into())]; + let mut lexer = Lexer::new(input); + + for token in expected.into_iter() { + let got = lexer.next_token().unwrap(); + assert_eq!(got, token); + } + } + + #[test] + fn test_span() { + let input = "let x = 5"; + + // Let + let start_position = Position::default(); + let let_position = start_position + 2; + let let_token = Token::Keyword(Keyword::Let).into_span(start_position, let_position); + + // Skip whitespace + let whitespace_position = let_position + 1; + + // Identifier position + let ident_position = whitespace_position + 1; + let ident_token = Token::Ident("x".to_string()).into_single_span(ident_position); + + // Skip whitespace + let whitespace_position = ident_position + 1; + + // Assign position + let assign_position = whitespace_position + 1; + let assign_token = Token::Assign.into_single_span(assign_position); + + // Skip whitespace + let whitespace_position = assign_position + 1; + + // Int position + let int_position = whitespace_position + 1; + let int_token = Token::Int(5_i128.into()).into_single_span(int_position); + + let expected = vec![let_token, ident_token, assign_token, int_token]; + let mut lexer = Lexer::new(input); + + for spanned_token in expected.into_iter() { + let got = lexer.next_token().unwrap(); + assert_eq!(got.to_span(), spanned_token.to_span()); + assert_eq!(got, spanned_token); + } + } + + #[test] + fn test_basic_language_syntax() { + let input = " + let five = 5; + let ten : Field = 10; + let mul = fn(x, y) { + x * y; + }; + constrain mul(five, ten) == 50; + assert(ten + five == 15); + "; + + let expected = vec![ + Token::Keyword(Keyword::Let), + Token::Ident("five".to_string()), + Token::Assign, + Token::Int(5_i128.into()), + Token::Semicolon, + Token::Keyword(Keyword::Let), + Token::Ident("ten".to_string()), + Token::Colon, + Token::Keyword(Keyword::Field), + Token::Assign, + Token::Int(10_i128.into()), + Token::Semicolon, + Token::Keyword(Keyword::Let), + Token::Ident("mul".to_string()), + Token::Assign, + Token::Keyword(Keyword::Fn), + Token::LeftParen, + Token::Ident("x".to_string()), + Token::Comma, + Token::Ident("y".to_string()), + Token::RightParen, + Token::LeftBrace, + Token::Ident("x".to_string()), + Token::Star, + Token::Ident("y".to_string()), + Token::Semicolon, + Token::RightBrace, + Token::Semicolon, + Token::Keyword(Keyword::Constrain), + Token::Ident("mul".to_string()), + Token::LeftParen, + Token::Ident("five".to_string()), + Token::Comma, + Token::Ident("ten".to_string()), + Token::RightParen, + Token::Equal, + Token::Int(50_i128.into()), + Token::Semicolon, + Token::Keyword(Keyword::Assert), + Token::LeftParen, + Token::Ident("ten".to_string()), + Token::Plus, + Token::Ident("five".to_string()), + Token::Equal, + Token::Int(15_i128.into()), + Token::RightParen, + Token::Semicolon, + Token::EOF, + ]; + let mut lexer = Lexer::new(input); + + for token in expected.into_iter() { + let got = lexer.next_token().unwrap(); + assert_eq!(got, token); + } + } +} diff --git a/crates/noirc_frontend/src/lexer/mod.rs b/compiler/noirc_frontend/src/lexer/mod.rs similarity index 100% rename from crates/noirc_frontend/src/lexer/mod.rs rename to compiler/noirc_frontend/src/lexer/mod.rs diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs new file mode 100644 index 00000000000..adbf8f65758 --- /dev/null +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -0,0 +1,741 @@ +use acvm::FieldElement; +use noirc_errors::{Position, Span, Spanned}; +use std::{fmt, iter::Map, vec::IntoIter}; + +use crate::lexer::errors::LexerErrorKind; + +/// Represents a token in noir's grammar - a word, number, +/// or symbol that can be used in noir's syntax. This is the +/// smallest unit of grammar. A parser may (will) decide to parse +/// items differently depending on the Tokens present but will +/// never parse the same ordering of identical tokens differently. +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +pub enum Token { + Ident(String), + Int(FieldElement), + Bool(bool), + Str(String), + FmtStr(String), + Keyword(Keyword), + IntType(IntType), + Attribute(Attribute), + /// < + Less, + /// <= + LessEqual, + /// > + Greater, + /// >= + GreaterEqual, + /// == + Equal, + /// != + NotEqual, + /// + + Plus, + /// - + Minus, + /// * + Star, + /// / + Slash, + /// % + Percent, + /// & + Ampersand, + /// ^ + Caret, + /// << + ShiftLeft, + /// >> + ShiftRight, + /// . + Dot, + /// .. + DoubleDot, + /// ( + LeftParen, + /// ) + RightParen, + /// { + LeftBrace, + /// } + RightBrace, + /// [ + LeftBracket, + /// ] + RightBracket, + /// -> + Arrow, + /// | + Pipe, + /// # + Pound, + /// , + Comma, + /// : + Colon, + /// :: + DoubleColon, + /// ; + Semicolon, + /// ! + Bang, + /// = + Assign, + #[allow(clippy::upper_case_acronyms)] + EOF, + + /// An invalid character is one that is not in noir's language or grammar. + /// + /// We don't report invalid tokens in the source as errors until parsing to + /// avoid reporting the error twice (once while lexing, again when it is encountered + /// during parsing). Reporting during lexing then removing these from the token stream + /// would not be equivalent as it would change the resulting parse. + Invalid(char), +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SpannedToken(Spanned); + +impl PartialEq for Token { + fn eq(&self, other: &SpannedToken) -> bool { + self == &other.0.contents + } +} +impl PartialEq for SpannedToken { + fn eq(&self, other: &Token) -> bool { + &self.0.contents == other + } +} + +impl From for Token { + fn from(spt: SpannedToken) -> Self { + spt.0.contents + } +} + +impl SpannedToken { + pub fn new(token: Token, span: Span) -> SpannedToken { + SpannedToken(Spanned::from(span, token)) + } + pub fn to_span(&self) -> Span { + self.0.span() + } + pub fn token(&self) -> &Token { + &self.0.contents + } + pub fn into_token(self) -> Token { + self.0.contents + } + pub fn kind(&self) -> TokenKind { + self.token().kind() + } +} + +impl std::fmt::Display for SpannedToken { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.token().fmt(f) + } +} + +impl fmt::Display for Token { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Token::Ident(ref s) => write!(f, "{s}"), + Token::Int(n) => write!(f, "{}", n.to_u128()), + Token::Bool(b) => write!(f, "{b}"), + Token::Str(ref b) => write!(f, "{b}"), + Token::FmtStr(ref b) => write!(f, "f{b}"), + Token::Keyword(k) => write!(f, "{k}"), + Token::Attribute(ref a) => write!(f, "{a}"), + Token::IntType(ref i) => write!(f, "{i}"), + Token::Less => write!(f, "<"), + Token::LessEqual => write!(f, "<="), + Token::Greater => write!(f, ">"), + Token::GreaterEqual => write!(f, ">="), + Token::Equal => write!(f, "=="), + Token::NotEqual => write!(f, "!="), + Token::Plus => write!(f, "+"), + Token::Minus => write!(f, "-"), + Token::Star => write!(f, "*"), + Token::Slash => write!(f, "/"), + Token::Percent => write!(f, "%"), + Token::Ampersand => write!(f, "&"), + Token::Caret => write!(f, "^"), + Token::ShiftLeft => write!(f, "<<"), + Token::ShiftRight => write!(f, ">>"), + Token::Dot => write!(f, "."), + Token::DoubleDot => write!(f, ".."), + Token::LeftParen => write!(f, "("), + Token::RightParen => write!(f, ")"), + Token::LeftBrace => write!(f, "{{"), + Token::RightBrace => write!(f, "}}"), + Token::LeftBracket => write!(f, "["), + Token::RightBracket => write!(f, "]"), + Token::Arrow => write!(f, "->"), + Token::Pipe => write!(f, "|"), + Token::Pound => write!(f, "#"), + Token::Comma => write!(f, ","), + Token::Colon => write!(f, ":"), + Token::DoubleColon => write!(f, "::"), + Token::Semicolon => write!(f, ";"), + Token::Assign => write!(f, "="), + Token::Bang => write!(f, "!"), + Token::EOF => write!(f, "end of input"), + Token::Invalid(c) => write!(f, "{c}"), + } + } +} + +#[derive(PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +/// The different kinds of tokens that are possible in the target language +pub enum TokenKind { + Token(Token), + Ident, + Literal, + Keyword, + Attribute, +} + +impl fmt::Display for TokenKind { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TokenKind::Token(ref tok) => write!(f, "{tok}"), + TokenKind::Ident => write!(f, "identifier"), + TokenKind::Literal => write!(f, "literal"), + TokenKind::Keyword => write!(f, "keyword"), + TokenKind::Attribute => write!(f, "attribute"), + } + } +} + +impl Token { + pub fn kind(&self) -> TokenKind { + match *self { + Token::Ident(_) => TokenKind::Ident, + Token::Int(_) | Token::Bool(_) | Token::Str(_) | Token::FmtStr(_) => TokenKind::Literal, + Token::Keyword(_) => TokenKind::Keyword, + Token::Attribute(_) => TokenKind::Attribute, + ref tok => TokenKind::Token(tok.clone()), + } + } + + pub fn is_ident(&self) -> bool { + matches!(self, Token::Ident(_)) + } + + pub(super) fn into_single_span(self, position: Position) -> SpannedToken { + self.into_span(position, position) + } + + pub(super) fn into_span(self, start: Position, end: Position) -> SpannedToken { + SpannedToken(Spanned::from_position(start, end, self)) + } + + /// These are all the operators allowed as part of + /// a short-hand assignment: a = b + pub fn assign_shorthand_operators() -> [Token; 10] { + use Token::*; + [Plus, Minus, Star, Slash, Percent, Ampersand, Caret, ShiftLeft, ShiftRight, Pipe] + } + + pub fn try_into_binary_op(self, span: Span) -> Option> { + use crate::BinaryOpKind::*; + let binary_op = match self { + Token::Plus => Add, + Token::Ampersand => And, + Token::Caret => Xor, + Token::ShiftLeft => ShiftLeft, + Token::ShiftRight => ShiftRight, + Token::Pipe => Or, + Token::Minus => Subtract, + Token::Star => Multiply, + Token::Slash => Divide, + Token::Equal => Equal, + Token::NotEqual => NotEqual, + Token::Less => Less, + Token::LessEqual => LessEqual, + Token::Greater => Greater, + Token::GreaterEqual => GreaterEqual, + Token::Percent => Modulo, + _ => return None, + }; + Some(Spanned::from(span, binary_op)) + } +} + +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +pub enum IntType { + Unsigned(u32), // u32 = Unsigned(32) + Signed(u32), // i64 = Signed(64) +} + +impl fmt::Display for IntType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + IntType::Unsigned(num) => write!(f, "u{num}"), + IntType::Signed(num) => write!(f, "i{num}"), + } + } +} + +impl IntType { + // XXX: Result + // Is not the best API. We could split this into two functions. One that checks if the the + // word is a integer, which only returns an Option + pub(crate) fn lookup_int_type(word: &str, span: Span) -> Result, LexerErrorKind> { + // Check if the first string is a 'u' or 'i' + + let is_signed = if word.starts_with('i') { + true + } else if word.starts_with('u') { + false + } else { + return Ok(None); + }; + + // Word start with 'u' or 'i'. Check if the latter is an integer + + let str_as_u32 = match word[1..].parse::() { + Ok(str_as_u32) => str_as_u32, + Err(_) => return Ok(None), + }; + + let max_bits = FieldElement::max_num_bits(); + + if str_as_u32 > max_bits { + return Err(LexerErrorKind::TooManyBits { span, max: max_bits, got: str_as_u32 }); + } + + if is_signed { + Ok(Some(Token::IntType(IntType::Signed(str_as_u32)))) + } else { + Ok(Some(Token::IntType(IntType::Unsigned(str_as_u32)))) + } + } +} + +/// TestScope is used to specify additional annotations for test functions +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +pub enum TestScope { + /// If a test has a scope of ShouldFailWith, then it can only pass + /// if it fails with the specified reason. If the reason is None, then + /// the test must unconditionally fail + ShouldFailWith { reason: Option }, + /// No scope is applied and so the test must pass + None, +} + +impl TestScope { + fn lookup_str(string: &str) -> Option { + match string.trim() { + "should_fail" => Some(TestScope::ShouldFailWith { reason: None }), + s if s.starts_with("should_fail_with") => { + let parts: Vec<&str> = s.splitn(2, '=').collect(); + if parts.len() == 2 { + let reason = parts[1].trim(); + let reason = reason.trim_matches('"'); + Some(TestScope::ShouldFailWith { reason: Some(reason.to_string()) }) + } else { + None + } + } + _ => None, + } + } +} + +impl fmt::Display for TestScope { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TestScope::None => write!(f, ""), + TestScope::ShouldFailWith { reason } => match reason { + Some(failure_reason) => write!(f, "(should_fail_with = ({failure_reason}))"), + None => write!(f, "should_fail"), + }, + } + } +} + +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +// Attributes are special language markers in the target language +// An example of one is `#[SHA256]` . Currently only Foreign attributes are supported +// Calls to functions which have the foreign attribute are executed in the host language +pub struct Attributes { + // Each function can have a single Primary Attribute + pub primary: Option, + // Each function can have many Secondary Attributes + pub secondary: Vec, +} + +impl Attributes { + pub fn empty() -> Self { + Self { primary: None, secondary: Vec::new() } + } + + /// Returns note if a deprecated secondary attribute is found + pub fn get_deprecated_note(&self) -> Option> { + self.secondary.iter().find_map(|attr| match attr { + SecondaryAttribute::Deprecated(note) => Some(note.clone()), + _ => None, + }) + } +} + +/// An Attribute can be either a Primary Attribute or a Secondary Attribute +/// A Primary Attribute can alter the function type, thus there can only be one +/// A secondary attribute has no effect and is either consumed by a library or used as a notice for the developer +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +pub enum Attribute { + Primary(PrimaryAttribute), + Secondary(SecondaryAttribute), +} + +impl fmt::Display for Attribute { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Attribute::Primary(attribute) => write!(f, "{}", attribute), + Attribute::Secondary(attribute) => write!(f, "{}", attribute), + } + } +} + +impl Attribute { + /// If the string is a fixed attribute return that, else + /// return the custom attribute + pub(crate) fn lookup_attribute(word: &str, span: Span) -> Result { + let word_segments: Vec<&str> = word + .split(|c| c == '(' || c == ')') + .filter(|string_segment| !string_segment.is_empty()) + .collect(); + + let validate = |slice: &str| { + let is_valid = slice + .chars() + .all(|ch| { + ch.is_ascii_alphabetic() + || ch.is_numeric() + || ch == '_' + || ch == '(' + || ch == ')' + || ch == '=' + || ch == '"' + || ch == ' ' + }) + .then_some(()); + + is_valid.ok_or(LexerErrorKind::MalformedFuncAttribute { span, found: word.to_owned() }) + }; + + let attribute = match &word_segments[..] { + // Primary Attributes + ["foreign", name] => { + validate(name)?; + Attribute::Primary(PrimaryAttribute::Foreign(name.to_string())) + } + ["builtin", name] => { + validate(name)?; + Attribute::Primary(PrimaryAttribute::Builtin(name.to_string())) + } + ["oracle", name] => { + validate(name)?; + Attribute::Primary(PrimaryAttribute::Oracle(name.to_string())) + } + ["test"] => Attribute::Primary(PrimaryAttribute::Test(TestScope::None)), + ["test", name] => { + validate(name)?; + let malformed_scope = + LexerErrorKind::MalformedFuncAttribute { span, found: word.to_owned() }; + match TestScope::lookup_str(name) { + Some(scope) => Attribute::Primary(PrimaryAttribute::Test(scope)), + None => return Err(malformed_scope), + } + } + // Secondary attributes + ["deprecated"] => Attribute::Secondary(SecondaryAttribute::Deprecated(None)), + ["deprecated", name] => { + if !name.starts_with('"') && !name.ends_with('"') { + return Err(LexerErrorKind::MalformedFuncAttribute { + span, + found: word.to_owned(), + }); + } + + Attribute::Secondary(SecondaryAttribute::Deprecated( + name.trim_matches('"').to_string().into(), + )) + } + tokens => { + tokens.iter().try_for_each(|token| validate(token))?; + Attribute::Secondary(SecondaryAttribute::Custom(word.to_owned())) + } + }; + + Ok(Token::Attribute(attribute)) + } +} + +/// Primary Attributes are those which a function can only have one of. +/// They change the FunctionKind and thus have direct impact on the IR output +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +pub enum PrimaryAttribute { + Foreign(String), + Builtin(String), + Oracle(String), + Test(TestScope), +} + +impl PrimaryAttribute { + pub fn builtin(self) -> Option { + match self { + PrimaryAttribute::Builtin(name) => Some(name), + _ => None, + } + } + + pub fn foreign(self) -> Option { + match self { + PrimaryAttribute::Foreign(name) => Some(name), + _ => None, + } + } + + pub fn is_foreign(&self) -> bool { + matches!(self, PrimaryAttribute::Foreign(_)) + } + + pub fn is_low_level(&self) -> bool { + matches!(self, PrimaryAttribute::Foreign(_) | PrimaryAttribute::Builtin(_)) + } +} + +impl fmt::Display for PrimaryAttribute { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + PrimaryAttribute::Test(scope) => write!(f, "#[test{}]", scope), + PrimaryAttribute::Foreign(ref k) => write!(f, "#[foreign({k})]"), + PrimaryAttribute::Builtin(ref k) => write!(f, "#[builtin({k})]"), + PrimaryAttribute::Oracle(ref k) => write!(f, "#[oracle({k})]"), + } + } +} + +/// Secondary attributes are those which a function can have many of. +/// They are not able to change the `FunctionKind` and thus do not have direct impact on the IR output +/// They are often consumed by libraries or used as notices for the developer +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +pub enum SecondaryAttribute { + Deprecated(Option), + Custom(String), +} + +impl fmt::Display for SecondaryAttribute { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + SecondaryAttribute::Deprecated(None) => write!(f, "#[deprecated]"), + SecondaryAttribute::Deprecated(Some(ref note)) => { + write!(f, r#"#[deprecated("{note}")]"#) + } + SecondaryAttribute::Custom(ref k) => write!(f, "#[{k}]"), + } + } +} + +impl AsRef for PrimaryAttribute { + fn as_ref(&self) -> &str { + match self { + PrimaryAttribute::Foreign(string) => string, + PrimaryAttribute::Builtin(string) => string, + PrimaryAttribute::Oracle(string) => string, + PrimaryAttribute::Test { .. } => "", + } + } +} + +impl AsRef for SecondaryAttribute { + fn as_ref(&self) -> &str { + match self { + SecondaryAttribute::Deprecated(Some(string)) => string, + SecondaryAttribute::Deprecated(None) => "", + SecondaryAttribute::Custom(string) => string, + } + } +} + +/// Note that `self` is not present - it is a contextual keyword rather than a true one as it is +/// only special within `impl`s. Otherwise `self` functions as a normal identifier. +#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone, PartialOrd, Ord)] +#[cfg_attr(test, derive(strum_macros::EnumIter))] +pub enum Keyword { + As, + Assert, + AssertEq, + Bool, + Char, + CompTime, + Constrain, + Contract, + Crate, + Dep, + Distinct, + Else, + Field, + Fn, + For, + FormatString, + Global, + If, + Impl, + In, + Internal, + Let, + Mod, + Mut, + Open, + Pub, + Return, + String, + Struct, + Trait, + Type, + Unconstrained, + Use, + Where, + While, +} + +impl fmt::Display for Keyword { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Keyword::As => write!(f, "as"), + Keyword::Assert => write!(f, "assert"), + Keyword::AssertEq => write!(f, "assert_eq"), + Keyword::Bool => write!(f, "bool"), + Keyword::Char => write!(f, "char"), + Keyword::CompTime => write!(f, "comptime"), + Keyword::Constrain => write!(f, "constrain"), + Keyword::Contract => write!(f, "contract"), + Keyword::Crate => write!(f, "crate"), + Keyword::Dep => write!(f, "dep"), + Keyword::Distinct => write!(f, "distinct"), + Keyword::Else => write!(f, "else"), + Keyword::Field => write!(f, "Field"), + Keyword::Fn => write!(f, "fn"), + Keyword::For => write!(f, "for"), + Keyword::FormatString => write!(f, "fmtstr"), + Keyword::Global => write!(f, "global"), + Keyword::If => write!(f, "if"), + Keyword::Impl => write!(f, "impl"), + Keyword::In => write!(f, "in"), + Keyword::Internal => write!(f, "internal"), + Keyword::Let => write!(f, "let"), + Keyword::Mod => write!(f, "mod"), + Keyword::Mut => write!(f, "mut"), + Keyword::Open => write!(f, "open"), + Keyword::Pub => write!(f, "pub"), + Keyword::Return => write!(f, "return"), + Keyword::String => write!(f, "str"), + Keyword::Struct => write!(f, "struct"), + Keyword::Trait => write!(f, "trait"), + Keyword::Type => write!(f, "type"), + Keyword::Unconstrained => write!(f, "unconstrained"), + Keyword::Use => write!(f, "use"), + Keyword::Where => write!(f, "where"), + Keyword::While => write!(f, "while"), + } + } +} + +impl Keyword { + /// Looks up a word in the source program and returns the associated keyword, if found. + pub(crate) fn lookup_keyword(word: &str) -> Option { + let keyword = match word { + "as" => Keyword::As, + "assert" => Keyword::Assert, + "assert_eq" => Keyword::AssertEq, + "bool" => Keyword::Bool, + "char" => Keyword::Char, + "comptime" => Keyword::CompTime, + "constrain" => Keyword::Constrain, + "contract" => Keyword::Contract, + "crate" => Keyword::Crate, + "dep" => Keyword::Dep, + "distinct" => Keyword::Distinct, + "else" => Keyword::Else, + "Field" => Keyword::Field, + "fn" => Keyword::Fn, + "for" => Keyword::For, + "fmtstr" => Keyword::FormatString, + "global" => Keyword::Global, + "if" => Keyword::If, + "impl" => Keyword::Impl, + "in" => Keyword::In, + "internal" => Keyword::Internal, + "let" => Keyword::Let, + "mod" => Keyword::Mod, + "mut" => Keyword::Mut, + "open" => Keyword::Open, + "pub" => Keyword::Pub, + "return" => Keyword::Return, + "str" => Keyword::String, + "struct" => Keyword::Struct, + "trait" => Keyword::Trait, + "type" => Keyword::Type, + "unconstrained" => Keyword::Unconstrained, + "use" => Keyword::Use, + "where" => Keyword::Where, + "while" => Keyword::While, + + "true" => return Some(Token::Bool(true)), + "false" => return Some(Token::Bool(false)), + _ => return None, + }; + + Some(Token::Keyword(keyword)) + } +} + +#[cfg(test)] +mod keywords { + use strum::IntoEnumIterator; + + use super::{Keyword, Token}; + + #[test] + fn lookup_consistency() { + for keyword in Keyword::iter() { + let resolved_token = + Keyword::lookup_keyword(&format!("{keyword}")).unwrap_or_else(|| { + panic!("Keyword::lookup_keyword couldn't find Keyword {}", keyword) + }); + + assert_eq!( + resolved_token, + Token::Keyword(keyword), + "Keyword::lookup_keyword returns unexpected Keyword" + ); + } + } +} + +pub struct Tokens(pub Vec); + +type TokenMapIter = Map, fn(SpannedToken) -> (Token, Span)>; + +impl<'a> From for chumsky::Stream<'a, Token, Span, TokenMapIter> { + fn from(tokens: Tokens) -> Self { + let end_of_input = match tokens.0.last() { + Some(spanned_token) => spanned_token.to_span(), + None => Span::single_char(0), + }; + + fn get_span(token: SpannedToken) -> (Token, Span) { + let span = token.to_span(); + (token.into_token(), span) + } + + let iter = tokens.0.into_iter().map(get_span as fn(_) -> _); + chumsky::Stream::from_iter(end_of_input, iter) + } +} diff --git a/crates/noirc_frontend/src/lib.rs b/compiler/noirc_frontend/src/lib.rs similarity index 100% rename from crates/noirc_frontend/src/lib.rs rename to compiler/noirc_frontend/src/lib.rs diff --git a/crates/noirc_frontend/src/monomorphization/ast.rs b/compiler/noirc_frontend/src/monomorphization/ast.rs similarity index 99% rename from crates/noirc_frontend/src/monomorphization/ast.rs rename to compiler/noirc_frontend/src/monomorphization/ast.rs index d648e181865..bc59249b489 100644 --- a/crates/noirc_frontend/src/monomorphization/ast.rs +++ b/compiler/noirc_frontend/src/monomorphization/ast.rs @@ -29,7 +29,7 @@ pub enum Expression { ExtractTupleField(Box, usize), Call(Call), Let(Let), - Constrain(Box, Location), + Constrain(Box, Location, Option), Assign(Assign), Semi(Box), } @@ -92,6 +92,7 @@ pub struct Unary { pub operator: crate::UnaryOp, pub rhs: Box, pub result_type: Type, + pub location: Location, } pub type BinaryOp = BinaryOpKind; diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs new file mode 100644 index 00000000000..2a7687731b9 --- /dev/null +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -0,0 +1,1496 @@ +//! Coming after type checking, monomorphization is the last pass in Noir's frontend. +//! It accepts the type checked HIR as input and produces a monomorphized AST as output. +//! This file implements the pass itself, while the AST is defined in the ast module. +//! +//! Unlike the HIR, which is stored within the NodeInterner, the monomorphized AST is +//! self-contained and does not need an external context struct. As a result, the NodeInterner +//! can be safely discarded after monomorphization. +//! +//! The entry point to this pass is the `monomorphize` function which, starting from a given +//! function, will monomorphize the entire reachable program. +use acvm::FieldElement; +use iter_extended::{btree_map, vecmap}; +use noirc_printable_type::PrintableType; +use std::collections::{BTreeMap, HashMap, VecDeque}; + +use crate::{ + hir_def::{ + expr::*, + function::{FuncMeta, FunctionSignature, Parameters}, + stmt::{HirAssignStatement, HirLValue, HirLetStatement, HirPattern, HirStatement}, + types, + }, + node_interner::{self, DefinitionKind, NodeInterner, StmtId}, + token::PrimaryAttribute, + ContractFunctionType, FunctionKind, Type, TypeBinding, TypeBindings, TypeVariableKind, + Visibility, +}; + +use self::ast::{Definition, FuncId, Function, LocalId, Program}; + +pub mod ast; +pub mod printer; + +struct LambdaContext { + env_ident: ast::Ident, + captures: Vec, +} + +/// The context struct for the monomorphization pass. +/// +/// This struct holds the FIFO queue of functions to monomorphize, which is added to +/// whenever a new (function, type) combination is encountered. +struct Monomorphizer<'interner> { + /// Globals are keyed by their unique ID and expected type so that we can monomorphize + /// a new version of the global for each type. Note that 'global' here means 'globally + /// visible' and thus includes both functions and global variables. + /// + /// Using nested HashMaps here lets us avoid cloning HirTypes when calling .get() + globals: HashMap>, + + /// Unlike globals, locals are only keyed by their unique ID because they are never + /// duplicated during monomorphization. Doing so would allow them to be used polymorphically + /// but would also cause them to be re-evaluated which is a performance trap that would + /// confuse users. + locals: HashMap, + + /// Queue of functions to monomorphize next + queue: VecDeque<(node_interner::FuncId, FuncId, TypeBindings)>, + + /// When a function finishes being monomorphized, the monomorphized ast::Function is + /// stored here along with its FuncId. + finished_functions: BTreeMap, + + /// Used to reference existing definitions in the HIR + interner: &'interner NodeInterner, + + lambda_envs_stack: Vec, + + next_local_id: u32, + next_function_id: u32, +} + +type HirType = crate::Type; + +/// Starting from the given `main` function, monomorphize the entire program, +/// replacing all references to type variables and NamedGenerics with concrete +/// types, duplicating definitions as necessary to do so. +/// +/// Instead of iterating over every function, this pass starts with the main function +/// and monomorphizes every function reachable from it via function calls and references. +/// Thus, if a function is not used in the program, it will not be monomorphized. +/// +/// Note that there is no requirement on the `main` function that can be passed into +/// this function. Typically, this is the function named "main" in the source project, +/// but it can also be, for example, an arbitrary test function for running `nargo test`. +pub fn monomorphize(main: node_interner::FuncId, interner: &NodeInterner) -> Program { + let mut monomorphizer = Monomorphizer::new(interner); + let function_sig = monomorphizer.compile_main(main); + + while !monomorphizer.queue.is_empty() { + let (next_fn_id, new_id, bindings) = monomorphizer.queue.pop_front().unwrap(); + monomorphizer.locals.clear(); + + perform_instantiation_bindings(&bindings); + monomorphizer.function(next_fn_id, new_id); + undo_instantiation_bindings(bindings); + } + + let functions = vecmap(monomorphizer.finished_functions, |(_, f)| f); + let FuncMeta { return_distinctness, .. } = interner.function_meta(&main); + Program::new(functions, function_sig, return_distinctness) +} + +impl<'interner> Monomorphizer<'interner> { + fn new(interner: &'interner NodeInterner) -> Self { + Monomorphizer { + globals: HashMap::new(), + locals: HashMap::new(), + queue: VecDeque::new(), + finished_functions: BTreeMap::new(), + next_local_id: 0, + next_function_id: 0, + interner, + lambda_envs_stack: Vec::new(), + } + } + + fn next_local_id(&mut self) -> LocalId { + let id = self.next_local_id; + self.next_local_id += 1; + LocalId(id) + } + + fn next_function_id(&mut self) -> ast::FuncId { + let id = self.next_function_id; + self.next_function_id += 1; + ast::FuncId(id) + } + + fn lookup_local(&mut self, id: node_interner::DefinitionId) -> Option { + self.locals.get(&id).copied().map(Definition::Local) + } + + fn lookup_function( + &mut self, + id: node_interner::FuncId, + expr_id: node_interner::ExprId, + typ: &HirType, + ) -> Definition { + let typ = typ.follow_bindings(); + match self.globals.get(&id).and_then(|inner_map| inner_map.get(&typ)) { + Some(id) => Definition::Function(*id), + None => { + // Function has not been monomorphized yet + let meta = self.interner.function_meta(&id); + match meta.kind { + FunctionKind::LowLevel => { + let attribute = meta.attributes.primary.expect("all low level functions must contain a primary attribute which contains the opcode which it links to"); + let opcode = attribute.foreign().expect( + "ice: function marked as foreign, but attribute kind does not match this", + ); + Definition::LowLevel(opcode) + } + FunctionKind::Builtin => { + let attribute = meta.attributes.primary.expect("all low level functions must contain a primary attribute which contains the opcode which it links to"); + let opcode = attribute.builtin().expect( + "ice: function marked as builtin, but attribute kind does not match this", + ); + Definition::Builtin(opcode) + } + FunctionKind::Normal => { + let id = self.queue_function(id, expr_id, typ); + Definition::Function(id) + } + FunctionKind::Oracle => { + let attr = meta + .attributes + .primary + .expect("Oracle function must have an oracle attribute"); + + match attr { + PrimaryAttribute::Oracle(name) => Definition::Oracle(name), + _ => unreachable!("Oracle function must have an oracle attribute"), + } + } + } + } + } + } + + fn define_local(&mut self, id: node_interner::DefinitionId, new_id: LocalId) { + self.locals.insert(id, new_id); + } + + /// Prerequisite: typ = typ.follow_bindings() + fn define_global(&mut self, id: node_interner::FuncId, typ: HirType, new_id: FuncId) { + self.globals.entry(id).or_default().insert(typ, new_id); + } + + fn compile_main(&mut self, main_id: node_interner::FuncId) -> FunctionSignature { + let new_main_id = self.next_function_id(); + assert_eq!(new_main_id, Program::main_id()); + self.function(main_id, new_main_id); + + let main_meta = self.interner.function_meta(&main_id); + main_meta.into_function_signature() + } + + fn function(&mut self, f: node_interner::FuncId, id: FuncId) { + let meta = self.interner.function_meta(&f); + let name = self.interner.function_name(&f).to_owned(); + + let return_type = Self::convert_type(meta.return_type()); + let parameters = self.parameters(meta.parameters); + let body = self.expr(*self.interner.function(&f).as_expr()); + let unconstrained = meta.is_unconstrained + || matches!(meta.contract_function_type, Some(ContractFunctionType::Open)); + + let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; + self.push_function(id, function); + } + + fn push_function(&mut self, id: FuncId, function: ast::Function) { + let existing = self.finished_functions.insert(id, function); + assert!(existing.is_none()); + } + + /// Monomorphize each parameter, expanding tuple/struct patterns into multiple parameters + /// and binding any generic types found. + fn parameters(&mut self, params: Parameters) -> Vec<(ast::LocalId, bool, String, ast::Type)> { + let mut new_params = Vec::with_capacity(params.len()); + for parameter in params { + self.parameter(parameter.0, ¶meter.1, &mut new_params); + } + new_params + } + + fn parameter( + &mut self, + param: HirPattern, + typ: &HirType, + new_params: &mut Vec<(ast::LocalId, bool, String, ast::Type)>, + ) { + match param { + HirPattern::Identifier(ident) => { + let new_id = self.next_local_id(); + let definition = self.interner.definition(ident.id); + let name = definition.name.clone(); + new_params.push((new_id, definition.mutable, name, Self::convert_type(typ))); + self.define_local(ident.id, new_id); + } + HirPattern::Mutable(pattern, _) => self.parameter(*pattern, typ, new_params), + HirPattern::Tuple(fields, _) => { + let tuple_field_types = unwrap_tuple_type(typ); + + for (field, typ) in fields.into_iter().zip(tuple_field_types) { + self.parameter(field, &typ, new_params); + } + } + HirPattern::Struct(_, fields, _) => { + let struct_field_types = unwrap_struct_type(typ); + assert_eq!(struct_field_types.len(), fields.len()); + + let mut fields = btree_map(fields, |(name, field)| (name.0.contents, field)); + + // Iterate over `struct_field_types` since `unwrap_struct_type` will always + // return the fields in the order defined by the struct type. + for (field_name, field_type) in struct_field_types { + let field = fields.remove(&field_name).unwrap_or_else(|| { + unreachable!("Expected a field named '{field_name}' in the struct pattern") + }); + + self.parameter(field, &field_type, new_params); + } + } + } + } + + fn expr(&mut self, expr: node_interner::ExprId) -> ast::Expression { + use ast::Expression::Literal; + use ast::Literal::*; + + match self.interner.expression(&expr) { + HirExpression::Ident(ident) => self.ident(ident, expr), + HirExpression::Literal(HirLiteral::Str(contents)) => Literal(Str(contents)), + HirExpression::Literal(HirLiteral::FmtStr(contents, idents)) => { + let fields = vecmap(idents, |ident| self.expr(ident)); + Literal(FmtStr( + contents, + fields.len() as u64, + Box::new(ast::Expression::Tuple(fields)), + )) + } + HirExpression::Literal(HirLiteral::Bool(value)) => Literal(Bool(value)), + HirExpression::Literal(HirLiteral::Integer(value)) => { + let typ = Self::convert_type(&self.interner.id_type(expr)); + Literal(Integer(value, typ)) + } + HirExpression::Literal(HirLiteral::Array(array)) => match array { + HirArrayLiteral::Standard(array) => self.standard_array(expr, array), + HirArrayLiteral::Repeated { repeated_element, length } => { + self.repeated_array(expr, repeated_element, length) + } + }, + HirExpression::Literal(HirLiteral::Unit) => ast::Expression::Block(vec![]), + HirExpression::Block(block) => self.block(block.0), + + HirExpression::Prefix(prefix) => { + let location = self.interner.expr_location(&expr); + ast::Expression::Unary(ast::Unary { + operator: prefix.operator, + rhs: Box::new(self.expr(prefix.rhs)), + result_type: Self::convert_type(&self.interner.id_type(expr)), + location, + }) + } + + HirExpression::Infix(infix) => { + let lhs = Box::new(self.expr(infix.lhs)); + let rhs = Box::new(self.expr(infix.rhs)); + let operator = infix.operator.kind; + let location = self.interner.expr_location(&expr); + ast::Expression::Binary(ast::Binary { lhs, rhs, operator, location }) + } + + HirExpression::Index(index) => self.index(expr, index), + + HirExpression::MemberAccess(access) => { + let field_index = self.interner.get_field_index(expr); + let expr = Box::new(self.expr(access.lhs)); + ast::Expression::ExtractTupleField(expr, field_index) + } + + HirExpression::Call(call) => self.function_call(call, expr), + + HirExpression::Cast(cast) => ast::Expression::Cast(ast::Cast { + lhs: Box::new(self.expr(cast.lhs)), + r#type: Self::convert_type(&cast.r#type), + location: self.interner.expr_location(&expr), + }), + + HirExpression::For(for_expr) => { + let start = self.expr(for_expr.start_range); + let end = self.expr(for_expr.end_range); + let index_variable = self.next_local_id(); + self.define_local(for_expr.identifier.id, index_variable); + + let block = Box::new(self.expr(for_expr.block)); + + ast::Expression::For(ast::For { + index_variable, + index_name: self.interner.definition_name(for_expr.identifier.id).to_owned(), + index_type: Self::convert_type(&self.interner.id_type(for_expr.start_range)), + start_range: Box::new(start), + end_range: Box::new(end), + start_range_location: self.interner.expr_location(&for_expr.start_range), + end_range_location: self.interner.expr_location(&for_expr.end_range), + block, + }) + } + + HirExpression::If(if_expr) => { + let cond = self.expr(if_expr.condition); + let then = self.expr(if_expr.consequence); + let else_ = if_expr.alternative.map(|alt| Box::new(self.expr(alt))); + ast::Expression::If(ast::If { + condition: Box::new(cond), + consequence: Box::new(then), + alternative: else_, + typ: Self::convert_type(&self.interner.id_type(expr)), + }) + } + + HirExpression::Tuple(fields) => { + let fields = vecmap(fields, |id| self.expr(id)); + ast::Expression::Tuple(fields) + } + HirExpression::Constructor(constructor) => self.constructor(constructor, expr), + + HirExpression::Lambda(lambda) => self.lambda(lambda, expr), + + HirExpression::MethodCall(_) => { + unreachable!("Encountered HirExpression::MethodCall during monomorphization") + } + HirExpression::Error => unreachable!("Encountered Error node during monomorphization"), + } + } + + fn standard_array( + &mut self, + array: node_interner::ExprId, + array_elements: Vec, + ) -> ast::Expression { + let typ = Self::convert_type(&self.interner.id_type(array)); + let contents = vecmap(array_elements, |id| self.expr(id)); + ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { contents, typ })) + } + + fn repeated_array( + &mut self, + array: node_interner::ExprId, + repeated_element: node_interner::ExprId, + length: HirType, + ) -> ast::Expression { + let typ = Self::convert_type(&self.interner.id_type(array)); + + let contents = self.expr(repeated_element); + let length = length + .evaluate_to_u64() + .expect("Length of array is unknown when evaluating numeric generic"); + + let contents = vec![contents; length as usize]; + ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { contents, typ })) + } + + fn index(&mut self, id: node_interner::ExprId, index: HirIndexExpression) -> ast::Expression { + let element_type = Self::convert_type(&self.interner.id_type(id)); + + let collection = Box::new(self.expr(index.collection)); + let index = Box::new(self.expr(index.index)); + let location = self.interner.expr_location(&id); + ast::Expression::Index(ast::Index { collection, index, element_type, location }) + } + + fn statement(&mut self, id: StmtId) -> ast::Expression { + match self.interner.statement(&id) { + HirStatement::Let(let_statement) => self.let_statement(let_statement), + HirStatement::Constrain(constrain) => { + let expr = self.expr(constrain.0); + let location = self.interner.expr_location(&constrain.0); + ast::Expression::Constrain(Box::new(expr), location, constrain.2) + } + HirStatement::Assign(assign) => self.assign(assign), + HirStatement::Expression(expr) => self.expr(expr), + HirStatement::Semi(expr) => ast::Expression::Semi(Box::new(self.expr(expr))), + HirStatement::Error => unreachable!(), + } + } + + fn let_statement(&mut self, let_statement: HirLetStatement) -> ast::Expression { + let expr = self.expr(let_statement.expression); + let expected_type = self.interner.id_type(let_statement.expression); + self.unpack_pattern(let_statement.pattern, expr, &expected_type) + } + + fn constructor( + &mut self, + constructor: HirConstructorExpression, + id: node_interner::ExprId, + ) -> ast::Expression { + let typ = self.interner.id_type(id); + let field_types = unwrap_struct_type(&typ); + + let field_type_map = btree_map(&field_types, |x| x.clone()); + + // Create let bindings for each field value first to preserve evaluation order before + // they are reordered and packed into the resulting tuple + let mut field_vars = BTreeMap::new(); + let mut new_exprs = Vec::with_capacity(constructor.fields.len()); + + for (field_name, expr_id) in constructor.fields { + let new_id = self.next_local_id(); + let field_type = field_type_map.get(&field_name.0.contents).unwrap(); + let typ = Self::convert_type(field_type); + + field_vars.insert(field_name.0.contents.clone(), (new_id, typ)); + let expression = Box::new(self.expr(expr_id)); + + new_exprs.push(ast::Expression::Let(ast::Let { + id: new_id, + mutable: false, + name: field_name.0.contents, + expression, + })); + } + + // We must ensure the tuple created from the variables here matches the order + // of the fields as defined in the type. To do this, we iterate over field_types, + // rather than field_type_map which is a sorted BTreeMap. + let field_idents = vecmap(field_types, |(name, _)| { + let (id, typ) = field_vars.remove(&name).unwrap_or_else(|| { + unreachable!("Expected field {name} to be present in constructor for {typ}") + }); + + let definition = Definition::Local(id); + let mutable = false; + ast::Expression::Ident(ast::Ident { definition, mutable, location: None, name, typ }) + }); + + // Finally we can return the created Tuple from the new block + new_exprs.push(ast::Expression::Tuple(field_idents)); + ast::Expression::Block(new_exprs) + } + + fn block(&mut self, statement_ids: Vec) -> ast::Expression { + ast::Expression::Block(vecmap(statement_ids, |id| self.statement(id))) + } + + fn unpack_pattern( + &mut self, + pattern: HirPattern, + value: ast::Expression, + typ: &HirType, + ) -> ast::Expression { + match pattern { + HirPattern::Identifier(ident) => { + let new_id = self.next_local_id(); + self.define_local(ident.id, new_id); + let definition = self.interner.definition(ident.id); + + ast::Expression::Let(ast::Let { + id: new_id, + mutable: definition.mutable, + name: definition.name.clone(), + expression: Box::new(value), + }) + } + HirPattern::Mutable(pattern, _) => self.unpack_pattern(*pattern, value, typ), + HirPattern::Tuple(patterns, _) => { + let fields = unwrap_tuple_type(typ); + self.unpack_tuple_pattern(value, patterns.into_iter().zip(fields)) + } + HirPattern::Struct(_, patterns, _) => { + let fields = unwrap_struct_type(typ); + assert_eq!(patterns.len(), fields.len()); + + let mut patterns = + btree_map(patterns, |(name, pattern)| (name.0.contents, pattern)); + + // We iterate through the type's fields to match the order defined in the struct type + let patterns_iter = fields.into_iter().map(|(field_name, field_type)| { + let pattern = patterns.remove(&field_name).unwrap(); + (pattern, field_type) + }); + + self.unpack_tuple_pattern(value, patterns_iter) + } + } + } + + fn unpack_tuple_pattern( + &mut self, + value: ast::Expression, + fields: impl Iterator, + ) -> ast::Expression { + let fresh_id = self.next_local_id(); + + let mut definitions = vec![ast::Expression::Let(ast::Let { + id: fresh_id, + mutable: false, + name: "_".into(), + expression: Box::new(value), + })]; + + for (i, (field_pattern, field_type)) in fields.into_iter().enumerate() { + let location = None; + let mutable = false; + let definition = Definition::Local(fresh_id); + let name = i.to_string(); + let typ = Self::convert_type(&field_type); + + let new_rhs = + ast::Expression::Ident(ast::Ident { location, mutable, definition, name, typ }); + + let new_rhs = ast::Expression::ExtractTupleField(Box::new(new_rhs), i); + let new_expr = self.unpack_pattern(field_pattern, new_rhs, &field_type); + definitions.push(new_expr); + } + + ast::Expression::Block(definitions) + } + + /// Find a captured variable in the innermost closure, and construct an expression + fn lookup_captured_expr(&mut self, id: node_interner::DefinitionId) -> Option { + let ctx = self.lambda_envs_stack.last()?; + ctx.captures.iter().position(|capture| capture.ident.id == id).map(|index| { + ast::Expression::ExtractTupleField( + Box::new(ast::Expression::Ident(ctx.env_ident.clone())), + index, + ) + }) + } + + /// Find a captured variable in the innermost closure construct a LValue + fn lookup_captured_lvalue(&mut self, id: node_interner::DefinitionId) -> Option { + let ctx = self.lambda_envs_stack.last()?; + ctx.captures.iter().position(|capture| capture.ident.id == id).map(|index| { + ast::LValue::MemberAccess { + object: Box::new(ast::LValue::Ident(ctx.env_ident.clone())), + field_index: index, + } + }) + } + + /// A local (ie non-global) ident only + fn local_ident(&mut self, ident: &HirIdent) -> Option { + let definition = self.interner.definition(ident.id); + let name = definition.name.clone(); + let mutable = definition.mutable; + + let definition = self.lookup_local(ident.id)?; + let typ = Self::convert_type(&self.interner.id_type(ident.id)); + + Some(ast::Ident { location: Some(ident.location), mutable, definition, name, typ }) + } + + fn ident(&mut self, ident: HirIdent, expr_id: node_interner::ExprId) -> ast::Expression { + let definition = self.interner.definition(ident.id); + match &definition.kind { + DefinitionKind::Function(func_id) => { + let mutable = definition.mutable; + let location = Some(ident.location); + let name = definition.name.clone(); + let typ = self.interner.id_type(expr_id); + + let definition = self.lookup_function(*func_id, expr_id, &typ); + let typ = Self::convert_type(&typ); + let ident = ast::Ident { location, mutable, definition, name, typ: typ.clone() }; + let ident_expression = ast::Expression::Ident(ident); + if self.is_function_closure_type(&typ) { + ast::Expression::Tuple(vec![ + ast::Expression::ExtractTupleField( + Box::new(ident_expression.clone()), + 0usize, + ), + ast::Expression::ExtractTupleField(Box::new(ident_expression), 1usize), + ]) + } else { + ident_expression + } + } + DefinitionKind::Global(expr_id) => self.expr(*expr_id), + DefinitionKind::Local(_) => self.lookup_captured_expr(ident.id).unwrap_or_else(|| { + let ident = self.local_ident(&ident).unwrap(); + ast::Expression::Ident(ident) + }), + DefinitionKind::GenericType(type_variable) => { + let value = match &*type_variable.borrow() { + TypeBinding::Unbound(_) => { + unreachable!("Unbound type variable used in expression") + } + TypeBinding::Bound(binding) => binding.evaluate_to_u64().unwrap_or_else(|| { + panic!("Non-numeric type variable used in expression expecting a value") + }), + }; + + let value = FieldElement::from(value as u128); + ast::Expression::Literal(ast::Literal::Integer(value, ast::Type::Field)) + } + } + } + + /// Convert a non-tuple/struct type to a monomorphized type + fn convert_type(typ: &HirType) -> ast::Type { + match typ { + HirType::FieldElement => ast::Type::Field, + HirType::Integer(sign, bits) => ast::Type::Integer(*sign, *bits), + HirType::Bool => ast::Type::Bool, + HirType::String(size) => ast::Type::String(size.evaluate_to_u64().unwrap_or(0)), + HirType::FmtString(size, fields) => { + let size = size.evaluate_to_u64().unwrap_or(0); + let fields = Box::new(Self::convert_type(fields.as_ref())); + ast::Type::FmtString(size, fields) + } + HirType::Unit => ast::Type::Unit, + + HirType::Array(length, element) => { + let element = Box::new(Self::convert_type(element.as_ref())); + + if let Some(length) = length.evaluate_to_u64() { + ast::Type::Array(length, element) + } else { + ast::Type::Slice(element) + } + } + + HirType::NamedGeneric(binding, _) => { + if let TypeBinding::Bound(binding) = &*binding.borrow() { + return Self::convert_type(binding); + } + + // Default any remaining unbound type variables. + // This should only happen if the variable in question is unused + // and within a larger generic type. + // NOTE: Make sure to review this if there is ever type-directed dispatch, + // like automatic solving of traits. It should be fine since it is strictly + // after type checking, but care should be taken that it doesn't change which + // impls are chosen. + *binding.borrow_mut() = TypeBinding::Bound(HirType::default_int_type()); + ast::Type::Field + } + + HirType::TypeVariable(binding, kind) => { + if let TypeBinding::Bound(binding) = &*binding.borrow() { + return Self::convert_type(binding); + } + + // Default any remaining unbound type variables. + // This should only happen if the variable in question is unused + // and within a larger generic type. + // NOTE: Make sure to review this if there is ever type-directed dispatch, + // like automatic solving of traits. It should be fine since it is strictly + // after type checking, but care should be taken that it doesn't change which + // impls are chosen. + let default = kind.default_type(); + let monomorphized_default = Self::convert_type(&default); + *binding.borrow_mut() = TypeBinding::Bound(default); + monomorphized_default + } + + HirType::Struct(def, args) => { + let fields = def.borrow().get_fields(args); + let fields = vecmap(fields, |(_, field)| Self::convert_type(&field)); + ast::Type::Tuple(fields) + } + + HirType::Tuple(fields) => { + let fields = vecmap(fields, Self::convert_type); + ast::Type::Tuple(fields) + } + + HirType::Function(args, ret, env) => { + let args = vecmap(args, Self::convert_type); + let ret = Box::new(Self::convert_type(ret)); + let env = Self::convert_type(env); + match &env { + ast::Type::Unit => ast::Type::Function(args, ret, Box::new(env)), + ast::Type::Tuple(_elements) => ast::Type::Tuple(vec![ + env.clone(), + ast::Type::Function(args, ret, Box::new(env)), + ]), + _ => { + unreachable!( + "internal Type::Function env should be either a Unit or a Tuple, not {env}" + ) + } + } + } + + HirType::MutableReference(element) => { + let element = Self::convert_type(element); + ast::Type::MutableReference(Box::new(element)) + } + + HirType::Forall(_, _) + | HirType::Constant(_) + | HirType::NotConstant + | HirType::Error => { + unreachable!("Unexpected type {} found", typ) + } + } + } + + fn is_function_closure(&self, raw_func_id: node_interner::ExprId) -> bool { + let t = Self::convert_type(&self.interner.id_type(raw_func_id)); + if self.is_function_closure_type(&t) { + true + } else if let ast::Type::Tuple(elements) = t { + if elements.len() == 2 { + matches!(elements[1], ast::Type::Function(_, _, _)) + } else { + false + } + } else { + false + } + } + + fn is_function_closure_type(&self, t: &ast::Type) -> bool { + if let ast::Type::Function(_, _, env) = t { + let e = (*env).clone(); + matches!(*e, ast::Type::Tuple(_captures)) + } else { + false + } + } + + fn function_call( + &mut self, + call: HirCallExpression, + id: node_interner::ExprId, + ) -> ast::Expression { + let original_func = Box::new(self.expr(call.func)); + let mut arguments = vecmap(&call.arguments, |id| self.expr(*id)); + let hir_arguments = vecmap(&call.arguments, |id| self.interner.expression(id)); + let func: Box; + let return_type = self.interner.id_type(id); + let return_type = Self::convert_type(&return_type); + let location = call.location; + + if let ast::Expression::Ident(ident) = original_func.as_ref() { + if let Definition::Oracle(name) = &ident.definition { + if name.as_str() == "println" { + // Oracle calls are required to be wrapped in an unconstrained function + // Thus, the only argument to the `println` oracle is expected to always be an ident + self.append_printable_type_info(&hir_arguments[0], &mut arguments); + } + } + } + + let mut block_expressions = vec![]; + + let is_closure = self.is_function_closure(call.func); + if is_closure { + let local_id = self.next_local_id(); + + // store the function in a temporary variable before calling it + // this is needed for example if call.func is of the form `foo()()` + // without this, we would translate it to `foo().1(foo().0)` + let let_stmt = ast::Expression::Let(ast::Let { + id: local_id, + mutable: false, + name: "tmp".to_string(), + expression: Box::new(*original_func), + }); + block_expressions.push(let_stmt); + + let extracted_func = ast::Expression::Ident(ast::Ident { + location: None, + definition: Definition::Local(local_id), + mutable: false, + name: "tmp".to_string(), + typ: Self::convert_type(&self.interner.id_type(call.func)), + }); + + func = Box::new(ast::Expression::ExtractTupleField( + Box::new(extracted_func.clone()), + 1usize, + )); + let env_argument = ast::Expression::ExtractTupleField(Box::new(extracted_func), 0usize); + arguments.insert(0, env_argument); + } else { + func = original_func.clone(); + }; + + let call = self + .try_evaluate_call(&func, &id, &return_type) + .unwrap_or(ast::Expression::Call(ast::Call { func, arguments, return_type, location })); + + if !block_expressions.is_empty() { + block_expressions.push(call); + ast::Expression::Block(block_expressions) + } else { + call + } + } + + /// Adds a function argument that contains type metadata that is required to tell + /// `println` how to convert values passed to an foreign call back to a human-readable string. + /// The values passed to an foreign call will be a simple list of field elements, + /// thus requiring extra metadata to correctly decode this list of elements. + /// + /// The Noir compiler has a `PrintableType` that handles encoding/decoding a list + /// of field elements to/from JSON. The type metadata attached in this method + /// is the serialized `PrintableType` for the argument passed to the function. + /// The caller that is running a Noir program should then deserialize the `PrintableType`, + /// and accurately decode the list of field elements passed to the foreign call. + fn append_printable_type_info( + &mut self, + hir_argument: &HirExpression, + arguments: &mut Vec, + ) { + match hir_argument { + HirExpression::Ident(ident) => { + let typ = self.interner.id_type(ident.id); + let typ: Type = typ.follow_bindings(); + let is_fmt_str = match typ { + // A format string has many different possible types that need to be handled. + // Loop over each element in the format string to fetch each type's relevant metadata + Type::FmtString(_, elements) => { + match *elements { + Type::Tuple(element_types) => { + for typ in element_types { + Self::append_printable_type_info_inner(&typ, arguments); + } + } + _ => unreachable!( + "ICE: format string type should be a tuple but got a {elements}" + ), + } + true + } + _ => { + Self::append_printable_type_info_inner(&typ, arguments); + false + } + }; + // The caller needs information as to whether it is handling a format string or a single type + arguments.push(ast::Expression::Literal(ast::Literal::Bool(is_fmt_str))); + } + _ => unreachable!("logging expr {:?} is not supported", arguments[0]), + } + } + + fn append_printable_type_info_inner(typ: &Type, arguments: &mut Vec) { + if let HirType::Array(size, _) = typ { + if let HirType::NotConstant = **size { + unreachable!("println does not support slices. Convert the slice to an array before passing it to println"); + } + } + let printable_type: PrintableType = typ.into(); + let abi_as_string = serde_json::to_string(&printable_type) + .expect("ICE: expected PrintableType to serialize"); + + arguments.push(ast::Expression::Literal(ast::Literal::Str(abi_as_string))); + } + + /// Try to evaluate certain builtin functions (currently only 'array_len' and field modulus methods) + /// at their call site. + /// NOTE: Evaluating at the call site means we cannot track aliased functions. + /// E.g. `let f = std::array::len; f(arr)` will fail to evaluate. + /// To fix this we need to evaluate on the identifier instead, which + /// requires us to evaluate to a Lambda value which isn't in noir yet. + fn try_evaluate_call( + &mut self, + func: &ast::Expression, + expr_id: &node_interner::ExprId, + result_type: &ast::Type, + ) -> Option { + if let ast::Expression::Ident(ident) = func { + if let Definition::Builtin(opcode) = &ident.definition { + // TODO(#1736): Move this builtin to the SSA pass + return match opcode.as_str() { + "modulus_num_bits" => Some(ast::Expression::Literal(ast::Literal::Integer( + (FieldElement::max_num_bits() as u128).into(), + ast::Type::Field, + ))), + "zeroed" => { + let location = self.interner.expr_location(expr_id); + Some(self.zeroed_value_of_type(result_type, location)) + } + "modulus_le_bits" => { + let bits = FieldElement::modulus().to_radix_le(2); + Some(self.modulus_array_literal(bits, 1)) + } + "modulus_be_bits" => { + let bits = FieldElement::modulus().to_radix_be(2); + Some(self.modulus_array_literal(bits, 1)) + } + "modulus_be_bytes" => { + let bytes = FieldElement::modulus().to_bytes_be(); + Some(self.modulus_array_literal(bytes, 8)) + } + "modulus_le_bytes" => { + let bytes = FieldElement::modulus().to_bytes_le(); + Some(self.modulus_array_literal(bytes, 8)) + } + _ => None, + }; + } + } + None + } + + fn modulus_array_literal(&self, bytes: Vec, arr_elem_bits: u32) -> ast::Expression { + use ast::*; + let int_type = Type::Integer(crate::Signedness::Unsigned, arr_elem_bits); + + let bytes_as_expr = vecmap(bytes, |byte| { + Expression::Literal(Literal::Integer((byte as u128).into(), int_type.clone())) + }); + + let typ = Type::Array(bytes_as_expr.len() as u64, Box::new(int_type)); + + let arr_literal = ArrayLiteral { typ, contents: bytes_as_expr }; + Expression::Literal(Literal::Array(arr_literal)) + } + + fn queue_function( + &mut self, + id: node_interner::FuncId, + expr_id: node_interner::ExprId, + function_type: HirType, + ) -> FuncId { + let new_id = self.next_function_id(); + self.define_global(id, function_type, new_id); + + let bindings = self.interner.get_instantiation_bindings(expr_id); + let bindings = self.follow_bindings(bindings); + + self.queue.push_back((id, new_id, bindings)); + new_id + } + + /// Follow any type variable links within the given TypeBindings to produce + /// a new TypeBindings that won't be changed when bindings are pushed or popped + /// during {perform,undo}_monomorphization_bindings. + /// + /// Without this, a monomorphized type may fail to propagate passed more than 2 + /// function calls deep since it is possible for a previous link in the chain to + /// unbind a type variable that was previously bound. + fn follow_bindings(&self, bindings: &TypeBindings) -> TypeBindings { + bindings + .iter() + .map(|(id, (var, binding))| { + let binding2 = binding.follow_bindings(); + (*id, (var.clone(), binding2)) + }) + .collect() + } + + fn assign(&mut self, assign: HirAssignStatement) -> ast::Expression { + let expression = Box::new(self.expr(assign.expression)); + let lvalue = self.lvalue(assign.lvalue); + ast::Expression::Assign(ast::Assign { expression, lvalue }) + } + + fn lvalue(&mut self, lvalue: HirLValue) -> ast::LValue { + match lvalue { + HirLValue::Ident(ident, _) => self + .lookup_captured_lvalue(ident.id) + .unwrap_or_else(|| ast::LValue::Ident(self.local_ident(&ident).unwrap())), + HirLValue::MemberAccess { object, field_index, .. } => { + let field_index = field_index.unwrap(); + let object = Box::new(self.lvalue(*object)); + ast::LValue::MemberAccess { object, field_index } + } + HirLValue::Index { array, index, typ } => { + let location = self.interner.expr_location(&index); + let array = Box::new(self.lvalue(*array)); + let index = Box::new(self.expr(index)); + let element_type = Self::convert_type(&typ); + ast::LValue::Index { array, index, element_type, location } + } + HirLValue::Dereference { lvalue, element_type } => { + let reference = Box::new(self.lvalue(*lvalue)); + let element_type = Self::convert_type(&element_type); + ast::LValue::Dereference { reference, element_type } + } + } + } + + fn lambda(&mut self, lambda: HirLambda, expr: node_interner::ExprId) -> ast::Expression { + if lambda.captures.is_empty() { + self.lambda_no_capture(lambda) + } else { + let (setup, closure_variable) = self.lambda_with_setup(lambda, expr); + ast::Expression::Block(vec![setup, closure_variable]) + } + } + + fn lambda_no_capture(&mut self, lambda: HirLambda) -> ast::Expression { + let ret_type = Self::convert_type(&lambda.return_type); + let lambda_name = "lambda"; + let parameter_types = vecmap(&lambda.parameters, |(_, typ)| Self::convert_type(typ)); + + // Manually convert to Parameters type so we can reuse the self.parameters method + let parameters = + vecmap(lambda.parameters, |(pattern, typ)| (pattern, typ, Visibility::Private)).into(); + + let parameters = self.parameters(parameters); + let body = self.expr(lambda.body); + + let id = self.next_function_id(); + let return_type = ret_type.clone(); + let name = lambda_name.to_owned(); + let unconstrained = false; + + let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; + self.push_function(id, function); + + let typ = + ast::Type::Function(parameter_types, Box::new(ret_type), Box::new(ast::Type::Unit)); + + let name = lambda_name.to_owned(); + ast::Expression::Ident(ast::Ident { + definition: Definition::Function(id), + mutable: false, + location: None, + name, + typ, + }) + } + + fn lambda_with_setup( + &mut self, + lambda: HirLambda, + expr: node_interner::ExprId, + ) -> (ast::Expression, ast::Expression) { + // returns (, ) + // which can be used directly in callsites or transformed + // directly to a single `Expression` + // for other cases by `lambda` which is called by `expr` + // + // it solves the problem of detecting special cases where + // we call something like + // `{let env$.. = ..;}.1({let env$.. = ..;}.0, ..)` + // which was leading to redefinition errors + // + // instead of detecting and extracting + // patterns in the resulting tree, + // which seems more fragile, we directly reuse the return parameters + // of this function in those cases + let ret_type = Self::convert_type(&lambda.return_type); + let lambda_name = "lambda"; + let parameter_types = vecmap(&lambda.parameters, |(_, typ)| Self::convert_type(typ)); + + // Manually convert to Parameters type so we can reuse the self.parameters method + let parameters = + vecmap(lambda.parameters, |(pattern, typ)| (pattern, typ, Visibility::Private)).into(); + + let mut converted_parameters = self.parameters(parameters); + + let id = self.next_function_id(); + let name = lambda_name.to_owned(); + let return_type = ret_type.clone(); + + let env_local_id = self.next_local_id(); + let env_name = "env"; + let env_tuple = ast::Expression::Tuple(vecmap(&lambda.captures, |capture| { + match capture.transitive_capture_index { + Some(field_index) => match self.lambda_envs_stack.last() { + Some(lambda_ctx) => ast::Expression::ExtractTupleField( + Box::new(ast::Expression::Ident(lambda_ctx.env_ident.clone())), + field_index, + ), + None => unreachable!( + "Expected to find a parent closure environment, but found none" + ), + }, + None => { + let ident = self.local_ident(&capture.ident).unwrap(); + ast::Expression::Ident(ident) + } + } + })); + let expr_type = self.interner.id_type(expr); + let env_typ = if let types::Type::Function(_, _, function_env_type) = expr_type { + Self::convert_type(&function_env_type) + } else { + unreachable!("expected a Function type for a Lambda node") + }; + + let env_let_stmt = ast::Expression::Let(ast::Let { + id: env_local_id, + mutable: false, + name: env_name.to_string(), + expression: Box::new(env_tuple), + }); + + let location = None; // TODO: This should match the location of the lambda expression + let mutable = true; + let definition = Definition::Local(env_local_id); + + let env_ident = ast::Ident { + location, + mutable, + definition, + name: env_name.to_string(), + typ: env_typ.clone(), + }; + + self.lambda_envs_stack + .push(LambdaContext { env_ident: env_ident.clone(), captures: lambda.captures }); + let body = self.expr(lambda.body); + self.lambda_envs_stack.pop(); + + let lambda_fn_typ: ast::Type = + ast::Type::Function(parameter_types, Box::new(ret_type), Box::new(env_typ.clone())); + let lambda_fn = ast::Expression::Ident(ast::Ident { + definition: Definition::Function(id), + mutable: false, + location: None, // TODO: This should match the location of the lambda expression + name: name.clone(), + typ: lambda_fn_typ.clone(), + }); + + let mut parameters = vec![]; + parameters.push((env_local_id, true, env_name.to_string(), env_typ.clone())); + parameters.append(&mut converted_parameters); + + let unconstrained = false; + let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; + self.push_function(id, function); + + let lambda_value = + ast::Expression::Tuple(vec![ast::Expression::Ident(env_ident), lambda_fn]); + let block_local_id = self.next_local_id(); + let block_ident_name = "closure_variable"; + let block_let_stmt = ast::Expression::Let(ast::Let { + id: block_local_id, + mutable: false, + name: block_ident_name.to_string(), + expression: Box::new(ast::Expression::Block(vec![env_let_stmt, lambda_value])), + }); + + let closure_definition = Definition::Local(block_local_id); + + let closure_ident = ast::Expression::Ident(ast::Ident { + location, + mutable: false, + definition: closure_definition, + name: block_ident_name.to_string(), + typ: ast::Type::Tuple(vec![env_typ, lambda_fn_typ]), + }); + + (block_let_stmt, closure_ident) + } + + /// Implements std::unsafe::zeroed by returning an appropriate zeroed + /// ast literal or collection node for the given type. Note that for functions + /// there is no obvious zeroed value so this should be considered unsafe to use. + fn zeroed_value_of_type( + &mut self, + typ: &ast::Type, + location: noirc_errors::Location, + ) -> ast::Expression { + match typ { + ast::Type::Field | ast::Type::Integer(..) => { + ast::Expression::Literal(ast::Literal::Integer(0_u128.into(), typ.clone())) + } + ast::Type::Bool => ast::Expression::Literal(ast::Literal::Bool(false)), + // There is no unit literal currently. Replace it with 'false' since it should be ignored + // anyway. + ast::Type::Unit => ast::Expression::Literal(ast::Literal::Bool(false)), + ast::Type::Array(length, element_type) => { + let element = self.zeroed_value_of_type(element_type.as_ref(), location); + ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { + contents: vec![element; *length as usize], + typ: ast::Type::Array(*length, element_type.clone()), + })) + } + ast::Type::String(length) => { + ast::Expression::Literal(ast::Literal::Str("\0".repeat(*length as usize))) + } + ast::Type::FmtString(length, fields) => { + let zeroed_tuple = self.zeroed_value_of_type(fields, location); + let fields_len = match &zeroed_tuple { + ast::Expression::Tuple(fields) => fields.len() as u64, + _ => unreachable!("ICE: format string fields should be structured in a tuple, but got a {zeroed_tuple}"), + }; + ast::Expression::Literal(ast::Literal::FmtStr( + "\0".repeat(*length as usize), + fields_len, + Box::new(zeroed_tuple), + )) + } + ast::Type::Tuple(fields) => ast::Expression::Tuple(vecmap(fields, |field| { + self.zeroed_value_of_type(field, location) + })), + ast::Type::Function(parameter_types, ret_type, env) => { + self.create_zeroed_function(parameter_types, ret_type, env, location) + } + ast::Type::Slice(element_type) => { + ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { + contents: vec![], + typ: ast::Type::Slice(element_type.clone()), + })) + } + ast::Type::MutableReference(element) => { + use crate::UnaryOp::MutableReference; + let rhs = Box::new(self.zeroed_value_of_type(element, location)); + let result_type = typ.clone(); + ast::Expression::Unary(ast::Unary { + rhs, + result_type, + operator: MutableReference, + location, + }) + } + } + } + + // Creating a zeroed function value is almost always an error if it is used later, + // Hence why std::unsafe::zeroed is unsafe. + // + // To avoid confusing later passes, we arbitrarily choose to construct a function + // that satisfies the input type by discarding all its parameters and returning a + // zeroed value of the result type. + fn create_zeroed_function( + &mut self, + parameter_types: &[ast::Type], + ret_type: &ast::Type, + env_type: &ast::Type, + location: noirc_errors::Location, + ) -> ast::Expression { + let lambda_name = "zeroed_lambda"; + + let parameters = vecmap(parameter_types, |parameter_type| { + (self.next_local_id(), false, "_".into(), parameter_type.clone()) + }); + + let body = self.zeroed_value_of_type(ret_type, location); + + let id = self.next_function_id(); + let return_type = ret_type.clone(); + let name = lambda_name.to_owned(); + + let unconstrained = false; + let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; + self.push_function(id, function); + + ast::Expression::Ident(ast::Ident { + definition: Definition::Function(id), + mutable: false, + location: None, + name: lambda_name.to_owned(), + typ: ast::Type::Function( + parameter_types.to_owned(), + Box::new(ret_type.clone()), + Box::new(env_type.clone()), + ), + }) + } +} + +fn unwrap_tuple_type(typ: &HirType) -> Vec { + match typ { + HirType::Tuple(fields) => fields.clone(), + HirType::TypeVariable(binding, TypeVariableKind::Normal) => match &*binding.borrow() { + TypeBinding::Bound(binding) => unwrap_tuple_type(binding), + TypeBinding::Unbound(_) => unreachable!(), + }, + other => unreachable!("unwrap_tuple_type: expected tuple, found {:?}", other), + } +} + +fn unwrap_struct_type(typ: &HirType) -> Vec<(String, HirType)> { + match typ { + HirType::Struct(def, args) => def.borrow().get_fields(args), + HirType::TypeVariable(binding, TypeVariableKind::Normal) => match &*binding.borrow() { + TypeBinding::Bound(binding) => unwrap_struct_type(binding), + TypeBinding::Unbound(_) => unreachable!(), + }, + other => unreachable!("unwrap_struct_type: expected struct, found {:?}", other), + } +} + +fn perform_instantiation_bindings(bindings: &TypeBindings) { + for (var, binding) in bindings.values() { + *var.borrow_mut() = TypeBinding::Bound(binding.clone()); + } +} + +fn undo_instantiation_bindings(bindings: TypeBindings) { + for (id, (var, _)) in bindings { + *var.borrow_mut() = TypeBinding::Unbound(id); + } +} + +#[cfg(test)] +mod tests { + use std::collections::{BTreeMap, HashMap}; + + use fm::FileId; + use iter_extended::vecmap; + use noirc_errors::Location; + + use crate::{ + graph::CrateId, + hir::{ + def_map::{CrateDefMap, LocalModuleId, ModuleData, ModuleDefId, ModuleId}, + resolution::{ + import::PathResolutionError, path_resolver::PathResolver, resolver::Resolver, + }, + }, + hir_def::function::HirFunction, + node_interner::{FuncId, NodeInterner}, + parse_program, + }; + + use super::monomorphize; + + // TODO: refactor into a more general test utility? + // mostly copied from hir / type_check / mod.rs and adapted a bit + fn type_check_src_code(src: &str, func_namespace: Vec) -> (FuncId, NodeInterner) { + let (program, errors) = parse_program(src); + let mut interner = NodeInterner::default(); + + // Using assert_eq here instead of assert(errors.is_empty()) displays + // the whole vec if the assert fails rather than just two booleans + assert_eq!(errors, vec![]); + + let main_id = interner.push_fn(HirFunction::empty()); + interner.push_function_definition("main".into(), main_id); + + let func_ids = vecmap(&func_namespace, |name| { + let id = interner.push_fn(HirFunction::empty()); + interner.push_function_definition(name.into(), id); + id + }); + + let mut path_resolver = TestPathResolver(HashMap::new()); + for (name, id) in func_namespace.into_iter().zip(func_ids.clone()) { + path_resolver.insert_func(name.to_owned(), id); + } + + let mut def_maps = BTreeMap::new(); + let file = FileId::default(); + + let mut modules = arena::Arena::new(); + let location = Location::new(Default::default(), file); + modules.insert(ModuleData::new(None, location, false)); + + def_maps.insert( + CrateId::dummy_id(), + CrateDefMap { + root: path_resolver.local_module_id(), + modules, + krate: CrateId::dummy_id(), + extern_prelude: BTreeMap::new(), + }, + ); + + let func_meta = vecmap(program.functions, |nf| { + let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); + let (hir_func, func_meta, _resolver_errors) = + resolver.resolve_function(nf, main_id, ModuleId::dummy_id()); + // TODO: not sure why, we do get an error here, + // but otherwise seem to get an ok monomorphization result + // assert_eq!(resolver_errors, vec![]); + (hir_func, func_meta) + }); + + println!("Before update_fn"); + + for ((hir_func, meta), func_id) in func_meta.into_iter().zip(func_ids.clone()) { + interner.update_fn(func_id, hir_func); + interner.push_fn_meta(meta, func_id); + } + + println!("Before type_check_func"); + + // Type check section + let errors = crate::hir::type_check::type_check_func( + &mut interner, + func_ids.first().cloned().unwrap(), + ); + assert_eq!(errors, vec![]); + (func_ids.first().cloned().unwrap(), interner) + } + + // TODO: refactor into a more general test utility? + // TestPathResolver struct and impls copied from hir / type_check / mod.rs + struct TestPathResolver(HashMap); + + impl PathResolver for TestPathResolver { + fn resolve( + &self, + _def_maps: &BTreeMap, + path: crate::Path, + ) -> Result { + // Not here that foo::bar and hello::foo::bar would fetch the same thing + let name = path.segments.last().unwrap(); + let mod_def = self.0.get(&name.0.contents).cloned(); + mod_def.ok_or_else(move || PathResolutionError::Unresolved(name.clone())) + } + + fn local_module_id(&self) -> LocalModuleId { + // This is not LocalModuleId::dummy since we need to use this to index into a Vec + // later and do not want to push u32::MAX number of elements before we do. + LocalModuleId(arena::Index::from_raw_parts(0, 0)) + } + + fn module_id(&self) -> ModuleId { + ModuleId { krate: CrateId::dummy_id(), local_id: self.local_module_id() } + } + } + + impl TestPathResolver { + fn insert_func(&mut self, name: String, func_id: FuncId) { + self.0.insert(name, func_id.into()); + } + } + + // a helper test method + // TODO: maybe just compare trimmed src/expected + // for easier formatting? + fn check_rewrite(src: &str, expected: &str) { + let (func, interner) = type_check_src_code(src, vec!["main".to_string()]); + let program = monomorphize(func, &interner); + // println!("[{}]", program); + assert!(format!("{}", program) == expected); + } + + #[test] + fn simple_closure_with_no_captured_variables() { + let src = r#" + fn main() -> pub Field { + let x = 1; + let closure = || x; + closure() + } + "#; + + let expected_rewrite = r#"fn main$f0() -> Field { + let x$0 = 1; + let closure$3 = { + let closure_variable$2 = { + let env$1 = (x$l0); + (env$l1, lambda$f1) + }; + closure_variable$l2 + }; + { + let tmp$4 = closure$l3; + tmp$l4.1(tmp$l4.0) + } +} +fn lambda$f1(mut env$l1: (Field)) -> Field { + env$l1.0 +} +"#; + check_rewrite(src, expected_rewrite); + } +} diff --git a/crates/noirc_frontend/src/monomorphization/printer.rs b/compiler/noirc_frontend/src/monomorphization/printer.rs similarity index 100% rename from crates/noirc_frontend/src/monomorphization/printer.rs rename to compiler/noirc_frontend/src/monomorphization/printer.rs diff --git a/crates/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs similarity index 88% rename from crates/noirc_frontend/src/node_interner.rs rename to compiler/noirc_frontend/src/node_interner.rs index 5a45cfee42b..5e4604d7bdc 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -7,7 +7,9 @@ use noirc_errors::{Location, Span, Spanned}; use crate::ast::Ident; use crate::graph::CrateId; -use crate::hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTypeAlias}; +use crate::hir::def_collector::dc_crate::{ + UnresolvedFunctions, UnresolvedStruct, UnresolvedTrait, UnresolvedTypeAlias, +}; use crate::hir::def_map::{LocalModuleId, ModuleId}; use crate::hir::StorageSlot; use crate::hir_def::stmt::HirLetStatement; @@ -70,6 +72,12 @@ pub struct NodeInterner { // TODO: We may be able to remove the Shared wrapper once traits are no longer types. // We'd just lookup their methods as needed through the NodeInterner. traits: HashMap>, + + // Trait implementation map + // For each type that implements a given Trait ( corresponding TraitId), there should be an entry here + // The purpose for this hashmap is to detect duplication of trait implementations ( if any ) + trait_implementaions: HashMap<(Type, TraitId), Ident>, + /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization /// to map call site types back onto function parameter types, and undo this binding as needed. @@ -138,8 +146,8 @@ impl FuncId { } } -#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] -pub struct StructId(pub ModuleId); +#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, PartialOrd, Ord)] +pub struct StructId(ModuleId); impl StructId { //dummy id for error reporting @@ -148,9 +156,21 @@ impl StructId { pub fn dummy_id() -> StructId { StructId(ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() }) } + + pub fn module_id(self) -> ModuleId { + self.0 + } + + pub fn krate(self) -> CrateId { + self.0.krate + } + + pub fn local_module_id(self) -> LocalModuleId { + self.0.local_id + } } -#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] +#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, PartialOrd, Ord)] pub struct TypeAliasId(pub usize); impl TypeAliasId { @@ -159,7 +179,7 @@ impl TypeAliasId { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct TraitId(pub ModuleId); impl TraitId { @@ -284,6 +304,7 @@ impl Default for NodeInterner { structs: HashMap::new(), type_aliases: Vec::new(), traits: HashMap::new(), + trait_implementaions: HashMap::new(), instantiation_bindings: HashMap::new(), field_indices: HashMap::new(), next_type_variable_id: 0, @@ -326,16 +347,16 @@ impl NodeInterner { self.id_to_type.insert(expr_id.into(), typ); } - pub fn push_empty_struct(&mut self, type_id: StructId, typ: &UnresolvedStruct) { - self.structs.insert( + pub fn push_empty_trait(&mut self, type_id: TraitId, typ: &UnresolvedTrait) { + self.traits.insert( type_id, - Shared::new(StructType::new( + Shared::new(Trait::new( type_id, - typ.struct_def.name.clone(), - typ.struct_def.span, + typ.trait_def.name.clone(), + typ.trait_def.span, Vec::new(), - vecmap(&typ.struct_def.generics, |_| { - // Temporary type variable ids before the struct is resolved to its actual ids. + vecmap(&typ.trait_def.generics, |_| { + // Temporary type variable ids before the trait is resolved to its actual ids. // This lets us record how many arguments the type expects so that other types // can refer to it with generic arguments before the generic parameters themselves // are resolved. @@ -346,6 +367,31 @@ impl NodeInterner { ); } + pub fn new_struct( + &mut self, + typ: &UnresolvedStruct, + krate: CrateId, + local_id: LocalModuleId, + ) -> StructId { + let struct_id = StructId(ModuleId { krate, local_id }); + let name = typ.struct_def.name.clone(); + + // Fields will be filled in later + let no_fields = Vec::new(); + let generics = vecmap(&typ.struct_def.generics, |_| { + // Temporary type variable ids before the struct is resolved to its actual ids. + // This lets us record how many arguments the type expects so that other types + // can refer to it with generic arguments before the generic parameters themselves + // are resolved. + let id = TypeVariableId(0); + (id, Shared::new(TypeBinding::Unbound(id))) + }); + + let new_struct = StructType::new(struct_id, name, typ.struct_def.span, no_fields, generics); + self.structs.insert(struct_id, Shared::new(new_struct)); + struct_id + } + pub fn push_type_alias(&mut self, typ: &UnresolvedTypeAlias) -> TypeAliasId { let type_id = TypeAliasId(self.type_aliases.len()); @@ -368,6 +414,11 @@ impl NodeInterner { f(&mut value); } + pub fn update_trait(&mut self, trait_id: TraitId, f: impl FnOnce(&mut Trait)) { + let mut value = self.traits.get_mut(&trait_id).unwrap().borrow_mut(); + f(&mut value); + } + pub fn set_type_alias(&mut self, type_id: TypeAliasId, typ: Type, generics: Generics) { let type_alias_type = &mut self.type_aliases[type_id.0]; type_alias_type.set_type_and_generics(typ, generics); @@ -660,6 +711,26 @@ impl NodeInterner { } } + pub fn get_previous_trait_implementation(&self, key: &(Type, TraitId)) -> Option<&Ident> { + self.trait_implementaions.get(key) + } + + pub fn add_trait_implementaion( + &mut self, + key: &(Type, TraitId), + trait_definition_ident: &Ident, + methods: &UnresolvedFunctions, + ) -> Vec { + self.trait_implementaions.insert(key.clone(), trait_definition_ident.clone()); + methods + .functions + .iter() + .flat_map(|(_, func_id, _)| { + self.add_method(&key.0, self.function_name(func_id).to_owned(), *func_id) + }) + .collect::>() + } + /// Search by name for a method on the given struct pub fn lookup_method(&self, id: StructId, method_name: &str) -> Option { self.struct_methods.get(&(id, method_name.to_owned())).copied() diff --git a/compiler/noirc_frontend/src/parser/errors.rs b/compiler/noirc_frontend/src/parser/errors.rs new file mode 100644 index 00000000000..45832ce39db --- /dev/null +++ b/compiler/noirc_frontend/src/parser/errors.rs @@ -0,0 +1,197 @@ +use crate::lexer::token::Token; +use crate::Expression; +use small_ord_set::SmallOrdSet; +use thiserror::Error; + +use iter_extended::vecmap; +use noirc_errors::CustomDiagnostic as Diagnostic; +use noirc_errors::Span; + +use super::labels::ParsingRuleLabel; + +#[derive(Debug, Clone, PartialEq, Eq, Error)] +pub enum ParserErrorReason { + #[error("Unexpected '{0}', expected a field name")] + ExpectedFieldName(Token), + #[error("expected a pattern but found a type - {0}")] + ExpectedPatternButFoundType(Token), + #[error("Expected a ; separating these two statements")] + MissingSeparatingSemi, + #[error("constrain keyword is deprecated")] + ConstrainDeprecated, + #[error("Expression is invalid in an array-length type: '{0}'. Only unsigned integer constants, globals, generics, +, -, *, /, and % may be used in this context.")] + InvalidArrayLengthExpression(Expression), + #[error("Early 'return' is unsupported")] + EarlyReturn, + #[error("Patterns aren't allowed in a trait's function declarations")] + PatternInTraitFunctionParameter, + #[error("comptime keyword is deprecated")] + ComptimeDeprecated, + #[error("{0} are experimental and aren't fully supported yet")] + ExperimentalFeature(&'static str), + #[error("Where clauses are allowed only on functions with generic parameters")] + WhereClauseOnNonGenericFunction, + #[error( + "Multiple primary attributes found. Only one primary attribute is allowed per function." + )] + MultiplePrimaryAttributesFound, + #[error("Assert statements can only accept string literals")] + AssertMessageNotString, +} + +/// Represents a parsing error, or a parsing error in the making. +/// +/// `ParserError` is used extensively by the parser, as it not only used to report badly formed +/// token streams, but also as a general intermediate that accumulates information as various +/// parsing rules are tried. This struct is constructed and destructed with a very high frequency +/// and as such, the time taken to do so significantly impacts parsing performance. For this +/// reason we use `SmallOrdSet` to avoid heap allocations for as long as possible - this greatly +/// inflates the size of the error, but this is justified by a resulting increase in parsing +/// speeds of approximately 40% in release mode. +/// +/// Both `expected_tokens` and `expected_labels` use `SmallOrdSet` sized 1. In the of labels this +/// is optimal. In the of tokens we stop here due to fast diminishing returns. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ParserError { + expected_tokens: SmallOrdSet<[Token; 1]>, + expected_labels: SmallOrdSet<[ParsingRuleLabel; 1]>, + found: Token, + reason: Option, + span: Span, +} + +impl ParserError { + pub fn empty(found: Token, span: Span) -> ParserError { + ParserError { + expected_tokens: SmallOrdSet::new(), + expected_labels: SmallOrdSet::new(), + found, + reason: None, + span, + } + } + + pub fn expected_label(label: ParsingRuleLabel, found: Token, span: Span) -> ParserError { + let mut error = ParserError::empty(found, span); + error.expected_labels.insert(label); + error + } + + pub fn with_reason(reason: ParserErrorReason, span: Span) -> ParserError { + let mut error = ParserError::empty(Token::EOF, span); + error.reason = Some(reason); + error + } + + pub fn found(&self) -> &Token { + &self.found + } + + pub fn span(&self) -> Span { + self.span + } +} + +impl std::fmt::Display for ParserError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut expected = vecmap(&self.expected_tokens, ToString::to_string); + expected.append(&mut vecmap(&self.expected_labels, |label| format!("{label}"))); + + if expected.is_empty() { + write!(f, "Unexpected {} in input", self.found) + } else if expected.len() == 1 { + let first = expected.first().unwrap(); + let vowel = "aeiou".contains(first.chars().next().unwrap()); + write!( + f, + "Expected a{} {} but found {}", + if vowel { "n" } else { "" }, + first, + self.found + ) + } else { + let expected = expected.iter().map(ToString::to_string).collect::>().join(", "); + + write!(f, "Unexpected {}, expected one of {}", self.found, expected) + } + } +} + +impl From for Diagnostic { + fn from(error: ParserError) -> Diagnostic { + match &error.reason { + Some(reason) => { + match reason { + ParserErrorReason::ConstrainDeprecated => Diagnostic::simple_warning( + "Use of deprecated keyword 'constrain'".into(), + "The 'constrain' keyword has been deprecated. Please use the 'assert' function instead.".into(), + error.span, + ), + ParserErrorReason::ComptimeDeprecated => Diagnostic::simple_warning( + "Use of deprecated keyword 'comptime'".into(), + "The 'comptime' keyword has been deprecated. It can be removed without affecting your program".into(), + error.span, + ), + ParserErrorReason::ExperimentalFeature(_) => Diagnostic::simple_warning( + reason.to_string(), + "".into(), + error.span, + ), + reason @ ParserErrorReason::ExpectedPatternButFoundType(ty) => { + Diagnostic::simple_error(reason.to_string(), format!("{ty} is a type and cannot be used as a variable name"), error.span) + } + other => { + + Diagnostic::simple_error(format!("{other}"), String::new(), error.span) + } + } + } + None => { + let primary = error.to_string(); + Diagnostic::simple_error(primary, String::new(), error.span) + } + } + } +} + +impl chumsky::Error for ParserError { + type Span = Span; + type Label = ParsingRuleLabel; + + fn expected_input_found(span: Self::Span, expected: Iter, found: Option) -> Self + where + Iter: IntoIterator>, + { + ParserError { + expected_tokens: expected.into_iter().map(|opt| opt.unwrap_or(Token::EOF)).collect(), + expected_labels: SmallOrdSet::new(), + found: found.unwrap_or(Token::EOF), + reason: None, + span, + } + } + + fn with_label(mut self, label: Self::Label) -> Self { + self.expected_tokens.clear(); + self.expected_labels.clear(); + self.expected_labels.insert(label); + self + } + + // Merge two errors into a new one that should encompass both. + // If one error has a more specific reason with it then keep + // that reason and discard the other if present. + // The spans of both errors must match, otherwise the error + // messages and error spans may not line up. + fn merge(mut self, mut other: Self) -> Self { + self.expected_tokens.append(&mut other.expected_tokens); + self.expected_labels.append(&mut other.expected_labels); + + if self.reason.is_none() { + self.reason = other.reason; + } + + self.span = self.span.merge(other.span); + self + } +} diff --git a/crates/noirc_frontend/src/parser/labels.rs b/compiler/noirc_frontend/src/parser/labels.rs similarity index 98% rename from crates/noirc_frontend/src/parser/labels.rs rename to compiler/noirc_frontend/src/parser/labels.rs index b43c10fb9e7..fd082dfbe56 100644 --- a/crates/noirc_frontend/src/parser/labels.rs +++ b/compiler/noirc_frontend/src/parser/labels.rs @@ -36,7 +36,7 @@ impl fmt::Display for ParsingRuleLabel { ParsingRuleLabel::Statement => write!(f, "statement"), ParsingRuleLabel::Term => write!(f, "term"), ParsingRuleLabel::TypeExpression => write!(f, "type expression"), - ParsingRuleLabel::TokenKind(token_kind) => write!(f, "{:?}", token_kind), + ParsingRuleLabel::TokenKind(token_kind) => write!(f, "{token_kind:?}"), } } } diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs new file mode 100644 index 00000000000..64f8c077648 --- /dev/null +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -0,0 +1,528 @@ +//! The parser is the second pass of the noir compiler. +//! The parser's job is to take the output of the lexer (a stream of tokens) +//! and parse it into a valid Abstract Syntax Tree (Ast). During this, the parser +//! validates the grammar of the program and returns parsing errors for any syntactically +//! invalid constructs (such as `fn fn fn`). +//! +//! This file is mostly helper functions and types for the parser. For the parser itself, +//! see parser.rs. The definition of the abstract syntax tree can be found in the `ast` folder. +mod errors; +mod labels; +#[allow(clippy::module_inception)] +mod parser; + +use std::sync::atomic::{AtomicU32, Ordering}; + +use crate::token::{Keyword, Token}; +use crate::{ast::ImportStatement, Expression, NoirStruct}; +use crate::{ + BlockExpression, ExpressionKind, ForExpression, Ident, IndexExpression, LetStatement, + MethodCallExpression, NoirFunction, NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, + Recoverable, Statement, TraitImpl, TypeImpl, UnresolvedType, UseTree, +}; + +use acvm::FieldElement; +use chumsky::prelude::*; +use chumsky::primitive::Container; +pub use errors::ParserError; +pub use errors::ParserErrorReason; +use noirc_errors::Span; +pub use parser::parse_program; + +/// Counter used to generate unique names when desugaring +/// code in the parser requires the creation of fresh variables. +/// The parser is stateless so this is a static global instead. +static UNIQUE_NAME_COUNTER: AtomicU32 = AtomicU32::new(0); + +#[derive(Debug, Clone)] +pub(crate) enum TopLevelStatement { + Function(NoirFunction), + Module(Ident), + Import(UseTree), + Struct(NoirStruct), + Trait(NoirTrait), + TraitImpl(TraitImpl), + Impl(TypeImpl), + TypeAlias(NoirTypeAlias), + SubModule(SubModule), + Global(LetStatement), + Error, +} + +// Helper trait that gives us simpler type signatures for return types: +// e.g. impl Parser versus impl Parser> +pub trait NoirParser: Parser + Sized + Clone {} +impl NoirParser for P where P: Parser + Clone {} + +// ExprParser just serves as a type alias for NoirParser + Clone +trait ExprParser: NoirParser {} +impl

ExprParser for P where P: NoirParser {} + +fn parenthesized(parser: P) -> impl NoirParser +where + P: NoirParser, + T: Recoverable, +{ + use Token::*; + parser.delimited_by(just(LeftParen), just(RightParen)).recover_with(nested_delimiters( + LeftParen, + RightParen, + [(LeftBracket, RightBracket)], + Recoverable::error, + )) +} + +fn spanned(parser: P) -> impl NoirParser<(T, Span)> +where + P: NoirParser, +{ + parser.map_with_span(|value, span| (value, span)) +} + +// Parse with the first parser, then continue by +// repeating the second parser 0 or more times. +// The passed in function is then used to combine the +// results of both parsers along with their spans at +// each step. +fn foldl_with_span( + first_parser: P1, + to_be_repeated: P2, + f: F, +) -> impl NoirParser +where + P1: NoirParser, + P2: NoirParser, + F: Fn(T1, T2, Span) -> T1 + Clone, +{ + spanned(first_parser) + .then(spanned(to_be_repeated).repeated()) + .foldl(move |(a, a_span), (b, b_span)| { + let span = a_span.merge(b_span); + (f(a, b, span), span) + }) + .map(|(value, _span)| value) +} + +/// Sequence the two parsers. +/// Fails if the first parser fails, otherwise forces +/// the second parser to succeed while logging any errors. +fn then_commit<'a, P1, P2, T1, T2: 'a>( + first_parser: P1, + second_parser: P2, +) -> impl NoirParser<(T1, T2)> + 'a +where + P1: NoirParser + 'a, + P2: NoirParser + 'a, + T2: Clone + Recoverable, +{ + let second_parser = skip_then_retry_until(second_parser) + .map_with_span(|option, span| option.unwrap_or_else(|| Recoverable::error(span))); + + first_parser.then(second_parser) +} + +fn then_commit_ignore<'a, P1, P2, T1: 'a, T2: 'a>( + first_parser: P1, + second_parser: P2, +) -> impl NoirParser + 'a +where + P1: NoirParser + 'a, + P2: NoirParser + 'a, + T2: Clone, +{ + let second_parser = skip_then_retry_until(second_parser); + first_parser.then_ignore(second_parser) +} + +fn ignore_then_commit<'a, P1, P2, T1: 'a, T2: Clone + 'a>( + first_parser: P1, + second_parser: P2, +) -> impl NoirParser + 'a +where + P1: NoirParser + 'a, + P2: NoirParser + 'a, + T2: Recoverable, +{ + let second_parser = skip_then_retry_until(second_parser) + .map_with_span(|option, span| option.unwrap_or_else(|| Recoverable::error(span))); + + first_parser.ignore_then(second_parser) +} + +fn skip_then_retry_until<'a, P, T: 'a>(parser: P) -> impl NoirParser> + 'a +where + P: NoirParser + 'a, + T: Clone, +{ + let terminators = [ + Token::EOF, + Token::Colon, + Token::Semicolon, + Token::RightBrace, + Token::Keyword(Keyword::Let), + Token::Keyword(Keyword::Constrain), + ]; + force(parser.recover_with(chumsky::prelude::skip_then_retry_until(terminators))) +} + +/// General recovery strategy: try to skip to the target token, failing if we encounter the +/// 'too_far' token beforehand. +/// +/// Expects all of `too_far` to be contained within `targets` +fn try_skip_until(targets: C1, too_far: C2) -> impl NoirParser +where + T: Recoverable + Clone, + C1: Container + Clone, + C2: Container + Clone, +{ + chumsky::prelude::none_of(targets) + .repeated() + .ignore_then(one_of(too_far.clone()).rewind()) + .try_map(move |peek, span| { + if too_far.get_iter().any(|t| t == peek) { + // This error will never be shown to the user + Err(ParserError::empty(Token::EOF, span)) + } else { + Ok(Recoverable::error(span)) + } + }) +} + +/// Recovery strategy for statements: If a statement fails to parse skip until the next ';' or fail +/// if we find a '}' first. +fn statement_recovery() -> impl NoirParser { + use Token::*; + try_skip_until([Semicolon, RightBrace], RightBrace) +} + +fn parameter_recovery() -> impl NoirParser { + use Token::*; + try_skip_until([Comma, RightParen], RightParen) +} + +fn parameter_name_recovery() -> impl NoirParser { + use Token::*; + try_skip_until([Colon, RightParen, Comma], [RightParen, Comma]) +} + +fn top_level_statement_recovery() -> impl NoirParser { + none_of([Token::Semicolon, Token::RightBrace, Token::EOF]) + .repeated() + .ignore_then(one_of([Token::Semicolon])) + .map(|_| TopLevelStatement::Error) +} + +/// Force the given parser to succeed, logging any errors it had +fn force<'a, T: 'a>(parser: impl NoirParser + 'a) -> impl NoirParser> + 'a { + parser.map(Some).recover_via(empty().map(|_| None)) +} + +/// A ParsedModule contains an entire Ast for one file. +#[derive(Clone, Debug, Default)] +pub struct ParsedModule { + pub imports: Vec, + pub functions: Vec, + pub types: Vec, + pub traits: Vec, + pub trait_impls: Vec, + pub impls: Vec, + pub type_aliases: Vec, + pub globals: Vec, + + /// Module declarations like `mod foo;` + pub module_decls: Vec, + + /// Full submodules as in `mod foo { ... definitions ... }` + pub submodules: Vec, +} + +/// A submodule defined via `mod name { contents }` in some larger file. +/// These submodules always share the same file as some larger ParsedModule +#[derive(Clone, Debug)] +pub struct SubModule { + pub name: Ident, + pub contents: ParsedModule, + pub is_contract: bool, +} + +impl ParsedModule { + fn push_function(&mut self, func: NoirFunction) { + self.functions.push(func); + } + + fn push_type(&mut self, typ: NoirStruct) { + self.types.push(typ); + } + + fn push_trait(&mut self, noir_trait: NoirTrait) { + self.traits.push(noir_trait); + } + + fn push_trait_impl(&mut self, trait_impl: TraitImpl) { + self.trait_impls.push(trait_impl); + } + + fn push_impl(&mut self, r#impl: TypeImpl) { + self.impls.push(r#impl); + } + + fn push_type_alias(&mut self, type_alias: NoirTypeAlias) { + self.type_aliases.push(type_alias); + } + + fn push_import(&mut self, import_stmt: UseTree) { + self.imports.extend(import_stmt.desugar(None)); + } + + fn push_module_decl(&mut self, mod_name: Ident) { + self.module_decls.push(mod_name); + } + + fn push_submodule(&mut self, submodule: SubModule) { + self.submodules.push(submodule); + } + + fn push_global(&mut self, global: LetStatement) { + self.globals.push(global); + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd)] +pub enum Precedence { + Lowest, + Or, + And, + Xor, + LessGreater, + Shift, + Sum, + Product, + Highest, +} + +impl Precedence { + // Higher the number, the higher(more priority) the precedence + // XXX: Check the precedence is correct for operators + fn token_precedence(tok: &Token) -> Option { + let precedence = match tok { + Token::Equal => Precedence::Lowest, + Token::NotEqual => Precedence::Lowest, + Token::Pipe => Precedence::Or, + Token::Ampersand => Precedence::And, + Token::Caret => Precedence::Xor, + Token::Less => Precedence::LessGreater, + Token::LessEqual => Precedence::LessGreater, + Token::Greater => Precedence::LessGreater, + Token::GreaterEqual => Precedence::LessGreater, + Token::ShiftLeft => Precedence::Shift, + Token::ShiftRight => Precedence::Shift, + Token::Plus => Precedence::Sum, + Token::Minus => Precedence::Sum, + Token::Slash => Precedence::Product, + Token::Star => Precedence::Product, + Token::Percent => Precedence::Product, + _ => return None, + }; + + assert_ne!(precedence, Precedence::Highest, "expression_with_precedence in the parser currently relies on the highest precedence level being uninhabited"); + Some(precedence) + } + + /// Return the next higher precedence. E.g. `Sum.next() == Product` + fn next(self) -> Self { + use Precedence::*; + match self { + Lowest => Or, + Or => Xor, + Xor => And, + And => LessGreater, + LessGreater => Shift, + Shift => Sum, + Sum => Product, + Product => Highest, + Highest => Highest, + } + } + + /// TypeExpressions only contain basic arithmetic operators and + /// notably exclude `>` due to parsing conflicts with generic type brackets. + fn next_type_precedence(self) -> Self { + use Precedence::*; + match self { + Lowest => Sum, + Sum => Product, + Product => Highest, + Highest => Highest, + other => unreachable!("Unexpected precedence level in type expression: {:?}", other), + } + } + + /// The operators with the lowest precedence still useable in type expressions + /// are '+' and '-' with precedence Sum. + fn lowest_type_precedence() -> Self { + Precedence::Sum + } +} + +enum ForRange { + Range(/*start:*/ Expression, /*end:*/ Expression), + Array(Expression), +} + +impl ForRange { + /// Create a 'for' expression taking care of desugaring a 'for e in array' loop + /// into the following if needed: + /// + /// { + /// let fresh1 = array; + /// for fresh2 in 0 .. std::array::len(fresh1) { + /// let elem = fresh1[fresh2]; + /// ... + /// } + /// } + fn into_for(self, identifier: Ident, block: Expression, for_loop_span: Span) -> ExpressionKind { + match self { + ForRange::Range(start_range, end_range) => { + ExpressionKind::For(Box::new(ForExpression { + identifier, + start_range, + end_range, + block, + })) + } + ForRange::Array(array) => { + let array_span = array.span; + let start_range = ExpressionKind::integer(FieldElement::zero()); + let start_range = Expression::new(start_range, array_span); + + let next_unique_id = UNIQUE_NAME_COUNTER.fetch_add(1, Ordering::Relaxed); + let array_name = format!("$i{next_unique_id}"); + let array_span = array.span; + let array_ident = Ident::new(array_name, array_span); + + // let fresh1 = array; + let let_array = Statement::Let(LetStatement { + pattern: Pattern::Identifier(array_ident.clone()), + r#type: UnresolvedType::unspecified(), + expression: array, + }); + + // array.len() + let segments = vec![array_ident]; + let array_ident = + ExpressionKind::Variable(Path { segments, kind: PathKind::Plain }); + + let end_range = ExpressionKind::MethodCall(Box::new(MethodCallExpression { + object: Expression::new(array_ident.clone(), array_span), + method_name: Ident::new("len".to_string(), array_span), + arguments: vec![], + })); + let end_range = Expression::new(end_range, array_span); + + let next_unique_id = UNIQUE_NAME_COUNTER.fetch_add(1, Ordering::Relaxed); + let index_name = format!("$i{next_unique_id}"); + let fresh_identifier = Ident::new(index_name.clone(), array_span); + + // array[i] + let segments = vec![Ident::new(index_name, array_span)]; + let index_ident = + ExpressionKind::Variable(Path { segments, kind: PathKind::Plain }); + + let loop_element = ExpressionKind::Index(Box::new(IndexExpression { + collection: Expression::new(array_ident, array_span), + index: Expression::new(index_ident, array_span), + })); + + // let elem = array[i]; + let let_elem = Statement::Let(LetStatement { + pattern: Pattern::Identifier(identifier), + r#type: UnresolvedType::unspecified(), + expression: Expression::new(loop_element, array_span), + }); + + let block_span = block.span; + let new_block = BlockExpression(vec![let_elem, Statement::Expression(block)]); + let new_block = Expression::new(ExpressionKind::Block(new_block), block_span); + let for_loop = ExpressionKind::For(Box::new(ForExpression { + identifier: fresh_identifier, + start_range, + end_range, + block: new_block, + })); + + ExpressionKind::Block(BlockExpression(vec![ + let_array, + Statement::Expression(Expression::new(for_loop, for_loop_span)), + ])) + } + } + } +} + +impl std::fmt::Display for TopLevelStatement { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TopLevelStatement::Function(fun) => fun.fmt(f), + TopLevelStatement::Module(m) => write!(f, "mod {m}"), + TopLevelStatement::Import(tree) => write!(f, "use {tree}"), + TopLevelStatement::Trait(t) => t.fmt(f), + TopLevelStatement::TraitImpl(i) => i.fmt(f), + TopLevelStatement::Struct(s) => s.fmt(f), + TopLevelStatement::Impl(i) => i.fmt(f), + TopLevelStatement::TypeAlias(t) => t.fmt(f), + TopLevelStatement::SubModule(s) => s.fmt(f), + TopLevelStatement::Global(c) => c.fmt(f), + TopLevelStatement::Error => write!(f, "error"), + } + } +} + +impl std::fmt::Display for ParsedModule { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for decl in &self.module_decls { + writeln!(f, "mod {decl};")?; + } + + for import in &self.imports { + write!(f, "{import}")?; + } + + for global_const in &self.globals { + write!(f, "{global_const}")?; + } + + for type_ in &self.types { + write!(f, "{type_}")?; + } + + for function in &self.functions { + write!(f, "{function}")?; + } + + for impl_ in &self.impls { + write!(f, "{impl_}")?; + } + + for type_alias in &self.type_aliases { + write!(f, "{type_alias}")?; + } + + for submodule in &self.submodules { + write!(f, "{submodule}")?; + } + + Ok(()) + } +} + +impl std::fmt::Display for SubModule { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "mod {} {{", self.name)?; + + for line in self.contents.to_string().lines() { + write!(f, "\n {line}")?; + } + + write!(f, "\n}}") + } +} diff --git a/crates/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs similarity index 88% rename from crates/noirc_frontend/src/parser/parser.rs rename to compiler/noirc_frontend/src/parser/parser.rs index f3b58617e45..34aa0ccb072 100644 --- a/crates/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -30,15 +30,17 @@ use super::{ ForRange, NoirParser, ParsedModule, ParserError, ParserErrorReason, Precedence, SubModule, TopLevelStatement, }; -use crate::ast::{Expression, ExpressionKind, LetStatement, Statement, UnresolvedType}; +use crate::ast::{ + Expression, ExpressionKind, LetStatement, Statement, UnresolvedType, UnresolvedTypeData, +}; use crate::lexer::Lexer; use crate::parser::{force, ignore_then_commit, statement_recovery}; -use crate::token::{Attribute, Keyword, Token, TokenKind}; +use crate::token::{Attribute, Attributes, Keyword, Token, TokenKind}; use crate::{ BinaryOp, BinaryOpKind, BlockExpression, ConstrainStatement, Distinctness, FunctionDefinition, FunctionReturnType, Ident, IfExpression, InfixExpression, LValue, Lambda, Literal, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, Recoverable, - TraitConstraint, TraitImpl, TraitImplItem, TraitItem, TypeImpl, UnaryOp, + TraitBound, TraitConstraint, TraitImpl, TraitImplItem, TraitItem, TypeImpl, UnaryOp, UnresolvedTypeExpression, UseTree, UseTreeKind, Visibility, }; @@ -159,7 +161,7 @@ fn contract(module_parser: impl NoirParser) -> impl NoirParser impl NoirParser { - attribute() + attributes() .or_not() .then(function_modifiers()) .then_ignore(keyword(Keyword::Fn)) @@ -170,12 +172,15 @@ fn function_definition(allow_self: bool) -> impl NoirParser { .then(where_clause()) .then(spanned(block(expression()))) .validate(|(((args, ret), where_clause), (body, body_span)), span, emit| { - let ((((attribute, modifiers), name), generics), parameters) = args; + let ((((attributes, modifiers), name), generics), parameters) = args; + + // Validate collected attributes, filtering them into primary and secondary variants + let attrs = validate_attributes(attributes, span, emit); validate_where_clause(&generics, &where_clause, span, emit); FunctionDefinition { span: body_span, name, - attribute, // XXX: Currently we only have one attribute defined. If more attributes are needed per function, we can make this a vector and make attribute definition more expressive + attributes: attrs, is_unconstrained: modifiers.0, is_open: modifiers.1, is_internal: modifiers.2, @@ -256,7 +261,7 @@ fn lambda_return_type() -> impl NoirParser { just(Token::Arrow) .ignore_then(parse_type()) .or_not() - .map(|ret| ret.unwrap_or(UnresolvedType::Unspecified)) + .map(|ret| ret.unwrap_or_else(UnresolvedType::unspecified)) } fn function_return_type() -> impl NoirParser<((Distinctness, Visibility), FunctionReturnType)> { @@ -266,7 +271,7 @@ fn function_return_type() -> impl NoirParser<((Distinctness, Visibility), Functi .then(spanned(parse_type())) .or_not() .map_with_span(|ret, span| match ret { - Some((head, (ty, span))) => (head, FunctionReturnType::Ty(ty, span)), + Some((head, (ty, _))) => (head, FunctionReturnType::Ty(ty)), None => ( (Distinctness::DuplicationAllowed, Visibility::Private), FunctionReturnType::Default(span), @@ -281,6 +286,10 @@ fn attribute() -> impl NoirParser { }) } +fn attributes() -> impl NoirParser> { + attribute().repeated() +} + fn struct_fields() -> impl NoirParser> { ident() .then_ignore(just(Token::Colon)) @@ -295,7 +304,7 @@ fn lambda_parameters() -> impl NoirParser> { let parameter = pattern() .recover_via(parameter_name_recovery()) - .then(typ.or_not().map(|typ| typ.unwrap_or(UnresolvedType::Unspecified))); + .then(typ.or_not().map(|typ| typ.unwrap_or_else(UnresolvedType::unspecified))); parameter .separated_by(just(Token::Comma)) @@ -345,12 +354,13 @@ fn self_parameter() -> impl NoirParser<(Pattern, UnresolvedType, Visibility)> { .map(|(pattern_keyword, span)| { let ident = Ident::new("self".to_string(), span); let path = Path::from_single("Self".to_owned(), span); - let mut self_type = UnresolvedType::Named(path, vec![]); + let mut self_type = UnresolvedTypeData::Named(path, vec![]).with_span(span); let mut pattern = Pattern::Identifier(ident); match pattern_keyword { Some((Token::Ampersand, _)) => { - self_type = UnresolvedType::MutableReference(Box::new(self_type)); + self_type = + UnresolvedTypeData::MutableReference(Box::new(self_type)).with_span(span); } Some((Token::Keyword(_), span)) => { pattern = Pattern::Mutable(Box::new(pattern), span); @@ -415,6 +425,38 @@ fn trait_function_declaration() -> impl NoirParser { ) } +fn validate_attributes( + attributes: Option>, + span: Span, + emit: &mut dyn FnMut(ParserError), +) -> Attributes { + if attributes.is_none() { + return Attributes::empty(); + } + + let attrs = attributes.unwrap(); + + let mut primary = None; + let mut secondary = Vec::new(); + + for attribute in attrs { + match attribute { + Attribute::Primary(attr) => { + if primary.is_some() { + emit(ParserError::with_reason( + ParserErrorReason::MultiplePrimaryAttributesFound, + span, + )); + } + primary = Some(attr); + } + Attribute::Secondary(attr) => secondary.push(attr), + } + } + + Attributes { primary, secondary } +} + fn validate_where_clause( generics: &Vec, where_clause: &Vec, @@ -524,19 +566,42 @@ fn trait_implementation_body() -> impl NoirParser> { } fn where_clause() -> impl NoirParser> { - let constraints = parse_type() - .then_ignore(just(Token::Colon)) - .then(ident()) - .then(generic_type_args(parse_type())) - .validate(|((typ, trait_name), trait_generics), span, emit| { + struct MultiTraitConstraint { + typ: UnresolvedType, + trait_bounds: Vec, + } + + let constraints = parse_type().then_ignore(just(Token::Colon)).then(trait_bounds()).validate( + |(typ, trait_bounds), span, emit| { emit(ParserError::with_reason(ParserErrorReason::ExperimentalFeature("Traits"), span)); - TraitConstraint { typ, trait_name, trait_generics } - }); + MultiTraitConstraint { typ, trait_bounds } + }, + ); keyword(Keyword::Where) .ignore_then(constraints.separated_by(just(Token::Comma))) .or_not() .map(|option| option.unwrap_or_default()) + .map(|x: Vec| { + let mut result: Vec = Vec::new(); + for constraint in x { + for bound in constraint.trait_bounds { + result + .push(TraitConstraint { typ: constraint.typ.clone(), trait_bound: bound }); + } + } + result + }) +} + +fn trait_bounds() -> impl NoirParser> { + trait_bound().separated_by(just(Token::Plus)).at_least(1).allow_trailing() +} + +fn trait_bound() -> impl NoirParser { + ident() + .then(generic_type_args(parse_type())) + .map(|(trait_name, trait_generics)| TraitBound { trait_name, trait_generics }) } fn block_expr<'a, P>(expr_parser: P) -> impl NoirParser + 'a @@ -582,7 +647,7 @@ fn check_statements_require_semicolon( fn optional_type_annotation<'a>() -> impl NoirParser + 'a { ignore_then_commit(just(Token::Colon), parse_type()) .or_not() - .map(|r#type| r#type.unwrap_or(UnresolvedType::Unspecified)) + .map(|r#type| r#type.unwrap_or_else(UnresolvedType::unspecified)) } fn module_declaration() -> impl NoirParser { @@ -669,6 +734,7 @@ where choice(( constrain(expr_parser.clone()), assertion(expr_parser.clone()), + assertion_eq(expr_parser.clone()), declaration(expr_parser.clone()), assignment(expr_parser.clone()), return_statement(expr_parser.clone()), @@ -684,7 +750,7 @@ where keyword(Keyword::Constrain).labelled(ParsingRuleLabel::Statement), expr_parser, ) - .map(|expr| Statement::Constrain(ConstrainStatement(expr))) + .map(|expr| Statement::Constrain(ConstrainStatement(expr, None))) .validate(|expr, span, emit| { emit(ParserError::with_reason(ParserErrorReason::ConstrainDeprecated, span)); expr @@ -695,9 +761,56 @@ fn assertion<'a, P>(expr_parser: P) -> impl NoirParser + 'a where P: ExprParser + 'a, { - ignore_then_commit(keyword(Keyword::Assert), parenthesized(expr_parser)) + let argument_parser = + expr_parser.separated_by(just(Token::Comma)).allow_trailing().at_least(1).at_most(2); + + ignore_then_commit(keyword(Keyword::Assert), parenthesized(argument_parser)) + .labelled(ParsingRuleLabel::Statement) + .validate(|expressions, span, emit| { + let condition = expressions.get(0).unwrap_or(&Expression::error(span)).clone(); + let mut message_str = None; + + if let Some(message) = expressions.get(1) { + if let ExpressionKind::Literal(Literal::Str(message)) = &message.kind { + message_str = Some(message.clone()); + } else { + emit(ParserError::with_reason(ParserErrorReason::AssertMessageNotString, span)); + } + } + + Statement::Constrain(ConstrainStatement(condition, message_str)) + }) +} + +fn assertion_eq<'a, P>(expr_parser: P) -> impl NoirParser + 'a +where + P: ExprParser + 'a, +{ + let argument_parser = + expr_parser.separated_by(just(Token::Comma)).allow_trailing().at_least(2).at_most(3); + + ignore_then_commit(keyword(Keyword::AssertEq), parenthesized(argument_parser)) .labelled(ParsingRuleLabel::Statement) - .map(|expr| Statement::Constrain(ConstrainStatement(expr))) + .validate(|exprs: Vec, span, emit| { + let predicate = Expression::new( + ExpressionKind::Infix(Box::new(InfixExpression { + lhs: exprs.get(0).unwrap_or(&Expression::error(span)).clone(), + rhs: exprs.get(1).unwrap_or(&Expression::error(span)).clone(), + operator: Spanned::from(span, BinaryOpKind::Equal), + })), + span, + ); + let mut message_str = None; + + if let Some(message) = exprs.get(2) { + if let ExpressionKind::Literal(Literal::Str(message)) = &message.kind { + message_str = Some(message.clone()); + } else { + emit(ParserError::with_reason(ParserErrorReason::AssertMessageNotString, span)); + } + } + Statement::Constrain(ConstrainStatement(predicate, message_str)) + }) } fn declaration<'a, P>(expr_parser: P) -> impl NoirParser + 'a @@ -859,11 +972,15 @@ fn maybe_comp_time() -> impl NoirParser<()> { } fn field_type() -> impl NoirParser { - maybe_comp_time().then_ignore(keyword(Keyword::Field)).map(|_| UnresolvedType::FieldElement) + maybe_comp_time() + .then_ignore(keyword(Keyword::Field)) + .map_with_span(|_, span| UnresolvedTypeData::FieldElement.with_span(span)) } fn bool_type() -> impl NoirParser { - maybe_comp_time().then_ignore(keyword(Keyword::Bool)).map(|_| UnresolvedType::Bool) + maybe_comp_time() + .then_ignore(keyword(Keyword::Bool)) + .map_with_span(|_, span| UnresolvedTypeData::Bool.with_span(span)) } fn string_type() -> impl NoirParser { @@ -871,7 +988,7 @@ fn string_type() -> impl NoirParser { .ignore_then( type_expression().delimited_by(just(Token::Less), just(Token::Greater)).or_not(), ) - .map(UnresolvedType::String) + .map_with_span(|expr, span| UnresolvedTypeData::String(expr).with_span(span)) } fn format_string_type( @@ -884,7 +1001,9 @@ fn format_string_type( .then(type_parser) .delimited_by(just(Token::Less), just(Token::Greater)), ) - .map(|(size, fields)| UnresolvedType::FormatString(size, Box::new(fields))) + .map_with_span(|(size, fields), span| { + UnresolvedTypeData::FormatString(size, Box::new(fields)).with_span(span) + }) } fn int_type() -> impl NoirParser { @@ -896,8 +1015,8 @@ fn int_type() -> impl NoirParser { } })) .validate(|(_, token), span, emit| { - let typ = UnresolvedType::from_int_token(token); - if let UnresolvedType::Integer(crate::Signedness::Signed, _) = &typ { + let typ = UnresolvedTypeData::from_int_token(token).with_span(span); + if let UnresolvedTypeData::Integer(crate::Signedness::Signed, _) = &typ.typ { let reason = ParserErrorReason::ExperimentalFeature("Signed integer types"); emit(ParserError::with_reason(reason, span)); } @@ -908,7 +1027,7 @@ fn int_type() -> impl NoirParser { fn named_type(type_parser: impl NoirParser) -> impl NoirParser { path() .then(generic_type_args(type_parser)) - .map(|(path, args)| UnresolvedType::Named(path, args)) + .map_with_span(|(path, args), span| UnresolvedTypeData::Named(path, args).with_span(span)) } fn generic_type_args( @@ -920,7 +1039,8 @@ fn generic_type_args( // separator afterward. Failing early here ensures we try the `type_expression` // parser afterward. .then_ignore(one_of([Token::Comma, Token::Greater]).rewind()) - .or(type_expression().map(UnresolvedType::Expression)) + .or(type_expression() + .map_with_span(|expr, span| UnresolvedTypeData::Expression(expr).with_span(span))) .separated_by(just(Token::Comma)) .allow_trailing() .at_least(1) @@ -934,7 +1054,9 @@ fn array_type(type_parser: impl NoirParser) -> impl NoirParser impl NoirParser { @@ -956,11 +1078,11 @@ where T: NoirParser, { let fields = type_parser.separated_by(just(Token::Comma)).allow_trailing(); - parenthesized(fields).map(|fields| { + parenthesized(fields).map_with_span(|fields, span| { if fields.is_empty() { - UnresolvedType::Unit + UnresolvedTypeData::Unit.with_span(span) } else { - UnresolvedType::Tuple(fields) + UnresolvedTypeData::Tuple(fields).with_span(span) } }) } @@ -969,30 +1091,22 @@ fn function_type(type_parser: T) -> impl NoirParser where T: NoirParser, { - let types = type_parser.clone().separated_by(just(Token::Comma)).allow_trailing(); - let args = parenthesized(types.clone()); + let args = parenthesized(type_parser.clone().separated_by(just(Token::Comma)).allow_trailing()); let env = just(Token::LeftBracket) - .ignore_then(types) + .ignore_then(type_parser.clone()) .then_ignore(just(Token::RightBracket)) .or_not() - .map(|args| match args { - Some(args) => { - if args.is_empty() { - UnresolvedType::Unit - } else { - UnresolvedType::Tuple(args) - } - } - None => UnresolvedType::Unit, - }); + .map_with_span(|t, span| t.unwrap_or_else(|| UnresolvedTypeData::Unit.with_span(span))); keyword(Keyword::Fn) .ignore_then(env) .then(args) .then_ignore(just(Token::Arrow)) .then(type_parser) - .map(|((env, args), ret)| UnresolvedType::Function(args, Box::new(ret), Box::new(env))) + .map_with_span(|((env, args), ret), span| { + UnresolvedTypeData::Function(args, Box::new(ret), Box::new(env)).with_span(span) + }) } fn mutable_reference_type(type_parser: T) -> impl NoirParser @@ -1002,7 +1116,9 @@ where just(Token::Ampersand) .ignore_then(keyword(Keyword::Mut)) .ignore_then(type_parser) - .map(|element| UnresolvedType::MutableReference(Box::new(element))) + .map_with_span(|element, span| { + UnresolvedTypeData::MutableReference(Box::new(element)).with_span(span) + }) } fn expression() -> impl ExprParser { @@ -1787,6 +1903,38 @@ mod test { "assert(x + x ^ x == y | m)", ], ); + + match parse_with(assertion(expression()), "assert(x == y, \"assertion message\")").unwrap() + { + Statement::Constrain(ConstrainStatement(_, message)) => { + assert_eq!(message, Some("assertion message".to_owned())); + } + _ => unreachable!(), + } + } + + /// This is the standard way to assert that two expressions are equivalent + #[test] + fn parse_assert_eq() { + parse_all( + assertion_eq(expression()), + vec![ + "assert_eq(x, y)", + "assert_eq(((x + y) == k) + z, y)", + "assert_eq(x + !y, y)", + "assert_eq(x ^ y, y)", + "assert_eq(x ^ y, y + m)", + "assert_eq(x + x ^ x, y | m)", + ], + ); + match parse_with(assertion_eq(expression()), "assert_eq(x, y, \"assertion message\")") + .unwrap() + { + Statement::Constrain(ConstrainStatement(_, message)) => { + assert_eq!(message, Some("assertion message".to_owned())); + } + _ => unreachable!(), + } } #[test] @@ -1838,6 +1986,19 @@ mod test { "fn f(f: pub Field, y : Field, z : comptime Field) -> u8 { x + a }", "fn f(f: pub Field, y : T, z : comptime Field) -> u8 { x + a }", "fn func_name(f: Field, y : T) where T: SomeTrait {}", + "fn func_name(f: Field, y : T) where T: SomeTrait + SomeTrait2 {}", + "fn func_name(f: Field, y : T) where T: SomeTrait, T: SomeTrait2 {}", + "fn func_name(f: Field, y : T) where T: SomeTrait + SomeTrait2 {}", + "fn func_name(f: Field, y : T) where T: SomeTrait + SomeTrait2 {}", + "fn func_name(f: Field, y : T) where T: SomeTrait + SomeTrait2 {}", + "fn func_name(f: Field, y : T) where T: SomeTrait + SomeTrait2 {}", + "fn func_name(f: Field, y : T) where T: SomeTrait + SomeTrait2 + TraitY {}", + "fn func_name(f: Field, y : T, z : U) where SomeStruct: SomeTrait {}", + // 'where u32: SomeTrait' is allowed in Rust. + // It will result in compiler error in case SomeTrait isn't implemented for u32. + "fn func_name(f: Field, y : T) where u32: SomeTrait {}", + // A trailing plus is allowed by Rust, so we support it as well. + "fn func_name(f: Field, y : T) where T: SomeTrait + {}", // The following should produce compile error on later stage. From the parser's perspective it's fine "fn func_name(f: Field, y : Field, z : Field) where T: SomeTrait {}", ], @@ -1854,6 +2015,9 @@ mod test { "fn func_name(f: Field, y : pub Field, z : pub [u8;5],) where SomeTrait {}", "fn func_name(f: Field, y : pub Field, z : pub [u8;5],) SomeTrait {}", "fn func_name(f: Field, y : pub Field, z : pub [u8;5],) where T: SomeTrait {}", + // A leading plus is not allowed. + "fn func_name(f: Field, y : T) where T: + SomeTrait {}", + "fn func_name(f: Field, y : T) where T: TraitX + {}", ], ); } @@ -2128,6 +2292,10 @@ mod test { ("assert", 1, "constrain Error"), ("constrain x ==", 2, "constrain (plain::x == Error)"), ("assert(x ==)", 1, "constrain (plain::x == Error)"), + ("assert(x == x, x)", 1, "constrain (plain::x == plain::x)"), + ("assert_eq(x,)", 1, "constrain (Error == Error)"), + ("assert_eq(x, x, x, x)", 1, "constrain (Error == Error)"), + ("assert_eq(x, x, x)", 1, "constrain (plain::x == plain::x)"), ]; let show_errors = |v| vecmap(v, ToString::to_string).join("\n"); diff --git a/compiler/noirc_printable_type/Cargo.toml b/compiler/noirc_printable_type/Cargo.toml new file mode 100644 index 00000000000..5f2eea92257 --- /dev/null +++ b/compiler/noirc_printable_type/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "noirc_printable_type" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +acvm.workspace = true +iter-extended.workspace = true +regex = "1.9.1" +serde.workspace = true +serde_json.workspace = true +thiserror.workspace = true + +[dev-dependencies] diff --git a/crates/noirc_printable_type/src/lib.rs b/compiler/noirc_printable_type/src/lib.rs similarity index 100% rename from crates/noirc_printable_type/src/lib.rs rename to compiler/noirc_printable_type/src/lib.rs diff --git a/crates/readme.md b/compiler/readme.md similarity index 100% rename from crates/readme.md rename to compiler/readme.md diff --git a/compiler/source-resolver/package-lock.json b/compiler/source-resolver/package-lock.json new file mode 100644 index 00000000000..aa58229f23d --- /dev/null +++ b/compiler/source-resolver/package-lock.json @@ -0,0 +1,3281 @@ +{ + "name": "@noir-lang/noir-source-resolver", + "version": "1.1.4", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@noir-lang/noir-source-resolver", + "version": "1.1.4", + "license": "MIT", + "devDependencies": { + "@types/node": "^20.5.7", + "ava": "^5.2.0", + "typescript": "4.9.4" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/node": { + "version": "20.5.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", + "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrgv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", + "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ava": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-5.2.0.tgz", + "integrity": "sha512-W8yxFXJr/P68JP55eMpQIa6AiXhCX3VeuajM8nolyWNExcMDD6rnIWKTjw0B/+GkFHBIaN6Jd0LtcMThcoqVfg==", + "dev": true, + "dependencies": { + "acorn": "^8.8.1", + "acorn-walk": "^8.2.0", + "ansi-styles": "^6.2.1", + "arrgv": "^1.0.2", + "arrify": "^3.0.0", + "callsites": "^4.0.0", + "cbor": "^8.1.0", + "chalk": "^5.2.0", + "chokidar": "^3.5.3", + "chunkd": "^2.0.1", + "ci-info": "^3.7.1", + "ci-parallel-vars": "^1.0.1", + "clean-yaml-object": "^0.1.0", + "cli-truncate": "^3.1.0", + "code-excerpt": "^4.0.0", + "common-path-prefix": "^3.0.0", + "concordance": "^5.0.4", + "currently-unhandled": "^0.4.1", + "debug": "^4.3.4", + "del": "^7.0.0", + "emittery": "^1.0.1", + "figures": "^5.0.0", + "globby": "^13.1.3", + "ignore-by-default": "^2.1.0", + "indent-string": "^5.0.0", + "is-error": "^2.2.2", + "is-plain-object": "^5.0.0", + "is-promise": "^4.0.0", + "matcher": "^5.0.0", + "mem": "^9.0.2", + "ms": "^2.1.3", + "p-event": "^5.0.1", + "p-map": "^5.5.0", + "picomatch": "^2.3.1", + "pkg-conf": "^4.0.0", + "plur": "^5.1.0", + "pretty-ms": "^8.0.0", + "resolve-cwd": "^3.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6", + "strip-ansi": "^7.0.1", + "supertap": "^3.0.1", + "temp-dir": "^3.0.0", + "write-file-atomic": "^5.0.0", + "yargs": "^17.6.2" + }, + "bin": { + "ava": "entrypoints/cli.mjs" + }, + "engines": { + "node": ">=14.19 <15 || >=16.15 <17 || >=18" + }, + "peerDependencies": { + "@ava/typescript": "*" + }, + "peerDependenciesMeta": { + "@ava/typescript": { + "optional": true + } + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/blueimp-md5": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", + "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.0.0.tgz", + "integrity": "sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dev": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chunkd": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", + "dev": true + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/ci-parallel-vars": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", + "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-yaml-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "dev": true, + "dependencies": { + "convert-to-spaces": "^2.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concordance": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz", + "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==", + "dev": true, + "dependencies": { + "date-time": "^3.1.0", + "esutils": "^2.0.3", + "fast-diff": "^1.2.0", + "js-string-escape": "^1.0.1", + "lodash": "^4.17.15", + "md5-hex": "^3.0.1", + "semver": "^7.3.2", + "well-known-symbols": "^2.0.0" + }, + "engines": { + "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14" + } + }, + "node_modules/convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/date-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", + "dev": true, + "dependencies": { + "time-zone": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/del": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-7.0.0.tgz", + "integrity": "sha512-tQbV/4u5WVB8HMJr08pgw0b6nG4RGt/tj+7Numvq+zqcvUFeMaIWWOUFltiU+6go8BSO2/ogsB4EasDaj0y68Q==", + "dev": true, + "dependencies": { + "globby": "^13.1.2", + "graceful-fs": "^4.2.10", + "is-glob": "^4.0.3", + "is-path-cwd": "^3.0.0", + "is-path-inside": "^4.0.0", + "p-map": "^5.5.0", + "rimraf": "^3.0.2", + "slash": "^4.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/del/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emittery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-1.0.1.tgz", + "integrity": "sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", + "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz", + "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==", + "dev": true, + "engines": { + "node": ">=10 <11 || >=12 <13 || >=14" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/irregular-plurals": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", + "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-error": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", + "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz", + "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/load-json-file": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", + "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/matcher": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", + "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/md5-hex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", + "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", + "dev": true, + "dependencies": { + "blueimp-md5": "^2.10.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mem": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz", + "integrity": "sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==", + "dev": true, + "dependencies": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sindresorhus/mem?sponsor=1" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "dev": true, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "dev": true, + "dependencies": { + "p-timeout": "^5.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "dependencies": { + "aggregate-error": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", + "integrity": "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-conf": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-4.0.0.tgz", + "integrity": "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==", + "dev": true, + "dependencies": { + "find-up": "^6.0.0", + "load-json-file": "^7.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/plur": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", + "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==", + "dev": true, + "dependencies": { + "irregular-plurals": "^3.3.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-ms": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz", + "integrity": "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==", + "dev": true, + "dependencies": { + "parse-ms": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/supertap": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz", + "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==", + "dev": true, + "dependencies": { + "indent-string": "^5.0.0", + "js-yaml": "^3.14.1", + "serialize-error": "^7.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "dev": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@types/node": { + "version": "20.5.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", + "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", + "dev": true + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "requires": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + } + }, + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true + }, + "arrgv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", + "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", + "dev": true + }, + "arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true + }, + "ava": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-5.2.0.tgz", + "integrity": "sha512-W8yxFXJr/P68JP55eMpQIa6AiXhCX3VeuajM8nolyWNExcMDD6rnIWKTjw0B/+GkFHBIaN6Jd0LtcMThcoqVfg==", + "dev": true, + "requires": { + "acorn": "^8.8.1", + "acorn-walk": "^8.2.0", + "ansi-styles": "^6.2.1", + "arrgv": "^1.0.2", + "arrify": "^3.0.0", + "callsites": "^4.0.0", + "cbor": "^8.1.0", + "chalk": "^5.2.0", + "chokidar": "^3.5.3", + "chunkd": "^2.0.1", + "ci-info": "^3.7.1", + "ci-parallel-vars": "^1.0.1", + "clean-yaml-object": "^0.1.0", + "cli-truncate": "^3.1.0", + "code-excerpt": "^4.0.0", + "common-path-prefix": "^3.0.0", + "concordance": "^5.0.4", + "currently-unhandled": "^0.4.1", + "debug": "^4.3.4", + "del": "^7.0.0", + "emittery": "^1.0.1", + "figures": "^5.0.0", + "globby": "^13.1.3", + "ignore-by-default": "^2.1.0", + "indent-string": "^5.0.0", + "is-error": "^2.2.2", + "is-plain-object": "^5.0.0", + "is-promise": "^4.0.0", + "matcher": "^5.0.0", + "mem": "^9.0.2", + "ms": "^2.1.3", + "p-event": "^5.0.1", + "p-map": "^5.5.0", + "picomatch": "^2.3.1", + "pkg-conf": "^4.0.0", + "plur": "^5.1.0", + "pretty-ms": "^8.0.0", + "resolve-cwd": "^3.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6", + "strip-ansi": "^7.0.1", + "supertap": "^3.0.1", + "temp-dir": "^3.0.0", + "write-file-atomic": "^5.0.0", + "yargs": "^17.6.2" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "blueimp-md5": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", + "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "callsites": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.0.0.tgz", + "integrity": "sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ==", + "dev": true + }, + "cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dev": true, + "requires": { + "nofilter": "^3.1.0" + } + }, + "chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chunkd": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", + "dev": true + }, + "ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true + }, + "ci-parallel-vars": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", + "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", + "dev": true + }, + "clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "requires": { + "escape-string-regexp": "5.0.0" + } + }, + "clean-yaml-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==", + "dev": true + }, + "cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "requires": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "dev": true, + "requires": { + "convert-to-spaces": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "concordance": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz", + "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==", + "dev": true, + "requires": { + "date-time": "^3.1.0", + "esutils": "^2.0.3", + "fast-diff": "^1.2.0", + "js-string-escape": "^1.0.1", + "lodash": "^4.17.15", + "md5-hex": "^3.0.1", + "semver": "^7.3.2", + "well-known-symbols": "^2.0.0" + } + }, + "convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "date-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", + "dev": true, + "requires": { + "time-zone": "^1.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "del": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-7.0.0.tgz", + "integrity": "sha512-tQbV/4u5WVB8HMJr08pgw0b6nG4RGt/tj+7Numvq+zqcvUFeMaIWWOUFltiU+6go8BSO2/ogsB4EasDaj0y68Q==", + "dev": true, + "requires": { + "globby": "^13.1.2", + "graceful-fs": "^4.2.10", + "is-glob": "^4.0.3", + "is-path-cwd": "^3.0.0", + "is-path-inside": "^4.0.0", + "p-map": "^5.5.0", + "rimraf": "^3.0.2", + "slash": "^4.0.0" + }, + "dependencies": { + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "emittery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-1.0.1.tgz", + "integrity": "sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", + "dev": true, + "requires": { + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", + "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "dependencies": { + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "ignore-by-default": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz", + "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "irregular-plurals": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", + "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-error": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", + "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-path-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz", + "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==", + "dev": true + }, + "is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + }, + "is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true + }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "load-json-file": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", + "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", + "dev": true + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "requires": { + "p-locate": "^6.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "matcher": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", + "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==", + "dev": true, + "requires": { + "escape-string-regexp": "^5.0.0" + } + }, + "md5-hex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", + "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", + "dev": true, + "requires": { + "blueimp-md5": "^2.10.0" + } + }, + "mem": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz", + "integrity": "sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^4.0.0" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", + "dev": true + }, + "p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "dev": true, + "requires": { + "p-timeout": "^5.0.2" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "requires": { + "p-limit": "^4.0.0" + } + }, + "p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "requires": { + "aggregate-error": "^4.0.0" + } + }, + "p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true + }, + "parse-ms": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", + "integrity": "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==", + "dev": true + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pkg-conf": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-4.0.0.tgz", + "integrity": "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==", + "dev": true, + "requires": { + "find-up": "^6.0.0", + "load-json-file": "^7.0.0" + } + }, + "plur": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", + "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==", + "dev": true, + "requires": { + "irregular-plurals": "^3.3.0" + } + }, + "pretty-ms": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz", + "integrity": "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==", + "dev": true, + "requires": { + "parse-ms": "^3.0.0" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "requires": { + "type-fest": "^0.13.1" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "supertap": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz", + "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==", + "dev": true, + "requires": { + "indent-string": "^5.0.0", + "js-yaml": "^3.14.1", + "serialize-error": "^7.0.1", + "strip-ansi": "^7.0.1" + } + }, + "temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "dev": true + }, + "time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + }, + "typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true + }, + "well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } + } +} diff --git a/compiler/source-resolver/package.json b/compiler/source-resolver/package.json new file mode 100644 index 00000000000..ca8f48ac3d7 --- /dev/null +++ b/compiler/source-resolver/package.json @@ -0,0 +1,35 @@ +{ + "name": "@noir-lang/noir-source-resolver", + "version": "1.1.4", + "license": "MIT", + "main": "./lib-node/index_node.js", + "types": "./types/index_node.d.ts", + "module": "./lib/index.js", + "browser": "./lib/index.js", + "exports": { + ".": { + "require": "./lib-node/index_node.js", + "import": "./lib/index.js" + } + }, + "scripts": { + "clean-modules": "rm -rf lib", + "build:node": "tsc -p tsconfig.cjs.json", + "build:web": "tsc -p tsconfig.esm.json", + "build": "npm run clean-modules && npm run build:node && npm run build:web && npm run generate-types", + "test": "node_modules/.bin/ava", + "generate-types": "tsc src/*.ts --declaration --emitDeclarationOnly --outDir types" + }, + "devDependencies": { + "@types/node": "^20.5.7", + "ava": "^5.2.0", + "typescript": "4.9.4" + }, + "files": [ + "lib", + "lib-node", + "src", + "types", + "package.json" + ] +} diff --git a/compiler/source-resolver/src/index.ts b/compiler/source-resolver/src/index.ts new file mode 100644 index 00000000000..a83b6b03728 --- /dev/null +++ b/compiler/source-resolver/src/index.ts @@ -0,0 +1,31 @@ +let resolveFunction: Function | null = null; + +export let read_file = function (source_id: any): string { + + if (resolveFunction) { + + const result = resolveFunction(source_id); + + if (typeof result === "string") { + return result; + } else { + throw new Error("Noir source resolver funtion MUST return String synchronously. Are you trying to return anything else, eg. `Promise`?"); + } + } else { + throw new Error('Not yet initialised. Use initialiseResolver(() => string)'); + } + +}; + +function initialise(noir_resolver: (source_id: String) => string): (source_id: String) => string { + + if (typeof noir_resolver === "function") { + return noir_resolver; + } else { + throw new Error("Provided Noir Resolver is not a function, hint: use function(module_id) => NoirSource as second parameter"); + } +} + +export function initialiseResolver(resolver: (source_id: String) => string): void { + resolveFunction = initialise(resolver); +} \ No newline at end of file diff --git a/compiler/source-resolver/src/index_node.ts b/compiler/source-resolver/src/index_node.ts new file mode 100644 index 00000000000..faa0d3efcdb --- /dev/null +++ b/compiler/source-resolver/src/index_node.ts @@ -0,0 +1,20 @@ +/// + +import { initialiseResolver, read_file } from './index.js'; + +initialiseResolver((source_id: String) => { + let fileContent = ""; + try { + const fs = require("fs"); + fileContent = + fs.readFileSync(source_id, { encoding: "utf8" }) as string + ; + } catch (e) { + console.log(e); + } + return fileContent; +}); + +export { initialiseResolver, read_file }; + + diff --git a/compiler/source-resolver/test/cjs_initialization.test.cjs b/compiler/source-resolver/test/cjs_initialization.test.cjs new file mode 100644 index 00000000000..d83f5b1b7cb --- /dev/null +++ b/compiler/source-resolver/test/cjs_initialization.test.cjs @@ -0,0 +1,51 @@ +const test = require('ava'); + +const { initialiseResolver, read_file } = require("../lib-node/index_node.js"); + +test('It reads file from file system within read_file using default implementation.', t => { + + const readResult = read_file("./package.json"); + + t.assert(readResult, "return from `read_file` should by truthy"); + +}); + +test('It calls function from initializer within read_file function.', t => { + + const RESULT_RESPONSE = "TEST"; + + initialiseResolver((source) => { + return source; + }); + + const readResult = read_file(RESULT_RESPONSE); + + t.is(readResult, RESULT_RESPONSE); + +}); + +test('It communicates error when resolver returns non-String to read_file function.', t => { + + const RESULT_RESPONSE = "TEST"; + + initialiseResolver((source) => { + return Promise.resolve(source); + }); + + const error = t.throws(() => { + read_file(RESULT_RESPONSE); + }, { instanceOf: Error }); + + t.is(error.message, 'Noir source resolver funtion MUST return String synchronously. Are you trying to return anything else, eg. `Promise`?'); + +}); + +test('It communicates error when resolver is initialized to anything but a function.', t => { + + const error = t.throws(() => { + initialiseResolver(null); + }, { instanceOf: Error }); + + t.is(error.message, 'Provided Noir Resolver is not a function, hint: use function(module_id) => NoirSource as second parameter'); + +}); diff --git a/compiler/source-resolver/test/esm_initialization.test.mjs b/compiler/source-resolver/test/esm_initialization.test.mjs new file mode 100644 index 00000000000..30f77dcf7a0 --- /dev/null +++ b/compiler/source-resolver/test/esm_initialization.test.mjs @@ -0,0 +1,58 @@ +/** + * Below tests are commented because they require + * "type": "module", in package.json + * Seems that both CJS and MJS modes are not going to work. +*/ +import test from 'ava'; + +import { initialiseResolver, read_file } from "../lib-node/index.js"; + +test('It communicates error when read_file was called before initialiseResolver.', t => { + + const error = t.throws(() => { + const readResult = read_file("./package.json"); + }, { instanceOf: Error }); + + t.is(error.message, 'Not yet initialised. Use initialiseResolver(() => string)'); + +}); + +test('It calls function from initializer within read_file function.', t => { + + const RESULT_RESPONSE = "TEST"; + + initialiseResolver((source) => { + return source; + }); + + const readResult = read_file(RESULT_RESPONSE); + + t.is(readResult, RESULT_RESPONSE); + +}); + +test('It communicates error when resolver returns non-String to read_file function.', t => { + + const RESULT_RESPONSE = "TEST"; + + initialiseResolver((source) => { + return Promise.resolve(source); + }); + + const error = t.throws(() => { + read_file(RESULT_RESPONSE); + }, { instanceOf: Error }); + + t.is(error.message, 'Noir source resolver funtion MUST return String synchronously. Are you trying to return anything else, eg. `Promise`?'); + +}); + +test('It communicates error when resolver is initialized to anything but a function.', t => { + + const error = t.throws(() => { + initialiseResolver(null); + }, { instanceOf: Error }); + + t.is(error.message, 'Provided Noir Resolver is not a function, hint: use function(module_id) => NoirSource as second parameter'); + +}); diff --git a/compiler/source-resolver/tsconfig.cjs.json b/compiler/source-resolver/tsconfig.cjs.json new file mode 100644 index 00000000000..51863a34cec --- /dev/null +++ b/compiler/source-resolver/tsconfig.cjs.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2018", + "moduleResolution": "node", + "outDir": "lib-node", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "noImplicitAny": true, + "removeComments": false, + "preserveConstEnums": true, + "sourceMap": true, + "importHelpers": true + }, + "include": ["src"] +} diff --git a/compiler/source-resolver/tsconfig.esm.json b/compiler/source-resolver/tsconfig.esm.json new file mode 100644 index 00000000000..dcf4441c4ad --- /dev/null +++ b/compiler/source-resolver/tsconfig.esm.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2018", + "moduleResolution": "node", + "outDir": "lib", + "module": "ES6", + "strict": true, + "esModuleInterop": true, + "noImplicitAny": true, + "removeComments": false, + "preserveConstEnums": true, + "sourceMap": true, + "importHelpers": true + }, + "include": ["src/index.ts"] +} diff --git a/compiler/source-resolver/types/index.d.ts b/compiler/source-resolver/types/index.d.ts new file mode 100644 index 00000000000..14f4c17445b --- /dev/null +++ b/compiler/source-resolver/types/index.d.ts @@ -0,0 +1,2 @@ +export declare let read_file: (source_id: any) => string; +export declare function initialiseResolver(resolver: (source_id: String) => string): void; diff --git a/compiler/source-resolver/types/index_node.d.ts b/compiler/source-resolver/types/index_node.d.ts new file mode 100644 index 00000000000..75e87c00efb --- /dev/null +++ b/compiler/source-resolver/types/index_node.d.ts @@ -0,0 +1,2 @@ +import { initialiseResolver, read_file } from './index.js'; +export { initialiseResolver, read_file }; diff --git a/compiler/utils/arena/Cargo.toml b/compiler/utils/arena/Cargo.toml new file mode 100644 index 00000000000..e82201a2cf4 --- /dev/null +++ b/compiler/utils/arena/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "arena" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +generational-arena = "0.2.8" diff --git a/crates/arena/src/lib.rs b/compiler/utils/arena/src/lib.rs similarity index 100% rename from crates/arena/src/lib.rs rename to compiler/utils/arena/src/lib.rs diff --git a/compiler/utils/iter-extended/Cargo.toml b/compiler/utils/iter-extended/Cargo.toml new file mode 100644 index 00000000000..c91e5ea6d77 --- /dev/null +++ b/compiler/utils/iter-extended/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "iter-extended" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/crates/iter-extended/src/lib.rs b/compiler/utils/iter-extended/src/lib.rs similarity index 100% rename from crates/iter-extended/src/lib.rs rename to compiler/utils/iter-extended/src/lib.rs diff --git a/crates/wasm/.gitignore b/compiler/wasm/.gitignore similarity index 100% rename from crates/wasm/.gitignore rename to compiler/wasm/.gitignore diff --git a/crates/wasm/.mocharc.json b/compiler/wasm/.mocharc.json similarity index 100% rename from crates/wasm/.mocharc.json rename to compiler/wasm/.mocharc.json diff --git a/crates/wasm/.yarn/releases/yarn-3.5.1.cjs b/compiler/wasm/.yarn/releases/yarn-3.5.1.cjs similarity index 100% rename from crates/wasm/.yarn/releases/yarn-3.5.1.cjs rename to compiler/wasm/.yarn/releases/yarn-3.5.1.cjs diff --git a/crates/wasm/CHANGELOG.md b/compiler/wasm/CHANGELOG.md similarity index 100% rename from crates/wasm/CHANGELOG.md rename to compiler/wasm/CHANGELOG.md diff --git a/compiler/wasm/Cargo.toml b/compiler/wasm/Cargo.toml new file mode 100644 index 00000000000..4514a6eaf0d --- /dev/null +++ b/compiler/wasm/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "noir_wasm" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + +[lib] +crate-type = ["cdylib"] + +[dependencies] +acvm.workspace = true +fm.workspace = true +nargo.workspace = true +noirc_driver.workspace = true +noirc_frontend.workspace = true +wasm-bindgen.workspace = true +serde.workspace = true + +console_error_panic_hook = "0.1.7" +gloo-utils = { version = "0.1", features = ["serde"] } + +log = "0.4.17" +wasm-logger = "0.2.0" + +# This is an unused dependency, we are adding it +# so that we can enable the js feature in getrandom. +getrandom = { version = "*", features = ["js"] } + +[build-dependencies] +build-data = "0.1.3" diff --git a/crates/wasm/README.md b/compiler/wasm/README.md similarity index 100% rename from crates/wasm/README.md rename to compiler/wasm/README.md diff --git a/crates/wasm/build.rs b/compiler/wasm/build.rs similarity index 100% rename from crates/wasm/build.rs rename to compiler/wasm/build.rs diff --git a/crates/wasm/build.sh b/compiler/wasm/build.sh similarity index 100% rename from crates/wasm/build.sh rename to compiler/wasm/build.sh diff --git a/crates/wasm/buildPhaseCargoCommand.sh b/compiler/wasm/buildPhaseCargoCommand.sh similarity index 100% rename from crates/wasm/buildPhaseCargoCommand.sh rename to compiler/wasm/buildPhaseCargoCommand.sh diff --git a/crates/wasm/installPhase.sh b/compiler/wasm/installPhase.sh similarity index 100% rename from crates/wasm/installPhase.sh rename to compiler/wasm/installPhase.sh diff --git a/crates/wasm/noir-script/Nargo.toml b/compiler/wasm/noir-script/Nargo.toml similarity index 100% rename from crates/wasm/noir-script/Nargo.toml rename to compiler/wasm/noir-script/Nargo.toml diff --git a/crates/wasm/noir-script/src/main.nr b/compiler/wasm/noir-script/src/main.nr similarity index 100% rename from crates/wasm/noir-script/src/main.nr rename to compiler/wasm/noir-script/src/main.nr diff --git a/compiler/wasm/package.json b/compiler/wasm/package.json new file mode 100644 index 00000000000..05fffcabac8 --- /dev/null +++ b/compiler/wasm/package.json @@ -0,0 +1,41 @@ +{ + "name": "@noir-lang/noir_wasm", + "collaborators": [ + "The Noir Team " + ], + "version": "0.11.1", + "license": "(MIT OR Apache-2.0)", + "main": "./nodejs/noir_wasm.js", + "types": "./web/noir_wasm.d.ts", + "module": "./web/noir_wasm.js", + "files": [ + "nodejs", + "web", + "package.json" + ], + "sideEffects": false, + "packageManager": "yarn@3.5.1", + "repository": { + "type": "git", + "url": "https://github.com/noir-lang/noir_wasm.git" + }, + "scripts": { + "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", + "test:node": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", + "test:browser": "web-test-runner" + }, + "peerDependencies": { + "@noir-lang/noir-source-resolver": "^1.1.3" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.3.4-fix.0", + "@noir-lang/noir-source-resolver": "^1.1.4", + "@web/dev-server-esbuild": "^0.3.6", + "@web/test-runner": "^0.15.3", + "@web/test-runner-playwright": "^0.10.0", + "chai": "^4.3.7", + "mocha": "^10.2.0", + "ts-node": "^10.9.1", + "typescript": "^5.0.4" + } +} diff --git a/crates/wasm/src/circuit.rs b/compiler/wasm/src/circuit.rs similarity index 100% rename from crates/wasm/src/circuit.rs rename to compiler/wasm/src/circuit.rs diff --git a/compiler/wasm/src/compile.rs b/compiler/wasm/src/compile.rs new file mode 100644 index 00000000000..c98e586ab45 --- /dev/null +++ b/compiler/wasm/src/compile.rs @@ -0,0 +1,138 @@ +use fm::FileManager; +use gloo_utils::format::JsValueSerdeExt; +use log::debug; +use noirc_driver::{ + add_dep, compile_contract, compile_main, prepare_crate, prepare_dependency, CompileOptions, +}; +use noirc_frontend::{graph::CrateGraph, hir::Context}; +use serde::{Deserialize, Serialize}; +use std::path::Path; +use wasm_bindgen::prelude::*; + +#[derive(Debug, Serialize, Deserialize)] +pub struct WASMCompileOptions { + #[serde(default = "default_entry_point")] + entry_point: String, + + #[serde(default = "default_circuit_name")] + circuit_name: String, + + // Compile each contract function used within the program + #[serde(default = "bool::default")] + contracts: bool, + + #[serde(default)] + compile_options: CompileOptions, + + #[serde(default)] + optional_dependencies_set: Vec, + + #[serde(default = "default_log_level")] + log_level: String, +} + +fn default_log_level() -> String { + String::from("info") +} + +fn default_circuit_name() -> String { + String::from("contract") +} + +fn default_entry_point() -> String { + String::from("main.nr") +} + +impl Default for WASMCompileOptions { + fn default() -> Self { + Self { + entry_point: default_entry_point(), + circuit_name: default_circuit_name(), + log_level: default_log_level(), + contracts: false, + compile_options: CompileOptions::default(), + optional_dependencies_set: vec![], + } + } +} + +fn add_noir_lib(context: &mut Context, library_name: &str) { + let path_to_lib = Path::new(&library_name).join("lib.nr"); + let library_crate_id = prepare_dependency(context, &path_to_lib); + + add_dep(context, *context.root_crate_id(), library_crate_id, library_name.parse().unwrap()); + + // TODO: Remove this code that attaches every crate to every other crate as a dependency + let root_crate_id = context.root_crate_id(); + let stdlib_crate_id = context.stdlib_crate_id(); + let other_crate_ids: Vec<_> = context + .crate_graph + .iter_keys() + .filter(|crate_id| { + // We don't want to attach this crate to itself or stdlib, nor re-attach it to the root crate + crate_id != &library_crate_id + && crate_id != root_crate_id + && crate_id != stdlib_crate_id + }) + .collect(); + + for crate_id in other_crate_ids { + context + .crate_graph + .add_dep(crate_id, library_name.parse().unwrap(), library_crate_id) + .unwrap_or_else(|_| panic!("ICE: Cyclic error triggered by {} library", library_name)); + } +} + +#[wasm_bindgen] +pub fn compile(args: JsValue) -> JsValue { + console_error_panic_hook::set_once(); + + let options: WASMCompileOptions = if args.is_undefined() || args.is_null() { + debug!("Initializing compiler with default values."); + WASMCompileOptions::default() + } else { + JsValueSerdeExt::into_serde(&args).expect("Could not deserialize compile arguments") + }; + + debug!("Compiler configuration {:?}", &options); + + let root = Path::new("/"); + let fm = FileManager::new(root); + let graph = CrateGraph::default(); + let mut context = Context::new(fm, graph); + + let path = Path::new(&options.entry_point); + let crate_id = prepare_crate(&mut context, path); + + for dependency in options.optional_dependencies_set { + add_noir_lib(&mut context, dependency.as_str()); + } + + // For now we default to plonk width = 3, though we can add it as a parameter + let np_language = acvm::Language::PLONKCSat { width: 3 }; + #[allow(deprecated)] + let is_opcode_supported = acvm::pwg::default_is_opcode_supported(np_language); + + if options.contracts { + let compiled_contract = compile_contract(&mut context, crate_id, &options.compile_options) + .expect("Contract compilation failed") + .0; + + let optimized_contract = + nargo::ops::optimize_contract(compiled_contract, np_language, &is_opcode_supported) + .expect("Contract optimization failed"); + + ::from_serde(&optimized_contract).unwrap() + } else { + let compiled_program = compile_main(&mut context, crate_id, &options.compile_options) + .expect("Compilation failed") + .0; + + let optimized_program = + nargo::ops::optimize_program(compiled_program, np_language, &is_opcode_supported) + .expect("Program optimization failed"); + + ::from_serde(&optimized_program).unwrap() + } +} diff --git a/crates/wasm/src/lib.rs b/compiler/wasm/src/lib.rs similarity index 100% rename from crates/wasm/src/lib.rs rename to compiler/wasm/src/lib.rs diff --git a/compiler/wasm/test/browser/index.test.ts b/compiler/wasm/test/browser/index.test.ts new file mode 100644 index 00000000000..da00d595aa0 --- /dev/null +++ b/compiler/wasm/test/browser/index.test.ts @@ -0,0 +1,35 @@ +import { expect } from "@esm-bundle/chai"; +import initNoirWasm from "../../result"; +import { compileNoirSource, nargoArtifactPath, noirSourcePath } from "../shared"; + +beforeEach(async () => { + await initNoirWasm(); +}); + +async function getFileContent(path: string): Promise { + const mainnrSourceURL = new URL(path, import.meta.url); + const response = await fetch(mainnrSourceURL); + return await response.text(); +} + +async function getSource(): Promise { + return getFileContent(noirSourcePath) +} + +async function getPrecompiledSource(): Promise { + const compiledData = await getFileContent(nargoArtifactPath); + return JSON.parse(compiledData).bytecode; +} + +describe("noir wasm compilation", () => { + it("matches nargos compilation", async () => { + const source = await getSource(); + + const wasmCircuitBase64 = await compileNoirSource(source); + + const cliCircuitBase64 = await getPrecompiledSource(); + + + expect(wasmCircuitBase64).to.equal(cliCircuitBase64); + }).timeout(20e3); // 20 seconds +}); diff --git a/crates/wasm/test/index.d.ts b/compiler/wasm/test/index.d.ts similarity index 100% rename from crates/wasm/test/index.d.ts rename to compiler/wasm/test/index.d.ts diff --git a/compiler/wasm/test/node/index.test.ts b/compiler/wasm/test/node/index.test.ts new file mode 100644 index 00000000000..f823db35944 --- /dev/null +++ b/compiler/wasm/test/node/index.test.ts @@ -0,0 +1,42 @@ +import { expect } from "chai"; +import { + compileNoirSource, + nargoArtifactPath, + noirSourcePath, +} from "../shared"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +async function getFileContent(path: string): Promise { + return readFileSync(join(__dirname, path)).toString(); +} + +async function getSource(): Promise { + return getFileContent(noirSourcePath); +} + +async function getPrecompiledSource(): Promise { + const compiledData = await getFileContent(nargoArtifactPath); + return JSON.parse(compiledData).bytecode; +} + +describe("noir wasm compilation", () => { + it("matches nargos compilation", async () => { + const source = await getSource(); + + const wasmCircuitBase64 = await compileNoirSource(source); + + const cliCircuitBase64 = await getPrecompiledSource(); + + console.log("wasm", wasmCircuitBase64); + + console.log("cli", cliCircuitBase64); + + console.log( + "Compilation is a match? ", + wasmCircuitBase64 === cliCircuitBase64, + ); + + expect(wasmCircuitBase64).to.equal(cliCircuitBase64); + }).timeout(10e3); +}); diff --git a/crates/wasm/test/shared.ts b/compiler/wasm/test/shared.ts similarity index 85% rename from crates/wasm/test/shared.ts rename to compiler/wasm/test/shared.ts index ee9c57d24f6..725e4fbd05e 100644 --- a/crates/wasm/test/shared.ts +++ b/compiler/wasm/test/shared.ts @@ -2,12 +2,13 @@ import { initialiseResolver } from "@noir-lang/noir-source-resolver"; import { compile } from "../result/"; export const noirSourcePath = "../../noir-script/src/main.nr"; -export const nargoArtifactPath = "../../noir-script/target/noir_wasm_testing.json"; +export const nargoArtifactPath = + "../../noir-script/target/noir_wasm_testing.json"; export async function compileNoirSource(noir_source: string): Promise { console.log("Compiling Noir source..."); - initialiseResolver((id: string) => { + initialiseResolver((id: String) => { console.log(`Resolving source ${id}`); const source = noir_source; diff --git a/crates/wasm/tsconfig.json b/compiler/wasm/tsconfig.json similarity index 100% rename from crates/wasm/tsconfig.json rename to compiler/wasm/tsconfig.json diff --git a/compiler/wasm/web-test-runner.config.mjs b/compiler/wasm/web-test-runner.config.mjs new file mode 100644 index 00000000000..5921e9add5f --- /dev/null +++ b/compiler/wasm/web-test-runner.config.mjs @@ -0,0 +1,25 @@ +import { fileURLToPath } from 'url'; +import { esbuildPlugin } from "@web/dev-server-esbuild"; +import { playwrightLauncher } from "@web/test-runner-playwright"; + +export default { + browsers: [ + playwrightLauncher({ product: "chromium" }), + playwrightLauncher({ product: "webkit" }), + playwrightLauncher({ product: "firefox" }), + ], + plugins: [ + esbuildPlugin({ + ts: true, + }), + ], + files: ["test/browser/**/*.test.ts"], + nodeResolve: true, + testFramework: { + config: { + ui: "bdd", + timeout: 40000, + }, + }, + rootDir: fileURLToPath(new URL('./../../', import.meta.url)), +}; diff --git a/crates/wasm/yarn.lock b/compiler/wasm/yarn.lock similarity index 100% rename from crates/wasm/yarn.lock rename to compiler/wasm/yarn.lock diff --git a/crates/arena/Cargo.toml b/crates/arena/Cargo.toml deleted file mode 100644 index 04e46791ce0..00000000000 --- a/crates/arena/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "arena" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -generational-arena = "0.2.8" diff --git a/crates/fm/Cargo.toml b/crates/fm/Cargo.toml deleted file mode 100644 index 2fc7eac6d8f..00000000000 --- a/crates/fm/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "fm" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -codespan-reporting.workspace = true -cfg-if.workspace = true -rust-embed = "6.6.0" -serde.workspace = true - -[target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen.workspace = true - -[dev-dependencies] -tempfile = "3.2.0" -iter-extended.workspace = true diff --git a/crates/fm/src/file_map.rs b/crates/fm/src/file_map.rs deleted file mode 100644 index 22ac6d4e179..00000000000 --- a/crates/fm/src/file_map.rs +++ /dev/null @@ -1,82 +0,0 @@ -use crate::FileManager; -use codespan_reporting::files::{SimpleFile, SimpleFiles}; -use serde::{Deserialize, Serialize}; -use std::path::PathBuf; - -// XXX: File and FileMap serve as opaque types, so that the rest of the library does not need to import the dependency -// or worry about when we change the dep - -#[derive(Clone, Debug)] -pub struct PathString(PathBuf); - -impl std::fmt::Display for PathString { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - f.write_str(&self.0.to_string_lossy()) - } -} - -impl PathString { - pub fn from_path(p: PathBuf) -> Self { - PathString(p) - } -} -impl From for PathString { - fn from(pb: PathBuf) -> PathString { - PathString::from_path(pb) - } -} -impl From<&PathBuf> for PathString { - fn from(pb: &PathBuf) -> PathString { - PathString::from(pb.to_owned()) - } -} -#[derive(Debug)] -pub struct FileMap(SimpleFiles); - -// XXX: Note that we derive Default here due to ModuleOrigin requiring us to set a FileId -#[derive( - Default, Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize, PartialOrd, Ord, -)] -pub struct FileId(usize); - -impl FileId { - //XXX: find a way to remove the need for this. Errors do not need to attach their FileIds immediately! - pub fn as_usize(&self) -> usize { - self.0 - } - - pub fn dummy() -> FileId { - FileId(0) - } -} - -pub struct File<'input>(&'input SimpleFile); - -impl<'input> File<'input> { - pub fn source(self) -> &'input str { - self.0.source() - } -} - -impl FileMap { - pub fn add_file(&mut self, file_name: PathString, code: String) -> FileId { - let file_id = self.0.add(file_name, code); - FileId(file_id) - } - pub fn get_file(&self, file_id: FileId) -> Option { - self.0.get(file_id.0).map(File).ok() - } -} - -impl Default for FileMap { - fn default() -> Self { - FileMap(SimpleFiles::new()) - } -} - -impl FileManager { - // Needed as code_span dep requires underlying SimpleFiles - pub fn as_simple_files(&self) -> &SimpleFiles { - &self.file_map.0 - } -} diff --git a/crates/fm/src/lib.rs b/crates/fm/src/lib.rs deleted file mode 100644 index ef976a80dbd..00000000000 --- a/crates/fm/src/lib.rs +++ /dev/null @@ -1,292 +0,0 @@ -#![forbid(unsafe_code)] -#![warn(unused_crate_dependencies, unused_extern_crates)] -#![warn(unreachable_pub)] -#![warn(clippy::semicolon_if_nothing_returned)] - -mod file_map; -mod file_reader; - -pub use file_map::{File, FileId, FileMap}; -use file_reader::is_stdlib_asset; - -use std::{ - collections::HashMap, - path::{Component, Path, PathBuf}, -}; - -pub const FILE_EXTENSION: &str = "nr"; - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -struct VirtualPath(PathBuf); - -#[derive(Debug)] -pub struct FileManager { - root: PathBuf, - file_map: file_map::FileMap, - id_to_path: HashMap, - path_to_id: HashMap, -} - -impl FileManager { - pub fn new(root: &Path) -> Self { - Self { - root: root.normalize(), - file_map: Default::default(), - id_to_path: Default::default(), - path_to_id: Default::default(), - } - } - - pub fn add_file(&mut self, file_name: &Path) -> Option { - // Handle both relative file paths and std/lib virtual paths. - let resolved_path: PathBuf = if is_stdlib_asset(file_name) { - // Special case for stdlib where we want to read specifically the `std/` relative path - // TODO: The stdlib path should probably be an absolute path rooted in something people would never create - file_name.to_path_buf() - } else { - self.root.join(file_name).normalize() - }; - - // Check that the resolved path already exists in the file map, if it is, we return it. - let path_to_file = virtualize_path(&resolved_path); - if let Some(file_id) = self.path_to_id.get(&path_to_file) { - return Some(*file_id); - } - - // Otherwise we add the file - let source = file_reader::read_file_to_string(&resolved_path).ok()?; - let file_id = self.file_map.add_file(resolved_path.into(), source); - self.register_path(file_id, path_to_file); - Some(file_id) - } - - fn register_path(&mut self, file_id: FileId, path: VirtualPath) { - let old_value = self.id_to_path.insert(file_id, path.clone()); - assert!( - old_value.is_none(), - "ice: the same file id was inserted into the file manager twice" - ); - let old_value = self.path_to_id.insert(path, file_id); - assert!(old_value.is_none(), "ice: the same path was inserted into the file manager twice"); - } - - pub fn fetch_file(&self, file_id: FileId) -> File { - // Unwrap as we ensure that all file_id's map to a corresponding file in the file map - self.file_map.get_file(file_id).unwrap() - } - pub fn path(&self, file_id: FileId) -> &Path { - // Unwrap as we ensure that all file_ids are created by the file manager - // So all file_ids will points to a corresponding path - self.id_to_path.get(&file_id).unwrap().0.as_path() - } - - pub fn find_module(&mut self, anchor: FileId, mod_name: &str) -> Result { - let mut candidate_files = Vec::new(); - - let anchor_path = self.path(anchor).to_path_buf(); - let anchor_dir = anchor_path.parent().unwrap(); - - // First we attempt to look at `base/anchor/mod_name.nr` (child of the anchor) - candidate_files.push(anchor_path.join(format!("{mod_name}.{FILE_EXTENSION}"))); - // If not found, we attempt to look at `base/mod_name.nr` (sibling of the anchor) - candidate_files.push(anchor_dir.join(format!("{mod_name}.{FILE_EXTENSION}"))); - - for candidate in candidate_files.iter() { - if let Some(file_id) = self.add_file(candidate) { - return Ok(file_id); - } - } - - Err(candidate_files.remove(0).as_os_str().to_str().unwrap().to_owned()) - } -} - -pub trait NormalizePath { - /// Replacement for `std::fs::canonicalize` that doesn't verify the path exists. - /// - /// Plucked from https://github.com/rust-lang/cargo/blob/fede83ccf973457de319ba6fa0e36ead454d2e20/src/cargo/util/paths.rs#L61 - /// Advice from https://www.reddit.com/r/rust/comments/hkkquy/comment/fwtw53s/ - fn normalize(&self) -> PathBuf; -} - -impl NormalizePath for PathBuf { - fn normalize(&self) -> PathBuf { - let components = self.components(); - resolve_components(components) - } -} - -impl NormalizePath for &Path { - fn normalize(&self) -> PathBuf { - let components = self.components(); - resolve_components(components) - } -} - -fn resolve_components<'a>(components: impl Iterator>) -> PathBuf { - let mut components = components.peekable(); - - // Preserve path prefix if one exists. - let mut normalized_path = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { - components.next(); - PathBuf::from(c.as_os_str()) - } else { - PathBuf::new() - }; - - for component in components { - match component { - Component::Prefix(..) => unreachable!("Path cannot contain multiple prefixes"), - Component::RootDir => { - normalized_path.push(component.as_os_str()); - } - Component::CurDir => {} - Component::ParentDir => { - normalized_path.pop(); - } - Component::Normal(c) => { - normalized_path.push(c); - } - } - } - - normalized_path -} - -#[cfg(test)] -mod path_normalization { - use iter_extended::vecmap; - use std::path::PathBuf; - - use crate::NormalizePath; - - #[test] - fn normalizes_paths_correctly() { - // Note that tests are run on unix so prefix handling can't be tested (as these only exist on Windows) - let test_cases = vecmap( - [ - ("/", "/"), // Handles root - ("/foo/bar/../baz/../bar", "/foo/bar"), // Handles backtracking - ("/././././././././baz", "/baz"), // Removes no-ops - ], - |(unnormalized, normalized)| (PathBuf::from(unnormalized), PathBuf::from(normalized)), - ); - - for (path, expected_result) in test_cases { - assert_eq!(path.normalize(), expected_result); - } - } -} - -/// Takes a path to a noir file. This will panic on paths to directories -/// Returns the file path with the extension removed -fn virtualize_path(path: &Path) -> VirtualPath { - let path = path.to_path_buf(); - let base = path.parent().unwrap(); - let path_no_ext: PathBuf = - path.file_stem().expect("ice: this should have been the path to a file").into(); - let path = base.join(path_no_ext); - VirtualPath(path) -} -#[cfg(test)] -mod tests { - use super::*; - use tempfile::{tempdir, TempDir}; - - fn create_dummy_file(dir: &TempDir, file_name: &Path) { - let file_path = dir.path().join(file_name); - let _file = std::fs::File::create(file_path).unwrap(); - } - - #[test] - fn path_resolve_file_module() { - let dir = tempdir().unwrap(); - - let entry_file_name = Path::new("my_dummy_file.nr"); - create_dummy_file(&dir, entry_file_name); - - let mut fm = FileManager::new(dir.path()); - - let file_id = fm.add_file(entry_file_name).unwrap(); - - let dep_file_name = Path::new("foo.nr"); - create_dummy_file(&dir, dep_file_name); - fm.find_module(file_id, "foo").unwrap(); - } - #[test] - fn path_resolve_file_module_other_ext() { - let dir = tempdir().unwrap(); - let file_name = Path::new("foo.noir"); - create_dummy_file(&dir, file_name); - - let mut fm = FileManager::new(dir.path()); - - let file_id = fm.add_file(file_name).unwrap(); - - assert!(fm.path(file_id).ends_with("foo")); - } - #[test] - fn path_resolve_sub_module() { - let dir = tempdir().unwrap(); - let mut fm = FileManager::new(dir.path()); - - // Create a lib.nr file at the root. - // we now have dir/lib.nr - let file_name = Path::new("lib.nr"); - create_dummy_file(&dir, file_name); - - let file_id = fm.add_file(file_name).unwrap(); - - // Create a sub directory - // we now have: - // - dir/lib.nr - // - dir/sub_dir - let sub_dir = TempDir::new_in(&dir).unwrap(); - let sub_dir_name = sub_dir.path().file_name().unwrap().to_str().unwrap(); - - // Add foo.nr to the subdirectory - // we no have: - // - dir/lib.nr - // - dir/sub_dir/foo.nr - create_dummy_file(&sub_dir, Path::new("foo.nr")); - - // Add a parent module for the sub_dir - // we no have: - // - dir/lib.nr - // - dir/sub_dir.nr - // - dir/sub_dir/foo.nr - create_dummy_file(&dir, Path::new(&format!("{}.nr", sub_dir_name))); - - // First check for the sub_dir.nr file and add it to the FileManager - let sub_dir_file_id = fm.find_module(file_id, sub_dir_name).unwrap(); - - // Now check for files in it's subdirectory - fm.find_module(sub_dir_file_id, "foo").unwrap(); - } - - /// Tests that two identical files that have different paths are treated as the same file - /// e.g. if we start in the dir ./src and have a file ../../foo.nr - /// that should be treated as the same file as ../ starting in ./ - /// they should both resolve to ../foo.nr - #[test] - fn path_resolve_modules_with_different_paths_as_same_file() { - let dir = tempdir().unwrap(); - let sub_dir = TempDir::new_in(&dir).unwrap(); - let sub_sub_dir = TempDir::new_in(&sub_dir).unwrap(); - - let mut fm = FileManager::new(dir.path()); - - // Create a lib.nr file at the root. - let file_name = Path::new("lib.nr"); - create_dummy_file(&dir, file_name); - - // Create another path with `./` and `../` inside it - let second_file_name = PathBuf::from(sub_sub_dir.path()).join("./../../lib.nr"); - - // Add both files to the file manager - let file_id = fm.add_file(file_name).unwrap(); - let second_file_id = fm.add_file(&second_file_name).unwrap(); - - assert_eq!(file_id, second_file_id); - } -} diff --git a/crates/iter-extended/Cargo.toml b/crates/iter-extended/Cargo.toml deleted file mode 100644 index b2c7aad20eb..00000000000 --- a/crates/iter-extended/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "iter-extended" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/crates/lsp/Cargo.toml b/crates/lsp/Cargo.toml deleted file mode 100644 index 00f4f9f9d82..00000000000 --- a/crates/lsp/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "noir_lsp" -description = "Language server for Noir" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -acvm.workspace = true -codespan-lsp.workspace = true -codespan-reporting.workspace = true -fm.workspace = true -lsp-types.workspace = true -nargo.workspace = true -nargo_toml.workspace = true -noirc_driver.workspace = true -noirc_errors.workspace = true -noirc_frontend.workspace = true -serde_json.workspace = true -toml.workspace = true -tower.workspace = true -async-lsp = { version = "0.0.5", default-features = false, features = ["omni-trait"] } - -[dev-dependencies] -tokio = { version = "1.0", features = ["macros"] } diff --git a/crates/lsp/src/lib.rs b/crates/lsp/src/lib.rs deleted file mode 100644 index 802ecab5798..00000000000 --- a/crates/lsp/src/lib.rs +++ /dev/null @@ -1,589 +0,0 @@ -use std::{ - future::{self, Future}, - ops::{self, ControlFlow}, - path::PathBuf, - pin::Pin, - task::{self, Poll}, -}; - -use async_lsp::{ - router::Router, AnyEvent, AnyNotification, AnyRequest, ClientSocket, Error, ErrorCode, - LanguageClient, LspService, ResponseError, -}; -use codespan_reporting::files; -use fm::FILE_EXTENSION; -use lsp_types::{ - notification, request, CodeLens, CodeLensOptions, CodeLensParams, Command, Diagnostic, - DiagnosticSeverity, DidChangeConfigurationParams, DidChangeTextDocumentParams, - DidCloseTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams, - InitializeParams, InitializeResult, InitializedParams, LogMessageParams, MessageType, Position, - PublishDiagnosticsParams, Range, ServerCapabilities, TextDocumentSyncOptions, -}; -use nargo::prepare_package; -use nargo_toml::{find_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_driver::check_crate; -use noirc_errors::{DiagnosticKind, FileDiagnostic}; -use noirc_frontend::hir::FunctionNameMatch; -use serde_json::Value as JsonValue; -use tower::Service; - -const ARROW: &str = "▶\u{fe0e}"; -const TEST_COMMAND: &str = "nargo.test"; -const TEST_CODELENS_TITLE: &str = "Run Test"; -const COMPILE_COMMAND: &str = "nargo.compile"; -const COMPILE_CODELENS_TITLE: &str = "Compile"; -const EXECUTE_COMMAND: &str = "nargo.execute"; -const EXECUTE_CODELENS_TITLE: &str = "Execute"; - -// State for the LSP gets implemented on this struct and is internal to the implementation -pub struct LspState { - root_path: Option, - client: ClientSocket, -} - -impl LspState { - fn new(client: &ClientSocket) -> Self { - Self { client: client.clone(), root_path: None } - } -} - -pub struct NargoLspService { - router: Router, -} - -impl NargoLspService { - pub fn new(client: &ClientSocket) -> Self { - let state = LspState::new(client); - let mut router = Router::new(state); - router - .request::(on_initialize) - .request::(on_shutdown) - .request::(on_code_lens_request) - .notification::(on_initialized) - .notification::(on_did_change_configuration) - .notification::(on_did_open_text_document) - .notification::(on_did_change_text_document) - .notification::(on_did_close_text_document) - .notification::(on_did_save_text_document) - .notification::(on_exit); - Self { router } - } -} - -// This trait implemented as a passthrough to the router, which makes -// our `NargoLspService` a normal Service as far as Tower is concerned. -impl Service for NargoLspService { - type Response = JsonValue; - type Error = ResponseError; - type Future = Pin> + Send>>; - - fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll> { - self.router.poll_ready(cx) - } - - fn call(&mut self, req: AnyRequest) -> Self::Future { - self.router.call(req) - } -} - -// This trait implemented as a passthrough to the router, which makes -// our `NargoLspService` able to accept the `async-lsp` middleware. -impl LspService for NargoLspService { - fn notify(&mut self, notification: AnyNotification) -> ControlFlow> { - self.router.notify(notification) - } - - fn emit(&mut self, event: AnyEvent) -> ControlFlow> { - self.router.emit(event) - } -} - -// Handlers -// The handlers for `request` are not `async` because it compiles down to lifetimes that can't be added to -// the router. To return a future that fits the trait, it is easiest wrap your implementations in an `async {}` -// block but you can also use `std::future::ready`. -// -// Additionally, the handlers for `notification` aren't async at all. -// -// They are not attached to the `NargoLspService` struct so they can be unit tested with only `LspState` -// and params passed in. - -fn on_initialize( - state: &mut LspState, - params: InitializeParams, -) -> impl Future> { - state.root_path = params.root_uri.and_then(|root_uri| root_uri.to_file_path().ok()); - - async { - let text_document_sync = - TextDocumentSyncOptions { save: Some(true.into()), ..Default::default() }; - - let code_lens = CodeLensOptions { resolve_provider: Some(false) }; - - Ok(InitializeResult { - capabilities: ServerCapabilities { - text_document_sync: Some(text_document_sync.into()), - code_lens_provider: Some(code_lens), - // Add capabilities before this spread when adding support for one - ..Default::default() - }, - server_info: None, - }) - } -} - -fn on_shutdown( - _state: &mut LspState, - _params: (), -) -> impl Future> { - async { Ok(()) } -} - -fn on_code_lens_request( - state: &mut LspState, - params: CodeLensParams, -) -> impl Future>, ResponseError>> { - let file_path = match params.text_document.uri.to_file_path() { - Ok(file_path) => file_path, - Err(()) => { - return future::ready(Err(ResponseError::new( - ErrorCode::REQUEST_FAILED, - "URI is not a valid file path", - ))) - } - }; - - let root_path = match &state.root_path { - Some(root) => root, - None => { - return future::ready(Err(ResponseError::new( - ErrorCode::REQUEST_FAILED, - "Could not find project root", - ))) - } - }; - - let toml_path = match find_package_manifest(root_path, &file_path) { - Ok(toml_path) => toml_path, - Err(err) => { - // If we cannot find a manifest, we log a warning but return no code lenses - // We can reconsider this when we can build a file without the need for a Nargo.toml file to resolve deps - let _ = state.client.log_message(LogMessageParams { - typ: MessageType::WARNING, - message: format!("{}", err), - }); - return future::ready(Ok(None)); - } - }; - let workspace = match resolve_workspace_from_toml(&toml_path, PackageSelection::All) { - Ok(workspace) => workspace, - Err(err) => { - // If we found a manifest, but the workspace is invalid, we raise an error about it - return future::ready(Err(ResponseError::new( - ErrorCode::REQUEST_FAILED, - format!("{}", err), - ))); - } - }; - - let mut lenses: Vec = vec![]; - - for package in &workspace { - let (mut context, crate_id) = prepare_package(package); - // We ignore the warnings and errors produced by compilation for producing code lenses - // because we can still get the test functions even if compilation fails - let _ = check_crate(&mut context, crate_id, false); - - let fm = &context.file_manager; - let files = fm.as_simple_files(); - let tests = context - .get_all_test_functions_in_crate_matching(&crate_id, FunctionNameMatch::Anything); - - for (func_name, func_id) in tests { - let location = context.function_meta(&func_id).name.location; - let file_id = location.file; - - // Ignore diagnostics for any file that wasn't the file we saved - // TODO: In the future, we could create "related" diagnostics for these files - // TODO: This currently just appends the `.nr` file extension that we store as a constant, - // but that won't work if we accept other extensions - if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { - continue; - } - - let range = byte_span_to_range(files, file_id.as_usize(), location.span.into()) - .unwrap_or_default(); - - let test_command = Command { - title: format!("{ARROW} {TEST_CODELENS_TITLE}"), - command: TEST_COMMAND.into(), - arguments: Some(vec![ - "--program-dir".into(), - format!("{}", workspace.root_dir.display()).into(), - "--package".into(), - format!("{}", package.name).into(), - "--exact".into(), - func_name.into(), - ]), - }; - - let test_lens = CodeLens { range, command: Some(test_command), data: None }; - - lenses.push(test_lens); - } - - if package.is_binary() { - if let Some(main_func_id) = context.get_main_function(&crate_id) { - let location = context.function_meta(&main_func_id).name.location; - let file_id = location.file; - - // Ignore diagnostics for any file that wasn't the file we saved - // TODO: In the future, we could create "related" diagnostics for these files - // TODO: This currently just appends the `.nr` file extension that we store as a constant, - // but that won't work if we accept other extensions - if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { - continue; - } - - let range = byte_span_to_range(files, file_id.as_usize(), location.span.into()) - .unwrap_or_default(); - - let compile_command = Command { - title: format!("{ARROW} {COMPILE_CODELENS_TITLE}"), - command: COMPILE_COMMAND.into(), - arguments: Some(vec![ - "--program-dir".into(), - format!("{}", workspace.root_dir.display()).into(), - "--package".into(), - format!("{}", package.name).into(), - ]), - }; - - let compile_lens = CodeLens { range, command: Some(compile_command), data: None }; - - lenses.push(compile_lens); - - let execute_command = Command { - title: EXECUTE_CODELENS_TITLE.to_string(), - command: EXECUTE_COMMAND.into(), - arguments: Some(vec![ - "--program-dir".into(), - format!("{}", workspace.root_dir.display()).into(), - "--package".into(), - format!("{}", package.name).into(), - ]), - }; - - let execute_lens = CodeLens { range, command: Some(execute_command), data: None }; - - lenses.push(execute_lens); - } - } - - if package.is_contract() { - // Currently not looking to deduplicate this since we don't have a clear decision on if the Contract stuff is staying - for contract in context.get_all_contracts(&crate_id) { - let location = contract.location; - let file_id = location.file; - - // Ignore diagnostics for any file that wasn't the file we saved - // TODO: In the future, we could create "related" diagnostics for these files - // TODO: This currently just appends the `.nr` file extension that we store as a constant, - // but that won't work if we accept other extensions - if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { - continue; - } - - let range = byte_span_to_range(files, file_id.as_usize(), location.span.into()) - .unwrap_or_default(); - - let compile_command = Command { - title: format!("{ARROW} {COMPILE_CODELENS_TITLE}"), - command: COMPILE_COMMAND.into(), - arguments: Some(vec![ - "--program-dir".into(), - format!("{}", workspace.root_dir.display()).into(), - "--package".into(), - format!("{}", package.name).into(), - ]), - }; - - let compile_lens = CodeLens { range, command: Some(compile_command), data: None }; - - lenses.push(compile_lens); - } - } - - if package.is_binary() { - if let Some(main_func_id) = context.get_main_function(&crate_id) { - let location = context.function_meta(&main_func_id).name.location; - let file_id = location.file; - - // Ignore diagnostics for any file that wasn't the file we saved - // TODO: In the future, we could create "related" diagnostics for these files - // TODO: This currently just appends the `.nr` file extension that we store as a constant, - // but that won't work if we accept other extensions - if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { - continue; - } - - let range = byte_span_to_range(files, file_id.as_usize(), location.span.into()) - .unwrap_or_default(); - - let command = Command { - title: format!("{ARROW} {COMPILE_CODELENS_TITLE}"), - command: COMPILE_COMMAND.into(), - arguments: Some(vec![ - "--program-dir".into(), - format!("{}", workspace.root_dir.display()).into(), - "--package".into(), - format!("{}", package.name).into(), - ]), - }; - - let lens = CodeLens { range, command: command.into(), data: None }; - - lenses.push(lens); - } - } - - if package.is_contract() { - // Currently not looking to deduplicate this since we don't have a clear decision on if the Contract stuff is staying - for contract in context.get_all_contracts(&crate_id) { - let location = contract.location; - let file_id = location.file; - - // Ignore diagnostics for any file that wasn't the file we saved - // TODO: In the future, we could create "related" diagnostics for these files - // TODO: This currently just appends the `.nr` file extension that we store as a constant, - // but that won't work if we accept other extensions - if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { - continue; - } - - let range = byte_span_to_range(files, file_id.as_usize(), location.span.into()) - .unwrap_or_default(); - - let command = Command { - title: format!("{ARROW} {COMPILE_CODELENS_TITLE}"), - command: COMPILE_COMMAND.into(), - arguments: Some(vec![ - "--program-dir".into(), - format!("{}", workspace.root_dir.display()).into(), - "--package".into(), - format!("{}", package.name).into(), - ]), - }; - - let lens = CodeLens { range, command: command.into(), data: None }; - - lenses.push(lens); - } - } - } - - let res = if lenses.is_empty() { Ok(None) } else { Ok(Some(lenses)) }; - - future::ready(res) -} - -fn on_initialized( - _state: &mut LspState, - _params: InitializedParams, -) -> ControlFlow> { - ControlFlow::Continue(()) -} - -fn on_did_change_configuration( - _state: &mut LspState, - _params: DidChangeConfigurationParams, -) -> ControlFlow> { - ControlFlow::Continue(()) -} - -fn on_did_open_text_document( - _state: &mut LspState, - _params: DidOpenTextDocumentParams, -) -> ControlFlow> { - ControlFlow::Continue(()) -} - -fn on_did_change_text_document( - _state: &mut LspState, - _params: DidChangeTextDocumentParams, -) -> ControlFlow> { - ControlFlow::Continue(()) -} - -fn on_did_close_text_document( - _state: &mut LspState, - _params: DidCloseTextDocumentParams, -) -> ControlFlow> { - ControlFlow::Continue(()) -} - -fn on_did_save_text_document( - state: &mut LspState, - params: DidSaveTextDocumentParams, -) -> ControlFlow> { - let file_path = match params.text_document.uri.to_file_path() { - Ok(file_path) => file_path, - Err(()) => { - return ControlFlow::Break(Err(ResponseError::new( - ErrorCode::REQUEST_FAILED, - "URI is not a valid file path", - ) - .into())) - } - }; - - let root_path = match &state.root_path { - Some(root) => root, - None => { - return ControlFlow::Break(Err(ResponseError::new( - ErrorCode::REQUEST_FAILED, - "Could not find project root", - ) - .into())); - } - }; - - let toml_path = match find_package_manifest(root_path, &file_path) { - Ok(toml_path) => toml_path, - Err(err) => { - // If we cannot find a manifest, we log a warning but return no diagnostics - // We can reconsider this when we can build a file without the need for a Nargo.toml file to resolve deps - let _ = state.client.log_message(LogMessageParams { - typ: MessageType::WARNING, - message: format!("{}", err), - }); - return ControlFlow::Continue(()); - } - }; - let workspace = match resolve_workspace_from_toml(&toml_path, PackageSelection::All) { - Ok(workspace) => workspace, - Err(err) => { - // If we found a manifest, but the workspace is invalid, we raise an error about it - return ControlFlow::Break(Err(ResponseError::new( - ErrorCode::REQUEST_FAILED, - format!("{}", err), - ) - .into())); - } - }; - - let mut diagnostics = Vec::new(); - - for package in &workspace { - let (mut context, crate_id) = prepare_package(package); - - let file_diagnostics = match check_crate(&mut context, crate_id, false) { - Ok(warnings) => warnings, - Err(errors_and_warnings) => errors_and_warnings, - }; - - if !file_diagnostics.is_empty() { - let fm = &context.file_manager; - let files = fm.as_simple_files(); - - for FileDiagnostic { file_id, diagnostic, call_stack: _ } in file_diagnostics { - // Ignore diagnostics for any file that wasn't the file we saved - // TODO: In the future, we could create "related" diagnostics for these files - // TODO: This currently just appends the `.nr` file extension that we store as a constant, - // but that won't work if we accept other extensions - if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { - continue; - } - - let mut range = Range::default(); - - // TODO: Should this be the first item in secondaries? Should we bail when we find a range? - for sec in diagnostic.secondaries { - // Not using `unwrap_or_default` here because we don't want to overwrite a valid range with a default range - if let Some(r) = byte_span_to_range(files, file_id.as_usize(), sec.span.into()) - { - range = r - } - } - let severity = match diagnostic.kind { - DiagnosticKind::Error => Some(DiagnosticSeverity::ERROR), - DiagnosticKind::Warning => Some(DiagnosticSeverity::WARNING), - }; - diagnostics.push(Diagnostic { - range, - severity, - message: diagnostic.message, - ..Diagnostic::default() - }) - } - } - } - - // We need to refresh lenses when we compile since that's the only time they can be accurately reflected - std::mem::drop(state.client.code_lens_refresh(())); - - let _ = state.client.publish_diagnostics(PublishDiagnosticsParams { - uri: params.text_document.uri, - version: None, - diagnostics, - }); - - ControlFlow::Continue(()) -} - -fn on_exit(_state: &mut LspState, _params: ()) -> ControlFlow> { - ControlFlow::Continue(()) -} - -fn byte_span_to_range<'a, F: files::Files<'a> + ?Sized>( - files: &'a F, - file_id: F::FileId, - span: ops::Range, -) -> Option { - // TODO(#1683): Codespan ranges are often (always?) off by some amount of characters - if let Ok(codespan_range) = codespan_lsp::byte_span_to_range(files, file_id, span) { - // We have to manually construct a Range because the codespan_lsp restricts lsp-types to the wrong version range - // TODO: codespan is unmaintained and we should probably subsume it. Ref https://github.com/brendanzab/codespan/issues/345 - let range = Range { - start: Position { - line: codespan_range.start.line, - character: codespan_range.start.character, - }, - end: Position { - line: codespan_range.end.line, - character: codespan_range.end.character, - }, - }; - Some(range) - } else { - None - } -} - -#[cfg(test)] -mod lsp_tests { - use lsp_types::TextDocumentSyncCapability; - use tokio::test; - - use super::*; - - #[test] - async fn test_on_initialize() { - // Not available in published release yet - let client = ClientSocket::new_closed(); - let mut state = LspState::new(&client); - let params = InitializeParams::default(); - let response = on_initialize(&mut state, params).await.unwrap(); - assert!(matches!( - response.capabilities, - ServerCapabilities { - text_document_sync: Some(TextDocumentSyncCapability::Options( - TextDocumentSyncOptions { save: Some(_), .. } - )), - code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(false) }), - .. - } - )); - assert!(response.server_info.is_none()); - } -} diff --git a/crates/nargo/Cargo.toml b/crates/nargo/Cargo.toml deleted file mode 100644 index 25c73a3c025..00000000000 --- a/crates/nargo/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "nargo" -description = "Noir's package manager" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[build-dependencies] -rustc_version = "0.4.0" - -[dependencies] -acvm.workspace = true -fm.workspace = true -noirc_abi.workspace = true -noirc_driver.workspace = true -noirc_frontend.workspace = true -noirc_printable_type.workspace = true -iter-extended.workspace = true -serde.workspace = true -thiserror.workspace = true -noirc_errors.workspace = true -base64.workspace = true diff --git a/crates/nargo/src/artifacts/contract.rs b/crates/nargo/src/artifacts/contract.rs deleted file mode 100644 index a718eac9796..00000000000 --- a/crates/nargo/src/artifacts/contract.rs +++ /dev/null @@ -1,43 +0,0 @@ -use acvm::acir::circuit::Circuit; -use noirc_abi::Abi; -use noirc_driver::ContractFunctionType; -use serde::{Deserialize, Serialize}; - -/// `PreprocessedContract` represents a Noir contract which has been preprocessed by a particular backend proving system. -/// -/// This differs from a generic Noir contract artifact in that: -/// - The ACIR bytecode has had an optimization pass applied to tailor it for the backend. -/// - Proving and verification keys have been pregenerated based on this ACIR. -#[derive(Serialize, Deserialize)] -pub struct PreprocessedContract { - /// The name of the contract. - pub name: String, - /// The identifier of the proving backend which this contract has been compiled for. - pub backend: String, - /// Each of the contract's functions are compiled into a separate program stored in this `Vec`. - pub functions: Vec, -} - -/// Each function in the contract will be compiled as a separate noir program. -/// -/// A contract function unlike a regular Noir program however can have additional properties. -/// One of these being a function type. -#[derive(Debug, Serialize, Deserialize)] -pub struct PreprocessedContractFunction { - pub name: String, - - pub function_type: ContractFunctionType, - - pub is_internal: bool, - - pub abi: Abi, - - #[serde( - serialize_with = "super::serialize_circuit", - deserialize_with = "super::deserialize_circuit" - )] - pub bytecode: Circuit, - - pub proving_key: Option>, - pub verification_key: Option>, -} diff --git a/crates/nargo/src/artifacts/debug.rs b/crates/nargo/src/artifacts/debug.rs deleted file mode 100644 index b6eefd17189..00000000000 --- a/crates/nargo/src/artifacts/debug.rs +++ /dev/null @@ -1,55 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::{ - collections::{BTreeMap, BTreeSet}, - path::PathBuf, -}; - -use fm::FileId; -use noirc_errors::debug_info::DebugInfo; -use noirc_frontend::hir::Context; - -/// For a given file, we store the source code and the path to the file -/// so consumers of the debug artifact can reconstruct the original source code structure. -#[derive(Debug, Serialize, Deserialize)] -pub struct DebugFile { - pub source: String, - pub path: PathBuf, -} - -/// A Debug Artifact stores, for a given program, the debug info for every function -/// along with a map of file Id to the source code so locations in debug info can be mapped to source code they point to. -#[derive(Debug, Serialize, Deserialize)] -pub struct DebugArtifact { - pub debug_symbols: Vec, - pub file_map: BTreeMap, -} - -impl DebugArtifact { - pub fn new(debug_symbols: Vec, compilation_context: &Context) -> Self { - let mut file_map = BTreeMap::new(); - - let files_with_debug_symbols: BTreeSet = debug_symbols - .iter() - .flat_map(|function_symbols| { - function_symbols - .locations - .values() - .filter_map(|call_stack| call_stack.last().map(|location| location.file)) - }) - .collect(); - - for file_id in files_with_debug_symbols { - let file_source = compilation_context.file_manager.fetch_file(file_id).source(); - - file_map.insert( - file_id, - DebugFile { - source: file_source.to_string(), - path: compilation_context.file_manager.path(file_id).to_path_buf(), - }, - ); - } - - Self { debug_symbols, file_map } - } -} diff --git a/crates/nargo/src/artifacts/program.rs b/crates/nargo/src/artifacts/program.rs deleted file mode 100644 index 6ca49b35dd9..00000000000 --- a/crates/nargo/src/artifacts/program.rs +++ /dev/null @@ -1,23 +0,0 @@ -use acvm::acir::circuit::Circuit; -use noirc_abi::Abi; -use serde::{Deserialize, Serialize}; - -/// `PreprocessedProgram` represents a Noir program which has been preprocessed by a particular backend proving system. -/// -/// This differs from a generic Noir program artifact in that: -/// - The ACIR bytecode has had an optimization pass applied to tailor it for the backend. -/// - Proving and verification keys have been pregenerated based on this ACIR. -#[derive(Serialize, Deserialize, Debug)] -pub struct PreprocessedProgram { - pub backend: String, - pub abi: Abi, - - #[serde( - serialize_with = "super::serialize_circuit", - deserialize_with = "super::deserialize_circuit" - )] - pub bytecode: Circuit, - - pub proving_key: Option>, - pub verification_key: Option>, -} diff --git a/crates/nargo/src/errors.rs b/crates/nargo/src/errors.rs deleted file mode 100644 index 1c99d27ae42..00000000000 --- a/crates/nargo/src/errors.rs +++ /dev/null @@ -1,17 +0,0 @@ -use acvm::pwg::OpcodeResolutionError; -use noirc_printable_type::ForeignCallError; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum NargoError { - /// Error while compiling Noir into ACIR. - #[error("Failed to compile circuit")] - CompilationError, - - /// ACIR circuit solving error - #[error(transparent)] - SolvingError(#[from] OpcodeResolutionError), - - #[error(transparent)] - ForeignCallError(#[from] ForeignCallError), -} diff --git a/crates/nargo/src/lib.rs b/crates/nargo/src/lib.rs deleted file mode 100644 index 2bc62f9a96d..00000000000 --- a/crates/nargo/src/lib.rs +++ /dev/null @@ -1,56 +0,0 @@ -#![forbid(unsafe_code)] -#![warn(unused_crate_dependencies, unused_extern_crates)] -#![warn(unreachable_pub)] -#![warn(clippy::semicolon_if_nothing_returned)] - -//! Nargo is the package manager for Noir -//! This name was used because it sounds like `cargo` and -//! Noir Package Manager abbreviated is npm, which is already taken. - -pub mod artifacts; -pub mod constants; -mod errors; -pub mod ops; -pub mod package; -pub mod workspace; - -use std::collections::BTreeMap; - -use fm::FileManager; -use noirc_driver::{add_dep, prepare_crate, prepare_dependency}; -use noirc_frontend::{ - graph::{CrateGraph, CrateId, CrateName}, - hir::Context, -}; -use package::{Dependency, Package}; - -pub use self::errors::NargoError; - -pub fn prepare_dependencies( - context: &mut Context, - parent_crate: CrateId, - dependencies: &BTreeMap, -) { - for (dep_name, dep) in dependencies.iter() { - match dep { - Dependency::Remote { package } | Dependency::Local { package } => { - let crate_id = prepare_dependency(context, &package.entry_path); - add_dep(context, parent_crate, crate_id, dep_name.clone()); - prepare_dependencies(context, crate_id, &package.dependencies); - } - } - } -} - -pub fn prepare_package(package: &Package) -> (Context, CrateId) { - // TODO: FileManager continues to leak into various crates - let fm = FileManager::new(&package.root_dir); - let graph = CrateGraph::default(); - let mut context = Context::new(fm, graph); - - let crate_id = prepare_crate(&mut context, &package.entry_path); - - prepare_dependencies(&mut context, crate_id, &package.dependencies); - - (context, crate_id) -} diff --git a/crates/nargo/src/ops/codegen_verifier.rs b/crates/nargo/src/ops/codegen_verifier.rs deleted file mode 100644 index 851f735ae55..00000000000 --- a/crates/nargo/src/ops/codegen_verifier.rs +++ /dev/null @@ -1,10 +0,0 @@ -use acvm::{acir::circuit::Circuit, SmartContract}; - -pub fn codegen_verifier( - backend: &B, - common_reference_string: &[u8], - circuit: &Circuit, - verification_key: &[u8], -) -> Result { - backend.eth_contract_from_vk(common_reference_string, circuit, verification_key) -} diff --git a/crates/nargo/src/ops/execute.rs b/crates/nargo/src/ops/execute.rs deleted file mode 100644 index 2a126443468..00000000000 --- a/crates/nargo/src/ops/execute.rs +++ /dev/null @@ -1,35 +0,0 @@ -use acvm::pwg::{ACVMStatus, ACVM}; -use acvm::BlackBoxFunctionSolver; -use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; - -use crate::NargoError; - -use super::foreign_calls::ForeignCall; - -pub fn execute_circuit( - _backend: &B, - circuit: Circuit, - initial_witness: WitnessMap, - show_output: bool, -) -> Result { - let mut acvm = ACVM::new(B::default(), circuit.opcodes, initial_witness); - - loop { - let solver_status = acvm.solve(); - - match solver_status { - ACVMStatus::Solved => break, - ACVMStatus::InProgress => { - unreachable!("Execution should not stop while in `InProgress` state.") - } - ACVMStatus::Failure(error) => return Err(error.into()), - ACVMStatus::RequiresForeignCall(foreign_call) => { - let foreign_call_result = ForeignCall::execute(&foreign_call, show_output)?; - acvm.resolve_pending_foreign_call(foreign_call_result); - } - } - } - - let solved_witness = acvm.finalize(); - Ok(solved_witness) -} diff --git a/crates/nargo/src/ops/mod.rs b/crates/nargo/src/ops/mod.rs deleted file mode 100644 index 6d55e5b0dad..00000000000 --- a/crates/nargo/src/ops/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -pub use self::codegen_verifier::codegen_verifier; -pub use self::execute::execute_circuit; -pub use self::preprocess::{preprocess_contract_function, preprocess_program}; -pub use self::prove::prove_execution; -pub use self::verify::verify_proof; - -mod codegen_verifier; -mod execute; -mod foreign_calls; -mod preprocess; -mod prove; -mod verify; diff --git a/crates/nargo/src/ops/preprocess.rs b/crates/nargo/src/ops/preprocess.rs deleted file mode 100644 index 0ee4e2590f9..00000000000 --- a/crates/nargo/src/ops/preprocess.rs +++ /dev/null @@ -1,70 +0,0 @@ -use acvm::ProofSystemCompiler; -use noirc_driver::{CompiledProgram, ContractFunction}; -use noirc_errors::debug_info::DebugInfo; - -use crate::artifacts::{contract::PreprocessedContractFunction, program::PreprocessedProgram}; - -// TODO(#1388): pull this from backend. -const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; - -pub fn preprocess_program( - backend: &B, - include_keys: bool, - common_reference_string: &[u8], - compiled_program: CompiledProgram, -) -> Result<(PreprocessedProgram, DebugInfo), B::Error> { - // TODO: currently `compiled_program`'s bytecode is already optimized for the backend. - // In future we'll need to apply those optimizations here. - let optimized_bytecode = compiled_program.circuit; - - let (proving_key, verification_key) = if include_keys { - let (proving_key, verification_key) = - backend.preprocess(common_reference_string, &optimized_bytecode)?; - (Some(proving_key), Some(verification_key)) - } else { - (None, None) - }; - - Ok(( - PreprocessedProgram { - backend: String::from(BACKEND_IDENTIFIER), - abi: compiled_program.abi, - bytecode: optimized_bytecode, - proving_key, - verification_key, - }, - compiled_program.debug, - )) -} - -pub fn preprocess_contract_function( - backend: &B, - include_keys: bool, - common_reference_string: &[u8], - func: ContractFunction, -) -> Result<(PreprocessedContractFunction, DebugInfo), B::Error> { - // TODO: currently `func`'s bytecode is already optimized for the backend. - // In future we'll need to apply those optimizations here. - let optimized_bytecode = func.bytecode; - let (proving_key, verification_key) = if include_keys { - let (proving_key, verification_key) = - backend.preprocess(common_reference_string, &optimized_bytecode)?; - (Some(proving_key), Some(verification_key)) - } else { - (None, None) - }; - - Ok(( - PreprocessedContractFunction { - name: func.name, - function_type: func.function_type, - is_internal: func.is_internal, - abi: func.abi, - - bytecode: optimized_bytecode, - proving_key, - verification_key, - }, - func.debug, - )) -} diff --git a/crates/nargo/src/ops/prove.rs b/crates/nargo/src/ops/prove.rs deleted file mode 100644 index 16839a1b060..00000000000 --- a/crates/nargo/src/ops/prove.rs +++ /dev/null @@ -1,13 +0,0 @@ -use acvm::acir::{circuit::Circuit, native_types::WitnessMap}; -use acvm::ProofSystemCompiler; - -pub fn prove_execution( - backend: &B, - common_reference_string: &[u8], - circuit: &Circuit, - solved_witness: WitnessMap, - proving_key: &[u8], -) -> Result, B::Error> { - // TODO(#1569): update from not just accepting `false` once we get nargo to interop with dynamic backend - backend.prove_with_pk(common_reference_string, circuit, solved_witness, proving_key, false) -} diff --git a/crates/nargo/src/ops/verify.rs b/crates/nargo/src/ops/verify.rs deleted file mode 100644 index 4cc6c9ce34b..00000000000 --- a/crates/nargo/src/ops/verify.rs +++ /dev/null @@ -1,21 +0,0 @@ -use acvm::acir::{circuit::Circuit, native_types::WitnessMap}; -use acvm::ProofSystemCompiler; - -pub fn verify_proof( - backend: &B, - common_reference_string: &[u8], - circuit: &Circuit, - proof: &[u8], - public_inputs: WitnessMap, - verification_key: &[u8], -) -> Result { - // TODO(#1569): update from not just accepting `false` once we get nargo to interop with dynamic backend - backend.verify_with_vk( - common_reference_string, - proof, - public_inputs, - circuit, - verification_key, - false, - ) -} diff --git a/crates/nargo_cli/Cargo.toml b/crates/nargo_cli/Cargo.toml deleted file mode 100644 index af5240aecbf..00000000000 --- a/crates/nargo_cli/Cargo.toml +++ /dev/null @@ -1,81 +0,0 @@ -[package] -name = "nargo_cli" -description = "Noir's package manager" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -# Rename binary from `nargo_cli` to `nargo` -[[bin]] -name = "nargo" -path = "src/main.rs" - -[build-dependencies] -rustc_version = "0.4.0" -build-data = "0.1.3" -toml.workspace = true - -[dependencies] -clap.workspace = true -dirs.workspace = true -iter-extended.workspace = true -nargo.workspace = true -nargo_toml.workspace = true -noir_lsp.workspace = true -noirc_driver.workspace = true -noirc_frontend.workspace = true -noirc_abi.workspace = true -noirc_errors.workspace = true -acvm.workspace = true -toml.workspace = true -serde.workspace = true -serde_json.workspace = true -prettytable-rs = "0.10" -thiserror.workspace = true -tower.workspace = true -async-lsp = { version = "0.0.5", default-features = false, features = [ - "client-monitor", - "stdio", - "tracing", - "tokio", -] } -const_format = "0.2.30" -hex = "0.4.2" -termcolor = "1.1.2" -color-eyre = "0.6.2" -tokio = { version = "1.0", features = ["io-std"] } -tokio-util = { version = "0.7.8", features = ["compat"] } - -# Backends -acvm-backend-barretenberg = { version = "0.11.0", default-features = false } - -[dev-dependencies] -tempdir = "0.3.7" -assert_cmd = "2.0.8" -assert_fs = "1.0.10" -predicates = "2.1.5" -fm.workspace = true -criterion = "0.5.0" -paste = "1.0.14" -pprof = { version = "0.12", features = [ - "flamegraph", - "frame-pointer", - "criterion", -] } -iai = "0.1.1" - -[[bench]] -name = "criterion" -harness = false - -[[bench]] -name = "iai" -harness = false - -[features] -default = ["plonk_bn254"] -# The plonk backend can only use bn254, so we do not specify the field -plonk_bn254 = ["acvm-backend-barretenberg/native"] -plonk_bn254_wasm = ["acvm-backend-barretenberg/wasm"] diff --git a/crates/nargo_cli/build.rs b/crates/nargo_cli/build.rs deleted file mode 100644 index 629d6fea340..00000000000 --- a/crates/nargo_cli/build.rs +++ /dev/null @@ -1,199 +0,0 @@ -use rustc_version::{version, Version}; -use std::fs::File; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::{env, fs}; - -fn check_rustc_version() { - assert!( - version().unwrap() >= Version::parse("1.66.0").unwrap(), - "The minimal supported rustc version is 1.66.0." - ); -} - -const GIT_COMMIT: &&str = &"GIT_COMMIT"; - -fn main() { - // Rebuild if the tests have changed - println!("cargo:rerun-if-changed=tests"); - - check_rustc_version(); - - // Only use build_data if the environment variable isn't set - // The environment variable is always set when working via Nix - if std::env::var(GIT_COMMIT).is_err() { - build_data::set_GIT_COMMIT(); - build_data::set_GIT_DIRTY(); - build_data::no_debug_rebuilds(); - } - - let out_dir = env::var("OUT_DIR").unwrap(); - let destination = Path::new(&out_dir).join("execute.rs"); - let mut test_file = File::create(destination).unwrap(); - - // Try to find the directory that Cargo sets when it is running; otherwise fallback to assuming the CWD - // is the root of the repository and append the crate path - let manifest_dir = match std::env::var("CARGO_MANIFEST_DIR") { - Ok(dir) => PathBuf::from(dir), - Err(_) => std::env::current_dir().unwrap().join("crates").join("nargo_cli"), - }; - let test_dir = manifest_dir.join("tests"); - - generate_execution_success_tests(&mut test_file, &test_dir); - generate_compile_success_empty_tests(&mut test_file, &test_dir); - generate_compile_success_contract_tests(&mut test_file, &test_dir); - generate_compile_failure_tests(&mut test_file, &test_dir); -} - -fn generate_execution_success_tests(test_file: &mut File, test_data_dir: &Path) { - let test_sub_dir = "execution_success"; - let test_data_dir = test_data_dir.join(test_sub_dir); - - let test_case_dirs = - fs::read_dir(test_data_dir).unwrap().flatten().filter(|c| c.path().is_dir()); - - for test_dir in test_case_dirs { - let test_name = - test_dir.file_name().into_string().expect("Directory can't be converted to string"); - if test_name.contains('-') { - panic!( - "Invalid test directory: {test_name}. Cannot include `-`, please convert to `_`" - ); - }; - let test_dir = &test_dir.path(); - - write!( - test_file, - r#" -#[test] -fn execution_success_{test_name}() {{ - let test_program_dir = PathBuf::from("{test_dir}"); - - let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.arg("--program-dir").arg(test_program_dir); - cmd.arg("execute"); - - cmd.assert().success(); -}} - "#, - test_dir = test_dir.display(), - ) - .expect("Could not write templated test file."); - } -} - -fn generate_compile_success_empty_tests(test_file: &mut File, test_data_dir: &Path) { - let test_sub_dir = "compile_success_empty"; - let test_data_dir = test_data_dir.join(test_sub_dir); - - let test_case_dirs = - fs::read_dir(test_data_dir).unwrap().flatten().filter(|c| c.path().is_dir()); - - for test_dir in test_case_dirs { - let test_name = - test_dir.file_name().into_string().expect("Directory can't be converted to string"); - if test_name.contains('-') { - panic!( - "Invalid test directory: {test_name}. Cannot include `-`, please convert to `_`" - ); - }; - let test_dir = &test_dir.path(); - - write!( - test_file, - r#" -#[test] -fn compile_success_empty_{test_name}() {{ - let test_program_dir = PathBuf::from("{test_dir}"); - - let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.arg("--program-dir").arg(test_program_dir); - cmd.arg("info"); - - // `compile_success_empty` tests should be able to compile down to an empty circuit. - cmd.assert().stdout(predicate::str::contains("| Package") - .and(predicate::str::contains("| Language")) - .and(predicate::str::contains("| ACIR Opcodes | Backend Circuit Size |")) - .and(predicate::str::contains("| PLONKCSat {{ width: 3 }} |")) - .and(predicate::str::contains("| 0 | 1 |"))); -}} - "#, - test_dir = test_dir.display(), - ) - .expect("Could not write templated test file."); - } -} - -fn generate_compile_success_contract_tests(test_file: &mut File, test_data_dir: &Path) { - let test_sub_dir = "compile_success_contract"; - let test_data_dir = test_data_dir.join(test_sub_dir); - - let test_case_dirs = - fs::read_dir(test_data_dir).unwrap().flatten().filter(|c| c.path().is_dir()); - - for test_dir in test_case_dirs { - let test_name = - test_dir.file_name().into_string().expect("Directory can't be converted to string"); - if test_name.contains('-') { - panic!( - "Invalid test directory: {test_name}. Cannot include `-`, please convert to `_`" - ); - }; - let test_dir = &test_dir.path(); - - write!( - test_file, - r#" -#[test] -fn compile_success_contract_{test_name}() {{ - let test_program_dir = PathBuf::from("{test_dir}"); - - let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.arg("--program-dir").arg(test_program_dir); - cmd.arg("compile"); - - cmd.assert().success(); -}} - "#, - test_dir = test_dir.display(), - ) - .expect("Could not write templated test file."); - } -} - -fn generate_compile_failure_tests(test_file: &mut File, test_data_dir: &Path) { - let test_sub_dir = "compile_failure"; - let test_data_dir = test_data_dir.join(test_sub_dir); - - let test_case_dirs = - fs::read_dir(test_data_dir).unwrap().flatten().filter(|c| c.path().is_dir()); - - for test_dir in test_case_dirs { - let test_name = - test_dir.file_name().into_string().expect("Directory can't be converted to string"); - if test_name.contains('-') { - panic!( - "Invalid test directory: {test_name}. Cannot include `-`, please convert to `_`" - ); - }; - let test_dir = &test_dir.path(); - - write!( - test_file, - r#" -#[test] -fn compile_failure_{test_name}() {{ - let test_program_dir = PathBuf::from("{test_dir}"); - - let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.arg("--program-dir").arg(test_program_dir); - cmd.arg("execute"); - - cmd.assert().failure(); -}} - "#, - test_dir = test_dir.display(), - ) - .expect("Could not write templated test file."); - } -} diff --git a/crates/nargo_cli/src/backends.rs b/crates/nargo_cli/src/backends.rs deleted file mode 100644 index bbec5c99006..00000000000 --- a/crates/nargo_cli/src/backends.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub(crate) use acvm_backend_barretenberg::Barretenberg as ConcreteBackend; - -#[cfg(not(any(feature = "plonk_bn254", feature = "plonk_bn254_wasm")))] -compile_error!("please specify a backend to compile with"); - -#[cfg(all(feature = "plonk_bn254", feature = "plonk_bn254_wasm"))] -compile_error!( - "feature \"plonk_bn254\" and feature \"plonk_bn254_wasm\" cannot be enabled at the same time" -); diff --git a/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs b/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs deleted file mode 100644 index 7662eaa8401..00000000000 --- a/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs +++ /dev/null @@ -1,111 +0,0 @@ -use std::path::PathBuf; - -use super::NargoConfig; -use super::{ - compile_cmd::compile_package, - fs::{ - common_reference_string::{ - read_cached_common_reference_string, update_common_reference_string, - write_cached_common_reference_string, - }, - create_named_dir, - program::read_program_from_file, - write_to_file, - }, -}; -use crate::errors::CliError; -use acvm::Backend; -use clap::Args; -use nargo::{ - ops::{codegen_verifier, preprocess_program}, - package::Package, -}; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_driver::CompileOptions; -use noirc_frontend::graph::CrateName; - -/// Generates a Solidity verifier smart contract for the program -#[derive(Debug, Clone, Args)] -pub(crate) struct CodegenVerifierCommand { - /// The name of the package to codegen - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Codegen all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &B, - args: CodegenVerifierCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml(&toml_path, selection)?; - - for package in &workspace { - let circuit_build_path = workspace.package_build_path(package); - - let smart_contract_string = smart_contract_for_package( - backend, - package, - circuit_build_path, - &args.compile_options, - )?; - - let contract_dir = workspace.contracts_directory_path(package); - create_named_dir(&contract_dir, "contract"); - let contract_path = contract_dir.join("plonk_vk").with_extension("sol"); - - let path = write_to_file(smart_contract_string.as_bytes(), &contract_path); - println!("[{}] Contract successfully created and located at {path}", package.name); - } - - Ok(()) -} - -fn smart_contract_for_package( - backend: &B, - package: &Package, - circuit_build_path: PathBuf, - compile_options: &CompileOptions, -) -> Result> { - let common_reference_string = read_cached_common_reference_string(); - let (common_reference_string, preprocessed_program) = if circuit_build_path.exists() { - let program = read_program_from_file(circuit_build_path)?; - let common_reference_string = - update_common_reference_string(backend, &common_reference_string, &program.bytecode) - .map_err(CliError::CommonReferenceStringError)?; - (common_reference_string, program) - } else { - let (_, program) = compile_package(backend, package, compile_options)?; - let common_reference_string = - update_common_reference_string(backend, &common_reference_string, &program.circuit) - .map_err(CliError::CommonReferenceStringError)?; - let (program, _) = preprocess_program(backend, true, &common_reference_string, program) - .map_err(CliError::ProofSystemCompilerError)?; - (common_reference_string, program) - }; - - let verification_key = preprocessed_program - .verification_key - .expect("Verification key should exist as `true` is passed to `preprocess_program`"); - let smart_contract_string = codegen_verifier( - backend, - &common_reference_string, - &preprocessed_program.bytecode, - &verification_key, - ) - .map_err(CliError::SmartContractError)?; - - write_cached_common_reference_string(&common_reference_string); - - Ok(smart_contract_string) -} diff --git a/crates/nargo_cli/src/cli/compile_cmd.rs b/crates/nargo_cli/src/cli/compile_cmd.rs deleted file mode 100644 index 0ccf8765975..00000000000 --- a/crates/nargo_cli/src/cli/compile_cmd.rs +++ /dev/null @@ -1,221 +0,0 @@ -use acvm::{acir::circuit::Circuit, compiler::AcirTransformationMap, Backend}; -use iter_extended::try_vecmap; -use nargo::artifacts::debug::DebugArtifact; -use nargo::package::Package; -use nargo::prepare_package; -use nargo::{artifacts::contract::PreprocessedContract, NargoError}; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_driver::{ - compile_contracts, compile_main, CompileOptions, CompiledContract, CompiledProgram, - ErrorsAndWarnings, Warnings, -}; -use noirc_errors::debug_info::DebugInfo; -use noirc_frontend::graph::CrateName; -use noirc_frontend::hir::Context; - -use clap::Args; - -use nargo::ops::{preprocess_contract_function, preprocess_program}; - -use crate::errors::{CliError, CompileError}; - -use super::fs::program::save_debug_artifact_to_file; -use super::fs::{ - common_reference_string::{ - read_cached_common_reference_string, update_common_reference_string, - write_cached_common_reference_string, - }, - program::{save_contract_to_file, save_program_to_file}, -}; -use super::NargoConfig; - -// TODO(#1388): pull this from backend. -const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; - -/// Compile the program and its secret execution trace into ACIR format -#[derive(Debug, Clone, Args)] -pub(crate) struct CompileCommand { - /// Include Proving and Verification keys in the build artifacts. - #[arg(long)] - include_keys: bool, - - /// Output debug files - #[arg(long, hide = true)] - output_debug: bool, - - /// The name of the package to compile - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Compile all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &B, - args: CompileCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml(&toml_path, selection)?; - let circuit_dir = workspace.target_directory_path(); - - let mut common_reference_string = read_cached_common_reference_string(); - - for package in &workspace { - let (mut context, crate_id) = prepare_package(package); - // If `contract` package type, we're compiling every function in a 'contract' rather than just 'main'. - if package.is_contract() { - let result = compile_contracts(&mut context, crate_id, &args.compile_options); - let contracts = report_errors(result, &context, args.compile_options.deny_warnings)?; - let optimized_contracts = - try_vecmap(contracts, |contract| optimize_contract(backend, contract))?; - - // TODO(#1389): I wonder if it is incorrect for nargo-core to know anything about contracts. - // As can be seen here, It seems like a leaky abstraction where ContractFunctions (essentially CompiledPrograms) - // are compiled via nargo-core and then the PreprocessedContract is constructed here. - // This is due to EACH function needing it's own CRS, PKey, and VKey from the backend. - let preprocessed_contracts: Result< - Vec<(PreprocessedContract, Vec)>, - CliError, - > = try_vecmap(optimized_contracts, |contract| { - let preprocess_result = try_vecmap(contract.functions, |func| { - common_reference_string = update_common_reference_string( - backend, - &common_reference_string, - &func.bytecode, - ) - .map_err(CliError::CommonReferenceStringError)?; - - preprocess_contract_function( - backend, - args.include_keys, - &common_reference_string, - func, - ) - .map_err(CliError::ProofSystemCompilerError) - })?; - - let (preprocessed_contract_functions, debug_infos): (Vec<_>, Vec<_>) = - preprocess_result.into_iter().unzip(); - - Ok(( - PreprocessedContract { - name: contract.name, - backend: String::from(BACKEND_IDENTIFIER), - functions: preprocessed_contract_functions, - }, - debug_infos, - )) - }); - for (contract, debug_infos) in preprocessed_contracts? { - save_contract_to_file( - &contract, - &format!("{}-{}", package.name, contract.name), - &circuit_dir, - ); - - if args.output_debug { - let debug_artifact = DebugArtifact::new(debug_infos, &context); - save_debug_artifact_to_file( - &debug_artifact, - &format!("{}-{}", package.name, contract.name), - &circuit_dir, - ); - } - } - } else { - let (context, program) = compile_package(backend, package, &args.compile_options)?; - - common_reference_string = - update_common_reference_string(backend, &common_reference_string, &program.circuit) - .map_err(CliError::CommonReferenceStringError)?; - - let (preprocessed_program, debug_info) = - preprocess_program(backend, args.include_keys, &common_reference_string, program) - .map_err(CliError::ProofSystemCompilerError)?; - save_program_to_file(&preprocessed_program, &package.name, &circuit_dir); - - if args.output_debug { - let debug_artifact = DebugArtifact::new(vec![debug_info], &context); - let circuit_name: String = (&package.name).into(); - save_debug_artifact_to_file(&debug_artifact, &circuit_name, &circuit_dir); - } - } - } - - write_cached_common_reference_string(&common_reference_string); - - Ok(()) -} - -pub(crate) fn compile_package( - backend: &B, - package: &Package, - compile_options: &CompileOptions, -) -> Result<(Context, CompiledProgram), CompileError> { - if package.is_library() { - return Err(CompileError::LibraryCrate(package.name.clone())); - } - - let (mut context, crate_id) = prepare_package(package); - let result = compile_main(&mut context, crate_id, compile_options); - let mut program = report_errors(result, &context, compile_options.deny_warnings)?; - // Apply backend specific optimizations. - let (optimized_circuit, location_map) = optimize_circuit(backend, program.circuit) - .expect("Backend does not support an opcode that is in the IR"); - // TODO(#2110): Why does this set `program.circuit` to `optimized_circuit` instead of the function taking ownership - // and requiring we use `optimized_circuit` everywhere after - program.circuit = optimized_circuit; - program.debug.update_acir(location_map); - - Ok((context, program)) -} - -pub(super) fn optimize_circuit( - backend: &B, - circuit: Circuit, -) -> Result<(Circuit, AcirTransformationMap), CliError> { - let result = acvm::compiler::compile(circuit, backend.np_language(), |opcode| { - backend.supports_opcode(opcode) - }) - .map_err(|_| NargoError::CompilationError)?; - - Ok(result) -} - -pub(super) fn optimize_contract( - backend: &B, - contract: CompiledContract, -) -> Result> { - let functions = try_vecmap(contract.functions, |mut func| { - let (optimized_bytecode, location_map) = optimize_circuit(backend, func.bytecode)?; - func.bytecode = optimized_bytecode; - func.debug.update_acir(location_map); - Ok::<_, CliError>(func) - })?; - - Ok(CompiledContract { functions, ..contract }) -} - -/// Helper function for reporting any errors in a Result<(T, Warnings), ErrorsAndWarnings> -/// structure that is commonly used as a return result in this file. -pub(crate) fn report_errors( - result: Result<(T, Warnings), ErrorsAndWarnings>, - context: &Context, - deny_warnings: bool, -) -> Result { - let (t, warnings) = result.map_err(|errors| { - noirc_errors::reporter::report_all(&context.file_manager, &errors, deny_warnings) - })?; - - noirc_errors::reporter::report_all(&context.file_manager, &warnings, deny_warnings); - Ok(t) -} diff --git a/crates/nargo_cli/src/cli/execute_cmd.rs b/crates/nargo_cli/src/cli/execute_cmd.rs deleted file mode 100644 index 0a391ac71a8..00000000000 --- a/crates/nargo_cli/src/cli/execute_cmd.rs +++ /dev/null @@ -1,184 +0,0 @@ -use acvm::acir::circuit::OpcodeLocation; -use acvm::acir::{circuit::Circuit, native_types::WitnessMap}; -use acvm::pwg::ErrorLocation; -use acvm::Backend; -use clap::Args; -use nargo::constants::PROVER_INPUT_FILE; -use nargo::package::Package; -use nargo::NargoError; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_abi::input_parser::{Format, InputValue}; -use noirc_abi::{Abi, InputMap}; -use noirc_driver::{CompileOptions, CompiledProgram}; -use noirc_errors::{debug_info::DebugInfo, CustomDiagnostic}; -use noirc_frontend::graph::CrateName; -use noirc_frontend::hir::Context; - -use super::compile_cmd::compile_package; -use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir}; -use super::NargoConfig; -use crate::errors::CliError; - -/// Executes a circuit to calculate its return value -#[derive(Debug, Clone, Args)] -pub(crate) struct ExecuteCommand { - /// Write the execution witness to named file - witness_name: Option, - - /// The name of the toml file which contains the inputs for the prover - #[clap(long, short, default_value = PROVER_INPUT_FILE)] - prover_name: String, - - /// The name of the package to execute - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Execute all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &B, - args: ExecuteCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml(&toml_path, selection)?; - let witness_dir = &workspace.target_directory_path(); - - for package in &workspace { - let (return_value, solved_witness) = - execute_package(backend, package, &args.prover_name, &args.compile_options)?; - - println!("[{}] Circuit witness successfully solved", package.name); - if let Some(return_value) = return_value { - println!("[{}] Circuit output: {return_value:?}", package.name); - } - if let Some(witness_name) = &args.witness_name { - let witness_path = save_witness_to_dir(solved_witness, witness_name, witness_dir)?; - - println!("[{}] Witness saved to {}", package.name, witness_path.display()); - } - } - Ok(()) -} - -fn execute_package( - backend: &B, - package: &Package, - prover_name: &str, - compile_options: &CompileOptions, -) -> Result<(Option, WitnessMap), CliError> { - let (context, compiled_program) = compile_package(backend, package, compile_options)?; - let CompiledProgram { abi, circuit, debug } = compiled_program; - - // Parse the initial witness values from Prover.toml - let (inputs_map, _) = - read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &abi)?; - let solved_witness = - execute_program(backend, circuit, &abi, &inputs_map, Some((debug, context)))?; - let public_abi = abi.public_abi(); - let (_, return_value) = public_abi.decode(&solved_witness)?; - - Ok((return_value, solved_witness)) -} - -/// There are certain errors that contain an [acvm::pwg::ErrorLocation]. -/// We need to determine whether the error location has been resolving during execution. -/// If the location has been resolved we return the contained [OpcodeLocation]. -fn extract_opcode_error_from_nargo_error( - nargo_err: &NargoError, -) -> Option<(OpcodeLocation, &acvm::pwg::OpcodeResolutionError)> { - let solving_err = match nargo_err { - nargo::NargoError::SolvingError(err) => err, - _ => return None, - }; - - match solving_err { - acvm::pwg::OpcodeResolutionError::IndexOutOfBounds { - opcode_location: error_location, - .. - } - | acvm::pwg::OpcodeResolutionError::UnsatisfiedConstrain { - opcode_location: error_location, - } => match error_location { - ErrorLocation::Unresolved => { - unreachable!("Cannot resolve index for unsatisfied constraint") - } - ErrorLocation::Resolved(opcode_location) => Some((*opcode_location, solving_err)), - }, - _ => None, - } -} - -/// Resolve an [OpcodeLocation] using debug information generated during compilation -/// to determine an opcode's call stack. Then report the error using the resolved -/// call stack and any other relevant error information returned from the ACVM. -fn report_error_with_opcode_location( - opcode_err_info: Option<(OpcodeLocation, &acvm::pwg::OpcodeResolutionError)>, - debug: &DebugInfo, - context: &Context, -) { - if let Some((opcode_location, opcode_err)) = opcode_err_info { - if let Some(locations) = debug.opcode_location(&opcode_location) { - // The location of the error itself will be the location at the top - // of the call stack (the last item in the Vec). - if let Some(location) = locations.last() { - let message = match opcode_err { - acvm::pwg::OpcodeResolutionError::IndexOutOfBounds { - index, - array_size, - .. - } => { - format!( - "Index out of bounds, array has size {array_size:?}, but index was {index:?}" - ) - } - acvm::pwg::OpcodeResolutionError::UnsatisfiedConstrain { .. } => { - "Failed constraint".into() - } - _ => { - // All other errors that do not have corresponding opcode locations - // should not be reported in this method. - // If an error with an opcode location is not handled in this match statement - // the basic message attached to the original error from the ACVM should be reported. - return; - } - }; - CustomDiagnostic::simple_error(message, String::new(), location.span) - .in_file(location.file) - .with_call_stack(locations) - .report(&context.file_manager, false); - } - } - } -} - -pub(crate) fn execute_program( - backend: &B, - circuit: Circuit, - abi: &Abi, - inputs_map: &InputMap, - debug_data: Option<(DebugInfo, Context)>, -) -> Result> { - let initial_witness = abi.encode(inputs_map, None)?; - let solved_witness_err = nargo::ops::execute_circuit(backend, circuit, initial_witness, true); - match solved_witness_err { - Ok(solved_witness) => Ok(solved_witness), - Err(err) => { - if let Some((debug, context)) = debug_data { - let opcode_err_info = extract_opcode_error_from_nargo_error(&err); - report_error_with_opcode_location(opcode_err_info, &debug, &context); - } - - Err(crate::errors::CliError::NargoError(err)) - } - } -} diff --git a/crates/nargo_cli/src/cli/fs/common_reference_string.rs b/crates/nargo_cli/src/cli/fs/common_reference_string.rs deleted file mode 100644 index a22c819d402..00000000000 --- a/crates/nargo_cli/src/cli/fs/common_reference_string.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::{env, path::PathBuf}; - -use acvm::{acir::circuit::Circuit, CommonReferenceString}; - -use super::{create_named_dir, write_to_file}; - -// TODO(#1388): pull this from backend. -const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; -const TRANSCRIPT_NAME: &str = "common-reference-string.bin"; - -fn common_reference_string_location() -> PathBuf { - let cache_dir = match env::var("NARGO_BACKEND_CACHE_DIR") { - Ok(cache_dir) => PathBuf::from(cache_dir), - Err(_) => dirs::home_dir().unwrap().join(".nargo").join("backends"), - }; - cache_dir.join(BACKEND_IDENTIFIER).join(TRANSCRIPT_NAME) -} - -pub(crate) fn read_cached_common_reference_string() -> Vec { - let crs_path = common_reference_string_location(); - - // TODO(#1390): Implement checksum - match std::fs::read(crs_path) { - Ok(common_reference_string) => common_reference_string, - Err(_) => vec![], - } -} - -pub(crate) fn update_common_reference_string( - backend: &B, - common_reference_string: &[u8], - circuit: &Circuit, -) -> Result, B::Error> { - use tokio::runtime::Builder; - - let runtime = Builder::new_current_thread().enable_all().build().unwrap(); - - // TODO(#1391): Implement retries - // If the read data is empty, we don't have a CRS and need to generate one - let fut = if common_reference_string.is_empty() { - backend.generate_common_reference_string(circuit) - } else { - backend.update_common_reference_string(common_reference_string.to_vec(), circuit) - }; - - runtime.block_on(fut) -} - -pub(crate) fn write_cached_common_reference_string(common_reference_string: &[u8]) { - let crs_path = common_reference_string_location(); - - create_named_dir(crs_path.parent().unwrap(), "crs"); - - write_to_file(common_reference_string, &crs_path); -} diff --git a/crates/nargo_cli/src/cli/fs/mod.rs b/crates/nargo_cli/src/cli/fs/mod.rs deleted file mode 100644 index 73229e0476c..00000000000 --- a/crates/nargo_cli/src/cli/fs/mod.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::{ - fs::File, - io::Write, - path::{Path, PathBuf}, -}; - -use crate::errors::FilesystemError; - -pub(super) mod common_reference_string; -pub(super) mod inputs; -pub(super) mod program; -pub(super) mod proof; -pub(super) mod witness; - -pub(super) fn create_named_dir(named_dir: &Path, name: &str) -> PathBuf { - std::fs::create_dir_all(named_dir) - .unwrap_or_else(|_| panic!("could not create the `{name}` directory")); - - PathBuf::from(named_dir) -} - -pub(super) fn write_to_file(bytes: &[u8], path: &Path) -> String { - let display = path.display(); - - let mut file = match File::create(path) { - Err(why) => panic!("couldn't create {display}: {why}"), - Ok(file) => file, - }; - - match file.write_all(bytes) { - Err(why) => panic!("couldn't write to {display}: {why}"), - Ok(_) => display.to_string(), - } -} - -pub(super) fn load_hex_data>(path: P) -> Result, FilesystemError> { - let hex_data: Vec<_> = std::fs::read(&path) - .map_err(|_| FilesystemError::PathNotValid(path.as_ref().to_path_buf()))?; - - let raw_bytes = hex::decode(hex_data).map_err(FilesystemError::HexArtifactNotValid)?; - - Ok(raw_bytes) -} diff --git a/crates/nargo_cli/src/cli/fs/program.rs b/crates/nargo_cli/src/cli/fs/program.rs deleted file mode 100644 index 3f7107de667..00000000000 --- a/crates/nargo_cli/src/cli/fs/program.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::path::{Path, PathBuf}; - -use nargo::artifacts::{ - contract::PreprocessedContract, debug::DebugArtifact, program::PreprocessedProgram, -}; -use noirc_frontend::graph::CrateName; - -use crate::errors::FilesystemError; - -use super::{create_named_dir, write_to_file}; - -pub(crate) fn save_program_to_file>( - compiled_program: &PreprocessedProgram, - crate_name: &CrateName, - circuit_dir: P, -) -> PathBuf { - let circuit_name: String = crate_name.into(); - save_build_artifact_to_file(compiled_program, &circuit_name, circuit_dir) -} - -pub(crate) fn save_contract_to_file>( - compiled_contract: &PreprocessedContract, - circuit_name: &str, - circuit_dir: P, -) -> PathBuf { - save_build_artifact_to_file(compiled_contract, circuit_name, circuit_dir) -} - -pub(crate) fn save_debug_artifact_to_file>( - debug_artifact: &DebugArtifact, - circuit_name: &str, - circuit_dir: P, -) -> PathBuf { - let artifact_name = format!("debug_{}", circuit_name); - save_build_artifact_to_file(debug_artifact, &artifact_name, circuit_dir) -} - -fn save_build_artifact_to_file, T: ?Sized + serde::Serialize>( - build_artifact: &T, - artifact_name: &str, - circuit_dir: P, -) -> PathBuf { - create_named_dir(circuit_dir.as_ref(), "target"); - let circuit_path = circuit_dir.as_ref().join(artifact_name).with_extension("json"); - - write_to_file(&serde_json::to_vec(build_artifact).unwrap(), &circuit_path); - - circuit_path -} - -pub(crate) fn read_program_from_file>( - circuit_path: P, -) -> Result { - let file_path = circuit_path.as_ref().with_extension("json"); - - let input_string = - std::fs::read(&file_path).map_err(|_| FilesystemError::PathNotValid(file_path))?; - - let program = serde_json::from_slice(&input_string).expect("could not deserialize program"); - - Ok(program) -} diff --git a/crates/nargo_cli/src/cli/info_cmd.rs b/crates/nargo_cli/src/cli/info_cmd.rs deleted file mode 100644 index a761c376973..00000000000 --- a/crates/nargo_cli/src/cli/info_cmd.rs +++ /dev/null @@ -1,144 +0,0 @@ -use acvm::Backend; -use clap::Args; -use iter_extended::try_vecmap; -use nargo::{package::Package, prepare_package}; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_driver::{compile_contracts, CompileOptions}; -use noirc_frontend::graph::CrateName; -use prettytable::{row, Table}; - -use crate::{cli::compile_cmd::compile_package, errors::CliError}; - -use super::{ - compile_cmd::{optimize_contract, report_errors}, - NargoConfig, -}; - -/// Provides detailed information on a circuit -/// -/// Current information provided: -/// 1. The number of ACIR opcodes -/// 2. Counts the final number gates in the circuit used by a backend -#[derive(Debug, Clone, Args)] -pub(crate) struct InfoCommand { - /// The name of the package to detail - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Detail all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &B, - args: InfoCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml(&toml_path, selection)?; - - let mut package_table = Table::new(); - package_table.add_row( - row![Fm->"Package", Fm->"Language", Fm->"ACIR Opcodes", Fm->"Backend Circuit Size"], - ); - let mut contract_table = Table::new(); - contract_table.add_row(row![ - Fm->"Contract", - Fm->"Function", - Fm->"Language", - Fm->"ACIR Opcodes", - Fm->"Backend Circuit Size" - ]); - - for package in &workspace { - if package.is_contract() { - count_opcodes_and_gates_in_contracts( - backend, - package, - &args.compile_options, - &mut contract_table, - )?; - } else { - count_opcodes_and_gates_in_package( - backend, - package, - &args.compile_options, - &mut package_table, - )?; - } - } - - if package_table.len() > 1 { - package_table.printstd(); - } - if contract_table.len() > 1 { - contract_table.printstd(); - } - - Ok(()) -} - -fn count_opcodes_and_gates_in_package( - backend: &B, - package: &Package, - compile_options: &CompileOptions, - table: &mut Table, -) -> Result<(), CliError> { - let (_, compiled_program) = compile_package(backend, package, compile_options)?; - - let num_opcodes = compiled_program.circuit.opcodes.len(); - let exact_circuit_size = backend - .get_exact_circuit_size(&compiled_program.circuit) - .map_err(CliError::ProofSystemCompilerError)?; - - table.add_row(row![ - Fm->format!("{}", package.name), - format!("{:?}", backend.np_language()), - Fc->format!("{}", num_opcodes), - Fc->format!("{}", exact_circuit_size), - ]); - - Ok(()) -} - -fn count_opcodes_and_gates_in_contracts( - backend: &B, - package: &Package, - compile_options: &CompileOptions, - table: &mut Table, -) -> Result<(), CliError> { - let (mut context, crate_id) = prepare_package(package); - let result = compile_contracts(&mut context, crate_id, compile_options); - let contracts = report_errors(result, &context, compile_options.deny_warnings)?; - let optimized_contracts = - try_vecmap(contracts, |contract| optimize_contract(backend, contract))?; - - for contract in optimized_contracts { - let function_info: Vec<(String, usize, u32)> = try_vecmap(contract.functions, |function| { - let num_opcodes = function.bytecode.opcodes.len(); - let exact_circuit_size = backend.get_exact_circuit_size(&function.bytecode)?; - - Ok((function.name, num_opcodes, exact_circuit_size)) - }) - .map_err(CliError::ProofSystemCompilerError)?; - - for info in function_info { - table.add_row(row![ - Fm->format!("{}", contract.name), - Fc->format!("{}", info.0), - format!("{:?}", backend.np_language()), - Fc->format!("{}", info.1), - Fc->format!("{}", info.2), - ]); - } - } - - Ok(()) -} diff --git a/crates/nargo_cli/src/cli/mod.rs b/crates/nargo_cli/src/cli/mod.rs deleted file mode 100644 index 2603db3ce19..00000000000 --- a/crates/nargo_cli/src/cli/mod.rs +++ /dev/null @@ -1,94 +0,0 @@ -use clap::{Args, Parser, Subcommand}; -use const_format::formatcp; -use nargo_toml::find_package_root; -use std::path::PathBuf; - -use color_eyre::eyre; - -mod fs; - -mod check_cmd; -mod codegen_verifier_cmd; -mod compile_cmd; -mod execute_cmd; -mod info_cmd; -mod init_cmd; -mod lsp_cmd; -mod new_cmd; -mod prove_cmd; -mod test_cmd; -mod verify_cmd; - -const GIT_HASH: &str = env!("GIT_COMMIT"); -const IS_DIRTY: &str = env!("GIT_DIRTY"); -const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); - -static VERSION_STRING: &str = - formatcp!("{} (git version hash: {}, is dirty: {})", CARGO_PKG_VERSION, GIT_HASH, IS_DIRTY); - -#[derive(Parser, Debug)] -#[command(name="nargo", author, version=VERSION_STRING, about, long_about = None)] -struct NargoCli { - #[command(subcommand)] - command: NargoCommand, - - #[clap(flatten)] - config: NargoConfig, -} - -#[non_exhaustive] -#[derive(Args, Clone, Debug)] -pub(crate) struct NargoConfig { - // REMINDER: Also change this flag in the LSP test lens if renamed - #[arg(long, hide = true, global = true, default_value = "./")] - program_dir: PathBuf, -} - -#[non_exhaustive] -#[derive(Subcommand, Clone, Debug)] -enum NargoCommand { - Check(check_cmd::CheckCommand), - CodegenVerifier(codegen_verifier_cmd::CodegenVerifierCommand), - #[command(alias = "build")] - Compile(compile_cmd::CompileCommand), - New(new_cmd::NewCommand), - Init(init_cmd::InitCommand), - Execute(execute_cmd::ExecuteCommand), - Prove(prove_cmd::ProveCommand), - Verify(verify_cmd::VerifyCommand), - Test(test_cmd::TestCommand), - Info(info_cmd::InfoCommand), - Lsp(lsp_cmd::LspCommand), -} - -pub(crate) fn start_cli() -> eyre::Result<()> { - let NargoCli { command, mut config } = NargoCli::parse(); - - // If the provided `program_dir` is relative, make it absolute by joining it to the current directory. - if !config.program_dir.is_absolute() { - config.program_dir = std::env::current_dir().unwrap().join(config.program_dir); - } - - // Search through parent directories to find package root if necessary. - if !matches!(command, NargoCommand::New(_) | NargoCommand::Init(_) | NargoCommand::Lsp(_)) { - config.program_dir = find_package_root(&config.program_dir)?; - } - - let backend = crate::backends::ConcreteBackend::default(); - - match command { - NargoCommand::New(args) => new_cmd::run(&backend, args, config), - NargoCommand::Init(args) => init_cmd::run(&backend, args, config), - NargoCommand::Check(args) => check_cmd::run(&backend, args, config), - NargoCommand::Compile(args) => compile_cmd::run(&backend, args, config), - NargoCommand::Execute(args) => execute_cmd::run(&backend, args, config), - NargoCommand::Prove(args) => prove_cmd::run(&backend, args, config), - NargoCommand::Verify(args) => verify_cmd::run(&backend, args, config), - NargoCommand::Test(args) => test_cmd::run(&backend, args, config), - NargoCommand::Info(args) => info_cmd::run(&backend, args, config), - NargoCommand::CodegenVerifier(args) => codegen_verifier_cmd::run(&backend, args, config), - NargoCommand::Lsp(args) => lsp_cmd::run(&backend, args, config), - }?; - - Ok(()) -} diff --git a/crates/nargo_cli/src/cli/prove_cmd.rs b/crates/nargo_cli/src/cli/prove_cmd.rs deleted file mode 100644 index e4766828a5b..00000000000 --- a/crates/nargo_cli/src/cli/prove_cmd.rs +++ /dev/null @@ -1,167 +0,0 @@ -use std::path::{Path, PathBuf}; - -use acvm::Backend; -use clap::Args; -use nargo::artifacts::program::PreprocessedProgram; -use nargo::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE}; -use nargo::ops::{preprocess_program, prove_execution, verify_proof}; -use nargo::package::Package; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_abi::input_parser::Format; -use noirc_driver::CompileOptions; -use noirc_frontend::graph::CrateName; - -use super::compile_cmd::compile_package; -use super::fs::{ - common_reference_string::{ - read_cached_common_reference_string, update_common_reference_string, - write_cached_common_reference_string, - }, - inputs::{read_inputs_from_file, write_inputs_to_file}, - program::read_program_from_file, - proof::save_proof_to_dir, -}; -use super::NargoConfig; -use crate::{cli::execute_cmd::execute_program, errors::CliError}; - -/// Create proof for this program. The proof is returned as a hex encoded string. -#[derive(Debug, Clone, Args)] -pub(crate) struct ProveCommand { - /// The name of the toml file which contains the inputs for the prover - #[clap(long, short, default_value = PROVER_INPUT_FILE)] - prover_name: String, - - /// The name of the toml file which contains the inputs for the verifier - #[clap(long, short, default_value = VERIFIER_INPUT_FILE)] - verifier_name: String, - - /// Verify proof after proving - #[arg(long)] - verify: bool, - - /// The name of the package to prove - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Prove all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &B, - args: ProveCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml(&toml_path, selection)?; - let proof_dir = workspace.proofs_directory_path(); - - for package in &workspace { - let circuit_build_path = workspace.package_build_path(package); - - prove_package( - backend, - package, - &args.prover_name, - &args.verifier_name, - &proof_dir, - circuit_build_path, - args.verify, - &args.compile_options, - )?; - } - - Ok(()) -} - -#[allow(clippy::too_many_arguments)] -pub(crate) fn prove_package( - backend: &B, - package: &Package, - prover_name: &str, - verifier_name: &str, - proof_dir: &Path, - circuit_build_path: PathBuf, - check_proof: bool, - compile_options: &CompileOptions, -) -> Result<(), CliError> { - let common_reference_string = read_cached_common_reference_string(); - - let (common_reference_string, preprocessed_program, debug_data) = if circuit_build_path.exists() - { - let program = read_program_from_file(circuit_build_path)?; - let common_reference_string = - update_common_reference_string(backend, &common_reference_string, &program.bytecode) - .map_err(CliError::CommonReferenceStringError)?; - (common_reference_string, program, None) - } else { - let (context, program) = compile_package(backend, package, compile_options)?; - let common_reference_string = - update_common_reference_string(backend, &common_reference_string, &program.circuit) - .map_err(CliError::CommonReferenceStringError)?; - let (program, debug) = preprocess_program(backend, true, &common_reference_string, program) - .map_err(CliError::ProofSystemCompilerError)?; - (common_reference_string, program, Some((debug, context))) - }; - - write_cached_common_reference_string(&common_reference_string); - - let PreprocessedProgram { abi, bytecode, proving_key, verification_key, .. } = - preprocessed_program; - - // Parse the initial witness values from Prover.toml - let (inputs_map, _) = - read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &abi)?; - - let solved_witness = execute_program(backend, bytecode.clone(), &abi, &inputs_map, debug_data)?; - - // Write public inputs into Verifier.toml - let public_abi = abi.public_abi(); - let (public_inputs, return_value) = public_abi.decode(&solved_witness)?; - - write_inputs_to_file( - &public_inputs, - &return_value, - &public_abi, - &package.root_dir, - verifier_name, - Format::Toml, - )?; - - let proving_key = - proving_key.expect("Proving key should exist as `true` is passed to `preprocess_program`"); - - let proof = - prove_execution(backend, &common_reference_string, &bytecode, solved_witness, &proving_key) - .map_err(CliError::ProofSystemCompilerError)?; - - if check_proof { - let public_inputs = public_abi.encode(&public_inputs, return_value)?; - let verification_key = verification_key - .expect("Verification key should exist as `true` is passed to `preprocess_program`"); - let valid_proof = verify_proof( - backend, - &common_reference_string, - &bytecode, - &proof, - public_inputs, - &verification_key, - ) - .map_err(CliError::ProofSystemCompilerError)?; - - if !valid_proof { - return Err(CliError::InvalidProof("".into())); - } - } - - save_proof_to_dir(&proof, &String::from(&package.name), proof_dir)?; - - Ok(()) -} diff --git a/crates/nargo_cli/src/cli/test_cmd.rs b/crates/nargo_cli/src/cli/test_cmd.rs deleted file mode 100644 index 94c8ff86dcd..00000000000 --- a/crates/nargo_cli/src/cli/test_cmd.rs +++ /dev/null @@ -1,152 +0,0 @@ -use std::io::Write; - -use acvm::{acir::native_types::WitnessMap, Backend}; -use clap::Args; -use nargo::{ops::execute_circuit, package::Package, prepare_package}; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_driver::{compile_no_check, CompileOptions}; -use noirc_frontend::{ - graph::CrateName, - hir::{Context, FunctionNameMatch}, - node_interner::FuncId, -}; -use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; - -use crate::{cli::check_cmd::check_crate_and_report_errors, errors::CliError}; - -use super::{compile_cmd::optimize_circuit, NargoConfig}; - -/// Run the tests for this program -#[derive(Debug, Clone, Args)] -pub(crate) struct TestCommand { - /// If given, only tests with names containing this string will be run - test_name: Option, - - /// Display output of `println` statements - #[arg(long)] - show_output: bool, - - /// Only run tests that match exactly - #[clap(long)] - exact: bool, - - /// The name of the package to test - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Test all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &B, - args: TestCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml(&toml_path, selection)?; - - let pattern = match &args.test_name { - Some(name) => { - if args.exact { - FunctionNameMatch::Exact(name) - } else { - FunctionNameMatch::Contains(name) - } - } - None => FunctionNameMatch::Anything, - }; - - for package in &workspace { - run_tests(backend, package, pattern, args.show_output, &args.compile_options)?; - } - - Ok(()) -} - -fn run_tests( - backend: &B, - package: &Package, - test_name: FunctionNameMatch, - show_output: bool, - compile_options: &CompileOptions, -) -> Result<(), CliError> { - let (mut context, crate_id) = prepare_package(package); - check_crate_and_report_errors(&mut context, crate_id, compile_options.deny_warnings)?; - - let test_functions = context.get_all_test_functions_in_crate_matching(&crate_id, test_name); - - println!("[{}] Running {} test functions", package.name, test_functions.len()); - let mut failing = 0; - - let writer = StandardStream::stderr(ColorChoice::Always); - let mut writer = writer.lock(); - - for (test_name, test_function) in test_functions { - write!(writer, "[{}] Testing {test_name}... ", package.name) - .expect("Failed to write to stdout"); - writer.flush().expect("Failed to flush writer"); - - match run_test(backend, &test_name, test_function, &context, show_output, compile_options) { - Ok(_) => { - writer - .set_color(ColorSpec::new().set_fg(Some(Color::Green))) - .expect("Failed to set color"); - writeln!(writer, "ok").expect("Failed to write to stdout"); - } - // Assume an error was already printed to stdout - Err(_) => failing += 1, - } - writer.reset().expect("Failed to reset writer"); - } - - if failing == 0 { - write!(writer, "[{}] ", package.name).expect("Failed to write to stdout"); - writer.set_color(ColorSpec::new().set_fg(Some(Color::Green))).expect("Failed to set color"); - writeln!(writer, "All tests passed").expect("Failed to write to stdout"); - } else { - let plural = if failing == 1 { "" } else { "s" }; - return Err(CliError::Generic(format!("[{}] {failing} test{plural} failed", package.name))); - } - - writer.reset().expect("Failed to reset writer"); - Ok(()) -} - -fn run_test( - backend: &B, - test_name: &str, - main: FuncId, - context: &Context, - show_output: bool, - config: &CompileOptions, -) -> Result<(), CliError> { - let mut program = compile_no_check(context, config, main).map_err(|err| { - noirc_errors::reporter::report_all(&context.file_manager, &[err], config.deny_warnings); - CliError::Generic(format!("Test '{test_name}' failed to compile")) - })?; - - // Note: We could perform this test using the unoptimized ACIR as generated by `compile_no_check`. - program.circuit = optimize_circuit(backend, program.circuit).unwrap().0; - - // Run the backend to ensure the PWG evaluates functions like std::hash::pedersen, - // otherwise constraints involving these expressions will not error. - match execute_circuit(backend, program.circuit, WitnessMap::new(), show_output) { - Ok(_) => Ok(()), - Err(error) => { - let writer = StandardStream::stderr(ColorChoice::Always); - let mut writer = writer.lock(); - writer.set_color(ColorSpec::new().set_fg(Some(Color::Red))).ok(); - writeln!(writer, "failed").ok(); - writer.reset().ok(); - Err(error.into()) - } - } -} diff --git a/crates/nargo_cli/src/cli/verify_cmd.rs b/crates/nargo_cli/src/cli/verify_cmd.rs deleted file mode 100644 index c2f21a2123b..00000000000 --- a/crates/nargo_cli/src/cli/verify_cmd.rs +++ /dev/null @@ -1,131 +0,0 @@ -use super::NargoConfig; -use super::{ - compile_cmd::compile_package, - fs::{ - common_reference_string::{ - read_cached_common_reference_string, update_common_reference_string, - write_cached_common_reference_string, - }, - inputs::read_inputs_from_file, - load_hex_data, - program::read_program_from_file, - }, -}; -use crate::errors::CliError; - -use acvm::Backend; -use clap::Args; -use nargo::constants::{PROOF_EXT, VERIFIER_INPUT_FILE}; -use nargo::ops::{preprocess_program, verify_proof}; -use nargo::{artifacts::program::PreprocessedProgram, package::Package}; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_abi::input_parser::Format; -use noirc_driver::CompileOptions; -use noirc_frontend::graph::CrateName; -use std::path::{Path, PathBuf}; - -/// Given a proof and a program, verify whether the proof is valid -#[derive(Debug, Clone, Args)] -pub(crate) struct VerifyCommand { - /// The name of the toml file which contains the inputs for the verifier - #[clap(long, short, default_value = VERIFIER_INPUT_FILE)] - verifier_name: String, - - /// The name of the package verify - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Verify all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &B, - args: VerifyCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml(&toml_path, selection)?; - let proofs_dir = workspace.proofs_directory_path(); - - for package in &workspace { - let circuit_build_path = workspace.package_build_path(package); - - let proof_path = proofs_dir.join(String::from(&package.name)).with_extension(PROOF_EXT); - - verify_package( - backend, - package, - &proof_path, - circuit_build_path, - &args.verifier_name, - &args.compile_options, - )?; - } - - Ok(()) -} - -fn verify_package( - backend: &B, - package: &Package, - proof_path: &Path, - circuit_build_path: PathBuf, - verifier_name: &str, - compile_options: &CompileOptions, -) -> Result<(), CliError> { - let common_reference_string = read_cached_common_reference_string(); - - let (common_reference_string, preprocessed_program) = if circuit_build_path.exists() { - let program = read_program_from_file(circuit_build_path)?; - let common_reference_string = - update_common_reference_string(backend, &common_reference_string, &program.bytecode) - .map_err(CliError::CommonReferenceStringError)?; - (common_reference_string, program) - } else { - let (_, program) = compile_package(backend, package, compile_options)?; - let common_reference_string = - update_common_reference_string(backend, &common_reference_string, &program.circuit) - .map_err(CliError::CommonReferenceStringError)?; - let (program, _) = preprocess_program(backend, true, &common_reference_string, program) - .map_err(CliError::ProofSystemCompilerError)?; - (common_reference_string, program) - }; - - write_cached_common_reference_string(&common_reference_string); - - let PreprocessedProgram { abi, bytecode, verification_key, .. } = preprocessed_program; - - // Load public inputs (if any) from `verifier_name`. - let public_abi = abi.public_abi(); - let (public_inputs_map, return_value) = - read_inputs_from_file(&package.root_dir, verifier_name, Format::Toml, &public_abi)?; - - let public_inputs = public_abi.encode(&public_inputs_map, return_value)?; - let proof = load_hex_data(proof_path)?; - - let verification_key = verification_key - .expect("Verification key should exist as `true` is passed to `preprocess_program`"); - let valid_proof = verify_proof( - backend, - &common_reference_string, - &bytecode, - &proof, - public_inputs, - &verification_key, - ) - .map_err(CliError::ProofSystemCompilerError)?; - - if valid_proof { - Ok(()) - } else { - Err(CliError::InvalidProof(proof_path.to_path_buf())) - } -} diff --git a/crates/nargo_cli/src/errors.rs b/crates/nargo_cli/src/errors.rs deleted file mode 100644 index dade4262431..00000000000 --- a/crates/nargo_cli/src/errors.rs +++ /dev/null @@ -1,102 +0,0 @@ -use acvm::{ - acir::native_types::WitnessMapError, Backend, CommonReferenceString, ProofSystemCompiler, - SmartContract, -}; -use hex::FromHexError; -use nargo::NargoError; -use nargo_toml::ManifestError; -use noirc_abi::errors::{AbiError, InputParserError}; -use noirc_errors::reporter::ReportedErrors; -use noirc_frontend::graph::CrateName; -use std::path::PathBuf; -use thiserror::Error; - -#[derive(Debug, Error)] -pub(crate) enum FilesystemError { - #[error("Error: {} is not a valid path\nRun either `nargo compile` to generate missing build artifacts or `nargo prove` to construct a proof", .0.display())] - PathNotValid(PathBuf), - #[error("Error: could not parse hex build artifact (proof, proving and/or verification keys, ACIR checksum) ({0})")] - HexArtifactNotValid(FromHexError), - #[error( - " Error: cannot find {0}.toml file.\n Expected location: {1:?} \n Please generate this file at the expected location." - )] - MissingTomlFile(String, PathBuf), - - /// Input parsing error - #[error(transparent)] - InputParserError(#[from] InputParserError), - - /// WitnessMap serialization error - #[error(transparent)] - WitnessMapSerialization(#[from] WitnessMapError), -} - -#[derive(Debug, Error)] -pub(crate) enum CliError { - #[error("{0}")] - Generic(String), - #[error("Error: destination {} already exists", .0.display())] - DestinationAlreadyExists(PathBuf), - - #[error("Failed to verify proof {}", .0.display())] - InvalidProof(PathBuf), - - #[error("Invalid package name {0}. Did you mean to use `--name`?")] - InvalidPackageName(String), - - /// ABI encoding/decoding error - #[error(transparent)] - AbiError(#[from] AbiError), - - /// Filesystem errors - #[error(transparent)] - FilesystemError(#[from] FilesystemError), - - #[error(transparent)] - LspError(#[from] async_lsp::Error), - - /// Error from Nargo - #[error(transparent)] - NargoError(#[from] NargoError), - - /// Error from Manifest - #[error(transparent)] - ManifestError(#[from] ManifestError), - - /// Error from the compilation pipeline - #[error(transparent)] - CompileError(#[from] CompileError), - - /// Backend error caused by a function on the SmartContract trait - #[error(transparent)] - SmartContractError(::Error), // Unfortunately, Rust won't let us `impl From` over an Associated Type on a generic - - /// Backend error caused by a function on the ProofSystemCompiler trait - #[error(transparent)] - ProofSystemCompilerError(::Error), // Unfortunately, Rust won't let us `impl From` over an Associated Type on a generic - - /// Backend error caused by a function on the CommonReferenceString trait - #[error(transparent)] - CommonReferenceStringError(::Error), // Unfortunately, Rust won't let us `impl From` over an Associated Type on a generic -} - -/// Errors covering situations where a package cannot be compiled. -#[derive(Debug, Error)] -pub(crate) enum CompileError { - #[error("Package `{0}` has type `lib` but only `bin` types can be compiled")] - LibraryCrate(CrateName), - - #[error("Package `{0}` is expected to have a `main` function but it does not")] - MissingMainFunction(CrateName), - - /// Errors encountered while compiling the Noir program. - /// These errors are already written to stderr. - #[error("Aborting due to {} previous error{}", .0.error_count, if .0.error_count == 1 { "" } else { "s" })] - ReportedErrors(ReportedErrors), -} - -impl From for CompileError { - fn from(errors: ReportedErrors) -> Self { - Self::ReportedErrors(errors) - } -} diff --git a/crates/nargo_cli/src/main.rs b/crates/nargo_cli/src/main.rs deleted file mode 100644 index 734dbdca2e7..00000000000 --- a/crates/nargo_cli/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![forbid(unsafe_code)] -#![warn(unused_extern_crates)] -#![warn(unreachable_pub)] -#![warn(clippy::semicolon_if_nothing_returned)] - -//! Nargo is the package manager for Noir -//! This name was used because it sounds like `cargo` and -//! Noir Package Manager abbreviated is npm, which is already taken. - -mod backends; -mod cli; -mod errors; - -use color_eyre::{config::HookBuilder, eyre}; - -const PANIC_MESSAGE: &str = "This is a bug. We may have already fixed this in newer versions of Nargo so try searching for similar issues at https://github.com/noir-lang/noir/issues/.\nIf there isn't an open issue for this bug, consider opening one at https://github.com/noir-lang/noir/issues/new?labels=bug&template=bug_report.yml"; - -fn main() -> eyre::Result<()> { - // Register a panic hook to display more readable panic messages to end-users - let (panic_hook, _) = - HookBuilder::default().display_env_section(false).panic_section(PANIC_MESSAGE).into_hooks(); - panic_hook.install(); - - cli::start_cli() -} diff --git a/crates/nargo_cli/tests/compile_failure/brillig_assert_fail/src/main.nr b/crates/nargo_cli/tests/compile_failure/brillig_assert_fail/src/main.nr deleted file mode 100644 index 320369c7b67..00000000000 --- a/crates/nargo_cli/tests/compile_failure/brillig_assert_fail/src/main.nr +++ /dev/null @@ -1,11 +0,0 @@ -// Tests a very simple program. -// -// The features being tested is using assert on brillig -fn main(x: Field) { - assert(1 == conditional(x as bool)); -} - -unconstrained fn conditional(x : bool) -> Field { - assert(x); - 1 -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_to_bits/src/main.nr b/crates/nargo_cli/tests/compile_success_empty/brillig_to_bits/src/main.nr deleted file mode 100644 index 65b0e5ca86c..00000000000 --- a/crates/nargo_cli/tests/compile_success_empty/brillig_to_bits/src/main.nr +++ /dev/null @@ -1,24 +0,0 @@ -use dep::std; - -unconstrained fn main() { - let field = 1000; - let be_bits = field.to_be_bits(16); - let le_bits = field.to_le_bits(16); - - for i in 0..16 { - let x = be_bits[i]; - let y = le_bits[15-i]; - assert(x == y); - } - - let x = 3; - let be_bits_x = x.to_be_bits(4); - let le_bits_x = x.to_le_bits(4); - - for i in 0..4 { - let be_bit = be_bits_x[i]; - let le_bit = le_bits_x[3-i]; - assert(be_bit == le_bit); - } - -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_success_empty/closure_explicit_types/src/main.nr b/crates/nargo_cli/tests/compile_success_empty/closure_explicit_types/src/main.nr deleted file mode 100644 index 1db36dcdd77..00000000000 --- a/crates/nargo_cli/tests/compile_success_empty/closure_explicit_types/src/main.nr +++ /dev/null @@ -1,60 +0,0 @@ - -fn ret_normal_lambda1() -> fn() -> Field { - || 10 -} - -// explicitly specified empty capture group -fn ret_normal_lambda2() -> fn[]() -> Field { - || 20 -} - -// return lamda that captures a thing -fn ret_closure1() -> fn[Field]() -> Field { - let x = 20; - || x + 10 -} - -// return lamda that captures two things -fn ret_closure2() -> fn[Field,Field]() -> Field { - let x = 20; - let y = 10; - || x + y + 10 -} - -// return lamda that captures two things with different types -fn ret_closure3() -> fn[u32,u64]() -> u64 { - let x: u32 = 20; - let y: u64 = 10; - || x as u64 + y + 10 -} - -// accepts closure that has 1 thing in its env, calls it and returns the result -fn accepts_closure1(f: fn[Field]() -> Field) -> Field { - f() -} - -// accepts closure that has 1 thing in its env and returns it -fn accepts_closure2(f: fn[Field]() -> Field) -> fn[Field]() -> Field { - f -} - -// accepts closure with different types in the capture group -fn accepts_closure3(f: fn[u32, u64]() -> u64) -> u64 { - f() -} - -fn main() { - assert(ret_normal_lambda1()() == 10); - assert(ret_normal_lambda2()() == 20); - assert(ret_closure1()() == 30); - assert(ret_closure2()() == 40); - assert(ret_closure3()() == 40); - - let x = 50; - assert(accepts_closure1(|| x) == 50); - assert(accepts_closure2(|| x + 10)() == 60); - - let y: u32 = 30; - let z: u64 = 40; - assert(accepts_closure3(|| y as u64 + z) == 70); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_success_empty/comptime_sort/src/main.nr b/crates/nargo_cli/tests/compile_success_empty/comptime_sort/src/main.nr deleted file mode 100644 index 72b05044331..00000000000 --- a/crates/nargo_cli/tests/compile_success_empty/comptime_sort/src/main.nr +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let unsorted: [u8; 3] = [3,1,2]; - let sorted = unsorted.sort(); - assert(sorted[0] == 1); - assert(sorted[1] == 2); - assert(sorted[2] == 3); -} diff --git a/crates/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/src/main.nr b/crates/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/src/main.nr deleted file mode 100644 index 767cff0c409..00000000000 --- a/crates/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/src/main.nr +++ /dev/null @@ -1,39 +0,0 @@ -use dep::std; - -fn g(x: &mut Field) -> () { - *x *= 2; -} - -fn h(x: &mut Field) -> () { - *x *= 3; -} - -fn selector(flag: &mut bool) -> fn(&mut Field) -> () { - let my_func = if *flag { - g - } else { - h - }; - - // Flip the flag for the next function call - *flag = !(*flag); - my_func -} - -fn main() { - - let mut flag: bool = true; - - let mut x: Field = 100; - let returned_func = selector(&mut flag); - returned_func(&mut x); - - assert(x == 200); - - let mut y: Field = 100; - let returned_func2 = selector(&mut flag); - returned_func2(&mut y); - - assert(y == 300); - -} diff --git a/crates/nargo_cli/tests/compile_success_empty/intrinsic_die/src/main.nr b/crates/nargo_cli/tests/compile_success_empty/intrinsic_die/src/main.nr deleted file mode 100644 index 2762baf929c..00000000000 --- a/crates/nargo_cli/tests/compile_success_empty/intrinsic_die/src/main.nr +++ /dev/null @@ -1,11 +0,0 @@ -use dep::std; - -// This test checks that we perform dead-instruction-elimination on intrinsic functions. - -fn main(x: Field) { - let bytes = x.to_be_bytes(32); - - let hash = std::hash::pedersen([x]); - let _p1 = std::scalar_mul::fixed_base(x); - -} diff --git a/crates/nargo_cli/tests/compile_success_empty/option/src/main.nr b/crates/nargo_cli/tests/compile_success_empty/option/src/main.nr deleted file mode 100644 index 0a41b9a629c..00000000000 --- a/crates/nargo_cli/tests/compile_success_empty/option/src/main.nr +++ /dev/null @@ -1,53 +0,0 @@ -use dep::std::option::Option; - -fn main() { - let none = Option::none(); - let some = Option::some(3); - - assert(none.is_none()); - assert(some.is_some()); - - assert(some.unwrap() == 3); - - assert(none.unwrap_or(2) == 2); - assert(some.unwrap_or(2) == 3); - - assert(none.unwrap_or_else(|| 5) == 5); - assert(some.unwrap_or_else(|| 5) == 3); - - assert(none.map(|x| x * 2).is_none()); - assert(some.map(|x| x * 2).unwrap() == 6); - - assert(none.map_or(0, |x| x * 2) == 0); - assert(some.map_or(0, |x| x * 2) == 6); - - assert(none.map_or_else(|| 0, |x| x * 2) == 0); - assert(some.map_or_else(|| 0, |x| x * 2) == 6); - - assert(none.and(none).is_none()); - assert(none.and(some).is_none()); - assert(some.and(none).is_none()); - assert(some.and(some).is_some()); - - let add1_u64 = |value: Field| Option::some(value as u64 + 1); - - assert(none.and_then(|_value| Option::none()).is_none()); - assert(none.and_then(add1_u64).is_none()); - assert(some.and_then(|_value| Option::none()).is_none()); - assert(some.and_then(add1_u64).unwrap() == 4); - - assert(none.or(none).is_none()); - assert(none.or(some).is_some()); - assert(some.or(none).is_some()); - assert(some.or(some).is_some()); - - assert(none.or_else(|| Option::none()).is_none()); - assert(none.or_else(|| Option::some(5)).is_some()); - assert(some.or_else(|| Option::none()).is_some()); - assert(some.or_else(|| Option::some(5)).is_some()); - - assert(none.xor(none).is_none()); - assert(none.xor(some).is_some()); - assert(some.xor(none).is_some()); - assert(some.xor(some).is_none()); -} diff --git a/crates/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/src/main.nr b/crates/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/src/main.nr deleted file mode 100644 index d3a3346b541..00000000000 --- a/crates/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/src/main.nr +++ /dev/null @@ -1,39 +0,0 @@ -use dep::std; - -fn f(x: Field) -> Field { - x + 1 -} - -fn ret_fn() -> fn(Field) -> Field { - f -} - -// TODO: in the advanced implicitly generic function with closures branch -// which would support higher-order functions in a better way -// support returning closures: -// -// fn ret_closure() -> fn(Field) -> Field { -// let y = 1; -// let inner_closure = |z| -> Field{ -// z + y -// }; -// inner_closure -// } - -fn ret_lambda() -> fn(Field) -> Field { - let cl = |z: Field| -> Field { - z + 1 - }; - cl -} - -fn main(x : Field) { - let result_fn = ret_fn(); - assert(result_fn(x) == x + 1); - - // let result_closure = ret_closure(); - // assert(result_closure(x) == x + 1); - - let result_lambda = ret_lambda(); - assert(result_lambda(x) == x + 1); -} diff --git a/crates/nargo_cli/tests/compile_success_empty/to_bits/src/main.nr b/crates/nargo_cli/tests/compile_success_empty/to_bits/src/main.nr deleted file mode 100644 index feeb5089d13..00000000000 --- a/crates/nargo_cli/tests/compile_success_empty/to_bits/src/main.nr +++ /dev/null @@ -1,24 +0,0 @@ -use dep::std; - -fn main() { - let field = 1000; - let be_bits = field.to_be_bits(16); - let le_bits = field.to_le_bits(16); - - for i in 0..16 { - let x = be_bits[i]; - let y = le_bits[15-i]; - assert(x == y); - } - - let x = 3; - let be_bits_x = x.to_be_bits(4); - let le_bits_x = x.to_le_bits(4); - - for i in 0..4 { - let be_bit = be_bits_x[i]; - let le_bit = le_bits_x[3-i]; - assert(be_bit == le_bit); - } - -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execute.rs b/crates/nargo_cli/tests/execute.rs deleted file mode 100644 index e53ad068c01..00000000000 --- a/crates/nargo_cli/tests/execute.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[allow(unused_imports)] -#[cfg(test)] -mod tests { - // Some of these imports are consumed by the injected tests - use assert_cmd::prelude::*; - use predicates::prelude::*; - use tempdir::TempDir; - - use std::collections::BTreeMap; - use std::fs; - use std::path::PathBuf; - use std::process::Command; - - use super::*; - - // include tests generated by `build.rs` - include!(concat!(env!("OUT_DIR"), "/execute.rs")); -} diff --git a/crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/target/1327_concrete_in_generic.bytecode b/crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/target/1327_concrete_in_generic.bytecode deleted file mode 100644 index 081e71b18e0..00000000000 --- a/crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/target/1327_concrete_in_generic.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/62PwQ2AMAwDU1goaZI2+bEKFen+IyCkIlC/4I/9OtsrACR4dOdtOH4TpcGcuYxFJGoOYtoxezNF0VaMjNT0yMYcJla9eUUn4aCuzn2Al/82Ypq+v/PVcwJ2MvbyJAEAAA== diff --git a/crates/nargo_cli/tests/execution_success/1_mul/target/1_mul.bytecode b/crates/nargo_cli/tests/execution_success/1_mul/target/1_mul.bytecode deleted file mode 100644 index c5f678deacc..00000000000 --- a/crates/nargo_cli/tests/execution_success/1_mul/target/1_mul.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2Z326CMBTGP2SIyCTLsmw3u+ARWv5ouZuPMjN8/0fYyFo5MHbFV6KJJyG1jf16/vT8NPoG4B2/Fvw8KzvmYr4azUM7D+0Dsb+zDzuqeabdeeDqKkzYTG3tUftyhszFgx0jsZbY0dWss7WoTSj2HsW+QIyB0DiKPVPvCf7RScSa258JX8DLiVqDfu9UJjTZDl8udVeEHH1TRXYO+GuksW6p9lXVHopWl/pTFc3J1KqqT3ujja5N/VWYsmxNZQ7NqTmoRldlq891U56t8BP8NGXI8bOwfuoHYswRsS7M/PmGcYQhbFh+Y8Jmai8OYwe2WKzdYczRXATGneM5ehjH8Adj10hsGD/jNmC8JsYcE+vCzJ9vGMcYwoblNyZspvbiMN7YUYLvDmOO5iIw7gqYo4dxAn8wdo3EhvELbgPGG2LMCbEuzPz5hnGCYWOz/MaEzdReHMZbO6Zi7Q5jjuYiMO4KmKOHcQp/MHaNxIbxK24DxltizCmxLleev0vMITHmlOjXI7gfZn+aHvxeZPos/d2J1+437NXEnfAATI3ROeM8egWqryLtPOhm4F1+X3Fn/BoN4HTNOZXfdtwfcmP7BvHx78jZGwAA diff --git a/crates/nargo_cli/tests/execution_success/1_mul/target/witness.tr b/crates/nargo_cli/tests/execution_success/1_mul/target/witness.tr deleted file mode 100644 index e01c75d888c..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/1_mul/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/2_div/target/2_div.bytecode b/crates/nargo_cli/tests/execution_success/2_div/target/2_div.bytecode deleted file mode 100644 index 0bf65746a8b..00000000000 --- a/crates/nargo_cli/tests/execution_success/2_div/target/2_div.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1Z207DMAx1W3aDrduYEELwUCbxnvSytW/sU5jo/v8ToCLZTGkZU4+rTdTSlCZqTpxj146zJyJ6oS9xPn+uaQPWd0t9z/Q98yuLY9pX06pmoh0clpLU0xXSkwT0tHJl2h4bG5nW2r6QPuPMY3OfK/h02LNr3vF+ecepwRmxMTvfZ7oQjhPVJ7g/KJ9hohXW9mMsjBDQ4ePsmT5VkIdamzt6pFZxnK/DXEf6TYXZNk1UnGxXqU51kibvYRpFeRqn62ybrVWm4yjXuySLdgasB8TqA7Esn33GZ9lBmq5h7YfGvSOZQIT2I0fIj1Qz0Uj+uiT5Xc9LTJID0w7ZWJckMZitJMnCgAEdkuSQLitJDoFYI8InyRHJJsmBAO49/b8kOQTq1RZ/TffsAfc8AOp1TdhDxo8gSvjkjdSZ63vDnm1F6lb4hEAC0lRap8yjaIKSMtKNAO6YcM4vte8x3kaip2Ekp+VKA61rge0K8wvC1oLY+zU4FxPT+mzslAphw+bVVQgbOl4hVOF0FUK97CuEwoABHSoEn+pPtKqZaHuHjj7RPpDMRwk6kYVGTz0B7tkH2gXJX921jyvgv2fEpWTgbT2oT007Y2OnBPUlm1cX1Jd0PKhX4XRBvV72QX3KyCz6hSGD0prnXK77QKxHuozkMAXueQa0K4A//Rf+VDPRyP/TZkCsOWGTaxvXHUidub637Lm77miIOTeEonEXdN7XHcW+F3gbiV53IDnlpyZbUZXlA/vP+pfeJAAA diff --git a/crates/nargo_cli/tests/execution_success/2_div/target/witness.tr b/crates/nargo_cli/tests/execution_success/2_div/target/witness.tr deleted file mode 100644 index 575c84704ad..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/2_div/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/3_add/target/3_add.bytecode b/crates/nargo_cli/tests/execution_success/3_add/target/3_add.bytecode deleted file mode 100644 index be9c4f2f422..00000000000 --- a/crates/nargo_cli/tests/execution_success/3_add/target/3_add.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1YW26DMBBcngkQ0b9+o5zA5hHMX3OUopL7H6FFNXRxjBo144pWsYQ2tvDsCw9DnojomT6H93H52hZs7hvzQM8DfZnD1/ZFW3HfkB4Qy8dhCUvq92JLh9izD59hhtpGbC1hfZzujbUdexGwvUe2z2PWYxhHtsd2j7eCk7C1aX/OYiFcTUTM/KIwc4aJDlhOhzFkxRznYyMLw2fgwDcKix/ISpzqemjLQVbyVZRdrxpRN/1JSSUb1byVqqoGVau267tWdLKuBnlpuuqiwXJyc7jN+v0wzlLHKUNgzhGwFxuv35xzAMw5AsYVA+s35nhFHgQnKYmMmce7Y7+nl4xveSYcEK8kw49ZR6fE7KpJOwe4e8I9/K7y3uN7tCCnLdd0TWGDY1bAl8i/UMWT8kwta7eo4jNd98pUxWf6XhXbcB6qeH3MqngsUkFfqjgl56pYAZTErBATwpFISlhVcgshbSDmiTQ6S7h/jpAybQ9s7fGZjsH8FULKaPmZPjayMHyiP5NSwhFSBozrQG4ON5qEMsISJ9HyP1RzvAPVuWfSjBUAAA== diff --git a/crates/nargo_cli/tests/execution_success/3_add/target/witness.tr b/crates/nargo_cli/tests/execution_success/3_add/target/witness.tr deleted file mode 100644 index e684b165451..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/3_add/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/4_sub/target/4_sub.bytecode b/crates/nargo_cli/tests/execution_success/4_sub/target/4_sub.bytecode deleted file mode 100644 index fe3fc2dd3b9..00000000000 --- a/crates/nargo_cli/tests/execution_success/4_sub/target/4_sub.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/81WbW7DIAzlI0nbTesZqp4AB2jg366yaOn9j7BFheqVpv3RGKlIkTHCz882OHwKIb7EZcj/TyV5AF0Vuk66Tl85VJLfSZp1gyRgWXNybhr6iSz9mD6OwRvnx1OgQD743z5YOwUXhjjGwURydqKzj/acwNR6XpQnC6G/M/bVhwLMJskW1nZQx7y3S3KuhQbbI9hJkBIwjmCztEc+wNnBWrbfAxfBlxPTgV8uzD1gchOmfBkbSOasz4U8FD51Bd8Zi/NCrsX64IvRPMvfizz7xJMaxphbxroy5I8q5u8as2aMuWXk1TGevznGu+Yh2JsUcXJGvhuY55+MWjgTFRovicJPmceqjblWkTYVcLeC7/DXinvLX6Ob5vTOOcVXU355l+MPfrsSyMILAAA= diff --git a/crates/nargo_cli/tests/execution_success/4_sub/target/witness.tr b/crates/nargo_cli/tests/execution_success/4_sub/target/witness.tr deleted file mode 100644 index d9f10aa2320..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/4_sub/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/5_over/target/5_over.bytecode b/crates/nargo_cli/tests/execution_success/5_over/target/5_over.bytecode deleted file mode 100644 index 14cbc3b6fe2..00000000000 --- a/crates/nargo_cli/tests/execution_success/5_over/target/5_over.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1YW26DMBAcIC+Imr9+VkpuYPM0f81Rigr3P0JLasgCRlHEbtRIWQlZRngYdr3jEQcA7/gL7/fy7Xgkc9/OA3uBPN/Gpx3VstAewWTEVXDEQmwtiN2/wyeYXd5X5F5ox65GbWxIbeiaM1nnkdEjGGeyxvWMN4MTOngeCBfw5URtwL7v1AHDfccJrrsmahNzxLWpVnYOyDXSGDdReZrWRVzrRH+puKxMptKsyo02OjPZd2ySpDapKcqqLFSp06TWTVYmjQV+g0xTBjw8Y8tTB4zfvGKsy6Pyp5bFRXgk8rcUa82YvwCOpgd/L3JypnypuHaHguvAEBBMjdF7xnkUFVSpIkkkagu+zS/13Vv+Gg3E6T/ndOxopTgzHiKSjtMIYg/c7M6O1Dne42ZPmNZq7GZPuO1mXTgvNzsfvZttC/iBq5sNMW0kblfC4STq5hLlDnwiEoLXlTxCkBg55w66TydIkR335N49grTGtFZjQVrjtiC5cF6CNB+9IEUkme18D3lBok20VJAi8AnSHjLNzf07IeLjqXzC0cc0fgAXnjWW6BQAAA== diff --git a/crates/nargo_cli/tests/execution_success/5_over/target/witness.tr b/crates/nargo_cli/tests/execution_success/5_over/target/witness.tr deleted file mode 100644 index a2d888f3003..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/5_over/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/6/target/6.bytecode b/crates/nargo_cli/tests/execution_success/6/target/6.bytecode deleted file mode 100644 index 6a0ae32948d..00000000000 --- a/crates/nargo_cli/tests/execution_success/6/target/6.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/6/target/witness.tr b/crates/nargo_cli/tests/execution_success/6/target/witness.tr deleted file mode 100644 index b1a3dda0f93..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/6/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/6_array/src/main.nr b/crates/nargo_cli/tests/execution_success/6_array/src/main.nr deleted file mode 100644 index 3b98a2b99bb..00000000000 --- a/crates/nargo_cli/tests/execution_success/6_array/src/main.nr +++ /dev/null @@ -1,58 +0,0 @@ -//Basic tests for arrays -fn main(x: [u32; 5], y: [u32; 5], mut z: u32, t: u32) { - let mut c = 2301; - z = y[4]; - //Test 1: - for i in 0..5 { - c = z*z*y[i]; - z -= c; - } - assert(z==0); //y[4]=0, so c and z are always 0 - - //Test 2: - c = 2301 as u32; - for i in 0..5 { - c = t+2 as u32; - c = z*z*x[i]; - z += x[i]*y[i] - c; - } - assert(z==3814912846); - - //Test 3: - c = 2300001 as u32; - z = y[4]; - for i in 0..5 { - z = z + x[i]*y[i]; - for _i in 0..3 { - c = i as u32 - 2 as u32; - z *= c; - } - } - assert(z==41472); - - //Test 4: - z = y[4]; - for i in 0..3 { - z += x[i] * y[i]; - for j in 0..2 { - z += x[i+j] - y[i+j]; - } - } - assert(z ==11539); - - //Test 5: - let cc = if z < 1 { x } else { y }; - assert(cc[0] == y[0]); - - // Test 6: for-each loops - for y_elem in y { - for x_elem in x { - assert(x_elem != y_elem); - } - } - - // Test 7: Arrays of tuples/structs - let mut tuple_array = [(1, 2), (3, 4), (5, 6)]; - tuple_array[1] = (7, 8); - assert(tuple_array[1].1 == 8); -} diff --git a/crates/nargo_cli/tests/execution_success/6_array/target/6_array.bytecode b/crates/nargo_cli/tests/execution_success/6_array/target/6_array.bytecode deleted file mode 100644 index 79c60fe2eaa..00000000000 --- a/crates/nargo_cli/tests/execution_success/6_array/target/6_array.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2dCZBdRRWG/yxMkjEixAgYQ2whxoAY35vJJJMYJMTIZoxsRmQnyQQRQRFBBZEgCrLvO8gmCIIgCIIgCIIgCIIgCCIgCIIgiJZlWZZlySn65Z57edGy+j/t7Vt9q1J9X1fm77O8/k6/7rcsGQb8+dV/ckkz3LdOPR5eeTyi8nhk5fEq/vEqr8muaPXfj/T9nb6eisaoyuPRlcdjKo971ZjD1Jg9Xmu0/5te9TdvqGiM9Y9H+H9Qdss117etsKvd6+0AV7eFLlegdttQe8UYw5XmG327quob49vOc1GuHpWbTq7kObWx+rthqh2mNDZWf9Pt/wxbic4Y1TdC2dkDekxaPaA/71qrKk22we3OJJIEOhSTalX/GLCbSFXd/taM6dOHZvYNtfvbu7X6Zi0eHGhNH1g8Y7A92B4YHFjaN9jfPzQ4fXDmrMWzZrZmtaf3D7WXDczqX+aF/wKbSTmCY2eft7P9RqLPqxLzwoyfNYytJjC6XIHa0WH8Jt+upvoyjDmaUWAsCXQoYLwa7GDc4xPAhvFfkQaM30T0eTViXpjxq8K4cw0nP5d66xVLS/BGh/rqvh2n+v4XqK+j/m5lUF8H/x3q3XQy1Fd+rYD66iqY8lgS6SpjjiCPbTUhQ7X+hjSKw+pEn8cR80qI3wqAWa/Ux6EMLZJuI6D+Zt+OV315pc7RjAJ1SaBDAfXxsFupdyYSe6X+d6QB4zcTfR5PzAszftYwFr9HgT4fGgHjt/h2DdWXYczRjAJjSaBDAeM1YAdjmUTjwYfxP5AGjN9C9HkNYl6Y8Yu1bTKuXrFs1LbJmr5dS/XlbROOZhSor4nytokk0lXGZG+bWE3IUK1/Io3isCbR57WIeSXEL9q2yVooQ4uk2wiov9W3E1RfXqlzNKNAXRLoUEB9AuxW6p2JxF6p/wtpwPitRJ8nEPPCjJ81jMXv0aDPh0bA+G2+naj6Mow5mlFgLAl0KGA8EXYwlkk0AXwYiyDJRlMYv43o80RiXpjxi7Vtsla9YtmobZO1fTtJ9eVtE45mFKivjfK2iSTSVcZkb5tYTchQreGJFIe1iT5PIuaVEL9o2yaTUIYWSbcRUH+7b53qyyt1jmYUqEsCHQqoO9it1DsTib1SH5kIjN9O9NkR88KMnzWMxe8x/PnQCBi/w7d6hZthzNGMAmNJoEMB43VgB2P9sWmtGwqmnkRg/A6iz+sQ89JjCOPOxd42mVSvWDZq22Rd305WfXnbhKMZBerrorxtIol0lTHZ2yZWEzJUa3QixWFdos+TiXklxC/atslklKFF0m0E1N/p2ymqL6/UOZpRoC4JdCigPgV2K/XORGKv1HsTgfE7iT5PIeaFGT9rGIvf+YumijE0jN/l26mqL8OYoxkFxpJAhwLGU2EHY5lEU8CH8dhEYPwuos9TiXkZawjjzsXeNplcr1g2attkPd+ur/rytglHMwrU10N520QS6SpjsrdNrCZk8DfyJVIc1iP6vD4xr4T4lbZNXvfkB3+hQfS/pe19t7of6dvhXZ4TBuBoozJONY6mYLFK0rsNdDcAbyJZ+b0BP0clONU5ptYv1yW+6xvHl6QdfWX3Ht9OU3355TpHM8rKThLoUKzspsHu5XpnIrFfrq+WyIrsPUSfpxHzwoyfNYynoTwpWHajyxWoHR3G7+1oqr4MY45mFBhLAh0KGLdgB2PRmwY+jMclAuP3En1uEfMyLiEYi17+kv5iDA3jzuvrPtWXYczRjAJjSaBDAeM+2MK4W6CCvwYzERi3iT73EfMy3hDGnWs4OefMYkSIZaMOsvp9O1315YMsjmYUqPejfJAliXSVMUlwM5+Qwd9cl0hx6Cf6PJ2YC0L8Vvr+385VLQ6tsIt5kNUmxrIRxWHAtzNUXy4OHM0oxWEA5eIgiXSVMdnvcrCakMFfy5lIcRgg+jyDmAtm/Ky3cWagDC2W3ehyBWpHh/pM3w6qvryNw9GMAnVJoEMB9UHYbeN0JhJ7G2dCIjCeSfR5kJiXCQnBeBDlt4Cx7EaXK1A7Ooxn+Xa26ssw5mhGgbEk0KGA8WzYwbgDezaMJyYC41lEn2cT8zIxIRjLcyj/nFYxhobx+3w7R/VlGHM0o8BYEuhQwHgObGE8CnwYT0oExu8j+jyHmJdJhjDuXOwDTmYxIsSyUQecG/r2/aov72FzNKNAfUOU97Alka4yJvuA02pCBn8tZyLFYUOiz+8n5oIQv+gHnMw9fGIsG1EcNqpoy5WLA0czSnHYCOXiIPquMib7gNNqQgZ/k14ixWEjos9ziblgxs96G0f7TdRtBNQ72yfzVF/exuFoRoG6BM6hgPo82G3jzPVa7G2cyYnAeGOiz/OIeZmcEIznVfRZdqPLFagdHcYf8O181ZdhzNGMAmNJoEMB4/mwg7EkYR74MJ6SCIw/QPR5PjEvUxKCsWjnH74txtAw/qBvN1F9GcYczSgwlgQ6FDDeBLYwHg0+jKcmAuMPEn3ehJiXqYYw7lzsA05mMSLEslEHnJv6djPVl/ewOZpRoL4pynvYkkhXGZN9wGk1IYO/ljOR4rAp0efNiLkgxC/6AedcohYxlo0oDpv7dgvVl4sDRzNKcdgc5eIgiXSVMdkHnHNhMyFDQblBIsVhc6LPWxBzwYyf9TbOFihDi2U3ulyB2tGh/iHfLlB9eRuHoxkF6pJAhwLqC2C3jdOZSOxtnGmJwPhDRJ8XEPMyLSEYi98jQZ8PjYDxh327UPVlGHM0o8BYEuhQwHgh7GAsCV8APoxbicD4w0SfFxLz0koIxvIcGsOfD42A8Ud8u6XqyzDmaEaBsSTQoYDxlrCF8RjwYdyXCIw/QvR5S2Je+gxh3LnYB5zMYkSIZaMOOLfy7daqL+9hczSjQH0rlPewJZGuMib7gNNqQgZ/XWsixWEros9bE3NBiF/0A07mHj4xlo0oDtv4dlvVl4sDRzNKcdgG5eIgiXSVMdkHnFYTMvjrWhMpDtsQfd6WmAtm/Ky3cbZFGVosu9HlCtSODvWP+naR6svbOBzNKFCXBDoUUF8Eu22czkRib+MMJgLjjxJ9XkTMy2BCMBa/VwF9PjQCxh/z7XaqL8OYoxkFxpJAhwLG28EOxjKJFoEP49mJwPhjRJ+3I+ZldkIwludQL+jzoREw/rhvt1d9GcYczSgwlgQ6FDDeHrYw7gUfxnMSgfHHiT5vT8zLHEMYdy72ASezGBFi2agDzh18u6Pqy3vYHM0oUN8B5T1sSaSrjMk+4LSakMFf15pIcdiB6POOxFwQ4hf9gJO5h0+MZSOKw06+3Vn15eLA0YxSHHZCuThIIl1lTPYBp9WEDP661kSKw05En3cm5sIqfuyCsDMxfrsQtFpLZi1tLVncPwJdJjz4r7x34Wm1tL27qvuRldzJ1ZkHBrBsozJONY6mMLVK0q4GuruB9+S38ns3fo5KQKlzTPMHdApbDbVXjKEBtdi3S1Rf3r/maEZZzUoCHYrV7BKYbXWsWI0tBm/yLyHGJMYHVdhwIvrfCCAt9e2Q6ssvrzmaUYC0FOWX15JIVxmT/fJaT6JQuC0FD25DSA9ITJu7mJsckJb5dnfVl1dIHM0oQJIEOhRA2h32QNKTKBRIy8AD0u5ID0hMm7uYmxyQPuHbPVRfBhJHMwqQJIEOBZD2gD2Q9CQKBdInwAPSHkgPSEybu5ibHJA+6ds9VV8GEkczCpAkgQ4FkPaEPZD0JAoF0ifBA9KesAMSG0T5jdnlMTSUPuXbvVRfhhJHMwqUJIEOBZT2gv3G9qfAA8lexJj8P96g3Aq72kSQtomxbATc9vbtp1Vf3iTnaEaB294ob5JLIl1lTPaKy2pCBv9K7TCbyc0uDnsTff40MRfzIhQH8iTrI/rfCKB/xrf7qL68WuVoRgG6JNChAPo+MAd6aRKFwu0z4MFtH6QHJKbNXcxNDkif9e2+qi8DiaMZBUiSQIcCSPvCHkh6EoUC6bPgAWlfpAckps1dzE0OSJ/z7X6qLwOJoxkFSJJAhwJI+8EeSHoShQLpc+ABaT/YTG72Ht5+RJ/3J2gNLVu2bGDotZ9Cf90TFvwDlv15WqWPDX1e3eePDQVq7u8Dytb9AnhPfiu/v8DPkenHhpgxtT5dFT2LCo4uV6B29NXYF317gOrLqzGOZpTVmCTQoViNHQD709Uvgjf5DyDGZHyCp6u9RC1iLBsBtwN9+yXVl09XOZpR4HYgyqerkkhXGZN9umo1IUNBOT+R09UDiT5/iZiL+QkWh2HEWPag1gCPXhwO8u2XVV8uDhzNKMXhIJSLgyTSVcZkFwerCRmqtUkixeEgos9fJuaVEL/o3w3ILI7EWDaiOBzs2+WqLxcHjmaU4nAwysVhOeyLg9WEDAXlZokUh4OJPi8n5oIZv1jFYTgxlqNQa4BHLw6H+PYrqi8XB45mlOJwCMrFQRLpKmOyi4PVhAzV2iKR4nAI0eevEPNKiF/0Vw7LiVrEWDaiOBzq26+qvlwcOJpRisOhKBcHSaSrjMkuDsthMyFDQbkgkeJwKNHnrxJzwYyf9btk5Lk+Sumz7EaXK1A7OtS/5tvDVF9+lwxHMwrUJYEOBdQPg/27ZL4GHpQOI8ZkUoLbGUwoE2PZCLgd7tuvq768YuVoRoHb4SivWCWRrjIme8VqNSFDQbkwkRXr4USfv07MxcIEi0Pe6+bHs3Md4dsjVV8uDhzNKMXhCJSLgyTSVcZkw+0I8CbkkcSYpLhXy4Q7MZaNgNtRvj1a9WW4cTSjwO0olOEmiXSVMdkrX6sJGQrKLRNZ+R5F9PloYi6Y8YtVHEYQYzkatQZ49OJwjG+PVX25OHA0oxSHY1AuDpJIVxmTXRysJmSo1taJFIdjiD4fS8wrIX7RXzkwiyMxlo0oDsf59njVl4sDRzNKcTgO5eIgiXSVMdnFwWpChoJy20SKw3FEn48n5oIZP+t3eYj2aKXPshtdrkDt6FA/wbcnqr78Lg+OZhSoSwIdCqifCPu97hPAg9KJxJhMTXA7gwllYiwbAbeTfHuy6ssrVo5mFLidhPKKVRLpKmOyV6xWEzIUlIsSWbGeRPT5ZGIuFiVYHPJeNzeeujic4ttTVV8uDhzNKMXhFJSLgyTSVcZkw+0U8CbkqcSYpLhXy4Q7MZaNgNtpvj1d9WW4cTSjwO00lOEmiXSVMdkrX6sJGQrK7RJZ+Z5G9Pl0Yi6Y8YtVHEYSYzkGtQZ49OJwhm/PVH25OHA0oxSHM1AuDpJIVxmTXRysJmSo1vaJFIcziD6fScwrIX7RXzkwiyMxlo0oDmf59mzVl4sDRzNKcTgL5eIgiXSVMdnFwWpChoJyx0SKw1lEn88m5sIqfuyCcDYxfucQtOSnvpb2DQ2NQJcJD/47XM7haZV+6usb6j7/1Feg5jk+oGzdc8F78lv5fS4/R6Y/9cWM6cpWxWybGeBf5q8u5ia3kj3Pt+ervryS5WhGWcmeh/JKVhLpKmOyV7KElcSKVd154EHkfNhM7upKLNROps8XEPMK8IErehd00Q31e2fyqpvttwDlPAO/d6n3qzXmrwp1rrbOdahduyYSvwuJ8SM+Z9rM+MV65UeMZemV3zfVfX7lF6h5oQ8oW/ci1PuVn/h9ET9Hpq/82DHtXOyF6jDYFLRQrYuRHkSZNmt7v6XuM0QDNS/2AWXrXoJ6Q1T8voSfo/8I0dA4XGJkZ51/oIQJ0UuRHkSZNmt7v63uM0QDNS/1AWXrXoZ6Q1T8voyfI1OIXoY0IMr8kBITopcjPYgybdb2fkfdZ4gGal7uA8rWvQL1hqj4fQU/R6YQvQJpQJT59lomRK9EehBl2qzt/a66zxAN1LzSB5StexXqDVHx+yp+jkwhehXSgOgqqCdEr0Z6EGXarO39nrrPEA3UvNoHlK17DeoNUfH7Gn6OTCF6DdKAKPNgifmjzdciPYgybdb2fl/dZ4gGal7rA8rWvQ71hqj4fR0/R6YQvQ5pQJR5sMSE6PVID6JMm7W9P1D3GaKBmtf7gLJ1b0C9ISp+38DPkSlEb0AaEGUeLDEheiPSgyjTZm3vD9V9hmig5o0+oGzdm1BviIrfN/FzZArRm5AGRJkHS0yI3oz0IMq0Wdv7I3WfIRqoebMPKFv3FtQbouL3LfwcmUL0FqQBUebBEhOityI9iDJt1vb+WN1niAZq3uoDyta9DfWGqPh9Gz9HphC9DWlAlHmwxPydyNuRHkSZNmt7f6LuM0QDNW/3AWXr3oF6Q1T8voOfI1OI3oE0IMo8WGJC9E6kB1Gmzdren6r7DNFAzTt9QNm6d6HeEBW/7+LnyBSidyENiNb1F8vvRnoQZdqs7f2Zus8QDdS82weUrXsP6g1R8fsefo5MIXoP0oAo82CJCdF7kR5EmTZre3+u7jNEAzXv9QFl696HekNU/L6PnyNTiN6HNCDKPFhiQvR+pAdRps3a3l+o+wzRQM37fUDZug+g3hAVvx/g58gUog8gDYgyD5aYP031INKDKNNmbe8v1X2GaKDmgz6gbN2HUG+Iit8P8XNkCtGHkAZEmQdLTIg+jPQgyrRZ2/srdZ8hGqj5sA8oW/cR1Bui4vcj/ByZQvQRpAFR5sESE6KPIj2IMm3W9v5a3WeIBmo+6gPK1n0M9Yao+P0YP0emEH0MaUC0rr80/RukB1Gmzdrex9V9hmigpiTpcQPdJ1BviIrfT/BzZArRJ5AGRJkHS0yIPon0IMq0Wdv7W3WfIRqo+aQPKFv3KdQbouL3U/wcmUL0KaQBUebBUi9R62mkB1Gmzdre36n7DNFAzad9QNm6z6DeEBW/n+HnyBSizyANiDIPlpgQfRbpQZRps7b39+o+QzRQ81kfULbuc6g3RMXv5/g5MoXoc0gDosyDJSZEn0d6EGXarO39g7rPEA3UfN4HlK37AuoNUfH7BX6OTCH6AtKAKPNgiQnRF5EeRJk2a3v/qO4zRAM1X/QBZeu+hHpDVPx+iZ8jU4i+hDQgyjxYYkL0ZaQHUabN2t4/qfsM0UDNl31A2bqvoN4QFb9f4efIFKKvEO0cq2yUySNPZplMAkCZOPI9nvKRSzkdF5C94dV/Y/H669/GWRU+qyICAA== diff --git a/crates/nargo_cli/tests/execution_success/6_array/target/witness.tr b/crates/nargo_cli/tests/execution_success/6_array/target/witness.tr deleted file mode 100644 index 8a348c2fcda..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/6_array/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/7/target/7.bytecode b/crates/nargo_cli/tests/execution_success/7/target/7.bytecode deleted file mode 100644 index ae55bc74385..00000000000 --- a/crates/nargo_cli/tests/execution_success/7/target/7.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/7/target/witness.tr b/crates/nargo_cli/tests/execution_success/7/target/witness.tr deleted file mode 100644 index 09b25ee04e9..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/7/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/7_function/src/main.nr b/crates/nargo_cli/tests/execution_success/7_function/src/main.nr deleted file mode 100644 index 26ecf6dda28..00000000000 --- a/crates/nargo_cli/tests/execution_success/7_function/src/main.nr +++ /dev/null @@ -1,151 +0,0 @@ -//Tests for function calling -use dep::std; - -fn f1(mut x: Field) -> Field { - x = x + 1; - x = f2(x); - x -} - -fn f2(mut x: Field) -> Field{ - x += 2; - x -} - -// Simple example -fn test0(mut a: Field) { - a = f2(a); - assert(a == 3); -} - -// Nested call -fn test1(mut a: Field) { - a = f1(a); - assert(a == 4); -} - -fn test2(z: Field, t: u32 ) { - let a = z + t as Field; - assert(a == 64); - let e = pow(z, t as Field); - assert(e == 714924299); -} - -fn pow(base: Field, exponent: Field) -> Field { - let mut r = 1 as Field; - let b = exponent.to_le_bits(32 as u32); - for i in 1..33 { - r = r*r; - r = (b[32-i] as Field) * (r * base) + (1 - b[32-i] as Field) * r; - } - r -} - -fn test3(x: [u8; 3]) -> [u8; 3] { - let mut buffer = [0 as u8; 3]; - for i in 0..3 { - buffer[i] = x[i]; - } - assert(buffer == x); - buffer -} - -fn test_multiple(x: u32, y: u32) -> (u32, u32) { - (y,x) -} - -fn test_multiple2() -> my_struct { - my_struct { a: 5 as u32, b: 7 as u32 } -} - -fn test_multiple3(x: u32, y: u32) { - assert(x == y); -} - -struct my_struct { - a: u32, - b: u32, -} - -struct my2 { - aa: my_struct, - bb: my_struct, -} - -fn test_multiple4(s: my_struct) { - assert(s.a == s.b+2); -} - -fn test_multiple5(a: (u32, u32)) { - assert(a.0 == a.1+2); -} - - -fn test_multiple6(a: my2, b: my_struct, c: (my2, my_struct)) { - test_multiple4(a.aa); - test_multiple5((b.a, b.b)); - assert(c.0.aa.a == c.1.a); -} - - - -fn foo(a: [Field; N]) -> [Field; N] { - a -} - -fn bar() -> [Field; 1] { - foo([0]) -} - -fn main(x: u32 , y: u32 , a: Field, arr1: [u32; 9], arr2: [u32; 9]) { - let mut ss: my_struct = my_struct { b: x, a: x+2, }; - test_multiple4(ss); - test_multiple5((ss.a,ss.b)); - let my = my2 { - aa: ss, - bb: ss, - }; - ss.a = 61; - test_multiple6(my, ss, (my,ss)); - - let my_block = { - let mut ab = f2(a); - ab = ab + a; - (x,ab) - }; - assert(my_block.1 == 4); - - test0(a); - test1(a); - test2(x as Field, y); - assert(bar()[0] == 0); - - let mut b = [0 as u8, 5 as u8, 2 as u8]; - let c = test3(b); - assert(b == c); - b[0] = 1 as u8; - let cc = test3(b); - assert(c != cc); - let e = test_multiple(x, y); - assert(e.1 == e.0 + 54 as u32); - let d = test_multiple2(); - assert(d.b == d.a + 2 as u32); - test_multiple3(y, y); - - //Regression test for issue #628: - let result = first(arr_to_field(arr1), arr_to_field(arr2)); - assert(result[0] == arr1[0] as Field); -} - -// Issue #628 -fn arr_to_field(arr: [u32; 9]) -> [Field; 9] { - let mut as_field: [Field; 9] = [0 as Field; 9]; - for i in 0..9 { - as_field[i] = arr[i] as Field; - } - as_field -} - -fn first(a: [Field; 9], _b: [Field; 9]) -> [Field; 9] { - a -} diff --git a/crates/nargo_cli/tests/execution_success/7_function/target/7_function.bytecode b/crates/nargo_cli/tests/execution_success/7_function/target/7_function.bytecode deleted file mode 100644 index cc603fd3f49..00000000000 --- a/crates/nargo_cli/tests/execution_success/7_function/target/7_function.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1dB5gVRda90yAoSFJAVFQE14j6ekiDARAVUIKBoCK6wDAEFxUVMEfARUUFzBFwUVEBcwRcAypgjqBrVtA1K+ia/V9BPba6fDz/tc+tqTuv6vv6q+n+lls31D11DoWzSyOit6vR6lGSfSI9NzPeI+u9uvW+nvVew3qvab2vb71vYL3Xst5rW+8b6vf11ri9+s+T9ms9vX5Nvc4G2l5t/edyNupYNuta7/Ws9/rWewPrfSPrfWPrvaH13siIocSIoY72pZ5es4G2vbG2of5cNf3Yo0TPnfScSTfiEpyt0jzuprUd535gsL12jciw2VjPmxjfcnXL9YkaNYx65Oqk9mZz+n2tSoyfI/2/qVbgf1OyDjsbGN9yf76u4QvhcpKpQfC9lqlr2EQ7HOearrGRTPWuCtnMWrMaw9o5W60ybVu3rmhXWhG3igdlStsPLmuTad1mcNuyuCxuU9ZmSGlZq1YVZa3L2rUf3L5dpn3culVFPLRN+9Kh2lbj9LZaaVuZTXAxlgZAWuNf7gcG22vXMAGpiZ43Nb4FQMLYdAJITSgJSKqQzaw1fQakJoQDpE2Jp7nR+duEKea0tjbDxZipRnk2P+EBHemz6e/mxs/V9Rzl2RMMwBGTtY6dR1Zg4SrS5gx2mxJu83PF3RRfowQ78DmngdWt8S/3A4PttWuY4LSFnrc0vgVWh7HphNVtQUlWpwrZzFrTZ1a3BeFAZEviaW6fWd2WQFtbkTxWh/TZ9LeZ8XNgdSltbkX//QtppN2tyW9Wp+LeGl8jVlaHzGlgdWv8y/3AYHvtGiY45dhUC+NbYHUYm05YXXNKsjpVyGbWmj6zuuaEA5EWxNPcPrO6FkBb25A8Vof02fT3L8bPgdWltLmNTija7rbkN6tTcW+LrxErq0PmNLC6Nf7lfmCwvXYNE5y20/P2xrfA6jA2nbC67SjJ6lQhm1lr+szqtiMciGxPPM0dWflD+pnW1g6wmFsNccXEcD4nmdiOxs+BiaW0uYNOKNruTuQ3E1Nx74SvESsTQ+c0NyKwn0g52xJgq2KoGuWtXQFfS+IBvp2NnwPwpbTZUicUbXcX8hv4VNy74GvECnzonOYGGPhW/wNjlJ+7Egr4hg51BXy7Eg/wmUULwJfS5q46oWi7MfkNfCruGF8jVuBD5zQ30IwPCXylQFuugK+UeICvlfFzAL6UNkt1QtF2W5PfwKfibo2vESvwoXOaGz4DXxuSB3xtiAf42ho/B+BLabONTijabjvyG/hU3O3wNWIFPnROc4PzciiTbqy+qUTFXAawpf++MHYFomXEA6LtjZ8DiKa0WaYTira7G/kNoiru3fA1YgVRZE7Nfx7B4WsEzGkzbWf37LNH9tkz+3TIPh31Gntln87ZZ+/ss0/22Tf7dMk+XbNPt+yzX/bZP/t0zz49sk/P7NMr+xyQfQ7MPgdln4OzT+/s0yf79M0+/bLPIdnn0OxzWPbpT//97TyR9sX8lwt7WO97Wu8drPeO1nsn630v672z9b639b6P9b6v9d7Feu9qvXez3vez3ve33rtb7z2s957Wey/r/QDr/UDr/SDr/WDrvbf13sd672u997PeD7HeD7XeD7Pe+9PvgR1NPpCEYXegrS0jHny085f2PmAPnK0hewLzt5WM/LXvgLMVdwTmr5mI/FXEnWC2yuO9gPnbWkT+yuLOMFuZeG9g/ppLyF9FJt4HZas8E+8LzF8LCfkry8RdULayZ3lXYP62EZC/imzM3UC2yrO29gPm7y8C8leWjXl/kK2sm3F3YP629T9/FSrmHhhb5cpWT2D+tvM/f2Uq5l4YW8rN+ABg/rb3Pn8Vq2M+EGKrfLWtg4D528H7/JWtjvlgiK3Vbsa9gfnb0ff8VayJuQ/CVvkaW32B+dvJ9/yVrYm5H8LWGjfjQ4D5a+l5/obomA8F2BqsbR0GzN/OnuevnY65P+H+LtH8O7u0+dvFUf4y6UYM/Hu2uBkwf7sKyR/w74ni5sD8ZYTkD/j3HPE2wPzFQvIH1OnxtsD8lQrJH1BnxtsD89dKSP6AOineEZi/1kLyB+T5cUtg/toIyR+Qp8a7APPXVkj+gDwrzgDz105I/oA8IS4F5q9MSP6A51zcGpi/9kLyB8TpuC0wf7sJyR8QZ+IyYP52F5I/YJ/EwD0TI/O3rl9VRtBcliJ/BVhsf+DzO/nrxQ7X8wDj2//y68V+M/5ciTGXGDZ+oz/+9WL57IRfL7busfbXi6kCPkz//UecA4w1yCiCufb/CHYZC+ziwwkHnAMI15D/399RWIk+W40eD83jrjgQOULPRxrf/hcQ6Uy/r5UNIp3pj0Ekn50AIusea0HkCEr+S/Aj6fcggroJytdEaQHpCKBfRxJPc6NB6AjcPgiM6Q/WMsHur3oeaHwLjAlj0wnYqQKajGkg8TOmvxKu8QcSriFdMaYUPldJxjRIz4ONb4ExYWw6AZFBlGRMg4mfMQ0kHCANAvo1mHiaGw1Cg3D7gOW/11b2+jPE3d/R302m9hNoqxxYF2D+Yin5G+Jp/oJSKbyWSTIq9GyCalAqGJtOSIYqoKlUhhK/UqkgHIgMJVxDulIqKXy2yUxFHnfFgcgwPQ83vgWlgrHpBESGUVKpDCd+pTKUcIA0DOjXcOJpbjQIDcPtAxalotj1EIa4R3get7I3giHuo4BxB4ZceC3zcPubnkca3wJDxth0cripApoMeSTxM+S/Ea7xRxKuIV0x5BQ+V0mGfLSejzG+BYaMsekERI6mJEM+hvgZ8kjCAdLRQL+OIZ7mRoPQ0bh9UPC3zKf1E/nfeB8L3Pv5apJJN9hUwShwrdFxqxofxRD3gMjvuNV+HMUQ9xERT2+jMfw4YC6BtY6l5O/4IshfUOOF1zKJ9Al6Hm18C2ocY9MJkVYFNNX4aOJX4ycQDpBGE64hXanxFD7bhH1IHnfFgcgYPY81vgU1jrHpBETGUFKNjyV+NT6acIA0BujXWOJpbjQIjcHtAxalopj68Qxxn+h53MreiQxxnwSMOzDkwmuZh9vJej7F+BYYMsamk8NNFdBkyKcQP0M+mXCNfwrhGtIVQ07hc5VkyKfq+TTjW2DIGJtOQORUSjLk04ifIZ9COEA6FejXacTT3GgQOhW3D1jvqw4F2joduPfz1SSTbrCpgjPAtUbHrWp8EkPcAz2/r1L78QyGuAdFPL2NxvAzgbkE1jqWkr+ziiB/QY0XXssk0mfr+RzjW1DjGJtOiLQqoKnGzyF+NX424QDpHMI1pCs1nsJnm7CX53FXHIiM0/N441tQ4xibTkBkHCXV+HjiV+PnEA6QxgH9Gk88zY0GoXG4fcCiVBRTP4sh7gmex63sTWCI+1xg3IEhF17LPNz+rueJxrfAkDE2nRxuqoAmQ55I/Az574Rr/ImEa0hXDDmFz1WSIZ+n5/ONb4EhY2w6AZHzKMmQzyd+hjyRcIB0HtCv84mnudEgdB5uH7DeVyH/P0gvAO79fDXJpBtsqmASuNbouFWNz2WIe4jn91VqP05iiLsi4ultNIZfCMwlsNaxlPxdVAT5C2q88Fomkb5Yz5ONb0GNY2w6IdKqgKYan0z8avxiwgHSZMI1pCs1nsJnm7APzuOuOBCZouepxregxjE2nYDIFEqq8anEr8YnEw6QpgD9mko8zY0GoSm4fcCiVBRTv4gh7ks8j1vZu4Qh7kuBcQeGXHgt83C7TM+XG98CQ8bYdHK4qQKaDPly4mfIlxGu8S8nXEO6YsgpfK6SDPkKPV9pfAsMGWPTCYhcQUmGfCXxM+TLCQdIVwD9upJ4mhsNQlfg9gHrfVU/oK2rgHs/X00y6QabKrgaXGt03KrGlzLEPdzz+yq1H69miHtExNPbaAy/BphLYK1jKfm7tgjyF9R44bVMIn2dnq83vgU1jrHphEirAppq/HriV+PXEQ6QridcQ7pS4yl8tgn7oDzuigORaXqebnwLahxj0wmITKOkGp9O/Gr8esIB0jSgX9OJp7nRIDQNtw9YlIpi6tcyxD3D87iVvRkMcd8AjDsw5MJrmYfbP/Q80/gWGDLGppPDTRXQZMgziZ8h/4NwjT+TcA3piiGn8LlKMuQb9XyT8S0wZIxNJyByIyUZ8k3Ez5BnEg6QbgT6dRPxNDcahG7E7QPW+6q+QFs3A/d+vppk0g02VTALXGt03KrGNzDEPdLz+yq1H2cxxH10xNPbaAy/BZhLYK1jKfm7tQjyF9R44bVMIn2bnmcb34Iax9h0QqRVAU01Ppv41fhthAOk2YRrSFdqPIXPNmFvn8ddcSAyR89zjW9BjWNsOgGROZRU43OJX43PJhwgzQH6NZd4mhsNQnNw+4BFqSimfitD3Ld7HreydztD3HcA4w4MufBa5uF2p57vMr4Fhoyx6eRwUwU0GfJdxM+Q7yRc499FuIZ0xZBT+FwlGfLder7H+BYYMsamExC5m5IM+R7iZ8h3EQ6Q7gb6dQ/xNDcahO7G7QPW+6o+QFv3Avd+vppk0g02VXAfuNbouFWN72CIe5Tn91VqP97HEPdxEU9vozH8fmAugbWOpeTvgSLIX1DjhdcyifSDen7I+BbUOMamEyKtCmiq8YeIX40/SDhAeohwDelKjafw2SbsZXncFQci8/Q83/gW1DjGphMQmUdJNT6f+NX4Q4QDpHlAv+YTT3OjQWgebh+wKBXF1B9giHuB53ErewsY4n4YGHdgyIXXMg+3f+r5EeNbYMgYm04ON1VAkyE/QvwM+Z+Ea/xHCNeQrhhyCp+rJEN+VM+PGd8CQ8bYdAIij1KSIT9G/Az5EcIB0qNAvx4jnuZGg9CjuH3Ael/VG2jrceDez1eTTLrBpgoWgmuNjlvV+GGGuEd7fl+l9uNChrjHRDy9jcbwJ4C5BNY6lpK/J4sgf0GNF17LJNJP6XmR8S2ocYxNJ0RaFdBU44uIX40/RThAWkS4hnSlxlP4bBP2dnncFQcii/W8xPgW1DjGphMQWUxJNb6E+NX4IsIB0mKgX0uIp7nRILQYtw9YlIpi6k8yxP2053Ere08zxP0MMO7AkAuvZR5uz+r5OeNbYMgYm04ON1VAkyE/R/wM+VnCNf5zhGtIVww5hc9VkiE/r+cXjG+BIWNsOgGR5ynJkF8gfob8HOEA6XmgXy8QT3OjQeh53D5gva86GGjrReDez1eTTLrBpgpeAtcaHbeq8TMMcZ/k+X2V2o8vMcR9csTT22gMfxmYS2CtYyn5e6UI8hfUeOG1TCL9qp5fM74FNY6x6YRIqwKaavw14lfjrxIOkF4jXEO6UuMpfLYJe9s87ooDkaV6XmZ8C2ocY9MJiCylpBpfRvxq/DXCAdJSoF/LiKe50SC0FLcPWJSKYuqvMMT9uudxK3uvM8T9BjDuwJALr2Uebv/S85vGt8CQMTadHG6qgCZDfpP4GfK/CNf4bxKuIV0x5BQ+V0mG/Jae3za+BYaMsekERN6iJEN+m/gZ8puEA6S3gH69TTzNjQaht3D7gPW+6iCgrXeAez9fTTLpBpsqeBdca3TcqsZvMMR9muf3VWo/vssQ9+kRT2+jMfw9YC6BtY6l5O/9IshfUOOF1zKJ9Ad6/tD4FtQ4xqYTIq0KaKrxD4lfjX9AOED6kHAN6UqNp/DZJuxt8rgrDkSW63mF8S2ocYxNJyCynJJqfAXxq/EPCQdIy4F+rSCe5kaD0HLcPmBRKoqpv88Q90eex63sfcQQ98fAuANDLryWebj9W8+fGN8CQ8bYdHK4qQKaDPkT4mfI/yZc439CuIZ0xZBT+FwlGfKnev7M+BYYMsamExD5lJIM+TPiZ8ifEA6QPgX69RnxNDcahD7F7QPW+6oDgbY+B+79fDXJpBtsquALcK3Rcasaf8wQ91me31ep/fgFQ9xnRzy9jcbwL4G5BNY6lpK/r4ogf0GNF17LJNJf6/kb41tQ4xibToi0KqCpxr8hfjX+NeEA6RvCNaQrNZ7CZ5uwt87jrjgQWannVca3oMYxNp2AyEpKqvFVxK/GvyEcIK0E+rWKeJobDUIrcfuARakopv4VQ9zfeh63svctQ9zfAeMODLnwWubh9h89f298CwwZY9PJ4aYKaDLk74mfIf+HcI3/PeEa0hVDTuFzlWTIP+j5R+NbYMgYm05A5AdKMuQfiZ8hf084QPoB6NePxNPcaBD6AbcPWO+rDgDa+gm49/PVJJNusKmCn8G1RsetavwdQ9zjPb+vUvvxZ4a4J0Q8vY3G8F+AuQTWOpaSv1+LIH9BjRdeyyTSa1WwwfiCGsfYdEKkVeJMNa5+6GStiVbjvxEOkEx/M6mGOzWewmebsLfK4644ECnRCY7+JIgENb7u4QREVAFNNR6V8Ktxs4nSAlJJCc6viKm50SBUUoLbZPn8y6QbsWLqvzLEXc3zuFeDWwk+7urAuANDLryWebitpwtZIzBkmYebKqDJkGs4YMjrAQ+kGgIZcg2mQzTlHqk0EKmpE7x+YMgyQaSmxZDXd8CQawAZck0gIK0vhCHXBDPF3EDfV/UC2toAFzPLfRWXKqjluSpQNa7OoAomen5fpfZjLYa4z4t4ehuN4bWB/QisdSwlfxsWQf6CGi+8lkmk62ggqRvUuEwiXcdS43UdqPE6QPJbV6AaT+GzTdhL87grDkTq6QTXD2pcJojUs9R4fQdqvC5QjdcDAlJ9puZGg1A9zxWaYuobMiiVBgLuqxowxL1RuK9KDD6/k4fbxrqQDQNDlnm4bWwx5IYOGPLGwAOpoUCG3JDpEE25RyoNRBrpBDcODFkmiDSyGHJjBwy5IZAhNwICUmMhDLkRmCnmBvq+qifQ1iae31dxqYImnqsCVeONGOKe5Pl9ldqPTRjivjDi6W00hm8K7EdgrWMp+dusCPIX1HjhtUwivbkGkqZBjcsk0ptbarypAzW+OZD8NhWoxlP4bBP2OI+74kBkC53gLYMalwkiW1hqfEsHarwpUI1vAQSkLZmaGw1CW3iu0BRT34xBqWwl4L5qK4a4m4X7qsTg8zt5uG2tC9k8MGSZh9vWFkNu7oAhbw08kJoLZMjNmQ7RlHuk0kCkhU7wNoEhywSRFhZD3sYBQ24OZMgtgIC0jRCG3ALMFHMDfV/VA2jrL57fV3Gpgm09VwWqxs0Y4p7s+X2V2o/bMsQ9JeLpbTSGbwfsR2CtYyn5274I8hfUeOG1TCK9gwaSHYMal0mkd7DU+I4O1PgOQPK7o0A1nsJnm7BXCRDZSSe4ZVDjMkFkJ0uNt3SgxncEqvGdgIDUkqm50SC0k+cKTTH17RmUys4C7qt2Zoh7l3BflRh8ficPt111ITOBIcs83Ha1GHLGAUPeFXggZQQy5AzTIZpyj1QaiMQ6waWBIcsEkdhiyKUOGHIGyJBjICCVCmHIMZgp5gb6vqo70FYrz++ruFRBa89VgarxLgxxX+r5fZXaj60Z4r4s4ultNIa3AfYjsNaxlPy1LYL8BTVeeC2TSLfTQFIW1LhMIt3OUuNlDtR4OyD5LROoxlP4bDf60DzuigOR9jrBuwU1LhNE2ltqfDcHarwMqMbbAwFpN6bmRoNQe88VmmLqbRmUyu4C7qt2Z4h7j3BflRh8ficPtz11ITsEhizzcNvTYsgdHDDkPYEHUgeBDLkD0yGaco9UGoh01AnuFBiyTBDpaDHkTg4YcgcgQ+4IBKROQhhyRzBTzA30fdX+QFt7eX5fxaUKOnuuClSN92CI+0rP76vUfuzMEPdVEU9vozF8b2A/AmsdS8nfPkWQv6DGC69lEul9NZB0CWpcJpHe11LjXRyo8X2B5LeLQDWewme70SvyuCsORLrqBHcLalwmiHS11Hg3B2q8C1CNdwUCUjem5kaDUFfPFZpi6vswKJX9BNxX7ccQ9/7hviox+PxOHm7ddSF7BIYs83DrbjHkHg4YcnfggdRDIEPuwXSIptwjlQYiPXWCewWGLBNEeloMuZcDhtwDyJB7AgGplxCG3BPMFHMDfV+1H9DWAZ7fV3GpggM9VwWqxvszxH2t5/dVaj8eyBD3dRFPb6Mx/CBgPwJrHUvJ38FFkL+gxguvZRLp3hpI+gQ1LpNI97bUeB8Harw3kPz2EajGU/hsN/qQPO6KA5G+OsH9ghqXCSJ9LTXez4Ea7wNU432BgNSPqbnRINTXc4WmmPrBDErlEAH3VYcwxH1ouK9KDD6/k4fbYbqQ/QNDlnm4HWYx5P4OGPJhwAOpv0CG3J/pEE25RyoNRA7XCR4QGLJMEDncYsgDHDDk/kCGfDgQkAYIYciHg5libqDvq7oBbR3h+X0Vlyo40nNVoGp8KEPc0z2/r1L78UiGuGdEPL2NxvC/AvsRWOtYSv4GFkH+ghovvJZJpAdpIBkc1LhMIj3IUuODHajxQUDyO1igGk/hs93o5XncFQci5TrBQ4Ialwki5ZYaH+JAjQ8GqvFyICANYWpuNAiVe67QFFMfyKBUKgTcV1UwxD003FclBp/fycNtmC7k8MCQZR5uwyyGPNwBQx4GPJCGC2TIw5kO0ZR7pNJAZIRO8FGBIcsEkREWQz7KAUMeDmTII4CAdJQQhjwCzBRzA31f1RVo62+e31dxqYKRnqsCVeOhDHHP9Py+Su3HkQxx3xjx9DYaw48G9iOw1rGU/B1TBPkLarzwWiaRPlYDyaigxmUS6WMtNT7KgRo/Fkh+RwlU4yl8tht9cB53xYHIcTrBxwc1LhNEjrPU+PEO1PgooBo/DghIxzM1NxqEjvNcoSmmfgyDUjlBwH3VCQxxjw73VYnB53fycBujCzk2MGSZh9sYiyGPdcCQxwAPpLECGfJYpkM05R6pNBA5USf4pMCQZYLIiRZDPskBQx4LZMgnAgHpJCEM+UQwU8wN9H1VF6Ctkz2/r+JSBad4rgpUjUczxD3L8/sqtR9PYYj7loint9EYfiqwH4G1jqXk77QiyF9Q44XXMon06RpIzghqXCaRPt1S42c4UOOnA8nvGQLVeAqf7UYflMddcSBypk7wWUGNywSRMy01fpYDNX4GUI2fCQSks5iaGw1CZ3qu0BRTP41BqZwt4L7qbIa4zwn3VYnB53fycBunCzk+MGSZh9s4iyGPd8CQxwEPpPECGXIKn6skQ56gE3xuYMgyQWSCxZDPdcCQxwMZ8gQgIJ0rhCFPADPF3EDfV+0LtPV3z++ruFTBRM9VgarxOQxxz/b8vkrtx4kMcc+JeHobjeHnAfsRWOtYSv7OL4L8BTVeeC2TSF+ggWRSUOMyifQFlhqf5ECNXwAkv5MEqvEUPtuN3j6Pu+JA5EKd4IuCGpcJIhdaavwiB2p8ElCNXwgEpIuYmhsNQhd6rtAUUz+fQalcLOC+6mKGuCeH+6rE4PM7ebhN0YWcGhiyzMNtisWQpzpgyFOAB9JUgQx5KtMhmnKPVBqIXKITfGlgyDJB5BKLIV/qgCFPBTLkS4CAdKkQhnwJmCnmBvq+ah+grcs8v6/iUgWXe64KVI0nM8R9h+f3VWo/Xs4Q950RT2+jMfwKYD8Cax1Lyd+VRZC/oMYLr2US6as0kFwd1LhMIn2VpcavdqDGrwKS36sFqvEUPtuNXpbHXXEgco1O8LVBjcsEkWssNX6tAzV+NVCNXwMEpGuZmhsNQtd4rtAUU7+SQalcJ+C+6jqGuK8P91WJwed38nCbpgs5PTBkmYfbNIshT3fAkKcBD6TpAhnydKZDNOUeqTQQmaETfENgyDJBZIbFkG9wwJCnAxnyDCAg3SCEIc8AM8XcQN9X7Q209Q/P76u4VMFMz1WBqvH1DHHf4/l9ldqPMxnivjfi6W00ht8I7EdgrWMp+bupCPIX1HjhtUwifbMGkllBjcsk0jdbanyWAzV+M5D8zhKoxlP4bDd6uzzuigORW3SCbw1qXCaI3GKp8VsdqPFZQDV+CxCQbmVqbjQI3eK5QlNM/SYGpXKbgPuq2xjinh3uqxKDz+/k4TZHF3JuYMgyD7c5FkOe64AhzwEeSHMFMuS5TIdoyj1SaSByu07wHYEhywSR2y2GfIcDhjwXyJBvBwLSHUIY8u1gppgb6PuqzkBbd3p+X8WlCu7yXBWoGs9miPsBz++r1H68iyHuByOe3kZj+N3AfgTWOpaSv3uKIH9BjRdeyyTS92oguS+ocZlE+l5Ljd/nQI3fCyS/9wlU4yl8thu9bR53xYHI/TrBDwQ1LhNE7rfU+AMO1Ph9QDV+PxCQHmBqbjQI3e+5QlNM/R4OpSLgvupBhrgfCvdVicHnd/Jwm6cLOT8wZJmH2zyLIc93wJDnAQ+k+QIZ8nymQzTlHqk0EFmgE/xwYMgyQWSBxZAfdsCQ5wMZ8gIgID0shCEvADPF3EDfV+0FtPVPz++ruFTBI56rAlXjhxjinu/5fZXaj48wxL0g4ultNIY/CuxHYK1jKfl7rAjyF9R44bVMIv24BpKFQY3LJNKPW2p8oQM1/jiQ/C4UqMZT+Gw3eps87ooDkSd0gp8MalwmiDxhqfEnHajxhUA1/gQQkJ5kam40CD3huUJTTP0xBqXylID7qqcY4l4U7qsSg8/v5OG2WBdySWDIMg+3xRZDXuKAIS8GHkhLBDLkJUyHaMo9Umkg8rRO8DOBIcsEkacthvyMA4a8BMiQnwYC0jNCGPLTYKaYG+j7qk5AW896fl/FpQqe81wVKDuLOO7pPL+vUvvxOYa4H414ehuN4c8D+xFY61hK/l4ogvwFNV54LZNIv6iB5KWgxmUS6RctNf6SAzX+IpD8viRQjafw2W701nncFQciL+sEvxLUuEwQedlS4684UOMvAdX4y0BAeoWpudEg9LLnCk0x9RcYlMqrAu6rXmWI+7VwX5UYfH4nD7elupDLAkOWebgttRjyMgcMeSnwQFomkCEvYzpEU+6RSgOR13WC3wgMWSaIvG4x5DccMORlQIb8OhCQ3hDCkF8HM8XcQN9XdQTa+pfn91VcquBNz1WBqvFrDHEv9Py+Su3HNxnifiLi6W00hr8F7EdgrWMp+Xu7CPIX1HjhtUwi/Y4GkneDGpdJpN+x1Pi7DtT4O0Dy+65ANZ7CZ7vRW+VxVxyIvKcT/H5Q4zJB5D1Ljb/vQI2/C1Tj7wEB6X2m5kaD0HueKzTF1N9mUCofCLiv+oAh7g/DfVVi8PmdPNyW60KuCAxZ5uG23GLIKxww5OXAA2mFQIa8gukQTblHKg1EPtIJ/jgwZJkg8pHFkD92wJBXABnyR0BA+lgIQ/4IzBRzA31f1QFo69+e31dxqYJPPFcFqsYfMsS9yPP7KrUfP2GIe3HE09toDP8U2I/AWsdS8vdZEeQvqPHCa5lE+nMNJF8ENS6TSH9uqfEvHKjxz4Hk9wuBajyFz3ajl+ZxVxyIfKkT/FVQ4zJB5EtLjX/lQI1/AVTjXwIB6Sum5kaD0JeeKzTF1D9jUCpfC7iv+poh7m/CfVVi8PmdPNxW6kKuCgxZ5uG20mLIqxww5JXAA2mVQIa8iukQTblHKg1EvtUJ/i4wZJkg8q3FkL9zwJBXARnyt0BA+k4IQ/4WzBRzA31ftSfQ1n88v6/iUgXfe64KVI2/YYj7Gc/vq9R+/J4h7mcjnt5GY/gPwH4E1jqWkr8fiyB/QY0XXssk0j9pIPk5qHGZRPonS43/7ECN/wQkvz8LVOMpfLYbPc7jrjgQ+UUn+NegxmWCyC+WGv/VgRr/GajGfwEC0q9MzY0GoV88V2iKqf/IoFR+E3Bf9RtD3BQYcmLw+Z083Er0S2R8DAwZY9PJ4aYKaDLkKOJnyCURrvGjCNeQrhhyCp+rJEOupl+q/0kQCQx53cMJiKgCmgy5esTPkKMIB0jVgIBUnam50SBUjenvZCOwn3sAba0H/DvZfDXJpBtsqqAGuNbouPfQGwcd9wuex632Yw2GuF9k6m00htcE9iOw1rGU/K1fBPkLarzwWgZnpg30S62gxmUS6Q0sNV7LgRrfAEh+awlU4yl85mz0SgOR2vplw6DGZYJIbUuNb+hAjdcCqvHaQEDakKm50SBU23Olopj6+hE+7jqex63s1WGIu25gyInB53fycKunX+oHhizzcKtnMeT6DhhyPeCBVF8gQ07hc5VkyA30y0aBIcsEkQYWQ97IAUOuD2TIDYCAtJEQhtwAzBRzIwL7uTvQ1sa4mFnuq7hUQUPPVYGqcV2GuF/xPG61HxsyxP0qU2+jMbwRsB+BtY5fBZwH5W3atoorhratRnkOYIa9BMxlxvS3sUHKqus5yrMnGMhLbO89O4+s5IarSI0jvN1NgASGK+5NIniNChKkTLoBzen/V1lm0o3Vqgpjq1XbPO6mtb2W4DLYXruGCU5N9Mumf1JZNqff18pWls3pj5VlPjtBWa57rFWWTSxlqQrZzFqzGnhts4n+ZOOX5pRlEyCIbBrxNDc6fyXEE3NaW5sBGZIrVof02fR388DqsEXanIHVNfWc1am4mwpjdcicNjJ8jPRmVs20Hq1pnJrZZ31ac9LXyj61s8+G2aeO3uT1sk/97NMg+2yUfTbOPg2zTyP6/fg/k5BEEaXOAwA= diff --git a/crates/nargo_cli/tests/execution_success/7_function/target/witness.tr b/crates/nargo_cli/tests/execution_success/7_function/target/witness.tr deleted file mode 100644 index 67fd0a31ccf..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/7_function/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/8_integration/src/main.nr b/crates/nargo_cli/tests/execution_success/8_integration/src/main.nr deleted file mode 100644 index 56b02650c27..00000000000 --- a/crates/nargo_cli/tests/execution_success/8_integration/src/main.nr +++ /dev/null @@ -1,283 +0,0 @@ -fn matrix_mul_2(a: [u32; 4], b: [u32; 4]) ->[u32; 4] { - let mut c = [0 as u32; 4]; - for i in 0..2 { - for j in 0..2 { - c[i+2*j] = 0; - for k in 0..2 { - c[i+2*j] += a[i+2*k] * b[k+2*j]; - } - } - } - c -} - -fn matrix_mul_10(a: [u32; 100], b: [u32; 100]) -> [u32; 100] { - let mut c = [0 as u32; 100]; - for i in 0..10 { - for j in 0..10 { - c[i+10*j] = 0 as u32; - - for k in 0..10 { - c[i+10*j] += a[i+10*k] * b[k+10*j]; - } - } - } - c -} - - -fn siggy(x: u32) -> u32 { - x * (10 as u32) -} - - -fn test4 (mut a: [u32; 4]) -> [u32; 4] { - for i in 3..4 { - a[i] = siggy(a[i-2]); - } - a -} - -fn iterate1(mut a0: u32) -> u32{ - let mut t1 = 0 as u32; - let mut t2 = 0 as u32; - let mut a = 1 as u32; - let mut f = 2 as u32; - let mut g = 3 as u32; - let mut h = 4 as u32; - - for _i in 0..2 { - t1 = h; - h = g; - g = f; - a = t1 + t2; - } - a0 += a; - a0 -} - -fn array_noteq(a: [u32; 4], b: [u32; 4]) { - assert(a != b); -} - -fn test3(mut b: [Field; 4]) -> [Field; 4] { - for i in 0..4 { - b[i] = i; - } - b -} - -fn iterate2(mut hash: [u32; 8]) -> [u32; 8] { - let mut t1 = 0 as u32; - - let mut a = hash[0]; - let mut e = hash[4]; - let mut f = hash[5]; - let mut g = hash[6]; - let mut h = hash[7]; - - for _i in 0..2 { - t1 = ch2(e, f); - h = g; - g = f; - a = t1; - } - - hash[0] = hash[0] + a; - hash -} - -fn iterate3( mut hash: [u32; 8]) -> [u32; 8] { - let mut t1 = 0 as u32; - let mut t2 = 0 as u32; - let mut a = hash[0]; - let mut b = hash[1]; - let mut c = hash[2]; - let mut d = hash[3]; - let mut e = hash[4]; - let mut f = hash[5]; - let mut g = hash[6]; - let mut h = hash[7]; - - for _i in 0..3 { - t1 = ep2(e)+ch2(e, f); - h = g; - g = f; - a = t1+t2; - } - assert(a == 2470696267); - hash[0] = hash[0] + a; - hash[1] = hash[1] + b; - hash[2] = hash[2] + c; - hash[3] = hash[3] + d; - hash[4] = hash[4] + e; - hash[5] = hash[5] + f; - hash[6] = hash[6] + g; - hash[7] = hash[7] + h; - hash -} - - -fn test5() { - let mut sha_hash = [ - 0 as u32, 1, 2, 3, - 4, 5, 6, 7 - ]; - - sha_hash = iterate2(sha_hash); - - assert(sha_hash[0] == 9); -} - - -fn ch2(x: u32, y: u32) -> u32 { - x + y -} - -fn ep2(x: u32) -> u32 { - (2 as u32) * too(x) -} - -fn too(x: u32) -> u32 { - (x + 17 as u32) * (x + 3 as u32) -} - -fn test6(x: [u8; 32]) -> [u32; 8] { - let mut sha_m = [0 as u32; 64]; - - let mut sha_hash = [ - 1 as u32, 2, 3, 4, 5, 6, 7, 8 - ]; - - let mut buffer = [0 as u8; 64]; - for i in 0..32 { - buffer[i] = x[i]; - } - - sha_m = iterate6_1(sha_m, buffer); - sha_hash = iterate6_2(sha_m, sha_hash); - sha_hash -} - -fn iterate6_1(mut sha_m: [u32; 64], next_chunk: [u8; 64]) -> [u32; 64] { - let mut j = 0; - for i in 0..16 { - j = (i ) * 4; - sha_m[i] = ((next_chunk[j] as u32) << 24 as u32) - | ((next_chunk[j + 1] as u32) << 16 as u32) - | ((next_chunk[j + 2] as u32) << 8 as u32) - | (next_chunk[j + 3] as u32); - } - for i in 16..64 { - sha_m[i] = sig1(sha_m[i - 2])+(sha_m[i - 7])+(sig0(sha_m[i - 15]))+(sha_m[i - 16]); - } - sha_m -} - -fn iterate6_2(sha_m: [u32; 64], mut hash: [u32; 8]) -> [u32; 8] { - let mut t1 = 0 as u32; - let mut t2 = 0 as u32; - let mut a = 1 as u32; - let mut b = 2 as u32; - let mut c = 3 as u32; - let mut d = 4 as u32; - let mut e = 5 as u32; - let mut f = 6 as u32; - let mut g = 7 as u32; - let mut h = 8 as u32; - - for i in 0..11 { - t1 = h + ep1(e) + ch(e, f, g) + sha_m[i]; - t2 = epo(a) + maj(a, b, c); - h = g; - g = f; - f = e; - e = d+t1; - d = c; - c = b; - b = a; - a = t1+t2; - } - - hash[0] = hash[0]+a; - hash[1] = hash[1]+b; - hash[2] = hash[2]+c; - hash[3] = hash[3]+d; - hash[4] = hash[4]+e; - hash[5] = hash[5]+f; - hash[6] = hash[6]+g; - hash[7] = hash[7]+h; - hash -} - -fn rot_right(a: u32, b: u32) -> u32 { - ((a >> b) | (a << (32 as u32 - b))) -} - - -fn ch(x: u32, y: u32, z: u32) -> u32 { - ((x & y) ^ (!x & z)) -} - - -fn maj(x: u32, y: u32, z: u32) -> u32 { - ((x & y) ^ (x & z) ^ (y & z)) -} - - -fn epo(x: u32) -> u32 { - (rot_right(x, 2) ^ rot_right(x, 13) ^ rot_right(x, 22)) -} - -fn ep1(x: u32) -> u32 { - (rot_right(x, 6) ^ rot_right(x, 11) ^ rot_right(x, 25)) -} - -fn sig0(x: u32) -> u32 { - (rot_right(x, 7) ^ rot_right(x, 18) ^ (x >> 3)) -} - -fn sig1(x: u32) -> u32 { - (rot_right(x, 17) ^ rot_right(x, 19) ^ (x >> 10)) -} - - -fn main(a: [u32; 100], b: [u32; 100], c: [u32; 4], mut d: [u32; 4], m: [u8; 32]) { - let e = matrix_mul_10(a,b); - assert(e[6] == 1866842232); - let f = matrix_mul_2(c,d); - assert(f[3] == 2082554100); - - let mut a = [1 as u32, 2, 3, 4]; - a = test4(a); - assert(a[3] == 20); - a = test4(c); - assert(a[3] == c[1] * 10); - - d[0] += c[0]; - d[0] += c[1]; - assert(d[0] == 2739986880); - - let h = iterate1(1); - assert(h == 4); - - let x = d; - array_noteq(x, [d[0], d[1], d[2], 0]); - - let mut h5 = [d[0] as Field, d[1] as Field, d[2] as Field, d[3] as Field]; - let t5 = test3(h5); - assert(t5[3] == 3); - h5 = test3(h5); - assert(h5[3] == 3); - - test5(); - - let mut sha_hash = [ - 0x6a09e667 as u32, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 - ]; - sha_hash = iterate3(sha_hash); - - let h6 = test6(m); - assert(h6[0]== 523008072); //31.. 3800709683 -} diff --git a/crates/nargo_cli/tests/execution_success/8_integration/target/8_integration.bytecode b/crates/nargo_cli/tests/execution_success/8_integration/target/8_integration.bytecode deleted file mode 100644 index bd5fc9ab6e6..00000000000 --- a/crates/nargo_cli/tests/execution_success/8_integration/target/8_integration.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/8_integration/target/witness.tr b/crates/nargo_cli/tests/execution_success/8_integration/target/witness.tr deleted file mode 100644 index b19f4717234..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/8_integration/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/9_conditional/src/main.nr b/crates/nargo_cli/tests/execution_success/9_conditional/src/main.nr deleted file mode 100644 index 48ac639ecf0..00000000000 --- a/crates/nargo_cli/tests/execution_success/9_conditional/src/main.nr +++ /dev/null @@ -1,277 +0,0 @@ -use dep::std; - -fn sort(mut a: [u32; 4]) -> [u32; 4] { - for i in 1..4 { - for j in 0..i { - if a[i] < a[j] { - let c = a[j]; - a[j] = a[i]; - a[i] = c; - } - } - } - a -} - -fn call_intrinsic(x: [u8; 5], result: [u8; 32]) { - let mut digest = std::hash::sha256(x); - digest[0] = 5 as u8; - digest = std::hash::sha256(x); - assert(digest == result); -} - -fn must_be_zero(x: u8) { - assert(x == 0); -} - -fn test3 (x: u8) { - if x == 0 { - must_be_zero(x); - } -} - -fn test4() -> [u32; 4] { - let b: [u32; 4] = [1,2,3,4]; - b -} - -fn main(a: u32, mut c: [u32; 4], x: [u8; 5], result: pub [u8; 32]){ - // Regression test for issue #547 - // Warning: it must be kept at the start of main - let arr: [u8; 2] = [1, 2]; - if arr[0] != arr[1] { - for i in 0..1 { - assert(i != 2); - } - } - - //Issue reported in #421 - if a == c[0] { - assert(c[0] == 0); - } else { - if a == c[1] { - assert(c[1] == 0); - } else { - if a == c[2] { - assert(c[2] == 0); - } - } - } - - //Regression for to_le_bits() constant evaluation - // binary array representation of u8 1 - let as_bits_hardcode_1 = [1, 0]; - let mut c1 = 0; - for i in 0..2 { - let mut as_bits = (arr[i] as Field).to_le_bits(2); - c1 = c1 + as_bits[0] as Field; - - if i == 0 { - assert(arr[i] == 1);// 1 - for k in 0..2 { - assert(as_bits_hardcode_1[k] == as_bits[k]); - } - } - if i == 1 { - assert(arr[i] == 2);//2 - for k in 0..2 { - assert(as_bits_hardcode_1[k] != as_bits[k]); - } - } - } - assert(c1==1); - - //Regression for Issue #579 - let result1_true = test(true); - assert(result1_true.array_param[0] == 1); - let result1_false = test(false); - assert(result1_false.array_param[0] == 0); - - //Test case for short-circuit - let mut data = [0 as u32; 32]; - let mut ba = a; - for i in 0..32 { - let i_u32 = i as u32; - if i_u32 == a { - for j in 0..4 { - data[i + j] = c[4 - 1 - j]; - for k in 0..4 { - ba = ba +data[k]; - } - if ba == 4864 { - c[3]=ba; - } - } - } - } - assert(data[31] == 0); - assert(ba != 13); - //regression for short-circuit2 - if 35 == a { - assert(false); - } - bar(a as Field); - - if a == 3 { - c = test4(); - } - assert(c[1] != 2); - call_intrinsic(x, result); - - //Test case for conditional with arrays from function parameters - let b = sort([1,2,3,4]); - assert(b[0] == 1); - - if a == 0 { - must_be_zero(0); - c[0] = 3; - } else { - must_be_zero(1); - c[0] = 1; - c[1] = c[2] / a + 11 % a; - let f1 = a as Field; - assert(10/f1 != 0); - } - assert(c[0] == 3); - - let mut y = 0; - if a == 0 { - let digest = std::hash::sha256(x); - y = digest[0]; - } else { - y = 5; - } - assert(y == result[0]); - c = sort(c); - assert(c[0]==0); - - //test 1 - let mut x: u32 = 0; - if a == 0 { - c[0] = 12; - if a != 0 { - x = 6; - } else { - x = 2; - assert(x == 2); - } - } else { - x = 5; - assert(x == 5); - } - if c[0] == 0 { - x = 3; - } - assert(x == 2); - - //test2: loops! - x = 0; - x = a - a; - for i in 0..4 { - if c[i] == 0 { - x = i as u32 +2; - } - } - assert(x == 0); - - test3(1); - - if a == 0 { - c = test4(); - } else { - assert(c[1] != 2); - } - if false { - c[1] = 5; - } - assert(c[1] == 2); - - test5(4); - - // Regression for issue #661: - let mut c_661 :[u32;1]=[0]; - if a > 5 { - c_661 = issue_661_foo(issue_661_bar(c), a); - } else { - c_661 = issue_661_foo(issue_661_bar(c), x); - } - assert(c_661[0] < 20000); - - // Test case for function synchronisation - let mut c_sync = 0; - if a == 42 { - c_sync = foo2(); - } else { - c_sync = foo2() + foo2(); - } - assert(c_sync == 6); - - // Regression for predicate simplification - safe_inverse(0); -} - -fn test5(a : u32) { - if a > 1 { - let q = a / 2; - assert(q == 2); - } -} - - - -fn foo() { - let mut x = 1; - x /= 0; -} - -fn bar(x:Field) { - if x == 15 { - foo(); - } -} - - -struct MyStruct579 { - array_param: [u32; 2] -} - -impl MyStruct579 { - fn new(array_param: [u32; 2]) -> MyStruct579 { - MyStruct579 { - array_param: array_param - } - } -} - -fn test(flag: bool) -> MyStruct579 { - let mut my_struct = MyStruct579::new([0; 2]); - - if flag == true { - my_struct= MyStruct579::new([1; 2]); - } - my_struct -} - -fn issue_661_foo(array: [u32;4], b:u32) ->[u32;1] { - [array[0]+b] -} - -fn issue_661_bar(a : [u32;4]) ->[u32;4] { - let mut b:[u32;4] = [0;4]; - b[0]=a[0]+1; - b -} - -fn foo2() -> Field { - 3 -} - -fn safe_inverse(n: Field) -> Field -{ - if n == 0 { - 0 - } - else { - 1 / n - } -} diff --git a/crates/nargo_cli/tests/execution_success/9_conditional/target/9_conditional.bytecode b/crates/nargo_cli/tests/execution_success/9_conditional/target/9_conditional.bytecode deleted file mode 100644 index 1fe5a46f983..00000000000 --- a/crates/nargo_cli/tests/execution_success/9_conditional/target/9_conditional.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/9_conditional/target/witness.tr b/crates/nargo_cli/tests/execution_success/9_conditional/target/witness.tr deleted file mode 100644 index c3af8ea81f8..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/9_conditional/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/src/main.nr b/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/src/main.nr deleted file mode 100644 index 391aa27049d..00000000000 --- a/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/src/main.nr +++ /dev/null @@ -1,12 +0,0 @@ -// Tests a very simple program. -// -// The features being tested are: -// Binary addition, multiplication, division -// x = 3, y = 4, z = 5 -fn main(x : Field, y : Field, z : Field) -> pub Field { - let a = x + x; // 3 + 3 = 6 - let b = a - y; // 6 - 4 = 2 - let c = b * z; // 2 * 5 = 10 - let d = c / a; // 10 / 6 (This uses field inversion, so we test it by multiplying by `a`) - d * a -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/target/arithmetic_binary_operations.bytecode b/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/target/arithmetic_binary_operations.bytecode deleted file mode 100644 index 929c6f961c6..00000000000 --- a/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/target/arithmetic_binary_operations.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9WVSQ7DIAxFnTRjK/UsNkNidr1Ko5L7H6FCIhJK2YGl1BsjFvb/fkY8AGCC37jF/IoZy0I1SS2NizF+VZ40vVG5jS0auy1MTJbtR7HWng2vbnMrOjLa026d3mOxtmKtrp5HDDNrMrNsBGeJhZHq7ZNzF3Ob2YmhvieCU5/zHJ+ZO5HmrSCs0mUd6ulCEIDYx+U48yn1LaE1LFmXqVuqdfwDRqOA76my7yOu/B7ni7MOTGYB1neo+2ke3gPrW8L+0B36fQEsj335qQgAAA== diff --git a/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/target/witness.tr b/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/target/witness.tr deleted file mode 100644 index 1d167a816d6..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/array_dynamic/src/main.nr b/crates/nargo_cli/tests/execution_success/array_dynamic/src/main.nr deleted file mode 100644 index 69e5fdc93db..00000000000 --- a/crates/nargo_cli/tests/execution_success/array_dynamic/src/main.nr +++ /dev/null @@ -1,32 +0,0 @@ - -fn main(x: [u32; 5], mut z: u32, t: u32, index: [Field;5], index2: [Field;5], offset: Field, sublen: Field) { - let idx = (z - 5*t - 5) as Field; - //dynamic array test - dyn_array(x, idx, idx - 3); - - //regression for issue 1283 - let mut s = 0; - let x3 = [246,159,32,176,8]; - for i in 0..5 { - s += x3[index[i]]; - } - assert(s!=0); - - if 3 < (sublen as u32) { - assert(index[offset + 3] == index2[3]); - } -} - -fn dyn_array(mut x: [u32; 5], y: Field, z: Field) { - assert(x[y] == 111); - assert(x[z] == 101); - x[z] = 0; - assert(x[y] == 111); - assert(x[1] == 0); - if y as u32 < 10 { - x[y] = x[y] - 2; - } else { - x[y] = 0; - } - assert(x[4] == 109); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/array_dynamic/target/array_dynamic.bytecode b/crates/nargo_cli/tests/execution_success/array_dynamic/target/array_dynamic.bytecode deleted file mode 100644 index a6ede115a64..00000000000 --- a/crates/nargo_cli/tests/execution_success/array_dynamic/target/array_dynamic.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/array_dynamic/target/witness.tr b/crates/nargo_cli/tests/execution_success/array_dynamic/target/witness.tr deleted file mode 100644 index e2ef1e6b213..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/array_dynamic/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/array_len/src/main.nr b/crates/nargo_cli/tests/execution_success/array_len/src/main.nr deleted file mode 100644 index ac9811e021e..00000000000 --- a/crates/nargo_cli/tests/execution_success/array_len/src/main.nr +++ /dev/null @@ -1,28 +0,0 @@ -use dep::std; - -fn len_plus_1(array: [T; N]) -> Field { - array.len() + 1 -} - -fn add_lens(a: [T; N], b: [Field; M]) -> Field { - a.len() + b.len() -} - -fn nested_call(b: [Field; N]) -> Field { - len_plus_1(b) -} - -fn main(x: Field, len3: [u8; 3], len4: [Field; 4]) { - assert(len_plus_1(len3) == 4); - assert(len_plus_1(len4) == 5); - assert(add_lens(len3, len4) == 7); - assert(nested_call(len4) == 5); - - // std::array::len returns a compile-time known value - assert(len4[len3.len()] == 4); - - // Regression for #1023, ensure .len still works after calling to_le_bytes on a witness. - // This was needed because normally .len is evaluated before acir-gen where to_le_bytes - // on a witness is only evaluated during/after acir-gen. - assert(x.to_le_bytes(8).len() != 0); -} diff --git a/crates/nargo_cli/tests/execution_success/array_len/target/array_len.bytecode b/crates/nargo_cli/tests/execution_success/array_len/target/array_len.bytecode deleted file mode 100644 index 5e53c96c71f..00000000000 --- a/crates/nargo_cli/tests/execution_success/array_len/target/array_len.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9VXWVLDMAx1mlC6ZZ9S6BdHsGKncf64Cpkm9z8CTiszxsCXZSZoRuO8LM/Sk5f4lTF2ZneLtK/QNxaOHZwgfsDvYmzNuwk+i/CaIV5rf8RvbVth+4Yt9zPYWFyCX6Qcu2YEAe+86QfVctkOFwUKWtVeGyXEqKTq+qHveA9SjDC1vZiQbEvANU43u8aoiWsRcf5bOi5ux7uzrhOndvY4WAfIiTn9uDpmP9wj7TxEkXYBePeMbvCHyntPXyNuUS5aU7PAhoo1ItTULNQH7Sm7T7Jce6G91F5przEJsznM79qbRergzMG5gwsHlw6uHFyz7xtKHFBT3/ofCLmOLMz8cfXz2/g4pERccy0yQv2eFq/fjRpyf64Gc4aCUL/TkvWTn3FC6cfFrZyhItTvean6NV/ihJouTjgS6vfyR/pxPwPCdQZOhPqd/4l+hPMECMcMUOpn/mHsQ7c5SP92cJ7tA2qRbWPBDwAA diff --git a/crates/nargo_cli/tests/execution_success/array_len/target/witness.tr b/crates/nargo_cli/tests/execution_success/array_len/target/witness.tr deleted file mode 100644 index 64c8af00834..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/array_len/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/array_neq/target/array_neq.bytecode b/crates/nargo_cli/tests/execution_success/array_neq/target/array_neq.bytecode deleted file mode 100644 index 3414dcf03c1..00000000000 --- a/crates/nargo_cli/tests/execution_success/array_neq/target/array_neq.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/array_sort/target/array_sort.bytecode b/crates/nargo_cli/tests/execution_success/array_sort/target/array_sort.bytecode deleted file mode 100644 index f3e6a4e51af..00000000000 --- a/crates/nargo_cli/tests/execution_success/array_sort/target/array_sort.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1bzW7bMAym7SRt0tT9yZoV7XZZd+h26MTYbuzbXqVB7fd/hFaNDNBOgR700bCAEAhkORFNfSQ/SkpSEBHTXqL3V+zaU9GPe/3E9aduXNIbn4hWviel7f93rfETjnC6jLatcUC2JmBb23g4cTE0p69jIzPPeV5vNzVn/GI21a4sTF7snksuuSiL102ZZXWZl9tqV21NxXlWc1NUWSOee6Kg9w6IjVacacz7HjzvVhKwncA86+SBr10/BsLP+AkD45vvgfj9DCT+FkD8gDHDaPzQvGVrwoLwvPWLwogb4Fqms9bwteuBwuAtoJ/5AYjf70Di7wygq272AuQaRuOH5i27nj0jPG89Uhh5h+StOyB+fwLBD7iu5kcgfn8pDN6aAPEDxgwPhZ/xE+haAZm/T4Hgh1x3PAHx+0dh5O+URslZPBR+xk+gZxQzoC7kvkueKUuJwbGIrCVTlC7uxg8h40dTt6strSxdey7uzYUf28/OXCvPja1fFmJcJNpI6FjQ4XcPUe/6Mz1zca8dnwpbCIfJR46B9yAmpcPzdOgC34K7FGDavnXkae+ZY17cIQvNhmjUxXW/ETe8BM75HOgLGH49AkNv7pH4DVXEYIXnff4zCqDQDFjEUtdeiHvHIobROUgRS6lbxKwjtYuYVkL62pVTGEUsBc75AugLGH7KRQyJn7QzBts5Adp5SdjCfUBMCn66xOnq/ELoSlxPer6z0uarAqkz9Z7Tx1GV9LWcdKWg95qwSaox72u8j1SJD41pK2jiQ+5MV4QqvE0zFPGtSIf4vonrI/F56lw5QNF6b2jcxGfnfYP3kSrxoTFtBU18yN3MmmDEVw9FfGvSIb7v4vpIfJ461w5QtN5bGjfx2Xnf4n2kSnxITD/7g0tf3gB2Lz+NSTMAAA== diff --git a/crates/nargo_cli/tests/execution_success/array_sort/target/witness.tr b/crates/nargo_cli/tests/execution_success/array_sort/target/witness.tr deleted file mode 100644 index e886e599a5a..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/array_sort/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/assert/target/assert.bytecode b/crates/nargo_cli/tests/execution_success/assert/target/assert.bytecode deleted file mode 100644 index 61126dfa0c4..00000000000 --- a/crates/nargo_cli/tests/execution_success/assert/target/assert.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/82SMQ7DIAxFTSAdexYbQzBbr1JUcv8jtAODRbPVSP2LEUjP/v7sALDDt7ZRH6PibyKnWIxHSr3ETkxPjLVJxpTbISSUJb+iMHdJUmqrBSsl7nTmyueAbYYs/2G4C//O2P9mx0I9r1fnMGWn328LPMHUZ97j/eLOtPmKkPwCbgC7D7vKd7DPCBXyr3fqphm13hKQ6RMhBQAA diff --git a/crates/nargo_cli/tests/execution_success/assert/target/witness.tr b/crates/nargo_cli/tests/execution_success/assert/target/witness.tr deleted file mode 100644 index 87be1158f1b..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/assert/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/assert_statement/src/main.nr b/crates/nargo_cli/tests/execution_success/assert_statement/src/main.nr deleted file mode 100644 index 7dab317d924..00000000000 --- a/crates/nargo_cli/tests/execution_success/assert_statement/src/main.nr +++ /dev/null @@ -1,6 +0,0 @@ -// Tests a very simple program. -// -// The features being tested is assertion -fn main(x : Field, y : Field) { - assert(x == y); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/assert_statement/target/assert_statement.bytecode b/crates/nargo_cli/tests/execution_success/assert_statement/target/assert_statement.bytecode deleted file mode 100644 index 16e4554e9e8..00000000000 --- a/crates/nargo_cli/tests/execution_success/assert_statement/target/assert_statement.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/81TMQ7DIAw0JGTsW2wMwWz9SlHJ/59QqaISStlipNxixHC+O9sbADj4x9Lqs1W8BjIdF+MeQk2+EtMLfS4SMcSyCwlFiW8vzFWCpFxywkyBKx0x89HIrCLXoufxy2UGWRrlLDU193rXwdsOdmKb4AlOfc45PgZ/qs1nDGmdwOtAb/ln+Xb6M8KO8taZ2k5jfzw/fADLYG+4cQUAAA== diff --git a/crates/nargo_cli/tests/execution_success/assert_statement/target/witness.tr b/crates/nargo_cli/tests/execution_success/assert_statement/target/witness.tr deleted file mode 100644 index 05fde3ae664..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/assert_statement/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/assign_ex/target/assign_ex.bytecode b/crates/nargo_cli/tests/execution_success/assign_ex/target/assign_ex.bytecode deleted file mode 100644 index 00426c00195..00000000000 --- a/crates/nargo_cli/tests/execution_success/assign_ex/target/assign_ex.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2UwQ7CIAyGO7bh9OCztAO2cvNVXIT3fwQzgwmZ3FaMiesFwuGj/dv+ZwC4wGe06bylE/cFNYIslbEMTtaGeQxk6I6jX9ihdcvExOTYPUY2JrDl2S9+Rk/WBIrOm5hgrQArxFeEldUUtGyEtWzlWJjn2xXuqjATukJNsPlnq+O18Cb6eY0mdRW4PcgNf626e/keYYb8O01Xnipw9+aqQcz84rfMT0Md8ztl98P8djJ1ElSaO8BvL+pa9yDfo6rmJ6mpynLMl+cdT6hUcv5uCgAA diff --git a/crates/nargo_cli/tests/execution_success/assign_ex/target/witness.tr b/crates/nargo_cli/tests/execution_success/assign_ex/target/witness.tr deleted file mode 100644 index 61d1e648a1c..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/assign_ex/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/bit_and/target/bit_and.bytecode b/crates/nargo_cli/tests/execution_success/bit_and/target/bit_and.bytecode deleted file mode 100644 index 1c050588357..00000000000 --- a/crates/nargo_cli/tests/execution_success/bit_and/target/bit_and.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2YW27DIBBFx3bzfr+aLqALgNhO8F+30qj2/qVK/W1DC+3ESZoPX5A/QIpAlnO5zJgjmCcieqaflphfvUWmfzG9aNZkhNMSV+xitKVD7ZN6zDRtzB/Ys4HpY/PTrcvywf/zSZe5itg4Nu8k/7wT3dAZXPE5ZV4IFxPRJfi3JqZME234+0OOTWA+zESxSUq/NmfiYG6rlYp9lpWHXSlT+Sp2xVHlIsuPeyWVzFX+tlNpWqpMHYpjcRCFzNJSVnmRlpVuQiYArcoYe8CtUfgCUkwBSBxIHdPzTR6AhNH0AiSdQA4kvRDXQOKbqCmQOoQDUhe3RmETZwFv49q7E9sWQVX2gL76hIX9xcYgPOyRnrlfDiZ7krt2ynMAFUm1eepxdAodV0kaONAdEu7jd7XuIT5HZyeHNsfUFwSQV1Dud8TGAQINNSMTULTumNoNAa03xufoDAIx2DPi9GdjOiHUSbKSvoAyITdAmbJxAEpDzUnNNEp3Ru0Gil73DJ8jJ17HN7wiThahuG2a8ldLmpt+wZ6FWhJG00stSSfwnf5qSTqRo9qcrS1uKyHnhIPIArfGUNzmzSOQlqZfsWcBSBhNL0DSCeRA0ol0DSRYcfsEpCXhgLTCrfH32mEBb+O6vhPbFkFVroG+NoSFvY9rKNIz9/vIxuEa2lBzYwKK1t1Su6+het1bfI6cFreRMY2ZR755bPsC74CZ84wlAAA= diff --git a/crates/nargo_cli/tests/execution_success/bit_and/target/witness.tr b/crates/nargo_cli/tests/execution_success/bit_and/target/witness.tr deleted file mode 100644 index 545657e08fe..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/bit_and/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/src/main.nr b/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/src/main.nr deleted file mode 100644 index 87e8479300e..00000000000 --- a/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/src/main.nr +++ /dev/null @@ -1,13 +0,0 @@ -fn main(x: u64) { - let two: u64 = 2; - let three: u64 = 3; - - // shifts on constant values - assert(two << 2 == 8); - assert((two << 3) / 8 == two); - assert((three >> 1) == 1); - - // shifts on runtime values - assert(x << 1 == 128); - assert(x >> 2 == 16); -} diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/target/bit_shifts_comptime.bytecode b/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/target/bit_shifts_comptime.bytecode deleted file mode 100644 index 8295790b4bf..00000000000 --- a/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/target/bit_shifts_comptime.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1W7W6DIBS9oLW6Lv2zFwHBin8WuzeZKb7/I0w32K7Yblm9NDbpTQhE8dyPw5XzDAAv8GVsGNzN7TASN0Jjbm7dLJZZyeiwxJlwr8WWEbFnvjjC9Gtc+wK98+8zxIffmw7jDeZcMbTmbk/yyx52AadAz/z3exQL0NVEZEB+1sQeYVIHLH0DcVRM7grVBj4TWt+TJlLioLWtSyuVfBdl05lK6Ko7GGlkZapTaZSyRpu66ZpaNEIrK/uqUb3Lg1+PJQMskUCc5ubE3CWEOacEWLYfzXzGNTuwQN4YMqXDEjjeDVqnAXej+T6I0OwSAj9hHaP+DGKRtImAmwHd4Y+Vd4wbBkGuuqY3UmJypUosNB0Re6LEtm7O0bP/KLEjzLkKldgR/lZi53AeSuyyfSuxkcBX+FFiOUxvH1w8St8ea9nt35+2QPcTyeE+lBhlzgUdFzdTYgXEUWJPaP1QYgsxC1dQatwdrFuJjXnv6DmKqsQoa8qCGLF9AFmXhFRMEwAA diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/target/witness.tr b/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/target/witness.tr deleted file mode 100644 index 343cc4642c5..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/target/bit_shifts_runtime.bytecode b/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/target/bit_shifts_runtime.bytecode deleted file mode 100644 index 4238ab74c41..00000000000 --- a/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/target/bit_shifts_runtime.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/target/witness.tr b/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/target/witness.tr deleted file mode 100644 index dcb5e52682c..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/bool_not/src/main.nr b/crates/nargo_cli/tests/execution_success/bool_not/src/main.nr deleted file mode 100644 index d6b4d7a9fad..00000000000 --- a/crates/nargo_cli/tests/execution_success/bool_not/src/main.nr +++ /dev/null @@ -1,5 +0,0 @@ -use dep::std; -fn main(x: u1) { - assert(!x == 0); -} - diff --git a/crates/nargo_cli/tests/execution_success/bool_not/target/bool_not.bytecode b/crates/nargo_cli/tests/execution_success/bool_not/target/bool_not.bytecode deleted file mode 100644 index 5ab66c438c8..00000000000 --- a/crates/nargo_cli/tests/execution_success/bool_not/target/bool_not.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/6WOwQ3AMAgDQyaCAAn8ukqjkv1H6KNUivrtSZbtj+VaSqnlATJDauftRzr+g2DbYuwiMVoQ04nNpymKzm5kpKZXM+YwseHTBzoJBy11XjkGn487N8yEX77gAAAA diff --git a/crates/nargo_cli/tests/execution_success/bool_or/src/main.nr b/crates/nargo_cli/tests/execution_success/bool_or/src/main.nr deleted file mode 100644 index 4a74027e4aa..00000000000 --- a/crates/nargo_cli/tests/execution_success/bool_or/src/main.nr +++ /dev/null @@ -1,7 +0,0 @@ -use dep::std; -fn main(x: u1, y: u1) { - assert(x | y == 1); - - assert(x | y | x == 1); -} - diff --git a/crates/nargo_cli/tests/execution_success/bool_or/target/bool_or.bytecode b/crates/nargo_cli/tests/execution_success/bool_or/target/bool_or.bytecode deleted file mode 100644 index afcdc64c263..00000000000 --- a/crates/nargo_cli/tests/execution_success/bool_or/target/bool_or.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+WU0QrDIAxFY6X9nsQkNXnbr0xm//8TNmgFGXurg5UdkIs+XGOuZAGABXbCa02Hhm7fzqDT26GMq0jNqRLTHZMXUxQtq5GRmj6SMVcTy148o5NwpU2dN9zp7+h98RwUBnpNA9/7zR7GP+lhHFfXlfJIv5rHfIE84gdfPAfNA2ts86/9nXeejHS7tqgFAAA= diff --git a/crates/nargo_cli/tests/execution_success/bool_or/target/witness.tr b/crates/nargo_cli/tests/execution_success/bool_or/target/witness.tr deleted file mode 100644 index e8991a6747f..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/bool_or/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/target/brillig_acir_as_brillig.bytecode b/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/target/brillig_acir_as_brillig.bytecode deleted file mode 100644 index 37838982490..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/target/brillig_acir_as_brillig.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2bzY7bIBDHx+DPJLuHPkHUQ6XeTJxsnJsfpJdGm1RqL32LnvrOXXeZ9h+Mt6sY1jQCKYIEmPmB7RmY4BURvaPnlDx9hM7XTx+py2bi3zqd19OSStzJqpFXQHmv88r4vU85lDtHHLn7eaozYK0s47zX9amH6yNB3xp0psCT6TK3XVoYc/o7hs4hH1muIYEuZJEBsaQBsWQBsSQzs1Q0tH0V1GfwmzD69nUK6gtdFhY5haUdjr30MHbU08F31rUAhiIAliwgljQgFhkQizBYKqjHZ0oYfQsKy2e99hkvyLI26hzBo0zhWLYAWU39sN2e9puTatTnenM4trt6uzs+tKpVu3b3uGmb5tRu2/3heNjXB7VtTuq8OzRnLUw6kHU6P6e3WmxKd7IuFpuppYwLTVx0uB4TGXrMebwnzzerj4uUepCbkbub39e4M/fXqAaRQc+ppEur7YvZ4Y5TWXCnylZc8CD7jw40TuZqtE+8wxQ09H7oXfvn9D0Nr1UCZaHbyBfaJCNycKfL/XmnS27nxMuu3avx5ZBNDpPZf+8v5NrQKT3oZllXPvgb/eCrnNwZkYLcGmQzXEQUtEHyauwLT5x9+q7zioaG4lbCdr0xGAuL+dgCkWWOCHSNhcXmZklmZhkL/5gr+7EtpG2ryfUZ5N+gPrfILiyyMUxncv0rnOQjlDYWHmBdY+GkuVhkQCxm2CShy/DDmob3l4Q2H3R+p/uWRl/zfpXQ5iP0HbNJlYd5wdRBmXWN2aS5WdKAWLKAWPKAWIqAWMqAWJKZWcb8KddjqHWhy+g7hUUe24YFyEB/yuPHvitdlhZ9SwvXytIX55L7dDqvp6Xfc4l6Ovi+hPEmBt+cLGVALEVALHlALFlALGlALDIgFmGwJFDP6zm2Vbie4zZfdM5rwTujbwV9OOc2X6FvQZd7CtveA23qa/Y6Xv8u+9/PKZVQ/mmZWE7xnNKLKZ5T8sgSzynFc0pmu3hOKZ5TiueUpnNHn+WHJfqs2/RZn6A++qxpLNFnRZ91DXf0WX5Yos+6TZ/1A+qjz5rGEn1W9FnXcMf3QSyyS5A19eRl5UCWfh/k8a2C+pU7WRdB/QWU4/sgE2Xy3/Su5S7J3c3va9xL99fI6xFhl3OaGIyYfgFXBJCIukAAAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/target/witness.tr deleted file mode 100644 index 3e61478b2cf..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_arrays/target/brillig_arrays.bytecode b/crates/nargo_cli/tests/execution_success/brillig_arrays/target/brillig_arrays.bytecode deleted file mode 100644 index 3241cb3905f..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_arrays/target/brillig_arrays.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1Zy1LCQBCckIjkKQgicvKoNx5FlcfcvHnTD/D/P0IXtyudTYCDM1RZMlXW7rLrdE87s5lgIiKx/NiVH7GOvn8Gfh37NT7HGaHPnNV+XP3O1pGer5UVx8Ef4BgbcIQ9+zH1ecI2pHmtg78d6uuzcjmPvK8870QZQwhDSCvgZNKtwaE0GtY6PNbsPyFM4MS0X/ixNNRkJMc1ufbzEfHMdHlsXe6m0rYoWNc0z4hLrstlZfU3L4g/Ys1pLCgmjIUyj4gw4Rfrwg5353yUJ+Ive3iUZ4y/NMNdfzof1Yn4qx4e1RnjZ355D1fcA672RsE5q5yB/4QwgRPT/hNp53iGd4fqg/zSgLU5/vcG7MOPlwbsqG2cPofqJdRICD+V7kuRxUM6knaDWEu7EXSWE4eBHZdt3oOdnUeHfQN0retzN5TmQaKlkfPHzauzY/mUkmbaTaPD5calJgzGtWhoCoo9km4jFdP8URrjhgx5Bc6ZNE12eeB3wiaAm7jMOOZTTZy7O+7oTNbDm2sa+8h7fiHhWlN+8dnHkgaxpAFnvnMsX8LyHuzsgA7adw7iFNJfpH33sR7Y076n2H8i3bzgphONQOnPcb2Bn3YD73zcSGPArEgn1MAN8Rjr8tiw/4Qwx6QB9l8CnSZ0xpLfVBqbBPwcj1s/nxKPmS6PLftPCHNGGkwDTHzZY1Fjc2mM+xdogjtzTnsWOTwnTYBZkSbYfw00seCykK4mXE/3fr4gTSzydUGaAJPrCftvgSYWXJbS1YRr58HPl6SJRe0sSRNgcu1g/500Mf8CQKT9X5nQvgDrDxXyzhkAAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_assert/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_assert/src/main.nr deleted file mode 100644 index 320369c7b67..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_assert/src/main.nr +++ /dev/null @@ -1,11 +0,0 @@ -// Tests a very simple program. -// -// The features being tested is using assert on brillig -fn main(x: Field) { - assert(1 == conditional(x as bool)); -} - -unconstrained fn conditional(x : bool) -> Field { - assert(x); - 1 -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_assert/target/brillig_assert.bytecode b/crates/nargo_cli/tests/execution_success/brillig_assert/target/brillig_assert.bytecode deleted file mode 100644 index 218cb950d9d..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_assert/target/brillig_assert.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9VWUW7DIAw1kDbNtPUsEKCBv11l0cj9LzBt62prLsv6U1O1lhAkwOPxzCPZAcATnMJgqUNh/Yq1vS6cksOyK3SlsMeG2E4zTM30pxhYH/VvWT5obPddPuFvrhRraxxjLoxR/+AM7B3N3zMuIKeJ3YL4WbN7hilN+OcgU4I+cCGNQtWLmgZrE5a3hxDKNBbn3Zsd85yiDXE+JJdcTPF9TN6XFNKU5zzZ7IIvbonZl+UUWgBrQWJGbo92TUeQPyROkjPn27H2M9YD/Bqa4lHMtGFc+cVA+zmazbDnHdYvOE/aAwPT2KzoS309NLwEYEUIwr7WTJ0g1gZkDXMLYwpyPjMmN1xX5e4Yho2T3hNU69Q6Nv1itUpSC6F6kDv8rfbdy+fo7Jf2njVVFUceX3V6IAtXDAAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_assert/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_assert/target/witness.tr deleted file mode 100644 index fdd97d01fec..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_assert/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_blake2s/target/brillig_blake2s.bytecode b/crates/nargo_cli/tests/execution_success/brillig_blake2s/target/brillig_blake2s.bytecode deleted file mode 100644 index 416543ec5f4..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_blake2s/target/brillig_blake2s.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/brillig_blake2s/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_blake2s/target/witness.tr deleted file mode 100644 index 09b25ee04e9..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_blake2s/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls/target/brillig_calls.bytecode b/crates/nargo_cli/tests/execution_success/brillig_calls/target/brillig_calls.bytecode deleted file mode 100644 index f8ce233818b..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_calls/target/brillig_calls.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1czW7bMAym7fgvadL/7hoMw4DtZMdJk9z8AHuEXVY0HbBd9hY77Z1Xt+L6hZGzIpZqtZCAQop+yI+yREo03SMiOqfHFNz/hSqf3v9FqiwT19UqL7qlMjBHq0C8IZSXKs9FfZMSKNeGcCTm56mIAWuukXOi2gcWnk8E/KbAcwB4YlXmviMNxoSeZKgN4iPNMyTghVgih7AMHMISO4Ql6BlLTru6L4f2GOpCMbZpK6E9VeVQQyfV9EPZMwuyI58afjOvIWBIHcASO4Rl4BCWyCEsocCSQzvuqVCMTcktm/XcPZ6S5mxUGwKPNEPDtEOgVRXX8/lmOduUVfmtmK1vVotivri5XpWrcrFa3M5WVbVZzVfL9c16WazLebUp7xbr6k4RiwzQ2tw9ppc6bEbmaG0dNgeaMh408dBhWiYSfOQ8TsjyYrXxkAYW6MZkbvHbkjs2/4wKIOn0nEa0rbVtYTZ44yw1cLvSLrlggfY/Hqic5Gm0SXzDDGnX+qF1bfbpe9p9VgGUQ9Un2tMnaKGDN10ezzddMjsnVm7tVpUvu2wSmMzmd/Mgp4JnZIE30zpw48/Uxi8TMqdEUjKrkKW7iMhphWRV2aeWcDbpl8pz2lUUb8Vt1yiDNreYjSsQaeaIgFebW6xvLEHPWNrcP/Jk33aF1F01uT2G/Ce0JxraqYY2uukkrv+5k2y40trcA8yrzZ3UF5bIISzSbRLQtvthSrvrK4I+H1U+VmMzMVau1wj6fIKxbToptzAvmGooM682ndQ3loFDWGKHsCQOYUkdwpI5hCXoGUubPeV2dLUOVRltZ6ihx7phCDTQnrL8OPZIlSMNv5EG15FmLM4lj6lVXnRLD3OJfGr4PQJ5A4GvTyyZQ1hSh7AkDmGJHcIycAhL5BCWUGAJoJ3Pc6yr8DzHfb6rnM+CYzE2hzGcc58fMDal7TuF7u6BOvU5dx2rr8tee5xSBuU/monl5OOU9iYfp2QRi49T8nFKsp+PU/JxSj5OqTtub7PsYPE2623arK/Q7m1WNyzeZnmbdQhub7PsYPE2623arN/Q7m1WNyzeZnmbdQhu/z2IhnYGtLpGXuYGaKnvQW5fyqmfm6O15dQfQtl/D9KRJr+mN013ROYWvy25R+afkdUQYZNz+hrf7EmsX1T+2t/osfXbF8Js4xMD0swRkf5WGfSMpe2WEIm5wrWAr8rxv1TobgmZhh+/YcVTDIZESQx4IuMxGdThGM4xZFXysB1ahnxqgYExBQJfn1hCDRYbp3Dm2aQp7Z6kcQ3lgFuGlMh1gSElH1Q+VnKMzcoxw9AYKccYsE9UGUNjjoUcvJYnIAf3+SzkODUrR9XgOSG9HKcgx5kqn4Ac50IO3n9nIAf3KYQcl2blmDd4LkgvxyXIcaXKFyDHOyEH64wrkIP7XIMcrt34EnraC7UZLA/rPGnBsu+G3ORDs1iqfboD9RmGwzIWw/t/fuj+b+pw/3Md7yvUgbz/UB7eWxOoY77HUMdr4gTqeO3gvpZ71qo3gAnrDsZ/AfPEEVbPSwAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_calls/target/witness.tr deleted file mode 100644 index 3e61478b2cf..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_calls/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_array/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_calls_array/src/main.nr deleted file mode 100644 index 39b2ad1582c..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_calls_array/src/main.nr +++ /dev/null @@ -1,33 +0,0 @@ -// Tests a very simple program. -// -// The features being tested is brillig calls passing arrays around -fn main(x: [u32; 3]) { - assert(entry_point(x) == 9); - another_entry_point(x); -} - -unconstrained fn inner(x : [u32; 3]) -> [u32; 3] { - [x[0] + 1, x[1] + 1, x[2] + 1] -} - -unconstrained fn entry_point(x : [u32; 3]) -> u32 { - let y = inner(x); - y[0] + y[1] + y[2] -} - -unconstrained fn nested_fn_that_allocates(value: u32) -> u32 { - let x = [value, value, value]; - let y = inner(x); - y[0] + y[1] + y[2] -} - -unconstrained fn another_entry_point(x: [u32; 3]) { - assert(x[0] == 1); - assert(x[1] == 2); - assert(x[2] == 3); - assert(nested_fn_that_allocates(1) == 6); - // x should be unchanged - assert(x[0] == 1); - assert(x[1] == 2); - assert(x[2] == 3); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_array/target/brillig_calls_array.bytecode b/crates/nargo_cli/tests/execution_success/brillig_calls_array/target/brillig_calls_array.bytecode deleted file mode 100644 index 1a8863d91da..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_calls_array/target/brillig_calls_array.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2by3LaMBSGj28YY2yTkKSZrth2ZzAkZscT9B2aKXmI7rrrrn2zvkwfoJWrM/wcBG2nUhATa4axrdv59Eu+6EgMiSin3yH49Qv1cQbXobiO9HWiy0WifKR/AcRzHoI4FTb6WP9fmAf26qpdMYYXwBhZZAygv2M4f6+PmR4vGAZwvrHD0Qzs61QnwJoBM7enpN19hfGqTGS5z1BnrJfAFrIEZ2bJgIEgLhJa4fjgNKX7O0iPDWU4b2zIh21PHLQd7Wzgmm2NgCH2gCU0sAzssnTPqpR2IQJbzMFMKaQNLWui6sgMHEPgYPsZaIdlZgbWTJfFcop/bJd/oeooDPxj4Of7vAD+QvAzaw7MpSin4ip9XkIcj5cKNFBtje22tRszyQ77YJyOaP+ZQORk7Hb3USL0k+M3o91YQJbMMgu3W2qSgSY4ll1qMhKaDMEeM+UGlsIuS3dPlHSoSQG2+f4oHWtSCk3GYI81qQwsV3ZZGmVnQvvh1Hv5Cliu7bJ09/EUbDEX28khHZ/9U7scXf9ci/bzNfL9LWt+QazVmVkziJtAXCiYVf/LcWr14ckhtFx3DHU19cNyuX1cbOfN/EO9WD+1q3q5enpo5+181a4+Ltqm2bbL9nH9tH6s1/Nls50/r9bNs64ssVDX9rkLbWQSlOxPGhN7de1NGnEyKD/0VcAXse02kbAjdSzJ8WB10UkuhErJ3uB31e7Ufh/V2O8+a9p74g4ZX5snjkT4oY+X7oHj2VZJr2cWqo4zOpyFRpCHZx4FvYwnhXU55UkZ0G4muLHDsUDvDOuSAgPrwnmmQhfXHppQ9IfJQ6M4SrscDXp9WBe2W4IunOet0MX2+D3mCa8s2zk1y2VbyBJ5xBJ7xJJ4xDLwiCX1iGXoEUvmEcvII5bcI5axRyyFRyylRyzBmVmOrcyiB5Hj5EqQemd8g3T29IWGeiaGfNh2yx7xru1oZwPXbAtXZicesJQesRQesYw9Ysk9Yhl5xJJ5xDL0iCX1iGXgEUviEUvsEUvkEUtoYLG8WvwQgE32W/A3A9uKIM8nfWS/hQv/3w3tgsn/xz6lG9DFhf/vRugyBXusC+f5LHRx4f+7o0Nd0P93q8/vgNOF/+9O6HILDKwL5/kidHHh/7unQ13Q//dGn9+DLi78f/dCF7aL/j/O8xV0cbSjq8GdmRxOzUkc7o6suV4CLQjs5JCO/krXu8s2tO97I8N5z2qH9ZhP2sVOXBIsZNBFauYDi+sdyv/C4nrn9p9YjvlG5L9g0DeCa3bfIV3eA1jPwJAP2546aDva2cA1rqUFgu+cLLFHLJFHLKGBxfK3X/fuxLVfHrcvvPbbfYOa1qxGcGT7+A83LDMzsKrjWJRz8I3WfStWBv4S+NnvVgF/JfhxrZ/5J6KciuM5k2kHJqf1u/n73fwz6nfz97v5zUHV0e/mPy9rv5tfb44k2v/LuQw/AWJXNkDbPgAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_array/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_calls_array/target/witness.tr deleted file mode 100644 index 375119e60e3..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_calls_array/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/target/brillig_calls_conditionals.bytecode b/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/target/brillig_calls_conditionals.bytecode deleted file mode 100644 index 0c2206246c4..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/target/brillig_calls_conditionals.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2b227TShSGJz6PD0lhbyEuuOABuLBzoI7ERV6FivQCnhOeCwwe9c/UTTNkxl1C/5Kq2LGz1jfLjuOx+t0opd6oP7H49ReNr+9hPbLW43E9HT8XW5+Px7+FehzmvcP42l4X3cJfrhZ5E1j+NG7Q4/gwMlg+eOLI/PepTYFVA7MZz3Lcnvitux5qxUpNngN237DvA0vql6XV6qEHMdTJ/db5fU7a54VZN7UqYEgDslQTtUOPeRjPe/VwbuXQc7PPj/F1ON7/A5f2y7UeuIonuDRwmX2+Addb4Kr8cm0GrvIJrgq4zD7vgOurtZ+Czw6stV/W7tz3tZ5giQWxJIJYUkEsmSCWXBBLIYhFC2IpBbFUglgWL8yi1eP7qeE608I9azO+j7975vONerwfjmkZYExY5wDrplYJDI0AlkoQSymIRQtiKQSx5IJYMkEsqSCWRBBLLIglslg0bMf7+lUAPlPH5DXrphbOmeuALNVEbZx3DcvfgckEzsFCHD9l9cfEcoIlFsSSCGJJBbFkglhyQSyFIBYtiKUUxFIJYqkFsYT+DXdhCT2Pe47lqbnpFuam5vcV56b2by/uh2O6CTAmrHOAdVML56YrASyNIJZaEEsliKUUxKIFsRSCWHJBLJkgllQQSyKIJRbEElksGrbjPPBVAD5Tx+Q166YWztmXAVmqido4Tx+WPywemEzgnD3E8VNWf0zcqMcssSCWRBBLKoglE8SSC2IpBLFoQSylIJZKEEstiKURxLIUxBL63saFJfS8/zmWp55l9PAsw9x34LMM+54E98MxvQ4wJqxzgHVTC59lvBLAshLEshTE0ghiqQWxVIJYSkEsWhBLIYglF8SSCWJJBbEkglhiQSyRxaJhOz43+C8An6lj8pp1Uwuf8dwEZKkmauNznXKiJxr2fQ3vRVaefGSO/DLv0X+JJurHYev3L1z/1qW+fX/t7cTBnJ4H2CWQa9N+3G6Pt+tjt+k+t+v9Xb9rt7u7j33Xd7t+92XdbzbHftvf7u/2t+2+226O3f1uv7kfk6Uech3vf8fnuQS81F+uEwEvg+XEOnZKnV70fI9JWXXsPi5V4JM1xEEK0ahc+Tv5Q40793+MWkgpuqdzXQQiFeYiUMAyLdy/Dlq4Y15auLRwIWjhzsRCC5cWrgsLLVxauC4sixdmoYUbnoUWLi1cFxZauLRwXVho4dLCvaQ/yuqPCVq4l7PQwqWF68JCC5cWrgsLLVxauHOy0MKlhevCQguXFq4LCy1cWrjn+Gjhnu+Psvpjghbu5Sy0cGnhurDQwqWF68JCC5cW7nMstHDDs9DCpYXrwkILlxauCwstXFq4Liy0cGnhttcFLVz1j1u4BeS6VprTHnKNFu5+LgFP+8t1IuCVsEwL98qcWp3O9nzlrZS/kz/UuCv/x6iFlKJ7OtdFIFZhLgI1LNPC/eughTvmpYVLCxeCFu5MLLRwaeG6sNDCpYXrwrJ4YRZauOFZaOHSwnVhoYVLC9eFhRYuLdxL+qOs/pighXs5Cy1cWrguLLRwaeG6sNDCpYU7JwstXFq4Liy0cGnhurDQwqWFe46PFu75/iirPyZo4V7OQguXFq4LCy1cWrguLLRwaeE+x0ILNzwLLVxauC4stHBp4bqw0MKlhevCQguXFm57XdDCVf+4hVtDrmulucZDrtHC7ecS8Bp/uU4EPPxnMFq4V+ZsLGhfeVfK38kfatwr/8eohZSiexoD4/DlsU3MIX4Ch0phrQ6zAAA= diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/target/witness.tr deleted file mode 100644 index fecffa0ee8c..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_conditional/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_conditional/src/main.nr deleted file mode 100644 index 4ddd351ad04..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_conditional/src/main.nr +++ /dev/null @@ -1,14 +0,0 @@ -// Tests a very simple program. -// -// The features being tested is basic conditonal on brillig -fn main(x: Field) { - assert(4 == conditional(x as bool)); -} - -unconstrained fn conditional(x : bool) -> Field { - if x { - 4 - }else { - 5 - } -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_conditional/target/brillig_conditional.bytecode b/crates/nargo_cli/tests/execution_success/brillig_conditional/target/brillig_conditional.bytecode deleted file mode 100644 index 6ad9e8b7228..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_conditional/target/brillig_conditional.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9VWUU7EIBCdQrvdatLEm0CBLfx5FRvp/S9g1HUh+4rVnx2MOwmBAn3z5g1MeySiB7qYTK20JvXPqVe3mW74sNQOXS7sqSK2FoApQP9sA6zl9QPkI+9tP9s7fc9VA2OR9shf9jQ/4Awwl98fgQvxaaIOxH7W1AiY3IS/DnJO0FtyJJJQpVNZwXfGMupkbZynqI1+UVNYvFPWLSevvXbevU7emOitn8MSZhW0NVGvLpi4XkwwYK2JmOSLUe3pSPyHRHNyRr4tjJ9SP9D1Qme7l8vUAVcsDDme82WT8PwIOhwh1paXlxtoWxBzP4LPjtenRZ/djs+BrlpJmCuLeU8VCxRiigL71oveMmJ1jIn5q6LByHlTNLAYtEXuziZhH3dMVPgpdaz6Na2VpBpC9cR3+GvF3fPnaPO7/Z81bQqOaB8buBOz8wwAAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_conditional/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_conditional/target/witness.tr deleted file mode 100644 index 9462cea454b..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_conditional/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_ecdsa/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_ecdsa/src/main.nr deleted file mode 100644 index 978f2c3db4d..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_ecdsa/src/main.nr +++ /dev/null @@ -1,12 +0,0 @@ -use dep::std; - -// Tests a very simple program. -// -// The features being tested is ecdsa in brillig -fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { - assert(ecdsa(hashed_message, pub_key_x, pub_key_y, signature)); -} - -unconstrained fn ecdsa(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) -> bool { - std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message) -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_ecdsa/target/brillig_ecdsa.bytecode b/crates/nargo_cli/tests/execution_success/brillig_ecdsa/target/brillig_ecdsa.bytecode deleted file mode 100644 index 9c1c2a3f3b6..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_ecdsa/target/brillig_ecdsa.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+XdaU9TWxTG8S1DAZlEREREBhEREU8n2iJiQURERERERERaKeI8zxPOIyIiIiKC98X9nPeudDUcn/jOKnliE1P+JWl/Z+29CSEx5x9jzL8m+lj2/78EfU61dQJ0InQSdDK0AzoFOhU6DXo5dDp0BnQmdBZ0NvQK6BzoldC50Kug86BXQ+dDr4EugF4LXQi9DroIej10MXSJtqyb0Tbmx/VO0u87bOuXpmuTrmuQqbPO1pnm6OxydUZ5Oot8veYCvbZCvYYitRarIfb5peAtg94AXQ69EboCehN0JfRm6CroLdDV0Fuha6C3QVvQTmgXtBvaA+2FroX2QfuhA9B10Nuh66F3QDdA74QOmsX9KK+VmOhD9kGZrne5rmuFrl+lrlOVrke1zr1G52vpHF06L4/OpVav36/XWafXU6/uBvUFbb5G8DZB74Juht4N3QK9B7oVei90G/Q+6Hbo/dAd0AegO6EPQndBH4Luhj4M3QN9BLoX+ih0H/Qx6H7o49AD0CegB83ifoz9vJSH7IMmXe9mXdcWXb9WXac2XY92nXuHzrdT59il8+rWufTo9ffqdfbp9fSre0B9gzZfCLxh6JPQQ9AR6GHoU9Aj0Kehz0CfhT4HfR76AvRF6EvQl6GvQF+FvgZ9HfoG9E3oW9C3oe9A34W+B30f+gH0Q+hR6EfQj6GfQD+Ffgb9HPoF9EvoV9Cvod9Av4Ueg34HPQ79HnoC+gP0JPRH6CnoT9DT0J+hZ6C/QM9Cf4Weg/4GPQ+9YBZ/HsnvZkETfYRM9OzLeZczLudazrKc3xETPadyNuU8yhmUcydnTc6XnCk5R3J25LzIGZFzIWdB9r/sednnsrdlP8seln0re1X256iJ7kPZe7LfZI/JvpK9JPtH9ozsE9kbsh9kD4zpWo/rmk7o2k3qGk3pWkzrzGd0trM6wzmd1bzOJPZ7qjE//t5gbK8Z27ysX3s4l8XvvazfZUwgMCYSGJMIjMkERgeBMYXAmEpgTCMwLicwphMYMwiMmQTGLAJjNoFxBYExh8C4ksCYS2BcRWDMIzCuJjDmExjXEBgLCIxrCYyFBMZ1BMYiAuN6AmMxgbEkjsY/8bfIUoKZlhEYNxAYywmMGwmMFQTGTQTGSgLjZgJjFYFxC4GxmsC4lcBYQ2DcRmC0CIxOAqOLwOgmMHoIjF4CYy2B0Udg9BMYAwTGOgLjdgJjPYFxB4GxgcC4k8AYjKPxT/wtspFgpk0Exl0ExmYC424CYwuBcQ+BsZXAuJfA2EZg3EdgbCcw7icwdhAYDxAYOwmMBwmMXQTGQwTGbgLjYQJjD4HxCIGxl8B4lMDYR2A8RmDsJzAeJzAOEBhPEBgH42i0///p3+UNEcw0TGA8SWAcIjBGCIzDBMZTBMYRAuNpAuMZAuNZAuM5AuN5AuMFAuNFAuMlAuNlAuMVAuNVAuM1AuN1AuMNAuNNAuMtAuNtAuMdAuNdAuM9AuN9AuMDAuNDAuMogfERgfExgfEJgfEpgfEZgfE5gfEFgfElgfEVgfE1gfENgfEtgXGMwPiOwDhOYHxPYJwgMH4gME4SGD8SGKcIjJ8IjNMExs8ExhkC4xcC4yyB8SuBcY7A+I3AOE9gXIijMWaTx3fb11n6LPdSiN2fMdH2Wux+Nwm21xLhetNs3489HLavg3G5hpDliP+MrWT1G9uz/XqzzOI9KeP3uS4rQ2cb+5wUmH2JPidBJ4PDYbOn/uS12Pun2j7HvhfieFGW0/6e8T4M323v5bZqPZ6IzxVxup0hyxUI+72Wxxuu9Tv9Tq/fO+Tyu90Rv8fvC4QDPivg9LgjzmFvwD2sb7ZgMyaYpbsBaalZ2htONpqlvcFgyPzdNxTDx39FWV3dLXkAAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/src/main.nr deleted file mode 100644 index bae24b8c4b1..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/src/main.nr +++ /dev/null @@ -1,36 +0,0 @@ -struct MyStruct { - operation: fn (u32) -> u32, -} - -fn main(x: u32) { - assert(wrapper(increment, x) == x + 1); - assert(wrapper(increment_acir, x) == x + 1); - assert(wrapper(decrement, x) == x - 1); - assert(wrapper_with_struct(MyStruct { operation: increment }, x) == x + 1); - assert(wrapper_with_struct(MyStruct { operation: decrement }, x) == x - 1); - // https://github.com/noir-lang/noir/issues/1975 - assert(increment(x) == x + 1); -} - -unconstrained fn wrapper(func: fn (u32) -> u32, param: u32) -> u32 { - func(param) -} - -unconstrained fn increment(x: u32) -> u32 { - x + 1 -} - -unconstrained fn decrement(x: u32) -> u32 { - x - 1 -} - -unconstrained fn wrapper_with_struct(my_struct: MyStruct, param: u32) -> u32 { - let func = my_struct.operation; - func(param) -} - - - -fn increment_acir(x: u32) -> u32 { - x + 1 -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/target/brillig_fns_as_values.bytecode b/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/target/brillig_fns_as_values.bytecode deleted file mode 100644 index c2d85c0264f..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/target/brillig_fns_as_values.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/target/witness.tr deleted file mode 100644 index 981a689c7e3..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_hash_to_field/target/brillig_hash_to_field.bytecode b/crates/nargo_cli/tests/execution_success/brillig_hash_to_field/target/brillig_hash_to_field.bytecode deleted file mode 100644 index 35a3ceb4afe..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_hash_to_field/target/brillig_hash_to_field.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/7WTUQ6AIAxDhwiEaPzxIngD7n8qs0iTZvLn7M+WkeyVolFEgjyK1LMw66O2b7qC367Gfhfqz1Grmasy9d3JR/bPqSXyWif3PMb56vw+yooi02/A5ibEVy/J10vDXgi+wNnofCEf2TmTQEzsTcT7i7uPO0fDAlvfqkxmyKJQff3b3TEcMQD0auQG4TTtV2UEAAA= diff --git a/crates/nargo_cli/tests/execution_success/brillig_identity_function/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_identity_function/src/main.nr deleted file mode 100644 index 5ad4e913e92..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_identity_function/src/main.nr +++ /dev/null @@ -1,35 +0,0 @@ -use dep::std; - -struct myStruct { - foo: Field, - foo_arr: [Field; 2], -} - -// Tests a very simple program. -// -// The features being tested is the identity function in Brillig -fn main(x : Field) { - assert(x == identity(x)); - // TODO: add support for array comparison - let arr = identity_array([x, x]); - assert(x == arr[0]); - assert(x == arr[1]); - - let s = myStruct { foo: x, foo_arr: [x, x] }; - let identity_struct = identity_struct(s); - assert(x == identity_struct.foo); - assert(x == identity_struct.foo_arr[0]); - assert(x == identity_struct.foo_arr[1]); -} - -unconstrained fn identity(x : Field) -> Field { - x -} - -unconstrained fn identity_array(arr : [Field; 2]) -> [Field; 2] { - arr -} - -unconstrained fn identity_struct(s : myStruct) -> myStruct { - s -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_identity_function/target/brillig_identity_function.bytecode b/crates/nargo_cli/tests/execution_success/brillig_identity_function/target/brillig_identity_function.bytecode deleted file mode 100644 index 361904605fa..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_identity_function/target/brillig_identity_function.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1XW27CMBDcvHiWV6FQ+tcb2HlA8sdVihruf4TGqi2tTP4yRo7klVAsE01mZzeT9RcRfdN/JN0voucwezd9FcNCRjgswfnGbD1n19jKZ8LWNxCPCV4nkTGu854813o/sfZ5zua/KfXU9oYhKjlmAsbmzVKIS1m217yVhfwReXOvK1FW90sta1nV1W9eF0Vbl/W1uTdX0ciyaOWjaoqHBouBWAkuR/GqFw/JmfNNe9ZxT084eEmees/WcU2OG99FkVIHuBnhmt9V3hm+RoJBeq0pb151tb9aPn+Fx8CxT1tlSFOm8YunhjxMDdYDUdjIqWECxJrR+KYGJGfOlzdnmBoGYs60oGjcBfk9Nai8F/gaOZ0a0Jqa8NlEp0CsJY3PRJGcOd83tg4mOhBzqQVF467IbxNVea/wNXJqokhNVfPa474LzujjTDgiYjlyPY15mb1N99uy/837wo9SEdsb8/FxxvIwwY+J5pkJ00rtpz33Zta9XJu0R0Nzfzh6drEGYu1ofFMTkjPn+87WYWoaiLnTgqJx9+T31KTy3uNr5HRqQmtqwmcT3QCxDjQ+E0Vy5nw/2DqY6EDMgxYUjXskv01U5X3E18ipiaI1NeGziW6BWCcan4kiOXO+n2wdTHQg5kkLisY9k98mqvI+42vk1ESRmkYWRx5/wNR6zuEoAAA= diff --git a/crates/nargo_cli/tests/execution_success/brillig_identity_function/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_identity_function/target/witness.tr deleted file mode 100644 index f58a9a214f5..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_identity_function/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_keccak/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_keccak/src/main.nr deleted file mode 100644 index 96c8178381c..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_keccak/src/main.nr +++ /dev/null @@ -1,27 +0,0 @@ -use dep::std; - -// Tests a very simple program. -// -// The features being tested is keccak256 in brillig -fn main(x: Field, result: [u8; 32]) { - // We use the `as` keyword here to denote the fact that we want to take just the first byte from the x Field - // The padding is taken care of by the program - let digest = keccak256([x as u8], 1); - assert(digest == result); - - //#1399: variable meesage size - let message_size = 4; - let hash_a = keccak256([1,2,3,4], message_size); - let hash_b = keccak256([1,2,3,4,0,0,0,0], message_size); - - assert(hash_a == hash_b); - - let message_size_big = 8; - let hash_c = keccak256([1,2,3,4,0,0,0,0], message_size_big); - - assert(hash_a != hash_c); -} - -unconstrained fn keccak256(data: [u8; N], msg_len: u32) -> [u8; 32] { - std::hash::keccak256(data, msg_len) -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_keccak/target/brillig_keccak.bytecode b/crates/nargo_cli/tests/execution_success/brillig_keccak/target/brillig_keccak.bytecode deleted file mode 100644 index ce2c4cf5765..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_keccak/target/brillig_keccak.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/brillig_keccak/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_keccak/target/witness.tr deleted file mode 100644 index 3dcb51e0f3b..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_keccak/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_loop/target/brillig_loop.bytecode b/crates/nargo_cli/tests/execution_success/brillig_loop/target/brillig_loop.bytecode deleted file mode 100644 index c98ae239095..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_loop/target/brillig_loop.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1UbQrCMAxN9ykInsEjJGu7pf+8isPu/kdQWYWs+G8pTPBBSWjhJS8p7wQAZ1hhXqdK8QpbVCneUrQ4OhenIZKlOw5hZo/OzyMTk2f/GNjayI6nMIcJAzkbafHBLrjCKHJVggv3YayT/hwm04/7QIo9o+y3FnmT7U6+dwU0QVYnn+Ply51q8RJLqgvwNqD3+UvpbvR3hILy8DP94MjG18LvGZ9izxvj60T+N76dnG2hQfVwbON76+71d1TU+DRnarIeJZ6CTQW3KgoAAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_loop/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_loop/target/witness.tr deleted file mode 100644 index c366b559bbe..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_loop/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/target/brillig_nested_arrays.bytecode b/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/target/brillig_nested_arrays.bytecode deleted file mode 100644 index 7a055b31419..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/target/brillig_nested_arrays.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2c63bbNgzH6btl+SZf0nZZsy7r9tmSbMf+5ldpNucZ9mB7oe1JNmrGzt8IrDgxUHM94jk9oUwG/AECaYYE2nHOddy/pfHPv7p7XmqHn7vDz8VlJa3pyVpYctaNOH25O8BGB7sjfyS8hzbUd0pMbX2bLVrAOjzUW7pjrL19msw+Nfa8g3oLbNg2sGFHV2buZXSBvwn8vsTQ3oG2ri5HMU+539FzF8aNdMfNInesvy9l7zcClp4uS/F+Y2W7ehl94CddiT2G9hh06ytz1GBMkkvPfbtxMy9j8IL+A4Fj8BX1Rz7sI83FHtPDwA9L52LPzkZ55I7196VsLg6AZajLYjYXR8BPuhJ7DO04F0fKHDUYk+TS8wjGtZiL5+rfD0B/i+/ac/XvXFl/x/pIa9GQ6WEwD0vXoqHduGtuC0n/kcBh8a5O6Y++OtYdt9gXof6+lK3FY2BJdFmKtXiiK3PpZUyBn3Ql9hjaJ6DbVJejeL+JO7YpPU/txl15GbMX9J8JHLOvqD/yYR9pLiZMDwM/LJ2Lid24r94XIYvy+zLbF82Bn3Ql9hjacV80V+aouWOf28HzHMa12Bedq38/AP0t9kXn6t+5sv6O9ZHWohnTw2rdPLUWod2o1IFF+VwqLVuL2gJLIyCWZkAshmeHr2bpBMTSDYglCoilFxBLHBBLPyCWQUAsw4BYRgGxjANiSQJimQTEMg2IpXZllsg9//svgvYmfEZ7wTp8RnvZBnxWF8ag9hl8RrJJht+z/HXmeDOhn7UtcZwdPON9Ro3xXZNlGhDLJCCWJCCWcUAso4BYhgGxDAJi6QfEEgfE0guIJQqIpRsQSycgllZALM2AWBoBsdQFlhtdli84pn8PtL+kcRrQ/ufhp/8+6NjYpji/Jt+su+PzTSoYY0Y2aoHdOqyf/13lWLeUc9D4EXwmnRljzFSP9bO6D5HORTGObShwxsA5EPpJsRdNeJZiQCx8ZQTc/P7Al0TQbQScY9bPylcSwXboK1OBMwHOCetn5SvSPT76ylzgnAKndMdzA3XSowG/Mxf6YX3IZFr50jvQS1p3Prjnur8DPd6zfla+hBw0PvrSrcD5ATi/Y/2sfOlW4ERf+ihw3gLn90I/rJOPvAc9LPziDhilNeaToMcd6PED62flF8hB46Nf3Aucn4DzR9bPyi/uBU70i88C5z1w/iT0+xnq1I5rzGehH9Y/Mpnebr+wfni2R21+r8HPD9VeasMdJ5n0nVyUxsut9DCSm1W8RbF6b2sjuUsjuSsjuf9rf6iSAC/nxAW+AfU/Dj/xMgcva66UIPhrW9+eFglz64jpj7biNnHONGluYbApK/wbg02lQwA8uHBCHS8RfcHEJQxy0t5QGtg4xeBbskVZMhcGCCknSBVB+Xw/dc0EKeVkh8L3xsDPE2TwAgP7YZ3sg4lUY6iTPbQTNQxsnJ6yx+gN9hiW2IPXaf52oS1m8gzmWm6wJmSvnb94AKvsI0UgPx5IEotjLFQME3yK+audqONlTICfbDqGZ/Ij7Id1sg8mokygTvbQTu4wsHF6yh7JG+wxfsEe2glgBjbOTtlD2z94XdqPxEyewdqztlgjyU5U6ky31+zPcH2X9mfK7A8GNl5esr5bJE3ipQmxOMZCBQNPlRMci/VdOWmwWN8x+YVsOoFnHmDC6zy5ERNmcD3TTrQ0sHF6yh7TN9hjUmIPXi9bzwwvBbcGa8Lqkr+vlH2k2J/hdw2xOMZCxTAxtpi/ygluxfzFS0oegIX+eupik+yDCZk3UCd7aCfnGdg4PWWP+RvsMXvBHsrsmYGNs1P20PYPXi/7e5PkSUHqfq/yO7RToX70n4JVAT/H41cBP1XADytVwA/Uq4Cfi0oV8AP1KuDnv1IF/ED9mwn4QZl1ZdkNkJUv1svl/iHbp3n6ZZFtHzerxXL1uN6km3S1Wf2WbfJ8v1luHraP24fFNl3m+/Rptc2fDsKaCrL2T0V5aEgGdfoBAU09WUcBAS2o8yAAX/CLRVsnx8bhdhw6Y2e1eEktA7ltp+f8Vnq39d+RaYSNpk3xtAonD5W/AX7Wo+3vXAAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/target/witness.tr deleted file mode 100644 index ce3a9267de0..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_slices/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_nested_slices/src/main.nr deleted file mode 100644 index f239d94fdc1..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_nested_slices/src/main.nr +++ /dev/null @@ -1,74 +0,0 @@ -use dep::std::slice; -use dep::std; - -// Tests nested slice passing to/from functions -unconstrained fn push_back_to_slice(slice: [T], item: T) -> [T] { - slice.push_back(item) -} - -struct NestedSliceStruct { - id: Field, - arr: [Field] -} - -unconstrained fn create_foo(id: Field, value: Field) -> NestedSliceStruct { - let mut arr = [id]; - arr = arr.push_back(value); - NestedSliceStruct { id, arr } -} - -unconstrained fn main(a: Field, b: Field) { - let mut slice = [create_foo(a, b), create_foo(b, a)]; - assert(slice.len() == 2); - - assert(slice[0].id == a); - assert(slice[0].arr[0] == a); - assert(slice[1].id == b); - assert(slice[1].arr[1] == a); - - slice = push_back_to_slice(slice, create_foo(0, 42)); - assert(slice.len() == 3); - - assert(slice[0].id == a); - assert(slice[0].arr[0] == a); - assert(slice[1].id == b); - assert(slice[1].arr[1] == a); - - assert(slice[2].id == 0); - assert(slice[2].arr[0] == 0); - assert(slice[2].arr[1] == 42); - - slice = slice.push_front(create_foo(1, 43)); - slice = slice.push_back(create_foo(2, 44)); - - assert(slice.len() == 5); - - let pop_front_result = slice.pop_front(); - slice = pop_front_result.1; - assert(pop_front_result.0.id == 1); - - let pop_back_result = slice.pop_back(); - slice = pop_back_result.0; - assert(pop_back_result.1.id == 2); - - assert(slice.len() == 3); - - let mut remove_result = slice.remove(0); - slice = remove_result.0; - let mut removed_item = remove_result.1; - assert(removed_item.arr[0] == a); - - remove_result = slice.remove(1); - slice = remove_result.0; - removed_item = remove_result.1; - assert(removed_item.arr[0] == 0); - - let last_item = slice[0]; - - assert(last_item.id == b); - slice = slice.insert(1, removed_item); - - assert(slice.len() == 2); - assert(slice[0].id == b); - assert(slice[1].id == 0); -} diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_slices/target/brillig_nested_slices.bytecode b/crates/nargo_cli/tests/execution_success/brillig_nested_slices/target/brillig_nested_slices.bytecode deleted file mode 100644 index cc11ca67f4f..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_nested_slices/target/brillig_nested_slices.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/brillig_not/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_not/src/main.nr deleted file mode 100644 index bc94810efb9..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_not/src/main.nr +++ /dev/null @@ -1,11 +0,0 @@ -// Tests a very simple Brillig function. -// -// The features being tested is not instruction on brillig -fn main(x: Field, y : Field) { - assert(false == not_operator(x as bool)); - assert(true == not_operator(y as bool)); -} - -unconstrained fn not_operator(x : bool) -> bool { - !x -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_not/target/brillig_not.bytecode b/crates/nargo_cli/tests/execution_success/brillig_not/target/brillig_not.bytecode deleted file mode 100644 index d77bd56fb4a..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_not/target/brillig_not.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1VW27EIAx0II9FrfYsEGADf71Ko5L7X6Bqla5RLUr70TgrZbUjRSCSDIONPQoAnuEKiU+JBscXHPU2mIaPS1fkcnGPO3IbQThzzFuypnAU+KzoST7oPx/wM1cNmQv8Rv7xTfMLj6roPBMtwBcT3QP7XdNnwskt+OsiCwzMO24kMCnlpnKHvTOX1Rfn0jQmY82rHuMcvHZ+vgQTjA/+bQzWpuDCFOc46WicTWbx0ablCsnAtaCwlu+MWtaSx39JDKdmqrcj8yccFXwXdMZRiqkjWmljyOfJjaFlzg9teLlptcXeiqzJSqzzuwF2bAiUswz+1sLqgLewbuH0glFzRe7hnD4Xz0DWHk7Pw3kTp1+FU6evdRNup6dFtNXpe+BrSAMcz+k5NVO9JzJ/OP2/cR9Or7fBnICvSAXRWF7GFZ+KOUARABAAAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_not/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_not/target/witness.tr deleted file mode 100644 index 438b4901fa7..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_not/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_oracle/target/brillig_oracle.bytecode b/crates/nargo_cli/tests/execution_success/brillig_oracle/target/brillig_oracle.bytecode deleted file mode 100644 index 850dfecc098..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_oracle/target/brillig_oracle.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/7VWTUvDQBDdJmnaxLZqWutHCgY8ekmw4EmIv6SgLJ4smFp/vxmdMc8xCpLNQJjZ3dn33kwnbT1jzMB8mg9xm5Xs805WrDXuPfuofjx1Fjrnz/MQ6nSFOawxhow141oCVcu4fuYcP9nXzXb//GCrzc6+7O320WLpPnsPYAQePyKvZQ/LwnsR4MpeaJoWl25aUQyAJ2BcH/jEj9zy5hHgj4B/BpyRU87ihmodA34GGoTLh5w16Eog78B8N8pPOaZRqeybrXb2r5GJ2XsAN2H/35GZgLRY7VF5U3Un72YfIxNDa0pYT4G3j5ERfByZFDj7GBkcyQw04MhITga6LkEr4Rz+guODl5wr1c9j01igzqj3Ryqvr14I/oBriJQWWidKC+XOVe0JaJfaJedaYZ6YxuRdwfuLljyJA+jNArjkPAcu0nbK61LOOzaNal+Crsw0dQkXzvUSdMtcE8YZx/prC2dHcm6hJrKLhv5rduQ+9e9c5UUQ4y96Chj6jg/nd8DfV09XoCsDndhT2VuBbnlPf/xzKh2KayWo7R3cEJu1vwkAAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_pedersen/target/brillig_pedersen.bytecode b/crates/nargo_cli/tests/execution_success/brillig_pedersen/target/brillig_pedersen.bytecode deleted file mode 100644 index 074aac798cf..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_pedersen/target/brillig_pedersen.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9WZ3XLTMBCF5Thx6ogG0h9oQxscGghQaJwMF1zmWbiBB+HB6Yo95FQIT2ZYDY1mMpa8yp5vVytHdSvnXOF+tfL+M3B/Nti3em3/ra0LO19tTs7egXCWB8LZPxDOQSZOaT/0Wt9/Ku336R72X0n3YO/RvTKKvSY7WkX9rVE8lX2+24HySxsr95Gtxkb8D6P8FNF4S/0jymFtHK/4GJEWuKDjyd4jjpEtR3gO11H8GDPfvqzlf2bNsVaVxmjoM9Qi51RaVy16iu+JMYv4G7rdusJ/nFuuw7EtQ9gPTyleaI5pfKx9nod+n+z8/IR9rtdj5Z/Y8q/Fx0mCf0LjZ9rneSfED3tF/LAvI/4zW/5Qj6fuYeuqxzNita4FYTlXX6ek89xWJzxPzqP4MIaWJ4ZxRhaf0M7xLOPcwrfU3mfSfGGruSmimBpigFZJc74T1xfty/650D7X6SX1L+h7iG8afUf0X9rGF+poShxbGkOL6+gyI4tPaI/+kocrY+2aNNG6niFXxHJtyxJ+T2akBS7oeLJPiWNmnJOCNOEX4xnp5jizGMcSfiM4Fmld68vxvTLOK84sWFf4Rx7ByWeWuTGDaDVu/3zMieW1LUtY7xtTn5uv4mNB/I1ewe7JfkOxLYzzXJAm/GK8IN0ce8g4lrCHOBZpXTXD8b0xziv2UKP+4B95BGfuc/9yF+5vTT73v9X+MjPHO+K4TnBAn+eh309wlmT/plc5vw/V33u9x7/Jt7ZxhePTB/XVI81b0ryz1Qw1/sk9bF01fkcsK1uWsK78Ag5c0PFk5zpvbTnCM2wVxY8x8+3LWj4C1lWCFed6qe+PiXncR11iXk3+eU+sM8TXRvFhDC0+r68ysviEdo73E3HMjdut1YTyj3uYy38bxnvY9GU7BGQTliqc+kfUTzXjoi+tGgAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_recursion/target/brillig_recursion.bytecode b/crates/nargo_cli/tests/execution_success/brillig_recursion/target/brillig_recursion.bytecode deleted file mode 100644 index 136286eb8dc..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_recursion/target/brillig_recursion.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/82Za26DMAzH84BQCmWPE3CE8GrhG1dpN3qkadIuu6Il6n9Z+qnJaksoxk7tnx0KQSjGWMZ+hF8OYcb6ckiju2Jtsxn1fdLwcLE08grQv8yYO/ZVFOhzIA4Vvk86BdbcU2dl/EmE9ZHQqxpyCLCrCHlTE4ubw+aQMNo5H2Zc2UrgitEPBVw19CGB9cmAYZWCXQX7tonAhzKDvvGwSEIsCSGWlBCLIsSSEWLhD2bJ2d9nZA7+DGzC+a17P7f3dOGJk3vmYe3bCLVjnhnOtzByh++RLBkhFkWIJSXEkhBikYRYhIelCMvScsjp7lsKyF86fLf2LbsIvUKZQd95WCQhloQQS0qIRRFiyQixbAix5IRYtoRYCkIsJSEW/mCWW3vundMr3HNbn7vnrowuPHEqzzys/SlC7ZhnhnObC/fcFQGWkhBLQYhlS4glJ8SyIcSSEWJRhFhSQiwJIRZJiEU4LBz8q9Ts+l/D5+azE2u1vRjd+taef3r84ob/1egvYLNzrS9jnm9Jsxn1fdJgTBE4toBYnd73/XJol6ZrjrqdTuOg++G0H5uxGcbhvR27bhn78TCdpoOemr5bmvMwdWcTTAaItZxXeTv+18c5GS7Wr49ziUcXYMOX+9A1MSeP28eKRb5YYyxSEiFuysJd/LHqTsOvkYaQpHvKHUaUb+IgIW7aHwAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_recursion/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_recursion/target/witness.tr deleted file mode 100644 index aab7ddd1f05..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_recursion/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_references/target/brillig_references.bytecode b/crates/nargo_cli/tests/execution_success/brillig_references/target/brillig_references.bytecode deleted file mode 100644 index b16745ba8a3..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_references/target/brillig_references.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2cS1PbMBSFZWwnkZVACK/0AaU8+qAPgqF0m/7Abrtr1/0L/XdFru70RIgwTHXJWfTOdCJZ9T3fPZIdJw5eM8YU5k+U0MaQbfPwOvu3uCjy5ZrFrL8CrL35txaN9aA9z6Tfy+/PrL7JUYdc64G7yqvR2jDfqXmOPTKgb4GtBF97efm6NVJHLDXo+XDAsKbI4u7QNgntWsEHE/kgUSdYSiKWioilWDGLNbePr9SxhOetGl5/FLf3wZo0jz85X8fHQAMMNQFLRcRSErHE66mBcTxfDPLyXfoc/ZCrAs0BaMu4vJGPwv9r8rJ073fWLMay47YBX1xelpnnGIZcFnRGeXW69TGM6huCzybUZqGtxeIS2k3Ch7veVzW8MZE3JuGNREnEUhGx1EQsPSKWPhHLgIhF+3z3EJaGiEXz3PtQliERS7Filruu20eRV3jdLmP+3PizuL0P1rSuUBPqzKEvWnjdPiJgGRKxOCKWhojFErEMiFj6RCw9IpaaiKUiYimJWOL3qwbG8Tot9+dfn2Mj5KpAU3RKGP8KjJ5lMy9L973A2CzGsuuCTUVfPMsk5BqDzlZenW59TKL6pL8FczGGthaLS2gr6LQ2qtnHsnkWfb/fdmhPgG8nsw8F6Ehe6e/APKTWR24Wl9BW0GltVLOPZXMi+n6/3dDeBr69zD4UoCN5pS9a6NVEkcUltJuEDw2M7wKjBH6nNlXwy0R+SUwTLCURS0XEUhOx9IhY+kQsAyIWS8TSELE4IpYhEcuIiGWdiGWDiGVMxLJJxDIhYtkiYtkmYtkhYtklYtkjYilWzHLXfZVp5BXeV5Gx+PdQ00RNTxRqQp059EUL76tMCVj2iFh2iVh2iFi2iVi2iFgmRCybRCxjIpYNIpZ1IpYREcuQiMURsTRELJaIZUDE0idi6RGx1EQsFRFLScQSf2ZpYBzv1TxN7PsstJ9CHfuZ6/A5nodcFWiKTgnjX8KHGrkH/yIvS3cf8MAsRhH159B+Ab68VGA5fADLS2A5yssy05r3Y+A/DK/C7mB8H2o7zsxRgKbklf6xnm7rc5zcU/9JguPkEesXLQvbDlbM4oDhUI+ldQltDR0b1exj2XGOc3Ia2kfA9yovXzcnpxGL9EULvTpQZHEJbQWd1kY1+1g2J8ii8Vus1yHXKei8yextATqSV/qihf47RRaX0FbQaW1Us49l8yz6fr+3of0a+M4y+1CAjuSV/hnMgzAcKbK4hHYD205h21nkjd/2LtrXM37Iy9jN53uzGMvm8wOwfMzLMtP6O9Zz4Jdahd3BOP4u5DwvR7cuP5pFT6V/rqd71eW4p/5ZgmP2iPWLloVt71bM4oDhvR5Ld80UazewDc8RMo7niIvEvm1oXwC3xu/Ar8zfaME34bgM7Svg0Di+JX8Fmvh36jL+LfosrPH57Nrc9mQfPPkU2tfgicYxfw2eiOY5eCLj38GTvln8LmYNGHM/d0PYDDAZs/jMjV6Co5+ZowAdySt90XLAUCmyuIR2P2z7/wwhrmcIKRwTn3HNo7erWvOp56A81pqP12LW4k1K4CZ+A56PDDZRTQAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/src/main.nr deleted file mode 100644 index 7941765a327..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/src/main.nr +++ /dev/null @@ -1,22 +0,0 @@ -use dep::std; - -unconstrained fn main( - a: Field, - a_pub_x: pub Field, - a_pub_y: pub Field, - b: Field, - b_pub_x: pub Field, - b_pub_y: pub Field -) { - let mut priv_key = a; - let mut pub_x: Field = a_pub_x; - let mut pub_y: Field = a_pub_y; - if a != 1 { // Change `a` in Prover.toml to test input `b` - priv_key = b; - pub_x = b_pub_x; - pub_y = b_pub_y; - } - let res = std::scalar_mul::fixed_base(priv_key); - assert(res[0] == pub_x); - assert(res[1] == pub_y); -} diff --git a/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/target/brillig_scalar_mul.bytecode b/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/target/brillig_scalar_mul.bytecode deleted file mode 100644 index 54f39157f74..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/target/brillig_scalar_mul.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9WX3VKDMBCFA4HSEGj9a7W+gjfIAzhce6fv/zA2uGfmNGa4MatlZ5hskibn201ZoDHGFObb7PnamJ+G+Una4Xf2WuTba9DkLFfCaVfCWa2Es14J50aJM9intO58NeLXNIY6UdEY5i2NYb6kMRvlw9E8jOvQlCnGTf4zGELMrey1E26XV2MM+22j/BRRfyLfUQu2LeXV5+Wb63kbsaDvqQVDqcjiE9oKOqOLYg62dCbQD+s68Vvi6zPnoSAd7It+T0xgsIosPqGtoDO6KOZgS2cC/bBuJ35HfPvMeShIB/uiDy3OVaXI4hPaGjqGdEI8ZULzViHPN7JXIRc0wGLpNy/E9ya+ozVcO+8UWKGDfdGHFtfOWpHFJ7Q5D+0V5IEZ/isP3RXkAQzNH+eB75HWpO+R+7wcc12HPmyprkO/E644Bn7/OORlnd+jj8QCzQPl7EH8I42xD3uUtkqssTT/Lm1v9Gr4KRHTnpifxD/RGHx+Jj9TTPEaS/MfFFP4j8fnnfUj34hAZS4/WAJQbS4/Rr4AiTwWkzERAAA= diff --git a/crates/nargo_cli/tests/execution_success/brillig_schnorr/Prover.toml b/crates/nargo_cli/tests/execution_success/brillig_schnorr/Prover.toml deleted file mode 100644 index c5c3ab5101a..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_schnorr/Prover.toml +++ /dev/null @@ -1,9 +0,0 @@ -message = [0,1,2,3,4,5,6,7,8,9] -pub_key_x = "0x17cbd3ed3151ccfd170efe1d54280a6a4822640bf5c369908ad74ea21518a9c5" -pub_key_y = "0x0e0456e3795c1a31f20035b741cd6158929eeccd320d299cfcac962865a6bc74" -signature = [ - 5, 202, 31, 146, 81, 242, 246, 69, 43, 107, 249, 153, 198, 44, 14, 111, 191, 121, 137, 166, - 160, 103, 18, 181, 243, 233, 226, 95, 67, 16, 37, 128, 85, 76, 19, 253, 30, 77, 192, 53, 138, - 205, 69, 33, 236, 163, 83, 194, 84, 137, 184, 221, 176, 121, 179, 27, 63, 70, 54, 16, 176, - 250, 39, 239, -] \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_schnorr/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_schnorr/src/main.nr deleted file mode 100644 index 0ffd6af6fcd..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_schnorr/src/main.nr +++ /dev/null @@ -1,10 +0,0 @@ -use dep::std; - -// Note: If main has any unsized types, then the verifier will never be able -// to figure out the circuit instance -unconstrained fn main(message: [u8; 10], pub_key_x: Field, pub_key_y: Field, signature: [u8; 64]) { - // Is there ever a situation where someone would want - // to ensure that a signature was invalid? - let valid_signature = std::schnorr::verify_signature(pub_key_x,pub_key_y,signature, message); - assert(valid_signature); -} diff --git a/crates/nargo_cli/tests/execution_success/brillig_schnorr/target/brillig_schnorr.bytecode b/crates/nargo_cli/tests/execution_success/brillig_schnorr/target/brillig_schnorr.bytecode deleted file mode 100644 index 37525d68f00..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_schnorr/target/brillig_schnorr.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9Xb91KrQBSA8TWYojd6vb3ae8feNfb+EL7/S5hPYVzjn8KM384wMOiEHyyB3XNO7kMIXeG5Je2lO9tmX2943fL/a2Xr9H1tpau4z0rLMlYExkRg7BYYqwJjTWCsC4wNgbFHYOwtwViG85PE2SzQGb9fy/L2hY9/j/YLjJ8FxgGB8YvA+FVg/CYwfhcYfwiMPwXGXwLjb4Hxj8D4V2D8JzD+FxgHBcYhgXFYYBwRGEcFxjGBcVxgnBAYJwXGKYFxWmCcERhnBcY5gXFeYFwQGBcFxiWBcVlgTAXGFYFxVWBcExjXBcYNgXFTYNwSGLcFxh2BcVdg3BMY9wXGA4HxUGA8EhhbAuOxwHgiMJ4KjGcC47nAeCEwXgqMVwLjtcB4IzDeCox3JRjz1p+tqbGtZttJtC//HUQl2pd0nGdP9Pe81aLtViH29Yda8dc25Zwb0bXgGPVij/HkbhR7LdJmZs37orOf8nPI+7TR0S9JtN0XrevRNS64A59v5JAdoBJefmhTjS48UG4oCqopVm5mMDqH4tCB9kJxI8WDFOdR/EZxGcVbFEdRfERxD8UzFKdQ/EFxBcULFAeMtJfR9kLymOQsyU+SiyTvSI6RfCK5Q/KE5ATBf4LrBK8JDvMNIrhJ8JDgHMEvgksEbwiOEHxgcs/kmckpkz8mV0xe8skBg1sGjwzOGPwwuODlzcuRlw8Pdx6ePJzuwtv2CCQHvQKtNAAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_schnorr/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_schnorr/target/witness.tr deleted file mode 100644 index 67be3f493a9..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_schnorr/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_sha256/target/brillig_sha256.bytecode b/crates/nargo_cli/tests/execution_success/brillig_sha256/target/brillig_sha256.bytecode deleted file mode 100644 index 62a42953dc2..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_sha256/target/brillig_sha256.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2d+5eNVRjHv2Oux7gmIclM97tz5mLOuI4QIYQQchkGIYQQQgghhBBCCCGEEKL+s/aTPcvTHqtf9ne33r3W+671rNnbWev7fr/P857Ptpg58yeAv/DwKjDVylaZ2hc6+yJnX+zsS5x9qbMvc/YZZ9/a2Zc7+zbOvq2zb+fs2zv7Ds6+o7N/wtl3cvZPOvvOzv4pZ9/F2Xd19t2c/dPOvruzf8bZ93D2zzr7ns6+wtlX2r3MEfZ14NHsi+xrJWqWGTuncjuPtrbv7W1/O9o+drL96mz70sXm72Zzdrd5eljfPe39K+29C9Dyav6zBvs163flCnha2QLlscKunzP1vKkXTL1o6iVTL5t6xdSrpl4z9bqpN0y9aeotU73Ei6mcqSpT1aZqTNWa6m2qzlTeVL2pPqb6mupnqr+pAaYG2kyDVN+62q8ZO1t9lah1A6kXJfxZZYuV14zy3JynnX29iHxfyVGo7lem7lmkeljMvW8uo/SbL/c90aDWxcpLCdeLPI7/vP/xmNxylavXC9VrpeSeFKDl89q8Lw1236psxrmvXP81C+2ljOolm2uDf8+gTN1Lrgr7NYNH7xP9vmml1s1eW7C2gWRWaxaStVspreps75qaprqqplx1bla2qr4xX5utqW3snc/lc7X52jlV+erqpnxNvq6+sb4uW5+rqW7Kza2tr55rxZ4jar3Ny5j9vw5Cpmftd7BaNz+wrR7zTAQ4MFo8e24f2yHwgx9iSIMD6A4B7+EPlXsIf0ZZOA8I03MhsafPE7WGIj44MT1rv++odQonT82htqFs3WFINpwk9zD+jILCqYjY0xeIWsMRH5yYnrXfd9U6hZOn5nDbULbuCCQbTpJ7BH9GQbzK3/CGPUbXt68jEQeUi4mZXyRqjUJ8UGZ61n7fU+sUyp6ao2xD2bqjkWwoS+7R/BkF8SqHx0jwoTwGcUC5hJj5JaLWWMQHZaZn7fd9tU6h7Kk51jaUrTsOyYay5B7Hn1EQr3J4jAEfyuMRB5RLiZlfJmpNQHxQZnrWfj9Q6xTKnpoTbEPZuhORbChL7on8GQXxKofHePChPAlxQLmMmPkVotZkxAdlpmft90O1TqHsqTnZNpStOwXJhrLknsKfURCvcnhMAh/KUxEHlDPEzK8StaYhPigzPWu/H6l1CmVPzWm2oWzd6Ug2lCX3dP6MgniVw2Mq+FCegTig3JqY+TWi1kzEB2WmZ+13llqnUPbUnGkbytZtRLKhLLkb+TMK4lUOjxngQ3k24oByOTHz60StOYgPykzP2m+TWqdQ9tScYxvK1p2LZENZcs/lzyiIVzk8ZoMP5XmIA8ptiJnfIGrNR3xQZnrWfj9W6xTKnprzbUPZuguQbChL7gX8GQXxKofHPPChvBBxQLktMfObRK1FiA/KTM/a7ydqnULZU3ORbShbdzGSDWXJvZg/oyBe5fBYCD6UlyAOKLcjZn6LqLUU8UGZ6Vn7/VStUyh7ai61DWXrLkOyoSy5l/FnFMSrHB5LwIfycsQB5fbEzL2IWisQH5SZnrXfz9Q6hbKn5grbULbuSiQbypJ7JX9GQbzK4bEcfCivQhxQ7kDMnCVqrUZ8UGZ61n4/V+sUyp6aq21D2bprkGwoS+41/BkF8SqHxyrwobwWcUC5IzFzjqi1DvFBmelZ+/1CrVMoe2qusw1l665HsqEsudfzZxTEqxwea8GH8gbEAeUniJmriFobER+UmZ613y/VOoWyp+ZG21C27iYkG8qSexN/RkG8yuGxAXwob0YcUO5EzFxN1NqC+KDM9Kz9fqXWKZQ9NbfYhrJ1tyLZUJbcW/kzCuJVDo/N4EN5G+KA8pPEzDVEre2ID8pMz9rv12qdQtlTc7ttKFt3B5INZcm9gz+jIF7l8NgGPpR3Ig4odyZmriVq7UJ8UGZ61n6/UesUyp6au2xD2bq7kWwoS+7d/BkF8SqHx07wobwHcUD5KWLm3kStvYgPykzP2u+3ap1C2VNzr20oW3cfkg1lyb2PP6MgXuXw2AM+lPcjDih3IWauI2odQHxQZnrWfr9T6xTKnpoHbEPZugeRbChL7oP8GQXxKofHfvChfAhxQLkrMXOeqHUY8UGZ6Vn7/V6tUyh7ah62DWXrHkGyoSy5j/BnFMSrHB6HwIfyUcQB5W7EzPVErWOID8pMz9rvD2qdQtlT85htKFv3OJINZcl9nD+jIF7l8DgKPpRPIA4oP03M3IeodRLxQZnpWfv9Ua1TKHtqnrQNZeueQrKhLLlP8WcUxKscHifAh/JpxAHl7sTMfYlaZxAflJmetd+f1DqFsqfmGdtQtu5ZJBvKkvssf0ZBvMrhcRp8KJ9DHFB+hpi5H1HrPOKDMtOz9vuzWqdQ9tQ8bxvK1r2AZENZcl/gzyiIVzk8zoEP5YuIA8o9iJn7E7UuIT4oMz1rv7+odQplT81LtqFs3ctINpQl92X+jIJ4lcPjIvhQvoI4oPwsMfMAotZVxAdlpmft91e1TqHsqXnVNpStew3JhrLkvsafURCvcnhcAR/K1xEHlHsSMw8kat1AfFBmetZ+f1PrFMqemjdsQ9m6N5FsKEvum/wZBfEqh8d18KF8C3FAuYKYuYGodRvxQZnpWfv9Xa1TKHtq3rYNZeveQbKhLLnv8GcUxKscHrfAh/JdxAHlSmLmQUSte4gPykzP2u8fap1C2VPznm0oW/c+kg1lyX2fP6MgXuXwuAs+lB8kPLfM58FjZuSbu9LqiF8Bh7yRBSTFeAiNUlNlpjKmWpsqNyW/UVt+gau8weXXU3UwJR++L5/1LB8tKp9kJx+cJJ/TIT8WLj+FKD/0It9jLd/SJ99BIv9hKf8+Lv8cU2GqEi2vvwFihR7EXboAAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_sha256/target/witness.tr b/crates/nargo_cli/tests/execution_success/brillig_sha256/target/witness.tr deleted file mode 100644 index 15a1553cc33..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/brillig_sha256/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_slices/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_slices/src/main.nr deleted file mode 100644 index 4455acc02f8..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_slices/src/main.nr +++ /dev/null @@ -1,152 +0,0 @@ -use dep::std::slice; -use dep::std; - -unconstrained fn main(x: Field, y: Field) { - let mut slice: [Field] = [y, x]; - assert(slice.len() == 2); - - slice = slice.push_back(7); - assert(slice.len() == 3); - assert(slice[0] == y); - assert(slice[1] == x); - assert(slice[2] == 7); - - // Array set on slice target - slice[0] = x; - slice[1] = y; - slice[2] = 1; - - assert(slice[0] == x); - assert(slice[1] == y); - assert(slice[2] == 1); - - slice = push_front_to_slice(slice, 2); - assert(slice.len() == 4); - assert(slice[0] == 2); - assert(slice[1] == x); - assert(slice[2] == y); - assert(slice[3] == 1); - - let (item, popped_front_slice) = slice.pop_front(); - slice = popped_front_slice; - assert(item == 2); - - assert(slice.len() == 3); - assert(slice[0] == x); - assert(slice[1] == y); - assert(slice[2] == 1); - - let (popped_back_slice, another_item) = slice.pop_back(); - slice = popped_back_slice; - assert(another_item == 1); - - assert(slice.len() == 2); - assert(slice[0] == x); - assert(slice[1] == y); - - slice = slice.insert(1, 2); - assert(slice.len() == 3); - assert(slice[0] == x); - assert(slice[1] == 2); - assert(slice[2] == y); - - let (removed_slice, should_be_2) = slice.remove(1); - slice = removed_slice; - assert(should_be_2 == 2); - - assert(slice.len() == 2); - assert(slice[0] == x); - assert(slice[1] == y); - - let (slice_with_only_x, should_be_y) = slice.remove(1); - slice = slice_with_only_x; - assert(should_be_y == y); - - assert(slice.len() == 1); - assert(slice[0] == x); - - let (empty_slice, should_be_x) = slice.remove(0); - assert(should_be_x == x); - assert(empty_slice.len() == 0); - - regression_merge_slices(x, y); -} - -// Tests slice passing to/from functions -unconstrained fn push_front_to_slice(slice: [T], item: T) -> [T] { - slice.push_front(item) -} - -// The parameters to this function must come from witness values (inputs to main) -unconstrained fn regression_merge_slices(x: Field, y: Field) { - merge_slices_if(x, y); - merge_slices_else(x); -} - -unconstrained fn merge_slices_if(x: Field, y: Field) { - let slice = merge_slices_return(x, y); - assert(slice[2] == 10); - assert(slice.len() == 3); - - let slice = merge_slices_mutate(x, y); - assert(slice[3] == 5); - assert(slice.len() == 4); - - let slice = merge_slices_mutate_in_loop(x, y); - assert(slice[6] == 4); - assert(slice.len() == 7); -} - -unconstrained fn merge_slices_else(x: Field) { - let slice = merge_slices_return(x, 5); - assert(slice[0] == 0); - assert(slice[1] == 0); - assert(slice.len() == 2); - - let slice = merge_slices_mutate(x, 5); - assert(slice[2] == 5); - assert(slice.len() == 3); - - let slice = merge_slices_mutate_in_loop(x, 5); - assert(slice[2] == 5); - assert(slice.len() == 3); -} - -// Test returning a merged slice without a mutation -unconstrained fn merge_slices_return(x: Field, y: Field) -> [Field] { - let slice = [0; 2]; - if x != y { - if x != 20 { - slice.push_back(y) - } else { - slice - } - } else { - slice - } -} - -// Test mutating a slice inside of an if statement -unconstrained fn merge_slices_mutate(x: Field, y: Field) -> [Field] { - let mut slice = [0; 2]; - if x != y { - slice = slice.push_back(y); - slice = slice.push_back(x); - } else { - slice = slice.push_back(x); - } - slice -} - -// Test mutating a slice inside of a loop in an if statement -unconstrained fn merge_slices_mutate_in_loop(x: Field, y: Field) -> [Field] { - let mut slice = [0; 2]; - if x != y { - for i in 0..5 { - slice = slice.push_back(i); - } - } else { - slice = slice.push_back(x); - } - slice -} diff --git a/crates/nargo_cli/tests/execution_success/brillig_slices/target/brillig_slices.bytecode b/crates/nargo_cli/tests/execution_success/brillig_slices/target/brillig_slices.bytecode deleted file mode 100644 index a6ccdec6237..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_slices/target/brillig_slices.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2dB5wkVbXGq6d6pqe7Js/upE29CZbcs4El7LK1sOScowiYUFFRMItKDuaIGBEQEFQMYIKFJYiKioCiEsQlGlAMRInv3bY++pszd+fB27o733vs/f3mNzfVOf9z7qlbVbdCx1EUFaL/pPi//5qi0Qntafa/tnppuJCfrFpIzqZAnC4t7f7P/3Lmd+Yve8ahhfJpTkwt+fus1kysHVm+OV8dc51/isY/BVNOKd9MPmwJwFLKZBVJT2u+eur7TMnYhzJ0JYYhFEvi0R1AzwjfIo01zsxSCcBSfhEsFWJJ8mWpzyVtpAtcCf1He0wcbfly1GMyMfajzHwvlLVpnFnLVFcaZxbex9hn6Feh/6grUl2bscPJ6PDY1hnANuiBXJQ7ia89y3cQS95zM8svkp+gJ6b2jbP/7RlfJ20H5q5otE97otE+7Q3gU+iBXJR7iS87pXi+zbFMzJdloZPZtwbsg//7yJYQeicYvd1Gb5l8jDTWvD+BePvz5a05vQMkPyUd3VQ/GMBPA2R7gXSgPqb89lEjDVIe+w+YXcz2efpxvtdsk1B7X2Cb+4kjpTJ0ublhETHkHJ/18e4zDCh3U32/x1995C+0Yy4oUzufL+Ycr8Nj8fN4gqEnIEvi0c1+KAn4AQy9VId+mFd4n+FjU7+xw9k26LFtKIBtg8Y2lIeID3PDYDiWeSy/SH6CnpjaD8v+43g/ibYD8+RotE+nRqN9Oi1fO+o+hR7IRXka8U3J8lPDsdR8LJMMi9NbDaCX5aekAzwx9Tkq+98eiMfJmBE1EmKjSuMxPctzP+SL1B7Tf7S/hfidrJm0HeTPyvIcj+uYOmf7uvnaXo9H6IFclNclvtlZfp1wLDUfy0zD4vTOCeADlp+SDvDE1Oe92f/2QDxOxvpRIyE25tB4rJfluR/yRWpvIn60n0T8TtYGtB3kb5jlOR43NnXO9k1ytr1AeiAX5U2Ib6Msv3E4lpqPZQPDEuLatmDkp6QDPDH1+Wj2vz0Qj5Mx3HDD87HRQuOBRfBhasv7+pTlF0nnRPIJ2s8knzi+ubQdmOdleY7xBabO2bFpvnbUYxx6IBflTYlvfpZfQCzVfFlqzuaFmaz5Hj8gjXVdvJD4Ns+Zz+ndguSnpIP1bpmv3mHWi+ti6EB9TPmvR420JeURY2B247qZpx/nF5htEmrfLLDNmxNHSmXocvvPOVnexQnidSFtt5nHlirZgvYmkrOQ5MO+zQLYt9DYt9Aw8zXr3IAsiUc3+6Ek4AcwLKA69ON5yo4dxzjPrVt4bAu530IuylsSH+Ka55a8z+OczVhD2tzjB6Sx5lZeg9oqX7763LqE5KekY5Gpz9MvrBdzK2SjPqb8zZHfN4gxMLtxXezpx/ktzDYJtS8ObPNWhsmOp9t/rs/yLk4Qr4tou8UeW+aQLWiPSc4ikg/7Fgewb5Gxb5Fh5rl1YUCWxKOb/VAS8AMYtqA69ON5yo4dxzjPrUs8tqUBbIMeyF1idDg+xDXPLXlfk4Sar5dmsrby+BZprPl6Kdm8Tb589fl6GclPSQfr3TZnv7BezNfQgfqY8o9FjbQt5RG3YHaxsrWnH+eXmG0Sat86sM3bEEdKZehy++SDWb5MupfSdlt7bGkhW9A+h+QsJfnov3UA+5Ya+5YaZp6vFwVkSTy62Q8lAT+AYQnVLTUslWj02HGM83y9zGNbyP0WclHelvgQ18vCsdR8LEsNS6h7DSw/JR08d6FPVza5h7zXwPfQERtVGo/tsjz3Q75I7by2i/Y+4neydqDtIH/HLM/xuLOpc7bvkq/t9XiEHshFeRfi2ynL7xyOpeZj2cGwhLrXwPJT0gGemPrMMPEY4l7DblEjITb4XsOuWZ77IV+kdr73hfY5Jh53p+0gf48sz/G4l6lztu+ds+0F0gO5KO9NfHtm+b3CsdR8LLsbllD3Glh+SjrAE1Of+SYeQ9xr2DdqpD2IDeOxT5bfl9pC7BeQXySdc8gnaN/SxPh+tB2Y98/yHOMHmjpnx0E521EgPZCL8kHEd0CWP5BY8h5bfi62ifQcGMDmyNgcGfuYJRZiKQqxNAuxtAixlIRYWoVYykIsFSGWRIilTYilXYilQ4ilU4ilS4ilW4ilR4ilV4hlghDLRCGWPiGWfiGWASGWQSGWISGWSUIsk4VYpgixTBVimSbEUhVimS7EMkOIZaYQyywhltlCLOsIsawrxDJHiGU9IZb1hVg2EGLZUIhlIyGWjYVYNhFiqQmxDAuxzBVimSfEMl+IZYEQy6ZCLAuFWDYTYtlciGULIZYthVgWCbEsFmLZSohliRBLKsSyVIhlayGWbYRYlgmxbCvEsp0Qy/ZCLDsIsewoxLKTEMvOQiy7CLHsKsSymxDL7kIsewix7CnEspcQy95CLPsIsewrxLKfEMv+QiwHCLEUxpmlHI1+t5rfk9iP6vDuwv5Ud3CWP4DqDiGbUNfk0Yt3AA6iOjyLfzDV4Zl4yHXll7eNZm2ibV6W5fmbDIdm+aKH9UCPTS+jOjAe6pHHY4ht0ux/bfVSfQxZT0pl6KoQw6ECLAcIsewvxLKfEMu+Qiz7CLHsLcSylxDLnkIsewix7C7EspsQy65CLLsIsewsxLKTEMuOQiw7CLFsL8SynRDLtkIsy4RYthFi2VqIZakQSyrEskSIZSshlsVCLIuEWLYUYtlCiGVzIZbNhFgWCrFsKsSyQIhlvhDLPCGWuUIsw0IsNSGWTYRYNhZi2UiIZUMhlg2EWNYXYllPiGWOEMu6QizrCLHMFmKZJcQyU4hlhhDLdCGWqhDLNCGWqUIsU4RYJguxTBJiGRJiGRRiGRBi6Rdi6RNimSjEMkGIpVeIpUeIpVuIpUuIpVOIpUOIpV2IpU2IJRFiqQixlIVYWoVYSkIsLUIszUIsRSGWWIilybDwewmhf3MAeiAXZX4HBQyHBGRJPLrZD6G/6/9C/ACGg6kO/fj3OuzYVUgO/8bIYR7bDg9gG/RALsqHE9/Ls/xh4Vjms/wi+Ql6Ymp/R7aD4ndbjqDtwPyKaLRPXxWN9umr87Wj7lPogVyUX018r8zyrwrHUvOxHGFYnN5qAL0sPyUd4Impz0k0niF4nIwjo0ZCbFRpPF6T5Y8k7pZ8Oeay/CLpbCGfoP0DJsZfS9uB+XVZnmP8KFPnZL8hXzvqMQ49kIvyG4jv9Vn+qHAsNR/Law2L0xvi9+BYfko6wBNTnzNNjIf43as3RY2E2ODfg3tjlud+yBepvYn40f4FE49H03aQ/+Ysz/F4jKlzth+bs+0F0gO5KB9LfG/J8seEY6n5WI42LCHmloKRn5IO8MTU56smHkPMdW+LGunNxIbxeGuW537IF6mdf58Q7ZeYeHw7bQf578jyHI/vMnWO59352l6PR+iBXJTfTXzvzPLvCsdS87G83bA4vUP56p1XMPJT0gGemPpcbuIxbx4n47iokRAbQzQe78nyxxF3iHka8oukk3+fEO3XmBh/L20H5vdleY7x402ds+OEnO0okB7IRfkE4nt/lj+eWE4OyIJrafjq5MB6TzJ632/0uvE4MRqZCqacUv4k4j0lAO/JRi/i5xTSe2q+eutz0GkkPyUdbO/pAew9jXxeIB2ojyl/Jw401C8in4G5Qv7ifpw/0WyTUPspgW0+lThSKkOXmz9ujhsMOcdZLTIMNsac/04w/nH7ycnEF4jNuw+cbPh4Xev4gCyJRzf7oSTgBzCcSHXox/tuiPNHjocTSJdLMbU/ZI6Tp9B2UVZ3qvGp8/Ppps7JPiNfO4Z5zoFclM8gPsxBpxNLiHMgngPgpyHyKdqfMD49g7YD8wc8Pv2Qx6cfDuBT6IFclD9MfB/M8h8Kx1LzsZxhWEKtsbH8lHSAJ6Y+xWzgQq6xfTRqJMRGlcbjI1me+yFfpHZef0B7hfidrI/RdpD/8SzP8fhJU+ds/1S+ttfjEXogF+VPEd8nsvwnw7HUfCwfMyyh1sNYfko6wBNTnz4TjyGus86MGgmxwethn87y3A/5IrXz+gPaJ5t4/AxtB/lnZXmOx8+ZOmf753O2vUB6IBflzxPfZ7P858Kx1HwsnzEsodbDWH5KOsATU585Jh5DnM98MWqks4gN4/GFLP9FaguxX0B+kXTy+gPaNzEx/iXaDsxnZ3mO8XNMnbPj3JztKJAeyEX5XOL7cpY/h1jOD8iCdQD46vzAes8zer9s9JbJHxH1jYzvkM4j3gvy5a3PBReS/JR0sN6vBvDThWR7gXSgPqb89ghw6ufS2dl/MLv4Ot/Tj/Pnmm0Saj8/sM0XEEdKZehyZi4qNhhyjs/6eJ9vGFA+j+qZ82zjG+fjr5h+ZWrntYKc43V4LH4eTzCcE5Al8ehmP5QE/ACGc6nOjneoYxrHA+KFj2loP8gc0y6g7aKs7kLjU+fni0yds+PinO0okB7IRfli4sP+exGxhDhfuYh8cwHpgk/R/krj04tpOzB/zePTb0SjfXpJAJ9CD+SifAnxfT3LfyMcS83HcrFhCbVWwPJT0gGemPocvQbWCr4VNRJio0rj8c0sz/2QL1I7rxWg/W0mHr9N20H+d7I8x+Nlps7Z/t18ba/HI/RALsrfJb5Ls/xl4VhqPpZvG5ZQawUsPyUd4ImpzwlrYK3g+1EjITZ4reB7WZ77IV+kdl4rQPtpJh5/QNtB/g+zPMfjFabO2b48Z9sLpAdyUV5OfJdn+SuIJe9xcDKvCmAfZDZlclHm34DO+/jp5K1YA2OFWFpBtoTQe6XRe7nR6+J1eTQyjXWdeSXxXp0vb31eu4bkp6TjKqq/NoCfriHbC6QD9THlz6PrzGsb2efnAjC7/W+Fpx/nl5ttEmpfEdjmq4kjpTJ0OTPPymwtEA/6w16MjU/mctPH2XINtYe2hceV867P5R626/Jlq8f0j0h+Sjo41q8P4JMfkb0F0oH6mPKXUUxf38g+P+ZgdjF9racf56822yTUfm1gm68jjpTK0OXMvIjWTnLer2o8d0AuyldRPXMuN75JqB3HtzJtz2snIfalqww/ytcQHxiuCMiSeHSzH0oCfgDDcqpDPxwrK9HosauQHD53XOGxLcTcDz2Qi/K1xIf9eAWxhHi2YQX5Bn7iZxvQfqM5H+fjFJiv8/j0eo9Pf5yvHcM8v0Iuyj8mPsy314djqflYrjUsodYrWH5KOsATU5/b18B6xU+jRkJsVGk8fpLluR/yRWrn9Qq0rzTxeANtB/k/y/Icj78wdc72G/O1vR6P0AO5KN9IfD/P8r8Ix1LzsdxgWEKtV7D8lHSAJ6Y+f10D6xU3RY2E2OD1il9m+ZuIO8QaMeQXSSevEaP9YRPjN9N2YL4ly3OM/9rUOdm35uzPAumBXJRvJb5fZflfh2Op+VhuNiyhnpdg+SnpAE9MfZ5bA89L/DZqpFuIDePxmyzP/ZAvUjuvyaG9ubnB72T9jraD/NuyPMfjHabO8dyZr+31eIQeyEX5TuK7PcvfQSwh1uTuCmAfZGJNDmVek1sZ0K+4dse4rwys9/dG7+1Gb5nGNqK+nFLK/554786Xtz4H3UPyU9JxF9XfG8BP95DtBdKB+pjyVXzAhPq5hP0WzG5fWenpx/k7zTYJta8MbPPdxJFSGbrcnDQxs7VAPOgPe3lsco6JYZ/elcZnPlvuNGx2jF2f2z38oWMrpfK9pPe+fPXW96X7SX5KOngfeyCAvfeTvQXSgfqY8vNoX3qgkX1+jMFcIX9xP87fbbZJqP3ewDbfRxwplaHL7UtzmhsMOcdZjecsyEX5LqpnztuMb5yP/2D6lWl7Xre7J4AP7zL8KEMXr9vdEZAl8ehmP5QE/ACGO6kO/fgYHeL8mOPhD6TLpZjatzPnuvfQdlFWd7fxqfPzvaYuwPw4PNb+wnPOyix/b2Cf8jGX52f4FO17GJ/eR9uB+X6PT/8Yjfbpn/K1o+5T6IFclP9EfJgT/xiOpeZjuc+whFpDZPkp6QBPTH0OofEMtYb4l6iREBtVGo8/Z3nuh3yR2puIH+1HmHh8kLaD/L9meY7Hh0yds/3v+dpej0fogVyU/058f8vyD4VjqflYHjQsodYQWX5KOsATU583mngMsYb4z6iREBu8hviPLM/9kC9SO6+voP1YE4//ou0g/+Esz/H4qKlztj+Ws+0F0gO5KD9GfI9k+UeJJcT6yhMB7INMrK+gzOsrTwb0K66xMO5PBtb7uNH7iNFbprGNqC+nlPKPE+9T+fLW56CnSX5KOp6g+mcC+Olpsr1AOlAfU/4jdE34TCP7/H4LZrevPOnpx/nHzDYJtT8Z2OaniCOlMnS5OekkWl950vSHvTw2OcfEsE/vk8ZnPlseM2x2jF2fRzz8oWMrpfIzpPfZfPXW96XnSH5KOngfw86ep73Pkb0F0oH6mPLn0L7EEw/GGMwV8teICYryT5ltEmp/JrDNzxJSyuVMl9uXzqT1lZzjrMZzFuSi/ATVMyf2X/RzPv636Vem7Xl95el8+UccmyEXZeji9ZVHA7IkHt3sh5KAH8DwGNWh3+O0PY8dxpbPS9F+qTkvfZq2i7K6p4z9zifPeHyS81w2PFZs8/xgj7Whrg/4+Ag/8Tt1aL/S+PRZ2g7Mz3l8WiiM9mlTgDmrUBjpU5Shy/Fh/kJbAJaajwW+aiK91Sh/vSw/JR3gianPDWtgLaRIfkBsQE/9G/w4nlC/Ih1j0M5rIWi/ycRjM20H+S0m9lw8tnrisRwgHltNDKBcpngsZfnWgHHhZCYB7EtobFIqV8mv7QH9ivNPjHt7IazeitFbMnrLNLZIpjji2rNCvB0B5qBOMxdAR0L1XQH81El+KpCOTpqDkH+Qzpe7yFnYbztoX4GfuR/ny2abhNrbA9vcYfb1DsPq5qSVdO3Zbvq3eMamIwCn1dtufOazpWzY7Bi7PqVxiK2Uyl2ktzvAvtRj9qVuE9OuvjeAvT1mX4KOHtqXkH+W9qVeGkOMcTftS/AX9+N8h9kmofauwDZ3m/jrNqxuX3qYrj27Aox3l2HoMvEdGc4W4xvn47bC6H4J2dBGx0+XYmpvzm5Ghjw36ySWVnPs5jm6TCz4TTbmDjVXcUopz/N7RLwqLEUhlmYhlhYhlpIQS2v2X4GlLMRSEWJJhFjahFjahVg6hFg6hVi6hFi6hVh6hFh6hVgmCLFMFGLpE2LpF2IZEGIZFGIZEmKZJMQyWYhlihDLVCGWaUIsVSGW6UIsM4RYZgqxzBJimS3Eso4Qy7pCLHOEWNYTYllfiGUDIZYNhVg2EmLZWIhlEyGWmhDLsBDLXCGWeUIs84VYFgixbCrEslCIZTMhls2FWLYQYtlSiGWREMtiIZathFiWCLGkQixLhVi2FmLZRohlmRDLtkIs2wmxbC/EsoMQy45CLDsJsewsxLKLEMuuQiy7CbHsLsSyhxDLnkIsewmx7C3Eso8Qy75CLPsJsewvxHKAEMuBQiwHCbEcLMRyiBDLy4RYDhViebkQy2FCLIcLsRwhxPIKIZZXCrG8Sojl1UIsrxFiOVKI5bVCLK8TYnm9EMtRQixvEGJ5oxDLm4RYjhZiebMQy1uEWI4RYjlWiOWtQixvE2J5uxDLO4RY3inE8i4hlncLsbxHiOU4IZb3CrG8T4jl/UIsxwuxnCDEcqIQy0lCLCcLsZwixHKqEMtpQiynC7GcIcTyASGWDwqxfEiI5cNCLB8RYvmoEMvHhFg+LsTyCSGWTwqxfEqI5dNCLGcKsXxGiOUsIZbPCrF8Tojl80IsXxBi+aIQy5eEWM4WYvmyEMs5QiznCrGcJ8TyFSGW84VYLhBiuVCI5atCLBcJsVwsxPI1IZavC7F8Q4jlEiGWbwqxfEuI5dtCLN8RYrlUiOUyIZbvCrF8T4jl+0IsPxBi+aEQy+VCLFcIsSwXYrlSiOUqIZYVQixXC7FcI8RyrRDLdUIsPxJiuV6I5cdCLD8RYvmpEMsNQiw/E2L5uRDLL4RYbhRi+aUQy01CLDcLsdwixPIrIZZfC7HcKsTyGyGW3wqx/E6I5TYhltuFWO4QYrlTiOX3Qix3CbH8QYhlpRDL3UIs9wix3CvEcp8Qy/1CLA8IsfxRiOVPQix/FmL5ixDLg0IsfxVi+ZsQy0NCLH8XYvmHEMs/hVj+JcTysBDLI0IsjwqxPCbE8rgQyxNCLP8WYnlSiOUpIZanhVieEWJ5VojlOSGWqKDDUhBiaRJiiYVYikIszUIsLUIsJSGWViGWshBLRYglEWJpE2LpVDo2RuPLUiYGpDK1N1Fde1YXU12TRx7a0b/5v/+OaxstJ7TtrCelMnRViKE9cEy8EBbEpQJLmxBLIsRSEWIpC7G0CrGUhFhahFiahViKQiyxEEuTEEtBiCUSYsE6jwLLs0IszwixPC3E8pQQy5NCLP8WYnlCiOVxIZbHhFgeFWJ5RIjlYSGWfwmx/FOI5R9CLH8XYnlIiOVvQix/FWJ5UIjlL0IsfxZi+ZMQyx+FWB4QYrlfiOU+IZZ7hVjuEWK5W4hlpRDLH4RY7hJi+b0Qy51CLHcIsdwuxHKbEMvvhFh+K8TyGyGWW4VYfi3E8ishlluEWG4WYrlJiOWXQiw3CrH8Qojl50IsPxNiuUGI5adCLD8RYvmxEMv1Qiw/EmK5TojlWiGWa4RYrhZiWSHEcpUQy5VCLMuFWK4QYrlciOWHQiw/EGL5vhDL94RYvivEcpkQy6VCLN8RYvm2EMu3hFi+KcRyiRDLN4RYvi7E8jUhlouFWC4SYvmqEMuFQiwXCLGcL8TyFSGW84RYzhViOUeI5ctCLGcLsXxJiOWLQixfEGL5vBDL54RYPivEcpYQy2eEWM4UYvm0EMunhFg+KcTyCSGWjwuxfEyI5aNCLB8RYvmwEMuHhFg+KMTyASGWM4RYThdiOU2I5VQhllOEWE4WYjlJiOVEIZYThFiOF2J5vxDL+4RY3ivEcpwQy3uEWN4txPIuIZZ3CrG8Q4jl7UIsbxNieasQy7FCLMcIsbxFiOXNQixHC7G8SYjljUIsbxBiOUqI5fVCLK8TYnmtEMuRQiyvEWJ5tRDLq4RYXinE8gohliOEWA4XYjlMiOXlQiyHCrG8TIjlECGWg4VYDhJiOVCI5QAhlv2FWPYTYtlXiGUfIZa9hVj2EmLZU4hlDyGW3YVYdhNi2VWIZRchlp2FWHYSYtlRiGUHIZbthVi2E2LZVohlmRDLNkIsWwuxLBViSYVYlgixbCXEsliIZZEQy5ZCLFsIsWwuxLKZEMtCIZZNhVgWCLHMF2KZJ8QyV4hlWIilJsSyiRDLxkIsGwmxbCjEsoEQy/pCLOsJscwRYllXiGUdIZbZQiyzhFhmCrHMEGKZLsRSFWKZJsQyVYhlihDLZCGWSUIsQ0Isg0IsA0Is/UIsfUIsE4VYJgix9Aqx9AixdAuxdAmxdAqxdAixtAuxtAmxJEIsFSGWshBLqxBLSYilRYilWYilKMQSC7E0GZZSxoN9PU8exCbkQjd0hdLbavQWjd5y1NiHkQqmnFK+lXgrAXjLRi/YKqQ3yVdvzeltI/kp6ShSfXsAe9vI5wXSgfqY8scgQ/3QJyLmEcfOyL9N2WyTUHslsM0JcaRUhi7n8yPbGgw5x1ktMgw2xhJqbyZ/8b6KuoqRUaZtW6nO7u/uf2z0lqNGvCUkl1mbiKGYr1+Gx9rvLVdE/AoshXFmKUej500eTx5/xFRMdU0eeWhvpv+Xto2WE9p21pNSGboqxNAswBILsTQZlrX78v/MEnrcXgzL/6V5xc4hzo/9HaO3YZtaAtjEetJo5DmUSzxfFAVYmoVYYiEWG09rz0VeGMtL5lyks9Fe8shu9cgue2RDZsnDyufQfN5t5bHPsU2a/a+tXhpxXYr9pWz4eE4rC7DEQiy+tY5Sviw131qHjasA15JzC0Z+Sjo4/tHntuz8vT0Qj5NBywQjzkXxH3MVr3nkfJ1/OMsvRqOv8XldY6XxSWe+LPVH1juIBXHRSSxov49YVnWs68qXb8w5HbpWdawbb5aiEEuzEEuLEEtJiKVViKUsxFIRYkmEWNqEWNqFWDqEWDqFWArjzLKqay+087kwnlnyXXuxPLSjvzvOlboa7b0e2RM8svFMXdHD0OthnUB1eNZrokce+xzbpNn/2uqlus9ZT0pl6OJrr4kCLJ1CLB1CLO1CLG1CLIkQS0WIpSzE0irEUhJiaRFiaRZiKQqxxEIsTR6W3nxZ6muB0Am59jwnxDpTwchPSQefj6HPntkBMeS6F94vcQnndZ00Hnjno5+4B/LlWMDyi6RzgHyC9gOMT4byZal/SmOQWBAXQ8SC9kOIZVVrgZPy5RvzGgO6VrUWON4sRSGWZiGWFiGWkhBLqxBLWYilIsSSCLG0CbG0C7F0CLF0CrF0CbF0C7H0CLH0CrFMEGKZKMTSJ8TSL8QyIMQyKMQyJMRSGGeWVd0PQjvfs8F3THz3g1ge2tHfXet8k+4HTfXInuaRXc3yRQ/DVA/rNKrD91+qHnnsc2yTZv9rq5fqPmc9KZWhi+8HVQVYhoRYBoVYBoRY+oVY+oRYJgqxTBBi6RVi6RFi6RZi6RJi6RRi6RBiaRdiaRNiSYRYKkIsZSGWViGWkhBLixBLsxBLUYglFmJp8rBMzZel/kwAdEKuvdZ1eqfnq3fTgpGfkg6+JkefJDs4twficTLwDWSXcG0/ncZjRpafSdwh7sNDfpF08n14tPcYn8zOl6X+EyiziAVxMZtY0N5HLPheUJwvz4K179j+zyyFcWZZ+47tf1Ka/a+tXlr7ju1qsjR5WP6fvGNb1/ti3rFdbI4XIb4f9b95xzYkB79jWyGfoH2Z8UlHgDHi74s5uYgNfj4h52cc6/sHy09JB79rjD47GT/kzeNkYA0M4xJFI5+5xLoUPxMQIja6iaGL9MMnaN/T+CTn53Hr76T3EAviopdY0L6vYVlT51YhnofmlFIeulZ1bjXeLEUhlmYhlhYhlpIQS6sQS1mIpSLEkgixtAmxtAuxdAixdAqxdAmxdAux9Aix9AqxFMaZZVVrQ2jna3U8X+FbG2J59h0++w2Afo/sAY9sfvfJMvR7WAeoDs+lDHrksc9zfn+s7nPWk1IZunhtaFCApVeIpUeIpVuIpUuIpVOIpUOIpV2IpU2IJRFiqQixlIVYWoVYSkIsLUIszUIsRSGWWIilycPSny9L/f4FdEKuPS8OsTZeMPJT0uH7PsIda2CtHs+EuITrgF4aDzyjMYm4816nZ/nFaORzIfiP9nuMT6bky1L/jsZkYkFcTCEWtD8wTvcvcn5easzr3OefVaK6WIilKMTSLMTSIsRSEmJpFWIpC7FUhFgSIZY2IZZ2IZYOIZZOIZYuIZZuIZYeIZZeIZYJQiwThVj6hFj6hVgGhFgGhViGhFgmCbFMFmKZIsRSGGeWVd03fqHf82jyyEM7+ttvhUz3yJ7hkc3v6liG6R7WGVRXzfIzPfLY59gmzf7XVi/Vfc56UipDF983ninAMkWIZbIQyyQhliEhlkEhlgEhln4hlj4hlolCLBOEWHqFWHqEWLqFWLqEWDqFWDqEWNqFWNqEWBIhlooQS1mIpVWIpSTE0iLE0izEUhRiiYVYmjws0/NlqT+vA52Qa9cjQj2vw/JT0sHrJuhzYXaiEPJ5HXynxCWsv/DzOvh2yWziDvG8DuQXSSc/r4P2S4xPQjyvsw6xIC74eR20f4dYSrQN/jcZO1qixnyY5sNb368wrxWyvxbDElOfn3c22n7Q2eDK+XsPc/l7IPy8RhJAD85JIvIDp5Ty/CxAW74sNScz599Cr7+L30H8sLWN7EE738/P+RsN9ThrMz5Fme/dv5Tt52/qVKiuTKwu1ffLrlCsw/PZPzwPhf7dX1zXYh6CDrDE1Od+moduCTwPgUN1Hsr7N+xC7Yf8u3iwtZfsQXvo96J7o5E+RZmffXgp28+/zczzUA+xuuT2vadp38s5DufxvsfPyEwMoIfHxqWx9j1+LqUvX5Zg+x7/FiNsBXtC7Rx7Ob/nUI+9vmikT32/AflStv/FsMbjzMrzxFi/187zBJ/X8+/M47ynm+pw3sPfb4ro+QF+Jgt1YOPvCvJ75PiPc5o+qos99uEaCDLw3U1cD6XZ/9rqpbmsC2msOYif7c/5mnAuf++R32cI8X3BkrEPZehKDEMolsSjO4CeEb5FGmucmSXn77TN5X3shbDwM/k5n//WQlxPOxn8XUB7HZVQOz9Xn/Pxpx7nifEpyny8eSnbX6a60jiz8FzAPrPfuIyikefCvvW6EOsI4MR1codhianPPl0Nvg27GvwdxI06XFuz7d2mztnUE8Am/m5lSuUe4vN9uzLE9ZFlga8mBNZrr8u6jF4+t0Iaa74OeM1U4/ND3IuADn7nJOR5KeIfOlAfU34ZYKKR59WIdTDzM0GrOhe357V8Lj4hsM0TiSONRr8f7vbjzWlNMOf4rI/3BMOAMrl4BGeP8U1C7Zgr+dqbz/Nyjtfhsfh5PMHQHZAl8ehmP5QE/AAGXvOx7+M7X51LxxQ7jvzMHx9T+j12hvi+Q7+xE2X+voNv/SHn35vwssBXQ4H1Dhq9fUYvXx8jjXVMCfhbr/U5ht8PSUkHH2tyvmc7zHpxTIEO/l1U5I+iCW9KI/t8rIOZn9fmfpwfMNsk1D4U2Gb+1kZKZehy+/HhdEzJOT7r4z1kGFDmtadJHn8Nkb/Qzu+MDJEN4A/xG7yr4ufxBEPI349OPLrZDyUBP4BhgOrQD/MK7zN8HJlk7ODfAQ79PYcpxjaUpxIf5gZ+p6y6Blh8v+8bQu+qfr+qSuMxNRqZxjqOTCPe6fnyjng+C8cR6ODjy8wAfppBtvMza/x8FvKfoOPIzEbW+7tYVU8/zk812yTUXg1s83TiSKnM7+2dRseRar4M9fGuGgaUJ1P9dI+/quQvtPO1SZVsAH/O8To8Fj+PJximBGRJPLrZDyUBP4CB36NFP8wr9tqkSvWom25s4ndD2c5ZAeycaexEeRbxYZ7wvbtapTpsw+OF5x1nUF2TR15s9PJ9qNnki7X3vHLRs/aeV5bW3vNae89r7T2vtfe8Xij/i7nn9Qzd87p17T2v/xXL2nteo9P/lXtef3sJ3fO6Z+09rzF9uPaeV/73vMrdDda8z1/YJ/wORkQ6c37meIGTOZizHTxHufQ+sovvIYXQO2D02t8O4rmlJetj7w3G1KevuzEOrZRHHPC3cPjcwq69u7GdbOpC38+CXLs+zWvqkz18/DtL9n4Ur/XyvYYmj7zY6OVr/qnkiwqV2Yd2jZ+//cU+rGb5NPtfW73kXfNGuUp8sJXXs2esARb7rbNQeqcbvZONXl4bRBrr/Gw68ea8Fl3f92eR/JR08Lr/7AB+mkW2F0gHv4uM/MZ0ss3vT9vvr/EaIPfjfNVsk0Sj1/5C2byqNUx+F3smHbdyjk/ve/go8/w30+OvGeQvtPM1xwyyAfwh7xdZfh5PMEwLyJJE/vVm1JUE/ACGKtWhX8B5pf676sw3weMn1I2Imyz27XyYGxgOuE5BUzQ6/ReF0vP2xfECAA== diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/src/main.nr deleted file mode 100644 index 508725407d0..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/src/main.nr +++ /dev/null @@ -1,14 +0,0 @@ -use dep::std; - -unconstrained fn main(x : Field) -> pub [u8; 31] { - // The result of this byte array will be big-endian - let byte_array = x.to_be_bytes(31); - let mut bytes = [0; 31]; - for i in 0..31 { - bytes[i] = byte_array[i]; - } - assert(bytes[30] == 60); - assert(bytes[29] == 33); - assert(bytes[28] == 31); - bytes -} diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/target/brillig_to_be_bytes.bytecode b/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/target/brillig_to_be_bytes.bytecode deleted file mode 100644 index fd4424a46a5..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/target/brillig_to_be_bytes.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1byW7bMBClLNvabGff7GxO0iROgkJKf4CH3voZafMb+cYee+yxxx56KhCUtDjVM8s2ATJqfBgCA1EUOW8RtUCgpkqpSNUlhjoWatNuW76sVBFfrjICjkeu3nFauiZ6JvomEhOpicxEbqIwMTAxNDEysWJi1cSaiXUTGyY2TWyZ2DaxY2LXxJ6JsYmJiX0TByYOHfYxePbBEcscHyx9qGsmH/r856nsAdcMOJOekTses+JW90UAy+J0efVV/lzXUCcs5BIvEZfolblk6s97RQbHO9DWc/UY2jqBfHS8B9sxXEdJIHcayJ0FclPOJMA1hTZ/vmM+9JzGaLctX1bmniOOhn3CyoFDtgRc4iXi0glwSXi53OJ8U8AJi4Z6AlwKVi7VPT3HnsulAC4DVi71s2fInNPmGAF/0joAPXR8CNpGvDzm82+gFj2l/RHgin5WXNGvRL/oF/2iX/SLftEv+kW/6Bf9ol/0i37RL/pFv+gX/aJf9It+0S/6Rb/oF/2voT+DtvSVuRRqcV1EO1zqNVqhecCsucwCOHbdzmfAXGXWZnNuMOuw525NNeUBdG2AljZw1z3cVQ/X9lkBDg/AlcbG0OcHnIcvrp5DPrwGtlj1VJ9sjm3VFMLcAh6brr4NPHZYeby7iyB/z2km3B3wjPp8dduh47gb8GrM69VHm2OimkKYY/Bqz9UnwGOflcft/L418bwi3H3wivp887w6CHh1xOvVnc1xrJpCmEfg1aGrHwOPKS+P+wjyk1eEOwWvqM93z6sTzyt7/zx19RNoo/VydCxx40+98VbjG1aN9T3pTDVFq2Z9JmFFUO+rxWfdGfhAfX6CD7ZcQH5a50njrc5zr5/FuGTVWa/RQx6kS3naqVwClytWLrXn15BfAwbi3vDiVogbuSAMao+hPgCDbprq73lJnO05nAX6Yf3CG1PA8VnLmq+Ah4Z9wrJzMgKtswBvfNel4+fAe8bM2+a4BB4Dj1sGOvD+cP0f/bsGT1LPL34u9Xuuj92W91dPeE9t1M9/D2b9D6Cq371Da/eTQBv+02LLc9ZF43rqDujIOXWU9b0P1z9rwMA12szroivEpXsfXtPkIdXfRk1f6mfP6SP41IV8Q/Du0RtDfXDtPOahsX6dzmMOPOk45kqf4NfCN4G5n7jmXcP+EPCnUcOB+X+EW/S06/LSHErb017inKA57J+Xtr850BwmDGqPof4eLnz8fkPzijjn4Bd+Rwldl21oykGThv0RtP+tD14vIY05bItAv3/5gt+1imfi4Ji2vz+hdg37+G2mgn+2iCM9RzK1eC+mNuKNz4aOpxP/ESugzf+Py+bwnz+sJigPYBl+PP0F1H72qsk7AAA= diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/src/main.nr deleted file mode 100644 index 964f4b49bf5..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/src/main.nr +++ /dev/null @@ -1,27 +0,0 @@ -use dep::std; - -unconstrained fn main(x : Field, _y: Field) { - // The result of this byte array will be big-endian - let y: Field = 2040124; - let be_byte_array = y.to_be_bytes(31); - // The result of this byte array will be little-endian - let le_byte_array = x.to_le_bytes(31); - - assert(le_byte_array[0] == 60); - assert(le_byte_array[0] == be_byte_array[30]); - assert(le_byte_array[1] == be_byte_array[29]); - assert(le_byte_array[2] == be_byte_array[28]); - - let z = 0 - 1; - let p_bytes = std::field::modulus_le_bytes(); - let z_bytes = z.to_le_bytes(32); - assert(p_bytes[10] == z_bytes[10]); - assert(p_bytes[0] == z_bytes[0] as u8 + 1 as u8); - - let p_bits = std::field::modulus_le_bits(); - let z_bits = z.to_le_bits(std::field::modulus_num_bits() as u32); - assert(z_bits[0] == 0); - assert(p_bits[100] == z_bits[100]); - - _y.to_le_bits(std::field::modulus_num_bits() as u32); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/target/brillig_to_bytes_integration.bytecode b/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/target/brillig_to_bytes_integration.bytecode deleted file mode 100644 index 8d3c09e4adc..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/target/brillig_to_bytes_integration.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/src/main.nr deleted file mode 100644 index a72b13dcdf5..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/src/main.nr +++ /dev/null @@ -1,12 +0,0 @@ -use dep::std; - -unconstrained fn main(x : Field) -> pub [u8; 31] { - // The result of this byte array will be little-endian - let byte_array = x.to_le_bytes(31); - assert(byte_array.len() == 31); - let mut bytes = [0; 31]; - for i in 0..31 { - bytes[i] = byte_array[i]; - } - bytes -} diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/target/brillig_to_le_bytes.bytecode b/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/target/brillig_to_le_bytes.bytecode deleted file mode 100644 index 6874d0d9044..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/target/brillig_to_le_bytes.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1bu3LbMBAERUsUSZGSbT1JSYnbVGS+gF/j3/BXpkyRKlX6VJ4cTNxoBWPsyfhoqTjM7BAEwNvdA0S6OD8YYyLTtxj62Hisc9fmY62N5GI1EWj84voj5+WGMCZMCAlhSkgJGSEnzAgFoSTMCQvCLeGOcE9YElaENWFD2BJ2hIpQE/aEA+HouL9Czh6csNTpwTaBfieUh4n8PjVj0JqCZvZTuvlYlLd9zANcludG1l/rn/UO+syFWuIr0hJdWEtqXr8rUpgfwdjY9WMYGwXi8fwYrhP4HSWB2NNA7DQQm2MmAa1TGPPPO8bDnPMznbs2H2svOUeeDu6ZKwMN6RVoia9IyyigJRHV0j4iJ39bDPDEMP/NXQunJRfV0nzn7xi2t363OeSlEM6L1TL7Dy0FaClFtfTfwblwTBtjAfrZawm55fk5eFvI6nj5LZTmPKd8vwBe9S/Kq/6N+lf/6l/9q3/1r/7Vv/pX/+pf/at/9a/+1b/6V//qX/2rf/Wv/tW/+lf/6v8S/lMYyy6sJQcNs8G09PVioXMg7LlJAzy2DuQHcErXnNiYS2Efdu/uzKk9ga8leBmC997jTTxeu+YWNDyBVn42hjW/YB9+un4G8fj82b1beVxYh8ZziXtm5T1vtWwGyMfanJqNyzVFG8jHBjTYNbxXa8gHr/ntrlxjs4P4XO+G74ett85yVKI++/og1MG+jOedWwVa9qJa+pwfIH4HHMh7lOVtkTdyYA4ej6H/15zaEfp8Llmz3cM6sA77O++ZHObrgT3vQUcH98xlz+QfWFMHdON3lue3oLsW1m1jVKCj9LSl5jz/rOPwifk7QE4yL1/yWvpvrM89VO737+Sex3id/w0WrYdu++9+qIY5CYxhbb9tb73nsBaZ60ZH4COT9NH07z6sA+2AI4HxmSxvi7z87mOOHHLI/So6reV1dk+fzXn9La8pIHfP3jO8BmuIMQ4/6/d5HzPQyfMYa/qOPvl62z6fWPvbwX0B/AXUzrPmMXiYgkYe888D/o2ENfF85rF2nj1jjFf/T9QJJsF4BNfwD0D/AOxznn9RNQAA diff --git a/crates/nargo_cli/tests/execution_success/brillig_top_level/target/brillig_top_level.bytecode b/crates/nargo_cli/tests/execution_success/brillig_top_level/target/brillig_top_level.bytecode deleted file mode 100644 index 88acb62001f..00000000000 --- a/crates/nargo_cli/tests/execution_success/brillig_top_level/target/brillig_top_level.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9WUbQ6DIAyGy4cgmuwEO4RuF+D+p5o4Gt5Vsz8rWXwTApRqn1ZsJCJDb7lt2Lo2dY9iv1zn5TetRu9dSy9GewFG14GxB6dX5DTAyHd22EYA/nudE7W7bMBm6VP4bNbhfAb9Oi4lzwh5sDifG9RDnnEdpm144Reo1SDrsK6Sw0Es1njCOQBnFH4B8s46nI8kOIqM2GdYJ2CZdFn2f3CmY304zgznHjhmXY69P08if2Sgk/U31vhn1gS2EWxWMBdO+e1VmzVRa1wOgnk6NrMXDKpTAaEHAAA= diff --git a/crates/nargo_cli/tests/execution_success/cast_bool/target/cast_bool.bytecode b/crates/nargo_cli/tests/execution_success/cast_bool/target/cast_bool.bytecode deleted file mode 100644 index 1b06f5c9bd2..00000000000 --- a/crates/nargo_cli/tests/execution_success/cast_bool/target/cast_bool.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1USxLCIAxNf9huPAvhU8LOq8hI738ERwcdrOwaHBZmkwyLl7yX8BYAWOA7hpQvKctjgV2GpeVqTHQqosarVD6QlcaGlZDQkr0p0jqSIeeDd9Kj0RE36/WWwHpGrIGP4xOrK2jZMWvJOXM+71io+8JNiAqcYNdnr+O58MbavMaSxgq4E/Adfy3eE/+OZAb5PsoWNRXAa06/MBQBdQzllNV/QzmIKZKg3LgztG0oD94z/44+DKVlTftsxvzzvOIOhKdrBcIJAAA= diff --git a/crates/nargo_cli/tests/execution_success/cast_bool/target/witness.tr b/crates/nargo_cli/tests/execution_success/cast_bool/target/witness.tr deleted file mode 100644 index 2147178e3c7..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/cast_bool/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/closures_mut_ref/src/main.nr b/crates/nargo_cli/tests/execution_success/closures_mut_ref/src/main.nr deleted file mode 100644 index ae990e004fd..00000000000 --- a/crates/nargo_cli/tests/execution_success/closures_mut_ref/src/main.nr +++ /dev/null @@ -1,20 +0,0 @@ -use dep::std; - -fn main(mut x: Field) { - let one = 1; - let add1 = |z| { - *z = *z + one; - }; - - let two = 2; - let add2 = |z| { - *z = *z + two; - }; - - add1(&mut x); - assert(x == 1); - - add2(&mut x); - assert(x == 3); - -} diff --git a/crates/nargo_cli/tests/execution_success/closures_mut_ref/target/closures_mut_ref.bytecode b/crates/nargo_cli/tests/execution_success/closures_mut_ref/target/closures_mut_ref.bytecode deleted file mode 100644 index 33565558fa9..00000000000 --- a/crates/nargo_cli/tests/execution_success/closures_mut_ref/target/closures_mut_ref.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1USwoCMQxNpzODK8+S9DNNd17FYuf+R1CwQqldaQoj+CAkZPGSvMBbAeAET+hHKHjHq3cpGb8DKTkurPedqnru9HTJ64CboJnT6nju9ESHj3jSNIBXV1wWN+dyMJksXdHExB6dTxsTk2d/M2xtZschphgwkrOZdh/tXshG3a3lf4QV5aE1/XUTmDv13wQ+5FRFRGneBY5vAov8j4aagKSmqtmxxh26pZbrMggAAA== diff --git a/crates/nargo_cli/tests/execution_success/closures_mut_ref/target/witness.tr b/crates/nargo_cli/tests/execution_success/closures_mut_ref/target/witness.tr deleted file mode 100644 index 036fce8ef5e..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/closures_mut_ref/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/constant_return/target/constant_return.bytecode b/crates/nargo_cli/tests/execution_success/constant_return/target/constant_return.bytecode deleted file mode 100644 index eb6a45b1dc7..00000000000 --- a/crates/nargo_cli/tests/execution_success/constant_return/target/constant_return.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/6WOwQ2AMAwDU1goaZI2+bEKFen+IyAESBU8ex9bftheASDBnzfbHmUsIlFzENOO2ZspirZiZKSmRzbmMLHqzSs6CQd1de54swxdOIemz8fRXzsnEg36itQAAAA= diff --git a/crates/nargo_cli/tests/execution_success/custom_entry/target/custom_entry.bytecode b/crates/nargo_cli/tests/execution_success/custom_entry/target/custom_entry.bytecode deleted file mode 100644 index 61126dfa0c4..00000000000 --- a/crates/nargo_cli/tests/execution_success/custom_entry/target/custom_entry.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/82SMQ7DIAxFTSAdexYbQzBbr1JUcv8jtAODRbPVSP2LEUjP/v7sALDDt7ZRH6PibyKnWIxHSr3ETkxPjLVJxpTbISSUJb+iMHdJUmqrBSsl7nTmyueAbYYs/2G4C//O2P9mx0I9r1fnMGWn328LPMHUZ97j/eLOtPmKkPwCbgC7D7vKd7DPCBXyr3fqphm13hKQ6RMhBQAA diff --git a/crates/nargo_cli/tests/execution_success/custom_entry/target/witness.tr b/crates/nargo_cli/tests/execution_success/custom_entry/target/witness.tr deleted file mode 100644 index 87be1158f1b..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/custom_entry/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/debug_logs/target/debug_logs.bytecode b/crates/nargo_cli/tests/execution_success/debug_logs/target/debug_logs.bytecode deleted file mode 100644 index bb21dde4222..00000000000 --- a/crates/nargo_cli/tests/execution_success/debug_logs/target/debug_logs.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/debug_logs/target/witness.tr b/crates/nargo_cli/tests/execution_success/debug_logs/target/witness.tr deleted file mode 100644 index 434b9fac277..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/debug_logs/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/diamond_deps_0/target/diamond_deps_0.bytecode b/crates/nargo_cli/tests/execution_success/diamond_deps_0/target/diamond_deps_0.bytecode deleted file mode 100644 index 6c9ac59d2b5..00000000000 --- a/crates/nargo_cli/tests/execution_success/diamond_deps_0/target/diamond_deps_0.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/62QUQ6AIAxDQTzQxjbY/ryKxHH/IxgTTEj8lP60X69N9xBCDF+l4cdw+KccF7K2iUVQmL1mR8ITsjUVYGlFUVFUrqxErqzVmlUwZHLsYtQHLK3bRe+Pcfp0m/LTdQNwRaP0cAEAAA== diff --git a/crates/nargo_cli/tests/execution_success/distinct_keyword/target/distinct_keyword.bytecode b/crates/nargo_cli/tests/execution_success/distinct_keyword/target/distinct_keyword.bytecode deleted file mode 100644 index 5e57db0556c..00000000000 --- a/crates/nargo_cli/tests/execution_success/distinct_keyword/target/distinct_keyword.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/9WRQQ6AIAwEEfU/LW2lvfkVifj/JxgSTEg8Cgf3srftTnd1zs3uLV99rw7fhFOTRbAx5xgyEh4QLKkAS9oUFUXlDEqUlTVasgiGTBkvMbpqmO/YaySz78g89+sFf9l5GcA8Nf6wl9+WWzcyyYCuDAMAAA== diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/src/main.nr b/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/src/main.nr deleted file mode 100644 index dfac8673b38..00000000000 --- a/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/src/main.nr +++ /dev/null @@ -1,11 +0,0 @@ -use dep::std; - - -fn main(message : [u8;38],hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { - // Hash the message, since secp256k1 expects a hashed_message - let expected= std::hash::sha256(message); - assert(hashed_message == expected); - - let valid_signature = std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); - assert(valid_signature); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/target/ecdsa_secp256k1.bytecode b/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/target/ecdsa_secp256k1.bytecode deleted file mode 100644 index c412b55c0d7..00000000000 --- a/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/target/ecdsa_secp256k1.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/target/witness.tr b/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/target/witness.tr deleted file mode 100644 index 4f7d415e499..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/src/main.nr b/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/src/main.nr deleted file mode 100644 index 058f4ca8fb1..00000000000 --- a/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/src/main.nr +++ /dev/null @@ -1,7 +0,0 @@ -use dep::std; - - -fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { - let valid_signature = std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); - assert(valid_signature); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/target/ecdsa_secp256r1.bytecode b/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/target/ecdsa_secp256r1.bytecode deleted file mode 100644 index e05337f93ba..00000000000 --- a/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/target/ecdsa_secp256r1.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+WYWXNUVRRGbyIiiIiIiIiYEBEjIvaYdCNiExEjIiIiIiImkY5xnucpzjggIiIiIsEHf6fu6r0qnfXKQx64ValTC6qSc/f0fXf/UxTFv0Xn6fn/pzfPRV3cK75CvEB8pXih+CrxIvFi8dXiJeJrxEvF14qXia8TLxdfL14hvkG8UnyjeJX4JvFq8c3iNeJbxGvFt4r7xP3JkbciuSjm5ntB/v/CrvwtztwsyRwszVgvy5guz9ityBitzFisyndene+2Jt9hbd61L+/A31+n+w6IbxOvF98u3iC+QzwovlO8UXyXeJP4bvFm8T3ikrgsroir4pq4Lh4SD4sb4qZ4i/he8VbxfeJt4vvFrWK2HuPf+ovOE3UwkPlen3ndkPkbzDxtzHxsyrhvzviWMo6VjFct4zKU79/I99yS77M1770t79fqut923XdE/IB4h/hB8U7xQ+JR8cPiXeJHxLvFj4r3iB8T7xU/Lt4nfkK8X/yk+ID4KfFB8dPiQ+JnxIfFz4qPiJ8TjxWz9ci8jCfqYCTzvSPzujPzN5p52pX52J1x35Px3Ztx3Jfx2p9xOZDvfzDf81C+z+G895G831jX/cZ13wnx8+Kj4rZ4UvyCeEr8ovgl8cviV8Svil8Tvy5+Q/ym+C3x2+J3xO+K3xO/L/5A/KH4I/HH4k/En4o/E38unhZ/If5S/JX4a/E34m/F34mPib8X/yD+UfyT+Lj4Z/EJ8S/ik+JfxafEv4lPi38XnxH/IT4r/lN8TvyX+Lz4b/EF8UwxO4/Cm7WKzjNedHo/+j16PPo6ejn6d6ro9Gn0ZvRj9GD0XfRa9Ff0VPRR9E70S/RI9EX0QtR/1HzUedR21HPUcNRt1GrU53TRqcOovai3qLGoq6ilqJ+omaiTqI2oh6iB45nrE5nTk5m7U5mj05mLMxnzsxnbcxnD8xmrCxmTiE940v6Mx7qM00Ce+ET8Ib4QP4gPHMwT34ffw+fh7/B1+Dl8HP4N34Zfw6fhz/Bl+DF8GP4L34Xfwmfhr/BV+Cl8VCvP/ozD9uSRPPEn+BL8CD4E/zGaJ34Dn4G/wFfgJ/AR+Ad8A34Bn4A/wBfgB/AB6D+6j96j8+g7uo6eo+Po91hXPOJBJ9FHdBE9RAfRP3RvKk90Dn1D19AzdAz9QrfQK3QKfUKX0CN0CP1Bd9AbdAZ9QVfQE3QE/UA3pvNEJ9AHdAE9QAeY/8z9Y3ky55nvzHXmOXOc+c3cZl4zp5nPzGXmMXOY+cvcZd4yZ5mvzFXmKXOU+cncnCnm9kNPcm+e7DPYY7C/YG/B9y4/7CfYS7CPYA/B/oG9A/sG9gzsF9grsE9gj8D+gL0B+wL2BOwH2AuwD2APwPc/3/19Xe8f58Vi7tOTZyvP0qU95Ytdv6taGqrV2sOVdrlaHi9VmhONeqlWnxhqlBvleqN+tNKoVtuNWmO4OdEcLjXLtWq7PFlvVifzl8103bG3mL9dRGjJfH57zve3xuXuLfz8ByllLvw4FQAA diff --git a/crates/nargo_cli/tests/execution_success/eddsa/src/main.nr b/crates/nargo_cli/tests/execution_success/eddsa/src/main.nr deleted file mode 100644 index 8de38011aaf..00000000000 --- a/crates/nargo_cli/tests/execution_success/eddsa/src/main.nr +++ /dev/null @@ -1,55 +0,0 @@ -use dep::std::compat; -use dep::std::ec::consts::te::baby_jubjub; -use dep::std::hash; -use dep::std::eddsa::eddsa_poseidon_verify; -use dep::std; - -fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { - // Skip this test for non-bn254 backends - if compat::is_bn254() { - let bjj = baby_jubjub(); - - let pub_key_a = bjj.curve.mul(_priv_key_a, bjj.curve.gen); - // let pub_key_b = bjj.curve.mul(_priv_key_b, bjj.curve.gen); - - // Manually computed as fields can't use modulo. Importantantly the commitment is within - // the subgroup order. Note that choice of hash is flexible for this step. - // let r_a = hash::pedersen([_priv_key_a, msg])[0] % bjj.suborder; // modulus computed manually - let r_a = 1414770703199880747815475415092878800081323795074043628810774576767372531818; - // let r_b = hash::pedersen([_priv_key_b, msg])[0] % bjj.suborder; // modulus computed manually - let r_b = 571799555715456644614141527517766533395606396271089506978608487688924659618; - - let r8_a = bjj.curve.mul(r_a, bjj.base8); - let r8_b = bjj.curve.mul(r_b, bjj.base8); - - // let h_a: [Field; 6] = hash::poseidon::bn254::hash_5([ - // r8_a.x, - // r8_a.y, - // pub_key_a.x, - // pub_key_a.y, - // msg, - // ]); - - // let h_b: [Field; 6] = hash::poseidon::bn254::hash_5([ - // r8_b.x, - // r8_b.y, - // pub_key_b.x, - // pub_key_b.y, - // msg, - // ]); - - // let s_a = (r_a + _priv_key_a * h_a) % bjj.suborder; // modulus computed manually - let s_a = 30333430637424319196043722294837632681219980330991241982145549329256671548; - // let s_b = (r_b + _priv_key_b * h_b) % bjj.suborder; // modulus computed manually - let s_b = 1646085314320208098241070054368798527940102577261034947654839408482102287019; - - // User A verifies their signature over the message - assert(eddsa_poseidon_verify(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg)); - - // User B's signature over the message can't be used with user A's pub key - assert(!eddsa_poseidon_verify(pub_key_a.x, pub_key_a.y, s_b, r8_b.x, r8_b.y, msg)); - - // User A's signature over the message can't be used with another message - assert(!eddsa_poseidon_verify(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg + 1)); - } -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/eddsa/target/eddsa.bytecode b/crates/nargo_cli/tests/execution_success/eddsa/target/eddsa.bytecode deleted file mode 100644 index d15ec3c916c..00000000000 --- a/crates/nargo_cli/tests/execution_success/eddsa/target/eddsa.bytecode +++ /dev/null @@ -1 +0,0 @@ -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Ho3rMbgei+txuB6P6wm4nojrSbiejOspuJ6K62m4no7rGbieietZuJ6N6zm4novrebiej+sFuF6I60W4XozrJbheiutluF6O6xW4XonrVbhejes1uF6L63W4Xo/rDbjeiOtNuN6M6y243orrbbjejusduN6J61243o3rPbjei+t9uC7E9X5cH8D1QVwfwvVhXB/B9VFcH8P1cVyfwPXLuD6J61dwfQrXr+L6NVy/frf/3jv+1//ZQ37r/+x1//f+t0/d/86p+989df97p+5//9T9H5y6/8NT93906v6PT93/yan7Pz11/2en7v/81P1fnLr/y1P3f3Xq/q9P3f/Nqfu/PXX/d6fu//7U/T+cuv/HU/f/dOr+n0/d/8up+389df9vp+7//dT9f5y6/89T9/916v5kPd7c/69T959+6v4zTt1/5qn7/33q/rNO3X/2qfvPOXX/uafuP+/U/eefuv+CU/dfeOr+IqfuL3rq/mKn7r/o1P3FT91f4tT9JU/dX+rU/aVP3V/m1P1lT91f7tT95U/dX+HU/RVP3V/p1P0Fp+6vfOr+Kqfur3rq/mqn7q9+6v4ap+6veer+Wqfur33q/jqn7q976v56p+6vf+r+Bqfub3jq/kan7m986l6duqdT9/rUvTl1b0/du1P3/tR9OHUfT92nU/c3OXV/01P3Nzt1f/NT97c4df/Fp+5veer+S07d3+rU/a1P3d/m1P1tT93f7tT9l566v/2p+zucur/jqfs7nbq/86n7Lzt1f5dT919+6v6up+6/4tT9V566/6pT91996v5rTt3f7dT91566/7pT919/6v4bTt1/46n7u5+6/6ZT99986v5bTt1/66n7fOq+nLqvp+7bqft+6n6cuv+2U/fffur+O07df+ep+3ucuv+uU/fffer+e07df++p++87df/9p+5/4NT9D566/6FT9/c8df/Dp+5/5NT9j566/7FT9z9+6v4nTt3f69T9T566v/ep+/ucur/vqfufOnV/v1P3P33q/v6n7h9w6v6Bp+5/5tT9z566/7lT9w86df/zp+5/4dT9L566/6VT9w8+df+QU/cPPXX/sFP3Dz91/4hT9488df+oU/ePPnX/mFP3jz11/7hT948/df+EU/dPPHX/pFP3Tz51/5RT9089df+0U/dPP3X/jFP3zzx1/6xT988+df+cU/fPPXX/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eGdb78z0zizvzPbOHO/M9c4872znne298zbv7OCdt3vnHd55p3d29M5O3tnZO+/yzi7e2dU7u3nn3d7Z3Tvv8c57vfM+7+zhnfd75wPe+aB39vTOXt7Z2zsf8s4+3pnvnX29s5939vfOAd450DsHeedg7xzinUO9c5h3DvfOEd450jsf9s5R3vmIdz7qnY9552jvHOOdj3vnE9451juf9M6nvPNp7xznneO9c4J3PuOdE73zWe98zjuf985J3vmCd77onS9552TvnOKdU73zZe+c5p2veOer3vmad073zhneOdM7X/fOWd75hne+6Z1veeds75zjnW975zveOdc753nnu975nnfO9873vfMD7/zQOxd450LvXOSdH3nnYu9c4p0fe+cn3rnUO5d553Lv/NQ7V3jnZ975uXd+4Z0rvXOVd672zi+9c413rvXOdd75lXeu986vvfMb7/zWOzd450bv3OSd33nnZu/83ju3eOcP3rnVO7d553bv/NE7d3jnT9650zt/9s5d3rnbO3/xzl+9c4937vXOfd75m3fu987fvfMP7/zTOw9450HvTMj32OydBbzzeO88wTtP9M6C3lnIO0/yzpO9s7B3nuKdp3rnad5ZxDtP984zvPNM7yzqnWd5ZzHvPNs7i3tnCe88xzvP9c6S3lnKO0t753neWcY7z/fOC7zzQu8s653lvLO8d17knRW8s6J3VvLOi72zsndW8c5LvPNS76zqndW8M+adyjsTvTPJO5O9M8U7U70zzTvTvTPDO6t7Zw3vrOmdl3lnLe+s7Z11vPNy76zrnfW8s753NvDOht7ZyDuv8M4rvbOxdzbxzqbeeZV3NvPOq73zmvz/WTuO89cQzYDjDrm+wbi+0bhublzfZFy3MK5vNq5bGte3GNe3GtetjOvWxnUb47qtcZ1pXGcZ19nGdY5xnWtc5xnX7Yzr9sb1bcZ1B+P6duP6DuP6TuO6o3HdybjubFzfZVx3Ma67GtfdjOu7jevuxvU9xvW9xvV9xnUP4/p+4/oB4/pB47qncd3LuO5tXD9kXPcxrvON677GdT/jur9xPcC4HmhcDzKuBxvXQ4zrocb1MON6uHE9wrgeaVw/bFyPMq4fMa4fNa4fM65HG9djjOvHjesnjOuxxvWTxvVTxvXTxvU443q8cT3BuH7GuJ5oXD9rXD9nXD9vXE8yrl8w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 diff --git a/crates/nargo_cli/tests/execution_success/eddsa/target/witness.tr b/crates/nargo_cli/tests/execution_success/eddsa/target/witness.tr deleted file mode 100644 index f666f55f303..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/eddsa/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/generics/target/generics.bytecode b/crates/nargo_cli/tests/execution_success/generics/target/generics.bytecode deleted file mode 100644 index 6728ba2f560..00000000000 --- a/crates/nargo_cli/tests/execution_success/generics/target/generics.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1USQ7CMAx0VwoH3hJnaZwbXyEi/f8TECiVrJJbHakIfLGVw3g8duYMABf4jC7nW85qX2DDsIyarU1eJzR4VzpEcsq6OBMSOnIPTcYksuRDDF4FtCbh4oJZMlgriNXJzfjGagpaNsJaSnLmfPtC3RZuYqwwE2z6bHW8Ft5Em9dYUl8BdwC546819yC/I8UgD6/pGr9ioiN8n4lKcuZ8T6z+m+hOzDELKo07wbFN9DX3JL+jqiYqqWnLOPLPs8YTFPqSLLYKAAA= diff --git a/crates/nargo_cli/tests/execution_success/generics/target/witness.tr b/crates/nargo_cli/tests/execution_success/generics/target/witness.tr deleted file mode 100644 index 5ea3587e89a..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/generics/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/global_consts/src/main.nr b/crates/nargo_cli/tests/execution_success/global_consts/src/main.nr deleted file mode 100644 index 13b9159b480..00000000000 --- a/crates/nargo_cli/tests/execution_success/global_consts/src/main.nr +++ /dev/null @@ -1,95 +0,0 @@ -mod foo; -mod baz; - -global M: Field = 32; -global L: Field = 10; // Unused globals currently allowed -global N: Field = 5; -global T_LEN = 2; // Type inference is allowed on globals -//global N: Field = 5; // Uncomment to see duplicate globals error - -struct Dummy { - x: [Field; N], - y: [Field; foo::MAGIC_NUMBER] -} - -struct Test { - v: Field, -} -global VALS: [Test; 1] = [Test { v: 100 }]; -global NESTED = [VALS, VALS]; - -fn main(a: [Field; M + N - N], b: [Field; 30 + N / 2], c : pub [Field; foo::MAGIC_NUMBER], d: [Field; foo::bar::N]) { - let test_struct = Dummy { x: d, y: c }; - - for i in 0..foo::MAGIC_NUMBER { - assert(c[i] == foo::MAGIC_NUMBER); - assert(test_struct.y[i] == foo::MAGIC_NUMBER); - assert(test_struct.y[i] != NESTED[1][0].v); - } - - assert(N != M); - - let expected: u32 = 42; - assert(foo::TYPE_INFERRED == expected); - - let mut y = 5; - let mut x = M; - for i in 0..N*N { - let M: Field = 10; - x = M; - - y = i; - } - assert(y == 24); - assert(x == 10); - - let q = multiplyByM(3); - assert(q == 96); - - arrays_neq(a, b); - - let t: [Field; T_LEN] = [N, M]; - assert(t[1] == 32); - - assert(15 == mysubmodule::my_helper()); - - let add_submodules_N = mysubmodule::N + foo::bar::N; - assert(15 == add_submodules_N); - let add_from_bar_N = mysubmodule::N + foo::bar::from_bar(1); - assert(15 == add_from_bar_N); - - // Example showing an array filled with (mysubmodule::N + 2) 0's - let sugared = [0; mysubmodule::N + 2]; - assert(sugared[mysubmodule::N + 1] == 0); - - let arr: [Field; mysubmodule::N] = [N; 10]; - assert((arr[0] == 5) & (arr[9] == 5)); - - foo::from_foo(d); - baz::from_baz(c); -} - -fn multiplyByM(x: Field) -> Field { - x * M -} - -fn arrays_neq(a: [Field; M], b: [Field; M]) { - assert(a != b); -} - -mod mysubmodule { - use dep::std; - - global N: Field = 10; - global L: Field = 50; - - fn my_bool_or(x: u1, y: u1) { - assert(x | y == 1); - } - - fn my_helper() -> Field { - let N: Field = 15; // Like in Rust, local variables override globals - let x = N; - x - } -} diff --git a/crates/nargo_cli/tests/execution_success/global_consts/target/global_consts.bytecode b/crates/nargo_cli/tests/execution_success/global_consts/target/global_consts.bytecode deleted file mode 100644 index 1b6c2fd5e46..00000000000 --- a/crates/nargo_cli/tests/execution_success/global_consts/target/global_consts.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/global_consts/target/witness.tr b/crates/nargo_cli/tests/execution_success/global_consts/target/witness.tr deleted file mode 100644 index cadba3b7801..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/global_consts/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/hash_to_field/target/hash_to_field.bytecode b/crates/nargo_cli/tests/execution_success/hash_to_field/target/hash_to_field.bytecode deleted file mode 100644 index f7205da47ee..00000000000 --- a/crates/nargo_cli/tests/execution_success/hash_to_field/target/hash_to_field.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/12JSQoAAAgCpzr0/w9HSTcFcZkCgpeybc857cO6+AJoTFxsSAAAAA== diff --git a/crates/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr b/crates/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr deleted file mode 100644 index 782b6af998e..00000000000 --- a/crates/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr +++ /dev/null @@ -1,107 +0,0 @@ -use dep::std; - -fn main() -> pub Field { - let f = if 3 * 7 > 200 as u32 { foo } else { bar }; - assert(f()[1] == 2); - // Lambdas: - assert(twice(|x| x * 2, 5) == 20); - assert((|x, y| x + y + 1)(2, 3) == 6); - - // nested lambdas - assert((|a, b| { - a + (|c| c + 2)(b) - })(0, 1) == 3); - - - // Closures: - let a = 42; - let g = || a; - assert(g() == 42); - - // When you copy mutable variables, - // the capture of the copies shouldn't change: - let mut x = 2; - x = x + 1; - let z = x; - - // Add extra mutations to ensure we can mutate x without the - // captured z changing. - x = x + 1; - assert((|y| y + z)(1) == 4); - - // When you capture mutable variables, - // again, the captured variable doesn't change: - let closure_capturing_mutable = (|y| y + x); - assert(closure_capturing_mutable(1) == 5); - x += 1; - assert(closure_capturing_mutable(1) == 5); - - regression_2154(); - - let ret = twice(add1, 3); - - test_array_functions(); - ret -} - -/// Test the array functions in std::array -fn test_array_functions() { - let myarray: [i32; 3] = [1, 2, 3]; - assert(myarray.any(|n| n > 2)); - - let evens: [i32; 3] = [2, 4, 6]; - assert(evens.all(|n| n > 1)); - - assert(evens.fold(0, |a, b| a + b) == 12); - assert(evens.reduce(|a, b| a + b) == 12); - - // TODO: is this a sort_via issue with the new backend, - // or something more general? - // - // currently it fails only with `--experimental-ssa` with - // "not yet implemented: Cast into signed" - // but it worked with the original ssa backend - // (before dropping it) - // - // opened #2121 for it - // https://github.com/noir-lang/noir/issues/2121 - - // let descending = myarray.sort_via(|a, b| a > b); - // assert(descending == [3, 2, 1]); - - assert(evens.map(|n| n / 2) == myarray); -} - -fn foo() -> [u32; 2] { - [1, 3] -} - -fn bar() -> [u32; 2] { - [3, 2] -} - -fn add1(x: Field) -> Field { - x + 1 -} - -fn twice(f: fn(Field) -> Field, x: Field) -> Field { - f(f(x)) -} - -// Fixing an ICE, where rewriting the closures -// during monomorphization didn't correspond -// to an internal `if` type -// found by @jfecher: -// https://github.com/noir-lang/noir/pull/1959#issuecomment-1658992989 -// issue https://github.com/noir-lang/noir/issues/2154 -fn regression_2154() { - let x: u32 = 32; - - let closure_if_else = if x > 2 { - || x - } else { - || x + 2342 - }; - - assert(closure_if_else() == 32); -} diff --git a/crates/nargo_cli/tests/execution_success/higher_order_functions/target/higher_order_functions.bytecode b/crates/nargo_cli/tests/execution_success/higher_order_functions/target/higher_order_functions.bytecode deleted file mode 100644 index 660387db26b..00000000000 --- a/crates/nargo_cli/tests/execution_success/higher_order_functions/target/higher_order_functions.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/higher_order_functions/target/witness.tr b/crates/nargo_cli/tests/execution_success/higher_order_functions/target/witness.tr deleted file mode 100644 index 28701fee014..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/higher_order_functions/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/if_else_chain/src/main.nr b/crates/nargo_cli/tests/execution_success/if_else_chain/src/main.nr deleted file mode 100644 index 5105c18c7de..00000000000 --- a/crates/nargo_cli/tests/execution_success/if_else_chain/src/main.nr +++ /dev/null @@ -1,16 +0,0 @@ - -fn main(a: u32, mut c: [u32; 4]){ - if a == c[0] { - assert(c[0] == 0); - } else if a == c[1] { - assert(c[1] == 0); - } else if a == c[2] { - assert(c[2] == 0); - } else if a == c[3] { - // expect to match this case - assert(c[3] == 0); - } else { - assert(c[0] == 10); - } -} - diff --git a/crates/nargo_cli/tests/execution_success/if_else_chain/target/if_else_chain.bytecode b/crates/nargo_cli/tests/execution_success/if_else_chain/target/if_else_chain.bytecode deleted file mode 100644 index a265d8d90e7..00000000000 --- a/crates/nargo_cli/tests/execution_success/if_else_chain/target/if_else_chain.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1c7U4UQRBs9gNOkBMERBDkEEEQkJ39uNszmmCiicbfPoAX797/EbR1NpndyK+p3vQlMwnZWQhFV/VM1c384DsR/aB/Y+XPV2SfI+c96rzHnfek857a99TiJvbZ/G7i/KwZsX3e22fmN8yKg1Vk47KcT/K5KczPLJ/O6iorq9m4NrWp6upXXhfFvC7ryXQ2nWRTUxZzs6imxcKCRUCsVRzHLLaad8cKWEtkzW69a87cXSPdNbEqwIk6f6er4/A/34P+cYkmrQngDgi3+KV4D/A96m1zRSSzuR4587C5PDEjKygad510by7mvY7vkUitA1trF9dX1/dg3s2IwXUijXoD2Bekfn2ZMpB/y5QfO/Ngyp6YG1ZQNO4m6TZl5r2J71HLnLRr2gzNx8YYiDWk5TNRZM1uvU+ceTBRT8yhFRSNu0W6TZR5b+F71DKnqIOt6RPeNlDLvgwlJhlDeerMg6F4YsZWUDTuDuk2FOa9g++RSK1sfNuEPyrvCvP2rU+K9wfl/eZ1uSvA+yPJBCf6amQPqCWw1wapX18hDNSyFcLPnHkIYU/MPSsoGnefdIcw897H90j0agStaTM0nz6ek8zmRXNGnmIPSM6wkOsReQWWALEOafnCElmzW+8LZx7C0hPz0AqKxj0i3WHJvI/wPRKplQPjgPAnmGNaPlNJSMZUXjrzYCqemIkVFI17QrpNhXmf4HskUiub3zHhTWUkzNu3Pine98r7zetyJMD7E5h3M9DXYKdALYG9Nkj9+gphoJatEH7lzEMIe2KeWkHRuGekO4SZ9xm+R6LXYNo1lTqBvBbqD/oqDHmaPSc500L2HHkVlgKxLmj5AhNZs1vvG2ceAtMT88IKisa9JN3mzrwv8T0SqZUD45zwQXRFy2cqKcmYyltnHkzFEzO1gqJxr0m3qTDva3yPRGpl87sivKncCPP2rU+K92fl/eZ1eSPA+wuYdzPQV2G3QC2BvTZI/foKYaCWrRB+58xDCHti3lpB0bh3pDuEmfcdvkeiV2HaNZU6gWRC/UFfhSFPs4ZkTCsC9zwCcs4BWPPF3zHpK+Rykgm5wpmHkPPEzK2gaNySdBsy8y7xPRKplUEN4cOjEuaNCDcJ3l+V95vXZSXA+xvJfFhAnzTHQC2BvTZI/foKYaCWrRCeOPMQwp6YYysoGrcm3SHMvGt8j0RPmkhNU6dG3jwP/adPHr8B1U0SW3ZUAAA= diff --git a/crates/nargo_cli/tests/execution_success/if_else_chain/target/witness.tr b/crates/nargo_cli/tests/execution_success/if_else_chain/target/witness.tr deleted file mode 100644 index ff71010966a..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/if_else_chain/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/import/target/import.bytecode b/crates/nargo_cli/tests/execution_success/import/target/import.bytecode deleted file mode 100644 index 6c8a599689e..00000000000 --- a/crates/nargo_cli/tests/execution_success/import/target/import.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/7VTMQ7DIAw0JGTsW2wMwWz9SlHJ/59QqSISSthibjFiON+d7Q0AHNyxtPpuFZ+BTMfFuIdQk6/E9EGfi0QMsexCQlHi1wtzlSApl5wwU+BKR8x8NDKryLXoefxzmUGWRjlLTc293nXwtoOd2CZ4gkufa46vwZ9q8xlDWifwOtBb/lm+nf6MsKO8aX6ag1PUaTuN/fGc+AEp7slRcQUAAA== diff --git a/crates/nargo_cli/tests/execution_success/integer_array_indexing/src/main.nr b/crates/nargo_cli/tests/execution_success/integer_array_indexing/src/main.nr deleted file mode 100644 index e89e2ffbb80..00000000000 --- a/crates/nargo_cli/tests/execution_success/integer_array_indexing/src/main.nr +++ /dev/null @@ -1,14 +0,0 @@ -use dep::std; - -global ARRAY_LEN: u32 = 3; - -fn main(arr: [Field; ARRAY_LEN], x: u32) -> pub Field { - - let mut value = arr[ARRAY_LEN - 1]; - - value += arr[0 as u32]; - value += arr[1 as Field]; - - value + (x as Field) - -} diff --git a/crates/nargo_cli/tests/execution_success/integer_array_indexing/target/integer_array_indexing.bytecode b/crates/nargo_cli/tests/execution_success/integer_array_indexing/target/integer_array_indexing.bytecode deleted file mode 100644 index 5f90fbc769e..00000000000 --- a/crates/nargo_cli/tests/execution_success/integer_array_indexing/target/integer_array_indexing.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/72TYQrDIAyFtbVs7BQ7QmK0Jv92lcns/Y+wjkVwv5v1QXgK4RE+kptzbnFfdZ/V/V6T/vs77HV3v+r9D3U4JvSGWdOQRbCm1EpsSPiEKJUzpFxXRsbM+RWZqHHiIlUKCCZquGWhTcMudnPBP/nNhlnBkN/1JH5H51wM+RnuDFryC5oz3ngYmHr1D4s3QqMLTiQEAAA= diff --git a/crates/nargo_cli/tests/execution_success/keccak256/target/keccak256.bytecode b/crates/nargo_cli/tests/execution_success/keccak256/target/keccak256.bytecode deleted file mode 100644 index 0816f65fefa..00000000000 --- a/crates/nargo_cli/tests/execution_success/keccak256/target/keccak256.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/keccak256/target/witness.tr b/crates/nargo_cli/tests/execution_success/keccak256/target/witness.tr deleted file mode 100644 index 42087edb0f9..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/keccak256/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/main_bool_arg/target/main_bool_arg.bytecode b/crates/nargo_cli/tests/execution_success/main_bool_arg/target/main_bool_arg.bytecode deleted file mode 100644 index ac87d3be310..00000000000 --- a/crates/nargo_cli/tests/execution_success/main_bool_arg/target/main_bool_arg.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/7VVUQ7DIAhFbV2yj51Fqrb4t6usmb3/EbZlNKGmf0US88BEeIDiDQDu8BfzXZbRCNs2tmN95HNWoIOjGMYnY7gmaISvGOaU6jJVjPgKU1kph5TXmZAwU35PFGOlREtZyxIKplhxyyVu7EzydMo8rSJPp+hr0MsxONHfnj3X5Cz5jkIfGO3JnfAdcoImTlvHx8meavAeTRo7+PWg++B75O31e3QYTi3nq3XwoDsEdo5nH8BPPgHj5KhlBgAA diff --git a/crates/nargo_cli/tests/execution_success/main_return/target/main_return.bytecode b/crates/nargo_cli/tests/execution_success/main_return/target/main_return.bytecode deleted file mode 100644 index e4e0c0ab30a..00000000000 --- a/crates/nargo_cli/tests/execution_success/main_return/target/main_return.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/2NiwASMSDQyGwBkySDbLAAAAA== diff --git a/crates/nargo_cli/tests/execution_success/merkle_insert/target/merkle_insert.bytecode b/crates/nargo_cli/tests/execution_success/merkle_insert/target/merkle_insert.bytecode deleted file mode 100644 index 9ad86b898a9..00000000000 --- a/crates/nargo_cli/tests/execution_success/merkle_insert/target/merkle_insert.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/merkle_insert/target/witness.tr b/crates/nargo_cli/tests/execution_success/merkle_insert/target/witness.tr deleted file mode 100644 index d53f276557b..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/merkle_insert/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/modules/target/modules.bytecode b/crates/nargo_cli/tests/execution_success/modules/target/modules.bytecode deleted file mode 100644 index 3da50d6cf0a..00000000000 --- a/crates/nargo_cli/tests/execution_success/modules/target/modules.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/7WTMRLEIAhFMYkp9ywgGrHbq6yz5v5H2JkdCyaxC9LgWDw+H9gBwMM91p7fPeOzIKdYjEeMLYdGTB8MpUrCmOohJJQkfYMwN4mSSy0ZC0VudKbCZ4cthqzVrsc/yw28dMZeWmrWerfBexnsxD6hJ7jUufr4GvyZFp8xpG0C14Pd8s/q29vPCBXypvmpDx7sD8opnfqIfsM1RNtxBQAA diff --git a/crates/nargo_cli/tests/execution_success/modules_more/target/modules_more.bytecode b/crates/nargo_cli/tests/execution_success/modules_more/target/modules_more.bytecode deleted file mode 100644 index 6c8a599689e..00000000000 --- a/crates/nargo_cli/tests/execution_success/modules_more/target/modules_more.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/7VTMQ7DIAw0JGTsW2wMwWz9SlHJ/59QqSISSthibjFiON+d7Q0AHNyxtPpuFZ+BTMfFuIdQk6/E9EGfi0QMsexCQlHi1wtzlSApl5wwU+BKR8x8NDKryLXoefxzmUGWRjlLTc293nXwtoOd2CZ4gkufa46vwZ9q8xlDWifwOtBb/lm+nf6MsKO8aX6ag1PUaTuN/fGc+AEp7slRcQUAAA== diff --git a/crates/nargo_cli/tests/execution_success/modulus/src/main.nr b/crates/nargo_cli/tests/execution_success/modulus/src/main.nr deleted file mode 100644 index 4a13a6e06ba..00000000000 --- a/crates/nargo_cli/tests/execution_success/modulus/src/main.nr +++ /dev/null @@ -1,27 +0,0 @@ -use dep::std; - -fn main(bn254_modulus_be_bytes : [u8; 32], bn254_modulus_be_bits : [u1; 254]) -> pub Field { - let modulus_size = std::field::modulus_num_bits(); - // NOTE: The constraints used in this circuit will only work when testing nargo with the plonk bn254 backend - assert(modulus_size == 254); - - let modulus_be_byte_array = std::field::modulus_be_bytes(); - for i in 0..32 { - assert(modulus_be_byte_array[i] == bn254_modulus_be_bytes[i]); - } - let modulus_le_byte_array = std::field::modulus_le_bytes(); - for i in 0..32 { - assert(modulus_le_byte_array[i] == bn254_modulus_be_bytes[31-i]); - } - - let modulus_be_bits = std::field::modulus_be_bits(); - for i in 0..254 { - assert(modulus_be_bits[i] == bn254_modulus_be_bits[i]); - } - let modulus_le_bits = std::field::modulus_le_bits(); - for i in 0..254 { - assert(modulus_le_bits[i] == bn254_modulus_be_bits[253-i]); - } - - modulus_size -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/modulus/target/modulus.bytecode b/crates/nargo_cli/tests/execution_success/modulus/target/modulus.bytecode deleted file mode 100644 index f5d9da09249..00000000000 --- a/crates/nargo_cli/tests/execution_success/modulus/target/modulus.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/modulus/target/witness.tr b/crates/nargo_cli/tests/execution_success/modulus/target/witness.tr deleted file mode 100644 index e267681b40a..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/modulus/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/target/nested_arrays_from_brillig.bytecode b/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/target/nested_arrays_from_brillig.bytecode deleted file mode 100644 index 60aafea2b48..00000000000 --- a/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/target/nested_arrays_from_brillig.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/92b7VbiMBCGw2cpxYoo8uk99BPKP25l3cUfe817MdvEzvElGyrKjEvNOTltSc0882ZmGisulVK+em296tivjq2yt8veKXu3Gu9X1y24h+5X8Jlu++oYXdbiFt9ckRRjuwGMnQYwdhvA2GsAY5+REXN9VJ17ZR+o19oxLHtQjd2UPSz7bdnHZb8r+0S9tT/VUf9cWx03rCN7HvZNn1/bSK//b2Du8c7/U2vTtbRpWdd7OMe67TH7quccMM+p1NszRzeKA2IfqrdYwPvwnPQhtgDG+3BkZo8FNI7JZ1uPAejhwzlpMbS0aFnz7OHaA01GMM7Ab2LkhnlOPUcIvpD/I9AhqM7xPjwn34ktgPEA9GBmjwU0jk/pcfMJPUbv6MEc34lAHqaogW6uGoK5Qkc6x5zBefZwPQBNmpgz9nqfEyN2XH2nnLHrwUf0eC9nmNkTAY2TU3pIxAd3vgvUpQ36o5vruXvuPsQDDVz7EGb2TEDjLfls64E19dJ9CNZU7vonUaf1HF/13OWufxJ1+pQeEvsy5vjOBfJwhxro5qohl+5DcO/exJxp0HP3S3KmQfuyRGJvc0oP7vjAd0xd6+cUjIWVdl1eP00e9Bz2uuBnpzrHdzh9Xg4Tf56Dow8cZB9rDXP9TU7pj7WS7OMeSmJdXPscXBd7nyO1LoGDA9eF7As+F826jBwcuC5kfwQczLXG/E4fOjiwLpD9EDhueTkyPcfYwXELHGR/DBx3vBy5nmPi4LgDDrI/AY57Xo6Nb3HoVvc++h5YHnhZTO5OwRZxkZ0AxjFnprwc5m+SD5b/dD0Fu4+8dhNfHfuvW91aPALLjJfFrMUcbBHXDPSncaznc14OsxYzy3+6Rr5zWYdXwIr3uGJ8ZvkhsL61MT6T0yj11bH/utXF+BxYFrwsJsaXYIu4yE4A4x3gWPJymLVYWP7TNfKdy9prEKt3Bax4jysfF5YfArFYm4+LT7CO/zOrwHqa5yP6r1td7VgCy4qXxdSONdgiLrITwDjuq9e8HGYtVpb/dI1857KGV8CK97hifGX5IbC+tTG+krP74ecjsjCvl4nxJ7BFXGQngHF8Pj7xcpi1WFv+0zXyncvaaxCrdwWseI8rH9eWH1K141Q+ki0fPpvAZ22LWWtq5xTrix9qHea5Pca5fJgrjTZZdtgmhziNf0TJ7rnIoyx/3hRxEedF/isp0vRQZMV297zbRrs4Sw/xS75LX6rJZoq36EjpFzLONWbUb/5F+l3Kec+oH2PMxHMGHw8vpm3xC/DYuL/Ey6hlhLxYJOmld9sREwJfnv2n9tk6hkq48Eos0oPAvFPFl5RSfk/51+ioOF2zpu/9l4zd/gJqB4bgajMAAA== diff --git a/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/target/witness.tr b/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/target/witness.tr deleted file mode 100644 index 878a2665415..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/pedersen_check/target/pedersen_check.bytecode b/crates/nargo_cli/tests/execution_success/pedersen_check/target/pedersen_check.bytecode deleted file mode 100644 index 7e0c2c4b29a..00000000000 --- a/crates/nargo_cli/tests/execution_success/pedersen_check/target/pedersen_check.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1X0Y6CMBBcQPDUU09Pzd1ftBSkvN2vHBH//wuMNLbJWn3rNMHESZoWSJaZ2Xaz/SWiPd2QDKMYRsqeL/b5Yt+Z71O6R2bnPzsrcayqvil7qeS/KNtO16Kqu6OWWta6PpVaqV5Xumm7thGtrFQvz3WrzuKGCYslwiALIK8PHC+RWX99JJ6XIgwSyZnznbH1xM7pkz1RRNBE3n98H1dP3kF/HiNJswhx54Tb/LF0z/E5Eizk6D11QBfRHKh5CuS1oNcrokjOnO8nW7+LaGDMhTUUHXdJ4y6iRvcSn6OoRRTtqUOG5akToOYUqPmH4uQZ7J/MgJpXQF5I/9ytyZ0Rw9PdltbD+KJ7+Gcp1JcNTEvZ+Vo2TMt2GN+eFnTTsgbmeAvktaPXa1qQnDnfPVu/m5bAmDtrKDrugcbdtBjdB3yOojYtSE9zxtEcHrOZzWHK6RFXJUaxiKMTAAA= diff --git a/crates/nargo_cli/tests/execution_success/pedersen_check/target/witness.tr b/crates/nargo_cli/tests/execution_success/pedersen_check/target/witness.tr deleted file mode 100644 index d6e19416a8c..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/pedersen_check/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/target/poseidon_bn254_hash.bytecode b/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/target/poseidon_bn254_hash.bytecode deleted file mode 100644 index 1d4140f175b..00000000000 --- a/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/target/poseidon_bn254_hash.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+z9d7imSVX2DW9GkkgSEBHJIiIi1qpc5CQiccg5VCQ1QUUyTRRHRMKQmoxZMSfEEQFHHHLOMAxpSEMyByR8q/rxOY77fr/3vzqvOnYd+23C9HTv3n3X71pX1Ypn/cI1Dg7u9gMHJ39c4P/84+CU//3n+f735xf435+f/39//fz/+2sX5P9d6GD/x//9szf+33+KsR90vp3vpYTVujpZSVEUMiRvhDbJevJkvCnSK1W99i6k4EQgrSo1E1T732/2vXufq5HWRirTJGmfTfDWeEc2tEwpF+9dEr7oIoS3vjRjg22taRGMrd7qVdZ8EfCazwdea38mF/l/+b6j6/4+3GcUK637ood83f25XHSDdV8MvO7/++Mwv9sXP1hjPzsFuOZL7H4uXkdT/LXVxxwCf6EMURhfRItepKBEdtI7JZKLSdlc+bs25YOouTnVzCprviR4zeh3uj+TSx7g3+nvPzjce9lW677UIV93fy6X2mDdlz5YYw9HvtuXOdj23SZbiyb+dCmFLLK1sRIFLXUrJeWUgyJdcmgllVqjMcVmq41WJesgVD15rl58g2d90/Nva+MyBZFS5GMxd4ShWXLVlZxa9bKK0pywMVktck1Su+QCxaCS01VZp2zptniZDdZ9s/NvY+PfA/6cPwB8X4DPmnb5SVGLrUYHGWoqIhvnguf3orkia9BZBSOpxBi0815KF3M0bPTK8qtgScUt+V32iPBDny3d7i67wXv3gweH+0zdat2XO+Tr7s/lchus+4cO1thnL3/w/+2zI/x+eJdfC6FYwSe48l6lxuGuy6IKyR6QcK5W7Sk6kZOSzhXNIbJL5By1JCny597lJ3WINXNoXFyQvn+pltlYFarwylFIylVtKUiqNolYggmOCvtR7E54DsT3+GnRivXZx5adV82myIDIF4bjhBNCSY7CtQ3J5CRsDdZ6KaSinIVJqm7J7wpHhB963+p2d4UD/L51xYPDvV9vte4rHfJ19+dypQ3WfeWDNc6pqxz8f/vsCL+r7j3nnK3UtiVSLTbvchCWJDXyDJUPUdeDUz5FU7VWJZ+UL9T/obKMKZVdfiSYBLMyPrcqyRtlm0pWVq2UScFwCOxkTxbILL1vqeUSAi9dy36QS7nHj6N+SyLIkjkkJkOF/+LIT06ozIwSGdeEMsaZVpVSxcpWoi4yGk4qpP18Kprf1Y4IP/S+1e3uagf4fetHDg73fr3Vuq9+yNfdn8vVN1j3jx6scU5d4+Bo7hP87ZJrmog/SNU5JJn4BI7NcBgW+fgNOlWXiWKRWjnPadDCUE2QKXoin3q8fPkN7OYWG+d5R/Pb3f+6ygbr/plDnt/u7/M1Nlj3LSflt8XYDwLaJe0+61F+P7tIfeDHgM8CaDO0y483YuIXPdYUa4xe+qicLXwOxKYjb/jZJ5ca56uK5kSVDL42x2dA/zVvpC1b8rvmEeGH9m+63V3zAL9v/fjBtvu1GPux2bqvdcjX3Z/LtTZY908crLHPXvvgaO+zgjNNVrE/J5wp7Ne2nL2wXFkoxauspJaS/0YZe4onch7HRm09p3X4F7VvTu2d84N5K+Q5f7tFzvmfPMDl6pD2t8tPOunYqU0yd4dfKI7vOExSvlKmokWRQilvjeR4UBmZMhmOvXwspbSQk/Nb8rvOEeGH3ve73V3nAL/v/9TB4T7vtlq3OOTr7s9FbLBuOlhjn5UHR3uflZzlCqlFrXkdOfrCf56Tai5wAot08yQDn9VJJO85zUGSU1mchePDWkpprN8/5wfzfshz/tRFznl1gMt1Iu3v1L28qa5ZmxzZPZMuy+p0TGwoMpIOOhdbWyq8MKU5I+aKTfzZQlX8lhg2CCW35KePCD/0vt/tTh/g931zcLjPu63WbQ/5uvtzsRus2x2ssc/6g6O5T4zWp3q+5tob2M0dD3l9qvuvcoN13+mQ16f6++w3WPedF6lPAe2S7gT0Z++yiD8bgM8CaDO0y49MMtLwLspLrMTZyuatzBxeNcf/tSImErz7GRGV4i0y9+2/NdvHvjg9KTfNW133iPBD+zfd7q57gN+3rnew7X4txn5stu7rH/J19+dy/Q3WfYODNfbZGx4c7X12tD51R2B9CnnO33ORc/5GB7i8KdL+9viV7FsstoSqkzLN1BKiKuQtu725cgJVVB97DtJ4TlnK4gTnU2vNzfIvNrslvxsfEX7off//2h1637/JweE+77Za900P+br7c7npBuu+2cEa++zND472Pjtan7ojsD6FPOfvvcg5/9MHuLwp0v52+XWdrWBay5LYJ8vRcvbLCcMmqVoy1tWoK78bvvFHpVZzcF4YQz5qfl9KyFvyu8UR4Yfe97vd3eJgg/mAg8N93m217lse8nX353LLDdb9swdr7LO3Ojia+8Rofarna264gd3c95DXp7r/evMN1n2/Q16f6u/zrTZY9/0XqU8B7ZLuB/Rn4yL+7K2BzwJoMxT3Zl6N5JAmJicpx9JqqI0jnSTItqx4W3C2xL79G+cDb4rkMi/WF2FDqcaELfnd5ojwQ/s33e5uc4Dft257sO1+LcZ+bLbu2x3ydffncrsN1n37gzX22VMPjuY+MerP9ud76gZ20yadz7K1YA3Xy6RJurnahPU+lZ4KFK1xVU6XFqvj1bKH61sjztmZrFWMNhtlyq5/I4lX7C3/NpfhChf6hEuSGQT+K0rpTqEV3SP2VCS7kFT59yQ/N87aiVRNQ/o3D5jEj6TznMTlmmUvPUpRpVCCI63KCUr+1LmKpJLij+5rppyEYXPjBQsfOLNZi0K+Kw3I74GL+Id3OMDxA9oM7fGLfXyzBs63i8IF6MwVgaCrtCr6Woz2uiiuA2j+veKs11x0L82WyllzH5JNW/K74xHhh/YXut3d8WCDftODw+0nbbXuOx/ydffncucN1n2XgzX22bseHM19YtQ/7M/3rhvYzbFZ/k1JnOCrLnppA0MkbbgWW1VxnMvm4iuXg5XlanXh7KhqWmufreLEHxmZPZe09/xD9tJVdOyzs6cUog1cuq3sAYZSok+ajHE6CtsiO4qpqpwDpZJUzPyVsiSD9A8fOit/GDlgIV+69nMwNgvL1XRfa8g9yW5yC1oI703MuTb+Gp9VEFpUTjFz9tjH+58f56sj/cOHLZJ/Bb4n9FAgv4cv4l/fDfgsgDZDu/yIOAHAJQqbyXlFtfWqiyyhpJp4p6HCO5IMHHny5lWpKOP4aKDqVeG3iXebLfnd/YjwQ/tb3e7ufoA/N+9xgH3vVln3PQ/5uvtzuecG677XwRr77L0PjuY+Mepf9+d77w3s5pGz/JumQ9BOxNBykt1f4/q6DoL9aXYJVSKTvM+SfeOe+za8IpKF/cVqqhJG7OVfSQv2rws75yn4XEpqsauHGe28jClI5ww7kH3GorLTzs6naEU1jpGy4OysgfrXvziLnzYx5RD7ipzUVFoOnIzlfCv7vczIcbqVUhIc6rFf7VuoUTSpRfDRcqyxl38djXWQ/vWjFsn/I/3rRwL5PXqR+AT4ntCjgPwes0h8ch/gswDaDD1mTyfCZ96ffD/oZMjG6JJImWhs8rxjFWqxVcOnqJFO1URS9HZ82yr1t1CWLfnd94jwQ/ur3e7ue7BBP98B9r1bZd33P+Tr7s/l/husOx6ssc+mg6O5T4zGJ/35pg3s5vgs/8aTM1Lp6DN/pVTSmuZV623lrmaOTYrQ0bH3mxN/bKs011jkyXgw8ge2aS8+EZFrL8kZW3MVPnHNJbckRbWNIXO236SQQ3PWnhzlEqlyYOKlaSVJEwQ0PnnSLP+afKVIXOgoJqQsQzMUs5fNRbJslCFw7KKCipUDPcWfPGefZFCmSRul93v9IYOxIjI+efIi9adjwPoJMj55yiLxCXCfoScB+T11EX7A94SeAuT3tEXiuwx8FkCboX1+xJtsqFY41VIga6ytkr0N3oCDKoLXE4nPO2lqTFJKIXTl34u8xcTAzsOW/MoR4Yf297vdlQO831YPsO/dKutuh3zd/bm0Ddb9gIM19tkHHhzNfWI0vuvP94Eb2M0zp/UnUZNcDBKSC3mpBO2t7oFYl95oJpYSZP+CLCwHKByM9RmMkHTmUI0ha7c338jlwVA803SNbFCixzYc/bRe/KtcDfTNcBBUK8eUTTcVXLKNuP7E0Y7lf0fGd786Kz6hyssKtillFEnNi+MQOCuVm+YoV7XqGzXPeEU1wqao+Aw4Gfw6ts2k9+K7wVgbGd89a5H65zFg/Q4Z3/3aIvU7ZHz3TCC/Zy8S3wH3GXoWkN9zFuEHfE/o2UB+z10kPn4Q8FkAbYaeu9c3ZBM7GLUffYmPON7zC5/7tgbyWvGvydI1wYKOijd/cpwNZd+Lk/SeT9SsNu3PfPAR4YeOl7rdPfgA7/c+5AD73q2y7mOHfN39uRzbYN0PPVhjn33YwdHcJ0bj4/58H7aB3ZyYNt/N0ZimzMGH0la1JhkF/4otjjMRxAV8wwFzzgzEGM5B5JhSsoHDDS5FcxJivz9TN+OoSH4Wmv8/KF2cMn0APhYXEwfLkiM8X6tKLnEA2IxKiQNyDgVzixoZH79kFr9cU1Zcd+cYzpciYxTBlxq05pSM47Ko4gxEJBmK4wROPhmopVSb6/NSttq9+HgwV4GMj1+6SP39GLB+jIyPX7ZI/fg4sH6MjI9fvkh8B9yn6SVAfq9YhB9wn6GXAfm9chF+wPeEXgHk96pF8gsPBz4LoM3QHj/bXNGtj/sL4s2W92V2nXhhgoR1piXN/qvRLvDxyQSKNKIGdoxd1xBn92FLfo84IvzQ8Wa3u0cc4OOGnzvAvnerrPvnD/m6+3P5+Q3W/QsHa+yzjzw4mvvEaH6hP99HbmA3vzfLv5GicOqglsyRMrnUSq8jKy4ZFxKly4Nojpe5jKyZemFSqRIvvnLIJzlwTvv190a9m7poZ7mqTrFfMkvB1GodB+AmcO2df8fJYFJyqva7tWrkdJC2ujfEI/MLvz+r/plFbpyGYcNQHCoLofqlJk3yZ9JKm1hDN0yO7JRXzmkOBVu/noSDWzbemvb6q0dzPcj8wmsW6f84BuxfQOYX/mCR/oXjwP4FZH7hDxfpX0DmF34PyO+PFomPgfs0vQbI748X4QfcZ+gPgfz+ZBF+wPeE/hjI708Xyc/8IvBZAG2G9vgV9stC4TORDzxSWhYpRWbPifd63v6jcSYGdty0KFqo3hfalxeLisH7ajedj3jUEeGHjte73T3qAB93PfoA+96tsu7HHPJ19+fymA3W/diDNfbZxx0czX1iND/Tn+/jNrCbM2bVj3lNlApHXqK3I4havVdRBm2k0RwbU6na6Wp1EU34EGUz/BFT4liNQzW33/8hSuJQLslctOWoJmVlWnacTzBd35azZ0VYm5OWFEkFjppLzZW/znqVUobmZ/52Wv9MrTKTKgyIufimYqHi2VA5PRikpv75GFcULTfOKLCNOV6S7nfRJ+vqXv/HYK4MmZ95/SL9R8eA/TPI/MzfLdI/cxzYP4PMz7xhkf6ZE8D+GWR+5o2LxMfAc47+FsjvTYvwA+7T9HdAfn+/CD/gPkNvBPI7cxF+wPeE/h7I7x8WyW89HvgsgDZDe/zYFQ1cd4yWpOUgwVaOwmI0OXS/XjvDlVYjuHrOPpWQXZyWWiqx6eLY121lS35POCL80PmObndPOMDHrU88wL53q6z7+CFfd38uxzdY95MO1thnn3xwNPeJ0fxWf75P3sBu3j2r/m757ywuZRctB8Uc/npbONjnlI2LghNYKQbpOEtgvPXJK052OU4xUK2cNnBp734nCsyFvMglFV57McGommWUilMRnFkQKnMoVzxHj6FkaRmx0SkkjrSN8ySQ+a33zIqPOaOnKKcW+4VNXmXPkT9Hv5lD4cRRMadcLUORORMvu+bMCHX/15o4OyvdXv/RYK4Rmd967yL9b8eA/VvI/Nb7FunfOg7s30Lmt96/SP/WCWD/FjK/9YFF+reQ+a13A/l9cJH8AvCco/cC+X1oEX7AfZreD+T34UX4AfcZ+iCQ30cW4Qd8T+jDQH4fXSQ/+BTgswDaDO3yY2+/6FyMUqG7uk2LEDI7U0qK4IpSHHWmRhyxtqyMaF0Lgb+UKiXJEGLdkt9Tjwg/dL6o291TD/Bx/9MOsO/dKut++iFfd38uT99g3b90sMY++4yDo7lPjOYH+/N9xgZ2c+6s/BZH/KmnUDg/p0IW3lqXTeB/jYI4ZhbCx1RSs9mTTDZ5/h1eurBUHbmY9/KDnETkDBaVEEvlFQuvNSdpOEXTnKgUDX/fHjkS53GdY5hMkONsIZvnj2AcMj/4+Vn8lLMc7CpOSpFssdmmDCdr+BcaZz59EMZx2rSJanzIgbN4WlbHHzUZFZSMae/+98FcLTI/+IVF+i+PAfsHkfnBLy7SP3gc2D+IzA9+aZH+wRPA/kFkfvDLi/QPngHsH0TmB89bJL8A9BPo80B+X1mEH/Ccoy8C+X11EX7AfZq+DOT3tUX4AfcZ+gqQ39cX4Qd8T+hrQH7fWCS/+svAZwG0GdrjZ4Vlv0BmQZakjK45jrxrUByixxRUSEpmdtaiybG0EHxW0hvZUlHZupq25HfaEeGHzrd1uzvtAJ83+ZUD7Hu3yrqfecjX3Z/LMzdY968erLHPPuvgaO4To/nV/nyftYHdfGuWf+NyVbIL5gnnjZMc/hflkiqZEQcfOTfTqmJCnOELSVRXHOdKo01Fc36ltt38qqTM6ZtKHEFzZsu20GIiTnYFIRMnw4WLJLIWhvklztzaYmzKldM5STNbTcj86rdn5ReE4TWoGoznRIMKrvcDi6Q5K+ijUoaThlnm1E7mVdjOLKexSUQmwGno3Pb05Udz3cj86ncW6f89BuxfReZXv7tI/+pxYP8qMr96cIFJ/AZzyieA/avI/Or5ZvEbzCmfAexfReZXT5nEbzSnjMyvfgvI73tm2d/YDwL6CfQdIL/zL8IPeM7R7p4/yu8Ci/AD7tN0CpDfBRfhB9xn6PxAfhdahB/wPaELAvldeBK/4XuWgc8CaDO0y49KDN6pWDg80pwlORn9UJcA89qxX8buG0evMdgOw0lnQjTFGY7za7AcP23J79lHhB86X9nt7tkH+LzTcw6w790q637uIV93fy7P3WDdzztYY589/eBo7hOj+en+fE/fwG4uOys+ljpzpioaIQ3niWWrnLYqNbfCuQAXmQXnkpkJ52kSccjciXL6NAb+rCIqt3//qSxZcLY2iNgkp7s5b8UlhBo4vdr/hFLKl8hpHdKNE2iav1aFUFUSxNlCkZH56R+cxI8CZ46DK5ydMZHIFZtdq5wODZF0qJVTo9Ina4kz/Vw9sb1+wp9ZR64JRE6y7ulfDtYKkPnpy83iN5iTPwbsn0bmp39oFr/BnPxxYP80Mj99+Vn8BnPyJ4D908j89A/Pio8Hc/JnAPunkfnpK8yyv8Gc/LnA/mlkfvqKi+RngH4W/SAwP3OlRfgB/QT6ISC/Ky/CD3jO0Q8D+V1lEX7AfZquCOR31UX4AfcZujKQ39UW4Qd8T+iqQH4/skh+//nAZwG0GdrlR15zWMWxfUu+1pbZ1RQ2696Glznp1Cg6w3GCI9V7Itl/Y5+uu8CafbfIgfmW/F5wRPih873d7l5wgM/bvfAA+96tsu4XHfJ19+fyog3W/eKDNfbZEwdHc58Yze/353tiA7uR0/L7nMeykjL1HKts5I1OnqsljZMqzffcMfPj/IqT0TGPZlzg5GrjTD6vxdFefl/KWDi7RfwT/vMhci2m9oSCy/yEQuY8beIshuc/avmvk5x0LborA2fOUgslkfl9NYsfk/KVMqetTDKi87GuKq84ARqj5FQop0iFZQPNhX/HSS5wENOOqSVOQZs9fY/BWgsyv69n+deDNY1jwP59ZH7fzLK/wZrGcWD/PjK/b2fZ32BN4wSwfx+Z33eL9O+fAezfR+b3/SL9++cC+/eR+f2wSP8+Mr8vgfmZ6y6S3wL6WaSB/K63CD+gn0AWyO/6i/ADnnPkgfxusAg/4D5N1wXyu+Ei/ID7DF0fyO9Gi/ADvid0QyC/Gy9SH3kJ8FkAbYb2+cXEuSTi2Cqnypk1o2vgwNGk7sIa8kHE6IrRnGCyvRdXy36BvWc3Npdcypb8XnpE+KHz5d3uXnqAz3u+7AD73q2y7pcf8nX35/LyDdb9ioM19tlXHhzNfWK0PtKf7ys3sJtT5/WvFk5Pi+abVs2GZHl1XqYUs4iaF+ubs7FnrxuXpgTnoji3IKLLiVP9Uu7p8/SrKXmJusjmOIlfKVVm0ITs6ezStKicQeRcoTJGBMG5DB+McJxIdMQZsBSQ9ZE7TMtveWW4EsSrS8H4xnWLKqTmQpAoKdrCWf/qHMlqFVedlJbBBi6AaC6phJ7v26+PjNWqkPWROy4yf3MMOD+CrI/caZH5kePA+RFkfeTOi8yPnADOjyDrI3dZZH7kDOD8CLI+ctdF5kfOBc6PIOsjd1tkfmS3PjJaa0HWR+6+SH4L6KfSHYD87rEIP6CfRXcC8rvnIvyAfgLdBcjvXovwA55zdDcgv3svwg+4T9M9gPzuswg/4D5D9wLyu+8i/IDvCd0HyO9+i9SXXgV8FkCbofvt9YVz6FODbhwgcfSpOVT0JQrlOQ2nlNcuBM4VlcgZkZxTYXc+E6dGqwxSkZN6S36vPiL80PWGbnevPsDnjX/9APverbLu3zjk6+7P5Tc2WPdvHqyxz/7WwdHcJ0brS/35/tYGdvOIaf3TmXPvXFriMkkjToWqGDxXiTiFHCr/U5GpXKxThlMsRVohSlSCv06o3BWz6t79DzJrzuwYUkW6pLkKpTQlLqhwakd7ypx95Ox24SwOJ8F8Lpz94QxklqVxsUVWjawv/dy8/ukSe00kRlV7raSygXCFw1ahc/Faq2B62tpzuSlw8pUrRKlxup8z9z5IE+9/flytD1lf+vlF5r+OAeeXkPWlX1hkfuk4cH4JWV965CLzSyeA80vI+tIvLjK/dAZwfglZX3rUIvNL5wLnl5D1pUcvMr902QvgalXI+tJjFplfQtaXHgHk99hF8oNAP5V+HsjvcYvwA/pZ9Eggv8cvwg/oJ9CjgPyesAg/4DlHjwHye+Ii/ID7ND0OyO/4IvyA+ww9AcjvSYvwA74ndBzI78mL1Od+G/gsgDZDu/ykjIFde5lL8L4pZTmh2Tjx29jD96Yp6UW/Iphzko6/SClRuiR+Yxdf9riJtuT3O0eEH7pe0+3udw7wefffPcC+d6us+/cO+br7c/m9Ddb9+wdr7LOvOTia+8Rofa4/39dsYDenT8tPN8XZLcUFEiuaMdZwXtkaw2W0YDXn46NUPQMvTeCMadDF8G9wPrkJTpNyimZv/it7y/Q1lcx1JDKUXOUynja2cBFVpJCqFEI7R1zki75JLg3afvkNFwNcDhZZn3v+NP+wM6mR62jRWa4RW6eq4fIcE2iB63RcP/NVay6SZE6IhsBGZvijc8LetkK0V58brJUi63MvWGT+8Bhwfg5Zn3vhIvNzx4Hzc8j63IsWmZ87AZyfQ9bnXrzI/NwZwPk5ZH3uxCLzc+cC5+eQ9bmXLDI/t6ePN1jrQ9bnXrrI/NypwPk5ZH3uZYvkB4F+Pj0fyO/li/AD+qn0QiC/VyzCD+hn0YuB/F65CD+gn0AvAfJ71SL8gOccvQzI79WL8APu0/QKIL9fX4QfcJ+hVwH5/cYi/IDvCf06kN9vLlLf/APgswDaDO3yI0kqG216MMC5S840cbYuc4qSg/QWXM6RMwCyR60kWmrOCxc4X56k42S993VLfn94RPih613d7v7wAF+3+KMD7Hu3yrr/+JCvuz+XP95g3X9ysMY++6cHR3OfGK1v9uf7pxvYzWtn+Te5RO1TNUqb7CtxBjnVppmoM1wHUpz/UkaXUHNppBMnWfsEoc9dVJSzo3KvvslPpVnJFc4+Wsg1EFFU4NIIRV+S5rxrv52NK32FPxP/dY0z2SKJ1kUfQ4wxI+ubfz0rP8gF21RDoeZKDUJyXl+T5MRnUFyMbFz91Fxba44z0i1xraiy+WbfKtsrI1Z2T99ysNaMrG++bpH512PA+U1kffNvFpnfPA6c30TWN89YZH7zBHB+E1nf/NtF5jfPAM5vIuubr19kfvNc4Pwmsr75d4vMb+7VNwdrpcj65hsWmd88FTi/iaxvvnGR+U1kffO1QH5vWiS/CvTz6XVAfn+/CD+gn0pnAPmduQg/oJ9Frwfy+4dF+AH9BHoDkN+bF+EHPOfoTUB+/7gIP+A+TWcC+Z21CD/gPkNvBvJ7yyL8gO8JnQXk99ZF6sN/BnwWQJuhXX7ScoqO05u6aNs4ycvBQGm8gC5axxlfz+k4x8kmjoWk4pBUcMIuc/4je65glODclvz+/IjwQ9cLu939+QG+7vMXB9j3bpV1/+UhX3d/Ln+5wbr/6mCNffa1B0dznxitD/fn+9oN7ObsWf5N4SKu9YJLmVw5stU1kjo5y5nB0i/r4yoxV+5k4nIHp5ZV4DKKI8VlE02NS2zxvnv1Ec7ac9aLoXGqLNRktAqu+sh/LlSuwBSviCQX970qSidOYOfKtJ0RXNJKElkf/uS0+jAXIxlFTNlzHtlz4llY2S9CNLVSVpHThSZly6U0qSK5klzlsgknrAsXOPW+Pu1grR5ZHz5nkfnrY8D5YWR9+FOLzA8fB84PI+vDn15kfvgEcH4YWR/+zCLzw2cA54eR9eHPLjI/fC5wfhhZH/7cIvPDe/XhwVozsj587iLzw6cC54eR9eHPLzI/fDpwfhhZH/7CIvlVYJxEnwTy++Ii/IB+Pn0KyO9Li/AD+qn0GSC/Ly/CD+hn0eeA/M5bhB/QT6DPA/l9ZRF+wHOOvgjk99VF+AH3afoykN/XFuEH3GfoK0B+X1+EH/A9oa8B+X1jkfr6XwOfBdBmaJef5GQFL9KLnvnmtJl1nKxzUgfFIRdHkI3zm7UVw1WgJJqsLhTJaXFpTHCScwFb8nvdEeGHrrd2u3vdAb5u9jcH2PdulXWfccjX3Z/LGRus+28P1thnX39wNPeJ0fp6f76v38Buzn/BSflBYwRX07kmzMU1pbg+Tlyv8MUKzxS4jMl5aOIaUA1cxU3y5A2m0XOJmJfDFcr9+WtOoXIKkWvKgWtJlhPVmvONwRGnoL3lMp8LnD2kytlFSo2z3b6mlMmEKJJt2iPr6xeYxE9WTu5z2ll4X1WSmYHxalpMVivtm7ScZjX8a6R6eZ2TppyfDiFzmY4rRr7ovfr6YK8Dsr5+wUn8RnsKjgHn15H19QvN4jfYU3AcOL+OrK9feNb7O9hTcAI4v46sr3/vLPsb7Ck4Azi/jqyvX2SW/Q32FJwLnF9H1te/b5b9DfYU7N3/OlirR9bXLzrt/BjrKTgVOL+OrK9fbBa/wZ6C04Hz68j6+sVn7X+DPQXI+vpuzDXK7xKz7G/sBwHjJLogkN8lF+EH9PPpwkB+378IP6CfShcB8rvUIvyAfhZdFMjv0ovwA/oJdHEgv8sswg94ztElgfx+YBF+wH2aLgXkd9lF+AH3GboMkN8PLsIP+J7QZYH8LjeJ37DOHPBZAG2G9vjFnuYxsSnBGaGouPTAdRfDtYlcax9y5KCdk0WcaWvVBs4GWCU5q1ejthy/2k3vv37DEeGHrld3u3vDAb7u+MYD7Hu3yrrfdMjX3Z/LmzZY998frLHPnnlwNPeJ0f6E/nzP3MBurjOtP4EK1257+jRx5rkwL14tJ5ZzPtk6wFl3kXLwKnAuuVJtLglKXMNLVgZBdq8/oeZMQmv+bU4iclKxBuIagHVBc6mF09Gc189WWKWYIRc8q7SlJfKZSzOFgkP2J/zULP+wBuGUL0ZxtYcrmI2rl71jQHI5LXE51/Xqpqona7hSN7ZSwQtWjStwWWubd/sTRntFkP0JYha/wZ6MY0D9BGR/Ak2rb471ZBwH6icg+xPkLPsb7Mk4AdRPQPYnqGn9HWM9GWcA9ROQ/Ql61vk72JNxLlA/AdmfYGbxG+zJ2Jv/H+x1QPYn2Fn8BnsyTgXqJyD7E9y882OoJ+N0oH4Csj/Bz7K/wZ6Ms4H6Ccj+hLBIfhoYZ9JPAflddxF+wDiJCMjveovwA/r5pID8rr8IP6CfSgbI7waL8AP6WeSA/G64CD+gn0AByO9Gi/ADnnN0PSC/Gy/CD7hP0w2A/G6yCD/gPkM3AvK76SL8gO8J3QTI72aL9Hf8A/BZAG2G9vipoLgkwdkh5znlbQ21wqW/YC0nlXqimDO9XF5QVceQuA6kHaeQfOG8lOaMMOUt+b35iPBD1/u73b35AF+3/ccD7Hu3yrrPOuTr7s/lrA3W/ZaDNfbZtx4czX1itL+jP9+3bmA395xVn3Nc2Fa9KUZyhc6GzEUlmVtKuVQix/lPzuMHLndykpTTzYWBW04zJx1tTc25vfsdAnEBz9fm2smLHLgkwD8tZGwymStNKitXGHFTunIly3M2OysmUCpX+lQOyP6Oe02bv24tq6xj4VJIMS45L7rihNciZcU1JranyuUStrMYuMLG+X02VKubl71G5Pb7O8Z6bZD9HfdeRP/kGFC/A9nfcZ9F9DuOA/U7kP0d911Ev+MEUL8D2d9xv0X0O84A6ncg+zvuv4h+x7lA/Q5kf0dcRL9jT39isFcE2d+RFtHvOBWo34Hs78iL6HecDtTvQPZ3lEX0O84G6ncg+zvqIvodyP6OewL5tUXy+8A4k+4N5PeARfgB4yS6L5DfAxfhB/Tz6f5Afg9ahB/QT6UE5PfgRfgB/SwqQH4PWYQf0E+gBuR3bBF+wHOOHgjk99BF+AH3aXowkN/DFuEH3GfoGJDfwxfhB3xP6GFAfo9YpD/mbcBnAbQZ2uPnPJdYOPstW+xVxlw4ES5bUlzg0ZyR5OSQ4Wpt4Xi/1x64tvV/EneSI/9WzKb3s7z9iPBD90t0u3v7Ab7u/Y4D7Hu3yrrfecjX3Z/LOzdY97sO1thn331wNPeJ0f6Y/nzfvYHdnDbtfJY2Uui3e3BSVZleR9Ne1Mw1Cy5wcAEycO2MapFJGpKc01dc4zUxBNtysXpP/8RZzcVkW/jBMDymXjntzDXTavv9OIGz244z01zT5HpSFllyLYbLgFy/j4Zz1BHZH/Mrs/zD4LhQmaPSMmWqJMnzxxacmOc6ZuCihraWq51SaMZBTI1tNzuvKuNORHa3P2a0VwnZH/PMRfR3jgH1Y5D9Mb+6iH7McaB+DLI/5lmL6MecAOrHIPtjfm0R/ZgzgPoxyP6YZy+iH3MuUD8G2R/znEX0Y3b7Y0Z7bZD9Mc9dRD/mVKB+DLI/5nmL6MecDtSPQfbHnL6IfszZQP0YZH/M8xfRj9ntjxnttUH2x7xgkfw+ME6nXwHye+Ei/IBxJv0qkN+LFuEHjJPo14D8XrwIP6CfT88B8juxCD+gn0rPA/J7ySL8gH4WPR/I76WL8AP6CfRCIL+XLcIPeM7Ri4H8Xr4IP+A+TS8B8nvFIvyA+wy9DMjvlYvwA74n9Aogv1ct0l/0HuCzANoM7fHjtJEKthinM5doVOFymOeSBWeAOevIqQ7V1QckZz64yFoy51O4JM5JzCiy4OzKpv1F7z0i/ND9Jt3u3nuA7xt43wH2vVtl3e8/5Ovuz+X9G6z7Awdr7LMfPDia+8Rof1F/vh/cwG5eN6u+GRtXQQzXy8hwfU5zrVsKLsIZUakY33VxVCqZ89MiSddKzqKKysV2LkfxA2i7/UUyGS6iFxs1V/S4KsIFJE5UF8EL5Foe1980/2rXifGcDw+WiXM9lUv10nOhgCufyP6iv5mV3ycuXXBVo+rG2XZdeE3krDXOu8KFIk7Lm5ILVzllULIVU4IwmSvFvaanSLb7nx/X64XsLzpjEf2nY0D9ImR/0d8uol90HKhfhOwvev0i+kUngPpFyP6iv1tEv+gMoH4Rsr/oDYvoF50L1C9C9he9cRH9oj39ncFeJWR/0ZsW0S86FahfhOwv+vtF9ItOB+oXIfuLzlxEv+hsoH4Rsr/oHxbRL9rtLxrtVUL2F715Ef0iZH/R64D8/nGR+ggwTqczgPzOWoQfMM6k1wP5vWURfsA4id4A5PfWRfgB/Xx6E5Df2xbhB/RT6Uwgv7cvwg/oZ9GbgfzesQg/oJ9AZwH5vXMRfsBzjt4K5PeuRfgB92l6O5DfuxfhB9xn6J1Afu9ZhB/wPaF3A/m9d5H+rA8BnwXQZmiXHxcHiuUMUo/sTbEc6/uYOTdUTebaRL+5J1auAmlXOVPCGQ3PxVyuPXJFl/PFTaQt+X34iPBD9+t0u/vwAb7v4iMH2PdulXV/9JCvuz+Xj26w7o8drLHPfvzgaO4To/1Z/fl+fAO7OW/a/HpoXFPyXD3KnOC3IXCVjasZVFXy1oWT3S6Ka2mF6xicwhYkmnQ5V8MlAa3K3v1olXIJsT8Urkdx3UCWFGuO/C24Fpc9PyXmWqwrKlnBRQIu4wWVauB6QnaUkP1ZX5nWX1S0rTnEkAyFqlTOQjatRC3VcRFE5pNFXS0F1zmkNvyryqfKZty7PULa038a7JVD9md9dRH9sWNA/Sxkf9bXFtHPOg7Uz0L2Z319Ef2sE0D9LGR/1jcW0c86A6ifhezP+qdF9LPOBepnIfuz/nkR/azd/qzRXi9kf9a/LKKfdSpQPwvZn/Wvi+hnnQ7Uz0L2Z/3bIvpZZwP1s5D9Wf++iH7W3v1og71eyP6s/1hEP+s0oH4Wsj/rPxepjwDzHPQVIL//WoQfME6nrwH5/fci/IBxJn0DyO+bi/ADxkn0z0B+/7MIP6CfT/8K5PetRfgB/VT6dyC/by/CD+hn0X8C+X1nEX5AP4H+G8jvu4vwA55z9D9AfgcXWoMfcJ+mbwP5nW8RfsB9hr4L5HfKIvyA7wnt2swov++ZxG/0c34C+CyANkO7/CRxVdtyHshz7pLzuyQzV7c5Cek4A8Q1VV5f5HIOL05wTUxwdVunoFz1oVZOvZst+Z19RPih+5263Z19gO9b+eQB9r1bZd3nHPJ19+dyzgbr/tTBGvvspw+O5j4x2t/Wn++nN7CbK006n7myZLVzXFUXSksum3E1M/fkfqzZcM3bdgktLpI45bmEFm2phZP2tVXDNbes6p7+WOASH5eYVctcTQpSG69k6fi1Fi5ELmNy9blLyEWu6AtdauPKYOMqlZXRVOj9hlee5R9yNTIKLvw4YZ1OXCfmIoY3iUtmuWrFFScuUZbA1lS4ms4GG1UkrsFlYXzkwuVuf9toryGyv+0qk/iN9vQdA+q3IfvbrjqL32BP33Ggfhuyv+1qs/a/wZ6+E0D9NmR/24/M2v8Ge/rOAOq3Ifvbrj6L32BP37lA/TZkf9uPztr/Bnv69u43HOyVQ/a3XWOW/Q329J0K1G9D9rf92Cz7G+zpOx2o34bsb7vmLPsb7Ok7G6jfhuxv+/Fp58dYT99ef9tgrxyyv+1as/gN9vSdBtRvQ/a3/cSs/W+wpw/Z33YlYH3k2ovUl4B5DroKkN9PLsIPGKfT1YD8rrMIP2CcSVcH8vupRfgB4yS6BpCfWIQf0M+nawL50SL8gH4qXQvITy7CD+hn0bWB/NQi/IB+Al0HyE8vwg94zpEA8jOL8APu0ySB/Owi/ID7DGkgP7cIP+B7QhbIzy/SH/gZ4LMA2gzt8iOvcs+gp5gEZ9e4ks/1LVdTLz0W2Th/xokmrqZyoZFLNKFaTv0WHYptkatCcdP7ST97RPih+8W63X32AN/387kD7Hu3yrrPPeTr7s/l3A3W/fmDNfbZLxwczX1itD+wP98vbGA3d56V32eQpJQTRhfDVUgjbOJSRnCV6xmqciFccRWEq3WKC72Kix1c/eDiiSuNv5h/utsfKETzkktzlYtuJPjbyByj6M1IRTeTqlZeOnaJMleWDPGaTUvJRS7VcUmV/z5kf+BdZvHjskjgKrq0RTMonUh366lcn0tUTKDsuTqkuIpbvNCODVg0LqRUabhWR1Lt9QcO9moi+wPvOqs/a7An8hhQPxDZH3i3af71WE/kcaB+ILI/8O7T+gPHeiJPAPUDkf2B95gVHw/2RJ4B1A9E9gfec1p/0VhP5LlA/UBkf+C9ZtnfYE/kfn/gWK8hsj/w3tP6K8d6Ik8F6gci+wPvM+v8GOyJPB2oH4jsD7zvLH6DPZFnA/UDkf2B95vmP4/1RO71Bw72GiL7A+8/7/wY6ok8DagfiOwPjLPsb7An8jygfiCyPzAtUl8C5onoLkB+eRF+wDwH3Q3IryzCDxin0z2A/Ooi/IBxJt0LyK8twg8YJ9F9gPwesAg/oJ9P9wPye+Ai/IB+KkUgvwctwg/oZ1EG8nvwIvyAfgJVIL+HLMIPeM7RA4D8ji3CD7hP04OA/B66CD/gPkMPAfJ72CL8gO8JPRTI7+GL9Fd+EfgsgDZDu/w4S6Z8zJHrBU2GECLXCaOLLXKuraTMJUjSjTNvrXGNQRrO9HKRQpzMTDbvA23J70tHhB+6367b3ZcO8H1TXz7AvnerrPu8Q77u/lzO22DdXzlYY5/96sHR3CdG+yv78/3qBnbzrGn9HVwVN5E/as5MTyuuoWXnGpfDS6nOeGVCEKamUnKwluudxIXNLnzJBboa1F5/pZc1uH6tMNeTpNC+yaoYaC9TNR9c8y5ygZOc4lpfrrFwMd8nqfnxJadERvZX/tos/1DlLBPX0QubSOTKeuLPbIXlgq3vpWL+uJqX4iUX1hJZEWu1RilbkxdVGrt3v/Bgryuyv/LZi+h/HgPqVyL7K5+ziH7lcaB+JbK/8rmL6FeeAOpXIvsrn7eIfuUZQP1KZH/l6YvoV54L1K9E9lc+fxH9yr37hQd7NZH9lS9YRL/yVKB+JbK/8oWL6FeeDtSvRPZXvmgR/cqzgfqVyP7KFy+iX7nbXznaq4nsrzyxiH7laUD9SmR/5UsW0a88D6hfieyvfOki+pXI/spnAfm9bJH6HDBPRM8G8nv5IvyAeQ56LpDfKxbhB4zT6XQgv1cuwg8YZ9ILgPxetQg/YJxELwLye/Ui/IB+Pp0A8vv1RfgB/VR6KZDfbyzCD+hn0cuB/H5zEX5AP4FeCeT3W4vwA55z9Gogv99ehB9wn6bfAPL7nUX4AfcZ+i0gv99dhB/wPaHfAfL7vUX6U78GfBZAm6E9fqbFqDQnL7W0nIRMnL/lchaXHqvnimrUxYXGmboWg07WROKydI2UubJrnJWb3g/+9SPCD92v2O3u6wf4vrNvHGDfu1XW/U+HfN39ufzTBuv+54M19tl/OTia+8Rof2p/vv+ygd2cNa0/gascKfXb1vlDBWW05jJ4ULJly6XcZiqXIyMXRhgJCRdd1pErnbUV3bhgUvbvB1dcom8+xkKJC3Ix+2q4ws5V4EqmBq4WS/4FrlApLjfXFiR/r8bfJ2pi6hbZn/qWafV1xTbBXJIVXDniVabIJTSXNHH5N6gqeSFcP7aCzUp060pBc0WqGC/Zitxef+pgrzCyP/Wts/gN9uQeA+qnIvtT3zZN/2msJ/c4UD8V2Z/69mnxyVhP7gmgfiqyP/Ud0/pTx3pyzwDqpyL7U985K78w2JN7LlA/Fdmf+q5p5+9YT+5ef+pgryuyP/Xd8/TvhnpyTwXqpyL7U98zzX8e68k9HaifiuxPfe+s82OwJ/dsoH4qsj/1fbP4Dfbk7ul/Dva6IvtT3z/Nfx7ryT0NqJ+K7E/9wLzzY6gn9zygfiqyP/WDs+xvsCd3tz91tNcV2Z/6oUXqc8A8G70FyO/Di/AD5onobUB+H1mEHzDPQe8A8vvoIvyAcTq9C8jvY4vwA8aZ9B4gv48vwg8YJ9H7gPw+sQg/oJ9PHwDyO3sRfkA/lT4E5PfJRfgB/Sz6CJDfOYvwA/oJ9DEgv08twg94ztEngPw+vQg/4D5NnwTy+8wi/ID7DH0KyO+zi/ADvif0GSC/zy3S3/uvwGcBtBna49fT3dY17znN6Yz3nDhvKiZjQq9k6WA58Rl73ZDrr9LybwQuWDirOQ9nOXe5Jb9/OyL80P2e3e7+7QDft/fvB9j3bpV1/8chX3d/Lv+xwbr/82CNffa/Do7mPjHa39uf739tYDenXHhSfclXrg57mykFFckxrSqZm8xGFi4s9SZfVRsvJGjbvCCbXbZGN+LSLymx299L1kTbOwJ1ilJnrtNxga/yP7hEVw1X442vmX+BK6VBmNKrxUpxvb7FbJ0q0P7e75nET/Jaa8qNlPUyaW3ZeLiMrk31MXUNXq4+ZlcFl3uba7Vl1Vs3VGacKttAe/29g73WyP7e88/iN9jTfAyo34vs773ArPd3sKf5OFC/F9nfe8FZ9jfY03wCqN+L7O+90Cx+gz3NZwD1e5H9vRee9f4O9jSfC9TvRfb3fu8kfqM9zZfd6w8c6xVG9vdeZBa/wZ7mU4H6vcj+3u+btf8N9jSfDtTvRfb3XnSW/Q32NJ8N1O9F9vdebJr/PNbTvKc/O9grjOzvvfgs+xvsaT4NqN+L7O+9xLTzY6yn+Tygfi+yv/eSs/gN9jTv9veO9goj+3u/f9b+N9jTjOzv3c3ZjfK71Cz7G/tBwDwbnR/I79KL8APmieiCQH6XWYQfMM9BFwby+4FF+AHjdLoIkN9lF+EHjDPpokB+P7gIP2CcRBcH8rvcIvyAfj5dEsjvhxbhB/RT6VJAfpdfhB/Qz6LLAPn98CL8gH4CXRbI7wqL8AOec3Q5IL8rLsIPuE/T5YH8rrQIP+A+Q1cA8rvyIvyA7wldCcjvKpP4jX7O/wY+C6DN0B4/rsdw2k1mLhxmLilwztO3krikrdXJCq1pXRqyF76o9twx58M9V7ycldpVuSm/bx4Rfuh+2W533zzA9z3+zwH2vVtl3d865Ovuz+VbG6z72wdr7LPfOTia+8Rof3R/vt/ZwG5uPK2+KavlGl1q1sRqSpKesUpTStQpc4VcZeKyu2kUucREKbcUrJfFyd7Kqtqe/rEpNpToixZcV27R62q4gOm69HFmrIHr6kE2Bhpq/5mooVATXK4qVGXRyP7om8zqb3M2tlxCrM0LZ12kQL3/J5sQe8sCl+9S7xdKptSgckqFS3bBCpF6W7Pc648e7VVH9kffdFp/0VhP+DGgfjSyP/pms/gN9oQfB+pHI/ujbz7r/R3sCT8B1I9G9kf/9LT4bqwn/AygfjSyP/oW0/qjx3rCzwXqRyP7o39mlv8y2BO+p3882GuN7I++5bT+yrGe8FOB+tHI/uifnWV/gz3hpwP1o5H90bea5v+N9YSfDdSPRvZH33rW+THYE77bHz3aa43sj77NtPhtrCf8NKB+NLI/+rbT/OexnvDzgPrRyP7o2807P4Z6wnf7o0d7rZH90befZX+DPeFnAfWjkf3Rpy5S3wTmKekmQH53WIQfMM9GNwPyu+Mi/IB5IvppIL87LcIPmOegnwHyu/Mi/IBxOv0skN9dFuEHjDPp1kB+d12EHzBOotsC+d1tEX5AP59uD+R390X4Af1UugOQ3z0W4Qf0s+hOQH73XIQf0E+guwD53WsRfsBzju4G5HfvRfgB92m6B5DffRbhB9xn6F5AfvddhB/wPaH7APndb5H+8u8CnwXQZmiXH/W6YPC5cZnR2ZxN69UroUyQ3nBBrPfr6VC4PCaj1ikScWFGNyGtklz68lvy642PR4Efut/4u//7TdF9o+c7H/a9W2XdpxzydffncsoG6/6e862xz57/iO4To/3l/fmefwO7efI0/4aLuEmKwGV2rtXKKn3pbVO6sxQ+qxB6zxpxZT2VwrC5Kp65MseVOktC5T39bRdz0qR9FK6UFoqqyUumaWrk6p+zXLTXztZgrXGNq5yGsq0p62pailUi+8ufMq2+rpQkL530KXPRXGg2jWSVYqKRi48tOetl9YHNxWbFpqu4Tpmkzi6wgbnd/vLRXn9kf/lTZ/Eb7Kk/BtQvR/aXP21af+BYT/1xoH45sr/86bPsb7Cn/gRQvxzZX/5Ls+xvsKf+DKB+ObK//Bmz+A321J8L1C9H9pf/8rT+/LGe+r3+8sFedWR/+Wmz/L/BnvpTgfrlyP7yX5k2nznWU386UL8c2V/+zGn95WM99WcD9cuR/eW/Osv+Bnvq9/S3B3vVkf3lz5rmP4/11J8G1C9H9pf/2iz7G+ypPw+oX47sL3/2tPNjrKd+r798sFcd2V/+nFn8BnvqzwLqlyP7y587a/8b7KlH9pc/GcjveYvUh4F5SnoqkN/pi/AD5tno6UB+z1+EHzBPRM8A8nvBIvyAeQ46DcjvhYvwA8bp9Ewgvxctwg8YZ9KzgPxevAg/YJxEzwbyO7EIP6CfT88F8nvJIvyAfiqdDuT30kX4Af0segGQ38sW4Qf0E+hFQH4vX4Qf8JyjE0B+r1iEH3CfppcC+b1yEX7AfYZeDuT3qkX4Ad8TeiWQ36sX6c+/ALBvFGgztMdPcenaVy5SkQ2cKJYyc3GnkFKcGfYmh1K4JMspTc/lM1uKbMmpGiR/YXJcJNyS3wWPCD90v3a3uwtu0Hd7oUPep77Vui98yNfdn8uFN1j39y7Sn3+RI7pPjPbn9+d7kQ3s5sxZ/g3Xt2UmLkryf5QTOscikq/Kc3kz1hZ14AKv9Skpr/hTB9NbhBhx9s3xB9/tz+cac7ZcAvZClMbrdKqoxJVNfjZex6C8lM2Zko01vU24OuepcJ1duN5+XhyyP/8fpvWXJ2kbVzeFI1+t0Yr/67h4rkwVXNIsVXqhVF+1IZLCuJYLf1ZvSVBKdq8/f3BWAtmf/+Zp/QljMwnHgPr5yP78f5zW3zY2k3AcqJ+P7M8/axa/wZmEE0D9fGR//lumzSeNzSScAdTPR/bnv3VafDw2k3AuUD8f2Z//tmn9+WMzCbv9+aO9/sj+/LfPOn8HZxJOBernI/vz3zGtv3dsJuF0oH4+sj//nbPsb3Am4Wygfj6yP/9d0/y/sZmE3f780V5/ZH/+u2edH4MzCacB9fOR/fnvmcVvcCbhPKB+PrI//73T/OexmYS9/vzBXn9kf/775p0fQzMJZwH185H9+e+fZX+DMwm7/fmjvf7I/vwPLFIfBuZ56R+A/D64CD9gnpL+EcjvQ4vwA+bZ6C1Afh9ehB8wT0RvA/L7yCL8gHkOegeQ30cX4QeM0+ldQH4fW4QfMM6k9wD5fXwRfsA4id4H5PeJRfgB/Xz6AJDf2YvwA/qp9CEgv08uwg/oZ9FHgPzOWYQf0E+gjwH5fWoRfsBzjj4B5PfpRfgB92n6JJDfZxbhB9xn6FNAfp9dhB/wPaHPAPl9bpH5hu8D9t0CbYZ2+VHLWUbFZXuuWZFPLgvdG/MkqdIzt1lwWt3XxjnewOu1hgs7jSQXgvj/m6hb8rvoEeGH7nfvdnfRDfqWL3bI+/y3WvfFD/m6+3O5+AbrvsQi8w2XPKL7xOh8Q3++l9zAbi74vZPqmyF4zwuuMXC1MWT+YFzSbEZErUg36r8WS7WlJcolyeKElsFpxb9schR78w1WR64r59CSlVwPtppsb5UrXPXkPx1ttL6pnLh271zi55P7jRJF29SpyIKcb7jQLH6iVO0VG5l0NmYT+J8m6t5DIAxTdFzuDcnIKiR/SlmVcsVSNF70NmAX9uYbBmdNkPMNF57Eb3Sm4xjw/gbkfMP3zrK/wZmO48D7G5DzDReZxG90puME8P4G5HzD982yv8GZjjOA9zcg5xsuOsv+Bmc6zgXe34Ccb7jYLH6DMx378w1jsxLI+YaLz3p/B2c6TgXe34Ccb7jELP9lcKbjdOD9Dcj5hkvO4jc403E28P4G5HzD98/a/wZnOnbnG0ZnJZDzDZeaZX+DMx2nAe9vQM43XHqa/zw203Ee8P4G5HzDZWbZ3+BMx+58w+isBHK+4QemnR9jMx1nAe9vQM43XHYWv8GZjt35htFZCeR8ww/O2v8GZzqQ8w27OeNRfpeblv8b+kHAPC9dGMjvhxbhB8xT0kWA/C6/CD9gno0uCuT3w4vwA+aJ6OJAfldYhB8wz0GXBPK74iL8gHE6XQrI70qL8APGmXQZIL8rL8IPGCfRZYH8rrIIP6CfT5cD8rvqIvyAfipdHsjvaovwA/pZdAUgvx9ZhB/QT6ArAfldfRF+wHOOrgLk96OL8APu03Q1IL9rLMIPuM/Q1YH8fmwRfsD3hK4B5HfNSfyG66zAvmWgzdAuPypcfuUCKZexVU05msAlBq+4jFi5mKWi6dWdrs1ucxaGuL7DSLgkVJJ0qYZN+V3qiPBDzwt0u7vUBn3flz7kcxJbrfsyh3zd/blcZoN1/8Ai8yGXPaL7xOh8SH++l93Abm4zqz+QrIjSkQnBU0vKy+B670arrvIHU0YQFzaN7F1/xQcjYqu1Zh2tTlGFsjcfwmXSZMhxaVkwLBVs4PKp6VdgGNOsVdI3CkUXJ4ySwooqsq1JNi9F86Eh50NuO4tfjJXXYajWlmri/3EJnCveUVFrXEHnT09aSOd00FnmZIz11hlbLK+ZGe7Oh4zO6iDnQ243y78enIk5Brw/BDkfcvtp/TFjMzHHgfeHIOdDTp3WXzk2E3MCeH8Icj7kDrP4Dc7EnAG8PwQ5H3LHWefH4EzMucD7Q5DzIXeall8Ym4nZnQ8ZnTVBzofcedp8yNhMzKnA+0OQ8yF3mXX+Ds7EnA68PwQ5H3LXaf3lYzMxZwPvD0HOh9xtlv0NzsTsz4eMzZog50PuPs3/G5uJOQ14fwhyPuQes86PwZmY84D3hyDnQ+45i9/gTMze/ReDsybI+ZB7TfOfx2ZizgLeH4KcD7n3vPNjaCZmdz5kdNYEOR9yn1n2NzgTcybw/hDkfMh9F6mvA/PkdFsgv/stwg+Y56XbA/ndfxF+wDwl3QHILy7CD5hnozsB+aVF+AHzRHQXIL+8CD9gnoPuBuRXFuEHjNPpHkB+dRF+wDiT7gXk1xbhB4yT6D5Afg9YhB/Qz6f7Afk9cBF+QD+VIpDfgxbhB/SzKAP5PXgRfkA/gSqQ30MW4Qc85+gBQH7HFuEH3KfpQUB+D12EH3CfoYcA+T1sEX7A94QeCuT38EXma34Q2PcNtBna46dEzc4KU0ov5UfqlQmRpDGByzymtmp9rib7pHnJ8eSSs5VFWOGTFHJLfpc7IvzQ8xbd7i63Qd/8Dx3yOZOt1n35Q77u/lwuv8G6f3iR+ZorHNF9YnS+pj/fK2xgNy+Y1p9Qo49Rk8hSGCu4mktcF099IkG2oG2uImup+vJToWgDZelIC+9FlVXvztfIIE42YQlbQyzKKy2Lbar5Rra10huHbSlVWqErowsyJnuyp18GS0Ja5HzNC6f1p55sG+cPFK3SXBrvAJRUoQQTUu+ft0J6cgzBquSkOdma0LySfVnZ7c3XDM46IedrXjSL3+BM0THg/TXI+ZoXT4tPxmaKjgPvr0HO15yYZX+DM0UngPfXIOdrXjKtP3pspugM4P01yPmal86yv8GZonOB99cg52teNsv+BmeKLrs3kzA2q4Ocr3n5LH6DM0WnAu+vQc7XvGKa/zc2U3Q68P4a5HzNK2f5L4MzRWcD769Bzte8atp89dhM0e58zeisDnK+5tXT5mvGZopOA95fg5yv+fVZ9jc4U3Qe8P4a5HzNb0zzn8dmivbuXxmc1UHO1/zmLPsbnCk6C3h/DXK+5remnR9jM0V78zWDszrI+ZrfnsVvcKboTOD9Ncj5mt+Ztf8NzhQh52teAOT3u4v0JwDz5PQiIL/fW4QfMM9LJ4D8fn8RfsA8Jb0UyO81i/AD5tno5UB+f7AIP2CeiF4J5PeHi/AD5jno1UB+f7QIP2CcTr8B5PfHi/ADxpn0W0B+f7IIP2CcRL8D5Peni/AD+vn0e0B+f7YIP6CfSq8B8vvzRfgB/Sz6QyC/v1iEH9BPoD8G8vvLRfgBzzn6UyC/v1qEH3Cfpj8H8nvtIvyA+wz9JZDfXy/CD/ie0GuB/F63yHzSFYF980CboT1+nFWPvR0iZJutsMqYqKrIVJPm+p9XufXWKS5062RCC8WpQI3LZKKkUiltye9KR4Qfel6l292VNpg7uPIhn9PZat1XOeTr7s/lKhus+6qLzCdd7YjuE6PzSf35Xm0DuzlnVn+lpWJL1b7m5EjmJrWXrg8g9KZAV1pWjv+pWi4nG4yYUlUyBRKq5Jpo7/6fZKxINUZngkmqai62+6yiSSkGJthiK40ZK5+Fp2xL0NWoWLTyLXstkPNJn5rW31tz9vxZo0xsOcJom0to1UddeHWu9e7w0HsLvCo2iCpDYbsl3Uc+2Lz25pMGZ8WQ80mfnmV/gzNZx4D3JyHnkz4zKz4ZnMk6Drw/CTmf9Nlp/VljM1kngPcnIeeTPjetv3dsJusM4P1JyPmkc2fxG5zJOhd4fxJyPunz0+arx2ay9u7/GZx1Qs4nfWFafmZsJutU4P1JyPmkL06bTxqbyTodeH8Scj7pS7PO38GZrLOB9ych55O+PG2+YWwma28+aXDWCTmfdN4s+xucyToNeH8Scj7pK9P8v7GZrPOA9ych55O+Ouv8GJzJ2p1PGp11Qs4nfW0Wv8GZrLOA9ych55O+Ps1/HpvJ2ptPGpx1Qs4nfWPe+TE0k3Um8P4k5HzSP82yv8GZrN35pNFZJ+R80j8v0p8ArDPQp4D8/mURfsA8OX0GyO9fF+EHzPPS54D8/m0RfsA8JX0eyO/fF+EHzLPRF4H8/mMRfsA8EX0ZyO8/F+EHzHPQV4D8/msRfsA4nb4G5Pffi/ADxpn0DSC/by7CDxgn0T8D+f3PIvyAfj79K5DftxbhB/RT6d+B/L69CD+gn0X/CeT3nUX4Af0E+m8gv+8uwg94ztH/APkdXGQNfsB9mr4N5He+RfgB9xn6LpDfKYvwA74ntGszo/y+ZxK/0c/5I8C5A6DN0C4/WaNxtVevXfGBS2VKc1WhcUmmcjmiN9HlHHt51nBpv/IP25TQWnHdu3IJu23J7+pHhB963qfb3dU3mNv40UM+57TVuq9xyNfdn8s1Nlj3jy0y33XNI7pPjM539ed7zQ3s5lqz/Buum6eidO9Yk8Jzlb213Lji3qdicm/aj85FKTMX3mvygqkUEo0sF+S1zHFvvktbkysjo6x1avw4SssxeGeC1YwslBpqVMpZzcuvnQtZoaW2OvmgFXK+6ydm8YuBlMxGy6aoFso1Kam9Z7MprjfsW1uk7U3nvcM0sAXpplvRzkarst+f7xqctUPOd117Er/RmbZjwPu7kPNdPzmL3+BM23Hg/V3I+a7rTIvvxmbaTgDv70LOd/3ULPsbnGk7A3h/F3K+S0ziNzrTdi7w/i7kfBfNsr/Bmbbd+a7RWTHkfJecZX+DM22nAu/vQs53qVn8BmfaTgfe34Wc79Kz3t/Bmbazgfd3Iee7zCz/ZXCmbXe+a3RWDDnfZafFb2MzbacB7+9Czne5Wfvf4EzbecD7u5DzXX6W/Q3OtO3dPzU4K4ac7wrT/OexmbazgPd3Iee7rjvL/gZn2nbnu0ZnxZDzXdebdn6MzbSdCby/Cznfdf1Z/AZn2nbnu0ZnxZDzXTeYtf8NzrQh57uuBexPuOEi/R3AOgNdG8jvRovwA+bJ6TpAfjdehB8wz0sCyO8mi/AD5ilJAvnddBF+wDwbaSC/my3CD5gnIgvkd/NF+AHzHOSB/H56EX7AOJ2uC+R3i0X4AeNMuj6Q388swg8YJ9ENgfxuuQg/oJ9PNwby+9lF+AH9VLopkN+tFuEH9LPo5kB+t16EH9BPoFsA+d1mEX7Ac45uCeR320X4AfdpuhWQ3+0W4QfcZ+g2QH63X4Qf8D2h2wH5nbrIfNyPA+c2gDZDe/yUdyXZ3HxV1mQucHFZ22rLdT8uRHMJv68pypRDDsLrxBUvSdpz8VBRjtpsye9aR4Qfel6q2921Nph7+YlDPie21bqvfcjX3Z/LtTdY908uMh93nSO6T4zOx/Xne50N7OYx0/oTgnDCSltNTtpH1VIfhGtZa+cU/7ISRhuna2+Roaz495NxJsnajArW3XdvPklFMppX3rw3hov0OvaRRl6dzfxIbHWOQl9sb49WXsvkQ0q+CuX6H0HOxz12Vn9CiM1nw58mOd9qEzVIkZ3h1SYlqLLJeq+KsHSyeVepwny1aL1Dkg3Y7M7Hjc4qIufjHjerP3pwJvAY8P445Hzc42fxG5wJPA68Pw45H/eEWfvf4EzgCeD9ccj5uCdO6w8cmwk8A3h/HHI+7vi0/vKxmcBzgffHIefjnjSL3+BM4N583OCsHXI+7snT5tPHZgJPBd4fh5yPe8q0/NbYTODpwPvjkPNxT502Hzc2E3g28P445Hzc06bpm4zNBO7dfzY4a4ecj3v6tPmasZnA04D3xyHn435plv0NzgSeB7w/Djkf94xp/t/YTODufNzorB1yPu6XZ50fgzOBZwHvj0POx502i9/gTODe/WeDs3bI+bhfmeY/j80Engm8Pw45H/fMeefH0Ezg7nzc6Kwdcj7uV2fZ3+BM4DnA++OQ83HPWqS/A1inoccC+f3aIvyAdQZ6PJDfsxfhB8yT0xOB/J6zCD9gnpeeBOT33EX4AfOU9BQgv+ctwg+YZ6OnAfmdvgg/YJ6IfgnI7/mL8APmOeiXgfxesAg/YJxOvwLk98JF+AHjTPpVIL8XLcIPGCfRrwH5vXgRfkA/n54D5HdiEX5AP5WeB+T3kkX4Af0sej6Q30sX4Qf0E+iFQH4vW4Qf8JyjFwP5vXwRfsB9ml4C5PeKRfgB9xl6GZDfKxfhB3xP6BVAfq9aZL7wp4BzL0CboV1+xHWslJPl4mEh0iXGXpKJSbTYZAvVqNR7YLnQ5WQsOhiu9VMOXPkhZ2VSW/ITR4Qfet6s253YYG6IDvmc3Vbrlod83f25yA3WrRaZL9RHdJ8YnS/sz1dvYDdvndXf1mKQLVGsIVijStGVknPFtJAySeurNdRv01Nkm8/VuSp1MSqXIvgr6+58oXTS+1gNY5HahNpqM0bwz2PwvaUm828ncq3ywws1lNj4UUnRXG9cJWWQ84Vvm+UfypJD9d4oV6Sy5BvZEJWzKRivRC29ezpla5pg0xGqWhmdDcXWWskqvzdfODjriZwvfPu0/uixmcpjwPsLkfOF75jW3zY2U3kceH8hcr7wnbP4Dc5UngDeX4icL3zXtPh4bKbyDOD9hcj5wnfPsr/BmcpzgfcXIucL3zNtPmRspnJ3vnB0VhE5X/jeWfY3OFN5KvD+QuR84ftm2d/gTOXpwPsLkfOF75/Fb3Cm8mzg/YXI+cIPTJvPHJup3JsvHJxVRM4XfnCW/zI4U3ka8P5C5Hzhh6bpS4zNVJ4HvL8QOV/44WnzhWMzlbvzhaOzisj5wo/Msr/BmcqzgPcXIucLPzrNfx6bqdy7f29wVhE5X/ixafm/sZnKM4H3FyLnCz8+7fwYm6ncmy8cnFVEzhd+Ypo+4NhM5TnA+wuR84VnT6t/jM1UIucL3wrk98lF+mOAdRp6O5DfOYvwA9YZ6J1Afp9ahB8wT07vBvL79CL8gHleei+Q32cW4QfMU9L7gfw+uwg/YJ6NPgjk97lF+AHzRPRhIL9zF+EHzHPQR4H8Pr8IP2CcTh8H8vvCIvyAcSadDeT3xUX4AeMkOgfI70uL8AP6+fRpIL8vL8IP6KfSZ4H8zluEH9DPonOB/L6yCD+gn0BfAPL76iL8gOccfQnI72uL8APu03QekN/XF+EH3Gfoq0B+31iEH/A9oa8D+f3TIvOZBjg3BLQZ2uVHwXhhbFM2cTGrFnLK65RUFLwQ47y2TSYlkuhtKcplqlyD5foPlwdrnwrakp89IvzQ83rd7uwGc1fukM8pbrVuf8jX3Z+L32DdYZH5zOse0X1idD6zP9/rbmA3l/++Sf4Nud4y710KRrjetOeFS6mkalvMkYLyojDQ3PhfW44ul1yjdTKRlsrszWcKEZXMmf9XyTXySldlTLYqt2Cojyym0KpINvGHsk1HR30agCTlKp2TyPnMH57Ej6SSLpRuMY0tI4Xew1FDDkoGSUmF7E7OhZRmZeO1yKJM1En02cFsqtydzxydlUXOZ15hlv0NzqQeA96fiZzPvOIs+xucST0OvD8TOZ95pVn8BmdSTwDvz0TOZ1551vs7OJN6BvD+TOR85lVm8RucST0XeH8mcj7zqpP4jc6k7s1nDs56IuczrzaL3+BM6qnA+zOR85k/Ms3/G5tJPR14fyZyPvPqk/iNzqSeDbw/Ezmf+aOz7G9wJnV3PnN01hM5n3mNWefv4EzqacD7M5HzmT826/wYnEk9D3h/JnI+85qz7G9wJnV/PnNs1hM5n/nj0/y/sZnUs4D3ZyLnM6816/wYnEndnc8cnfVEzmf+xCx+gzOpZwLvz0TOZ157mv88NpO6N585OOuJnM/8yXnnx9BM6jnA+zOR85nXmWV/gzOpu/OZo7OeyPnMn5plf2M/CFjnot2az7Cu9SL8gHUauiKQHy3CD1hnoCsD+clF+AHz5HRVID+1CD9gnpd+BMhPL8IPmKekHwXyM4vwA+bZ6MeA/Owi/IB5IvpxID+3CD9gnoN+AsjPL8IPGKfTTwL5hUX4AeNM+ikgv+suwg8YJxEB+V1vEX5AP58UkN/1F+EH9FPJAPndYBF+QD+LHJDfDRfhB/QTKAD53WgRfsBzjq4H5HfjRfgB92m6AZDfTRbhB9xn6EZAfjddhB/wPaGbAPndbFr/2qCfCpy7AtoM7fKTpYaQVHWOi9myZi6fBmdKn9CINdjC9WypUgtcGQvEv8flwVBF5DosSa64pi35Xf+I8EPPO3a7u/4Gc2s3OORznlut+4aHfN39udxwg3XfaJH51hsf0X1idL715PPdwG4eNqu/I+WQhRNGlaisEzWoqh0vT2kTa6EaXGq+2eibrI3pGm1Nb0zNTMDJvDvfSiXm0JoPfbCYhPNWkw0uWOd9aFo3Bl1Uyym2ULxrpvGj9IYfKn9jLRtyvvXhs/gJp5TpI4BR1lRbtEEJKt7YYm3KovnYSPZpLilaJLazlqso/fMHSmT27h8dnDVGzrc+YlZ/6uBM7zHg/a3I+dafm9afPzbTexx4fytyvvXnp/VXjs30ngDe34qcb/2FWfwGZ3rPAN7fipxvfeS0/MLYTO+5wPtbkfOtvzjL/gZnevfmWwdnZZHzrY+aNp80NtN7KvD+VuR866Nn2d/gTO/pwPtbkfOtj5llf4MzvWcD729Fzrc+dha/wZne/fnWsVlZ5Hzr46bNB4/N9J4GvL8VOd/6+Fn+y+BM73nA+1uR861PmKZvMjbTuzvfOjori5xvfeK0+daxmd6zgPe3Iudbj8+yv8GZ3r37RwdnZZHzrU+a5j+PzfSeCby/FTnf+uRZ9jc407s73zo6K4ucb33KtPNjbKb3HOD9rcj51qdO01ccm+ndnW8dnZVFzrc+bVr+fmymFznf+jBgf8zTF+kvAta56BFAfr+0CD9gnYZ+HsjvGYvwA9YZ6JFAfr+8CD9gnpweBeR32iL8gHleegyQ368swg+Yp6THAfk9cxF+wDwbPQHI71cX4QfME9FxIL9nLcIPmOegJwP5/doi/IBxOj0VyO/Zi/ADxpn0dCC/5yzCDxgn0TOA/J67CD+gn0+nAfk9bxF+QD+Vngnkd/oi/IB+Fj0LyO/5i/AD+gn0bCC/FyzCD3jO0XOB/F64CD/gPk2nA/m9aBF+wH2GXgDk9+JF+AHfE3oRkN+JReaDbwKcWwPaDJ3Ym1uTvDrhLdcTs9LEheyqpHIxR65AS516D0uVmYvfLoaampGp2D784nuTlNuS302PCD/0vGi3u5tuMPd3s0M+J7vVum9+yNfdn8vNN1j3Ty8yH3yLI7pPjM4H9+d7iw3s5s2z+ju0qMoWb42NqniqfTTJUtUyEuneGqSzKKq2fmtroxRSbpGaZsRNMLa9+2+T8VI2wQ+g8iPxSpcmovL8s94mnDJ/fW4luywoGxMoOV9SVX1O0epIyPngf5zFjw3ROi19rYm8KLUIzfYpbKpGUJH8E+lNc6WSNbGJZrSvvlG0tlln9e588OisNnI++KxZ/vXgTPQx4P3ByPngt0zrbxubiT4OvD8YOR/81lnzIYMz0SeA9wcj54PfNovf4Ez0GcD7g5HzwW+f9f4OzkSfC7w/GDkf/I5p/dFjM9G788Gjs8bI+eB3TpuvGZuJPhV4fzByPvhds/gNzkSfDrw/GDkf/O5p+hxjM9FnA+8PRs4Hv2dafnVsJnp3Pnh01hg5H/zeafPBYzPRpwHvD0bOB79vmj7R2Ez0ecD7g5Hzwe+fNl84NhO9Nx88OGuMnA/+wCz7G5yJPgt4fzByPviD0/y/sZno3fng0Vlj5Hzwh2adH4Mz0WcC7w9Gzgd/eBa/wZnovftvB2eNkfPBH5nmP4/NRJ8DvD8YOR/80Xnnx9BM9O588OisMXI++GOz7G9wJnp3Pnh01hg5H/zxRfqLgHVC+kcgv08swg9Y56K3APmdvQg/YJ2G3gbk98lF+AHrDPQOIL9zFuEHzJPTu4D8PrUIP2Cel94D5PfpRfgB85T0PiC/zyzCD5hnow8A+X12EX7APBF9CMjvc4vwA+Y56CNAfucuwg8Yp9PHgPw+vwg/YJxJnwDy+8Ii/IBxEn0SyO+Li/AD+vn0KSC/Ly3CD+in0meA/L68CD+gn0WfA/I7bxF+QD+BPg/k95VF+AHPOfoikN9XF+EH3Kfpy0B+X1uEH3Cfoa8A+X19EX7A94S+BuT3jUXmq38GOPcHtBna48f1RK7c2xBrViE1/vQ+yZyKVVR0v22Sy/vVFnIkScuYW5TJSy7x1yyoxS353fKI8EPP23a7u+UGc5M/e8jnjLda960O+br7c7nVBuu+9SLz1bc5ovvE6Hx1f7632cBurnDRSf6Ny4JXqXQTNaSSnK7GRE1R+Waki1JFb7T1LdvS50ZaFjXpWDLTkcLrvfuXVS4+SqGDCC4K7aMQMUZXojSFV55zEL2F1fuOV/VeJCVEC1mn5nQyyPnqK07ix7aWrbWyaBOSza2IVPrUuIjC1xCdcRSDV9JEcoFslRRbziLnlr1u1u7OV4/OuiPnq680i9/gTPkx4P3VyPnqK0/iNzpTfhx4fzVyvvoqs/a/wZnyE8D7q5Hz1Ved9f4OzpSfAby/GjlffbVZ/AZnys8F3l+NnK/+kVnv7+BM+e589eisNnK++uqz7G9wpvxU4P3VyPnqH511/g7OlJ8OvL8aOV99jVn2NzhTfjbw/mrkfPWPzbK/wZny6+yteWxWGzlffc1Z/AZnyk8D3l+NnK/+8Vnv7+BM+XnA+6uR89XXmuW/DM6U785Xj85qI+erf2IWv8GZ8rOA91cj56uvPWv/G5wp352vHp3VRs5X/+S8/OnQTPmZwPurkfPV15nmP4/NlO/dvzw4q42cr/6pWfY3OFN+DvD+auR8tZh2fozNlO/NVw/OaiPnq2kWv8GZ8t356tFZbeR8tZyWvx+bKUfOV+/WHEf5qWn5v6EfBKwT0pWA/PQi/IB1LroKkJ9ZhB+wTkNXA/Kzi/AD1hno6kB+bhF+wDw5XQPIzy/CD5jnpWsC+YVF+AHzlHQtIL/rLsIPmGejawP5XW8RfsA8EV0HyO/6i/AD5jlIAPndYBF+wDidJJDfDRfhB4wzSQP53WgRfsA4iSyQ340X4Qf088kD+d1kEX5AP5WuC+R300X4Af0suj6Q380W4Qf0E+iGQH43X4Qf8JyjGwP5/fQi/ID7NN0UyO8Wi/AD7jN0cyC/n1mEH/A9oVsA+d1yEr/Rz3lb4Nwk0GZol58UoTTXXOA6djp5m6lXPtggReXadGhEWTsZeH3kJJfCE38DrXrfJ7kQfNiS3+2OCD/0vHK3u9ttMHd6+0M+p73Vuk895Ovuz+XUDdZ9h0Xm0+94RPeJ0fn0/nzvuIHdPGpWf4xSqeiYGn8ua7Ur2apccmACVoegjOVPGlvSDF35YhT/J6vefJ5ctTXtzaf3fufgZGrWnmz4Z0bFUhG6pRRb8603tcZojOiziT6XZGTT0clIskiFnE9/9Kz+fE4xqxBSi9602HJKTpoQszddQkHorBQVFbRW2fRW1agrE/E6p1J7a/DufPqoVgByPv0xs+xvcCb/GPD+dOR8+mNnxSeDM/nHgfenI+fTHzetv3JsJv8E8P505Hz642ftf4Mz+WcA709Hzqc/YRa/wZn8c4H3pyPn05846/0dnMnfm08fnHVHzqcfn9afPzaTfyrw/nTkfPqTps13jc3knw68Px05n/7kafHH2Ez+2cD705Hz6U+Zpg8zNpO/d//34Kw7cj79qdPy02Mz+acB709Hzqc/bdp8+thM/nnA+9OR8+lPn6aPNTaTv3f/9+CsO3I+/ZemzbeOzeSfBbw/HTmf/oxZ9jc4k78/nz42646cT//laf7f2Ez+mcD705Hz6afNOj8GZ/J359NHZ92R8+m/Mk0fdWwm/xzg/enI+fRnTvOfx2by9+bTB2fdkfPpvzrv/Biayd+dTx+ddUfOpz9rlv0NzuS/GXh/OnI+/dcW6c8C1lnp0UB+z16EH7BOSI8F8nvOIvyAdS56PJDfcxfhB6zT0BOB/J63CD9gnYGeBOR3+iL8gHlyegqQ3/MX4QfM89LTgPxesAg/YJ6SfgnI74WL8APm2eiXgfxetAg/YJ6IfgXI78WL8APmOehXgfxOLMIPGKfTrwH5vWQRfsA4k54D5PfSRfgB4yR6HpDfyxbhB/Tz6flAfi9fhB/QT6UXAvm9YhF+QD+LXgzk98pF+AH9BHoJkN+rFuEHPOfoZUB+r16EH3CfplcA+f36IvyA+wy9CsjvNxbhB3xP6NeB/H5zkfn+OwHnToE2Q7v8JFUXsiw2a+m41B2iFb5k47MyvbfEkEtUrY6mGGddK6Vw4TaSrC2W6v2W/O58RPih57273d15g7nduxzyOfet1n3XQ77u/lzuusG677bIfP/dj+g+MTrf35/v3Tewm/fP6k91NjiXmYKPulRps+1j1TIE7wq12Lsig7KNIcSaRCmhmhRMlUFYW7Lcne+XLokWhfWqFpd7s2uQWvbeQKZgtEv8ZwpDMEyxlmb4LxDJGuYjTKMEne//wKz+LJUbfx6hFPXJI3IkVSIdo/JRUGMCUmWbrLbGBe/5J0JJoa1SzCepsnf//KDWAnK+/4Oz/OtBTYPd+f5RrQDkfP+HZtnfoKbB3v3zg1oByPn+D8/a/wY1Dfbm+we1ApDz/R+ZNp80pmmwN98/qBWAnO//6LT+8jFNg735/kGtAOR8/8dm8RvUNNib7x/UCkDO9398Wn5rTNNgd75/VCsAOd//iVn2N6hpsDffP6gVgJzvP3vafOaYpsHufP+oVgByvv+Ts+xvUNNgd75/VCsAOd9/ziz7G9Q0OG1vzWNaAcj5/k9Nyx+MaRrsz/ePaQUg5/s/PU0fYUzTYG++f1ArADnf/5lZ/sugpsHufP+oVgByvv+z0/SdxjQNduf7R7UCkPP9n5s23z+maXDmnj7CmFYAcr7/3Hn5vyFNg7375we1ApDz/Z+f5j+PaRrs3T8/qBWAnO//wiz7G9Q02J3vH9UKQM73f3Ha+TGmabA33z+oFYCc7//SNH3ZMU2D3fn+Ua0A5Hz/l6fl78c0DZDz/e8H8jtvkf42YJ2VPgjk95VF+AHrhPRhIL+vLsIPWOeijwL5fW0RfsA6DX0cyO/ri/AD1hnobCC/byzCD5gnp3OA/P5pEX7APC99GsjvnxfhB8xT0meB/P5lEX7APBudC+T3r4vwA+aJ6AtAfv+2CD9gnoO+BOT374vwA8bpdB6Q338swg8YZ9JXgfz+cxF+wDiJvg7k91+L8AP6+fRPQH7/vQg/oJ9K/wLk981F+AH9LPo3IL//WYQf0E+g/wDy+9Yi/IDnHP0XkN+3F+EH3Kfpm0B+31mEH3CfoW8B+X13EX7A94S+A+R3cLE5/EY/5z2Ac7tAm6E9fjpkXXkdrvc+xNK7uU0RLuhYKhlduTjdnDXK1Wr4S6JULkor+Q9py6XbLfnd84jwQ8/Ld7u75wZzz/c65DoBW6373od83f253HuDdd9nEX2E+x7RfWJUH6E/3/tuYDdi0vnMn0Mq1Vv9Su04yXtVbE0q2uR7k7nPTnsjpShBZ+WNK15QSL2nT1Wp77t3f7UIzlr+FuSMLdZZ5XVRyteqmm25ZZsyqZZy71WVpdg+8mRkcTHaKAmpj0CT+JF2LtXQRxmCMcblWrKzOQYhquxSCdSEtyZGE3xkq9EixpRclsy8/8KePsKgVgVSH0HOsr9BTYhdfYRRrQWkPoKaxW9QE2JXH2FUawGpj6An8RvVhNjVRxjVWkDqI5hZ/AY1IXb1EUa1FpD6CHbW+TGoCbGnjzCotYDUR3Cz+A1qQuzqI4xqLSD1Efys93dQE2JPH2FQawGpjxBm8RvUhNjVRxjVWkDqI1x3lv8yqAmxp48wqLWA1Ee43jT/eUwTYk8fYVBrAamPcP1Z58egJsSuPsKo1gJSH+EG0/L7Y5oQu/oIo1oLSH2EG86yv0FNiF19hFGtBaQ+wo1mnb+DmhC7+gijWgtIfYQbzzo/BjUh9vQRBrUWkPoIN5llf4OaEPv6CGNaC0h9hJtO8//GNCF29RFGtRaQ+gg3m5Z/HtOE2NVHGNVaQOoj3HwWv0FNiF19hFGtBaQ+wk9P85/HNCH29BEGtRaQ+gi3mHd+DGlC7OojjGotIPURfmaW/Q1qQuzqI4xqLSD1EW45y/7GfhCwTk27NdtRfj+7CD9gnZUUkN+tFuEHrBOSAfK79SL8gHUuckB+t1mEH7BOQwHI77aL8APWGeh6QH63W4QfME9ONwDyu/0i/IB5XroRkN+pi/AD5inpJkB+d1iEHzDPRjcD8rvjIvyAeSL6aSC/Oy3CD5jnoJ8B8rvzIvyAcTr9LJDfXRbhB4wz6dZAfnddhB8wTqLbAvndbRF+QD+fbg/kd/dF+AH9VLoDkN89FuEH9LPoTkB+91yEH9BPoLsA+d1rEX7Ac47uBuR370X4AfdpugeQ330W4QfcZ+heQH73XYQf8D2h+wD53W8RfYn7AeeegTZDu/zI21B07eMCSRGvRupINveCt7Yx6yCNzqoI05oyQsrobOozGNR88kmpLfnd/4jwQ+sNdLu7/wZz4/GQ6yxste50yNfdn0vaYN15EX2JckT3iVF9if58ywZ289xZ/b0i62x0al6KSElnH2WNImqhSgkhe5MkGRmyIqdcFZqx8teZ5IxrVsQ9fQntZcxeET8NX3SgIqozpStXSP52RvXJVl+q7/3sVUubtaHUu+JSNbo4pL7E82b5h7pFNsCcilAmaNP4UwVfRAmx6CSkbzolfr3I8AekGmMSubXQpSFks6Xu6UsMan0g9SVOn2V/g5oau/oSo1oVSH2J58+yv0FNjV19iVGtCqS+xAtm9acOamrs6kuMalUg9SVeOOv9HdTU2NOXGNSqQOpLvGjafNyYpsaevsSgVgVSX+LF0+YbxjQ19vQlBrUqkPoSJ2bxG9TU2NOXGNSqQOpLvGRafnBMU2NXX2JUqwKpL/HSWfY3qKmxpy8xqFWB1Jd42bT54DFNjV19iVGtCqS+xMtn2d+gpsauvsSoVgVSX+IVs+xvUFPjvL01j2lVIPUlXjkt/h3T1NjXlxjTqkDqS7xqmj7HmKbGnr7EoFYFUl/i1bP8l0FNjV19iVGtCqS+xK9P0xcb09TY1ZcY1apA6kv8xjR9iTFNjV19iVGtCqS+xG/Oy/8NaWrs6kuMalUg9SV+a5r/PKapsasvMapVgdSX+O1Z9jeoqbGrLzGqVYHUl/idaefHmKbGnr7EoFYFUl/id6fpG49pauzqS4xqVSD1JX5vWv5+TFMDqS/xXGB/2+8v0h8IrFPT6UB+r1mEH7DOSi8A8vuDRfgB64T0IiC/P1yEH7DORSeA/P5oEX7AOg29FMjvjxfhB6wz0MuB/P5kEX7APDm9EsjvTxfhB8zz0quB/P5sEX7APCX9BpDfny/CD5hno98C8vuLRfgB80T0O0B+f7kIP2Ceg34PyO+vFuEHjNPpNUB+r12EHzDOpD8E8vvrRfgB4yT6YyC/1y3CD+jn058C+f3NIvyAfir9OZDfGYvwA/pZ9JdAfn+7CD+gn0CvBfJ7/SL8gOccvQ7I7+8W4Qfcp+kMIL83LMIPuM/Q64H83rgIP+B7Qm8A8nvTIvocFTg3DrQZ2uUnVWpeNKO8MzbyiopvQjsK0SdbRe/6rqWenCptMTjqjd5CyKK0UUF5syW/dkT4ofUaut21DebuH3DIdSq2WvcDD/m6+3N54AbrftAi+hwPPqL7xKg+R3++D97Abv5lln/Tx2CcotYnCVuQUUknqtMlqWazTFaYokqSWrZQo3K29RE6H3PJPtaSd/U5hHEyJe0ctd7NZYojz38ieSuaMr7qGKuztTTte0OnFyalJE0VxmSSFarP8a/T5huCysVooXXKzgXtczPGpEi2FFus1C261jJZZ43obauRLVQII6POOfg9fY5BrRSkPse/zeoPHNQk2dPnGNT6QOpz/PssfoOaJLv6HKNaH0h9jv+YxW9Qk2RXn2NU6wOpz/Gfs/a/QU2SXX2OUa0PpD7Hf03rLx/TJNnV5xjV+kDqc/z3rPnMQU2SPX2OQa0PpD7HN2fxG9Qk2dXnGNX6QOpz/M+s93dQk2RPn2NQ6wOpz/GtafNJY5oku/oco1ofSH2Ob0+bbx3TJNnT5xjU+kDqc3xnmv88pkmyp88xqPWB1Of47jR9rDFNkl19jlGtD6Q+x8HFZ+XtxjRJdvU5RrU+kPoc55vEb1ST5Kw9fZMxrQ+kPscpk/iNapLs6nOMan0g9Tm+ZxK/UU2SPX2OQa0PpD7H+WfZ36Amyb4+x5jWB1Kf4wKz7G9Qk2RXn2NU6wOpz3HBWefHoCbJrj7HqNYHUp/jQrP4DWqS7OpzjGp9IPU5LjyL36AmyZ4+x6DWB1Kf43vnnR9DmiS7+hyjWh9IfY6LzLK/QU2SXX2OUa0PpD7H982yv7EfBKzz078C+V10EX7AOjX9O5DfxRbhB6yz0n8C+V18EX7AOiH9N5DfJRbhB6xz0f8A+V1yEX7AOg19G8jv+xfhB6wz0HeB/C61CD9gnpx2c8aj/C69CD9gnpe+B8jvMovwA+Yp6QJAfj+wCD9gno0uBOR32UX4AfNE9L1Afj+4CD9gnoO+D8jvcovwA8bpdDEgvx9ahB8wzqRLAPldfhF+wDiJvh/I74cX4Qf08+nSQH5XWIQf0E+lHwDyu+Ii/IB+Fv0gkN+VFuEH9BPoh4D8rrwIP+A5Rz8M5HeVRfgB92m6IpDfVRfhB9xn6MpAfldbhB/wPaGrAvn9yLT+3bHP+RDg3D3QZmiXn7S5VFksf/Tei2j6VI+SueqsW5S1ZSltyiY38sX2PhXZJw5yNsLaloLekt+xI8IPrXfR7e7YBroFDz3kOh9brfthh3zd/bk8bIN1P3wRfZNHHNF9YlTfpD/fR2xgN3ed1d8WinNdMsNaSpqUz7WKaGQjJ1xzJuoiTIlNmCZ1iKStCDXl5qzPJtR9fRN+EI74oeTGqzWu1NxFPChqx8vM1UUrGVpRJvlWomQOvfHNxaQVmVyQ+iZ3m+Uf9lY+XbKLsU9VO9cVSkhUIR3/vxNsVmyJoQVXU7RKtVhUUaT4K50qNuzqm4xqzSD1Te4+qz9/UNNlT99kUCsFqW9yj1n8BjVddvVNRrVSkPom95z1/g5quuzqm4xqpSD1Te416/wY1HTZ1TcZ1UpB6pvce9b7O6jpsqdvMqiVgtQ3uc+0+cwxTZc9fZNBrRSkvsl9p83XjGm67OmbDGqlIPVN7jfNfx7TdNnTNxnUSkHqm9x/Wn51TNNlV99kVCsFqW8SZ9nfoKbLnr7JoFYKUt8kTZtPH9N02dU3GdVKQeqb5Fn2N6jpsqtvMqqVgtQ3KbPsb1DT5c57ax7TSkHqm9Rp8e+Ypsu+vsmYVgpS36RN04cZ03TZ0zcZ1EpB6ps8YJb/MqjpsqtvMqqVgtQ3eeAsfoOaLrv6JqNaKUh9kwdN0zcZ03Q5Z08fZkwrBalv8uB5+b8hTZddfZNRrRSkvslDpvnPY5ouu/omo1opSH2TY7Psb1DTZVffZFQrBalv8tBp58eYpsuevsmgVgpS3+Rhs/gNarrs6puMaqUg9U0ePi1/P6bpgtQ3uSuwP/ARi/RXAuv8dHcgv59bhB+wTk33BPL7+UX4AeusdG8gv19YhB+wTkj3BfJ75CL8gHUuuj+Q3y8uwg9Yp6EE5PeoRfgB6wxUgPwevQg/YJ6cGpDfYxbhB8zz0gOB/B67CD9gnpIeDOT3uEX4AfNsdAzI7/GL8APmiehhQH5PWIQfMM9BjwDye+Ii/IBxOv08kN/xRfgB40x6JJDfkxbhB4yT6FFAfk9ehB/Qz6fHAPk9ZRF+QD+VHgfk99RF+AH9LHoCkN/TFuEH9BPoOJDf0xfhBzzn6MlAfr+0CD/gPk1PBfJ7xiL8gPsMPR3I75cX4Qd8T+gZQH6nLaIP83NA3QKgzdAuP9LC2aQUKVuzqBSz0cEqH3UKQqZo+pByE0ZG30h7oaWxVbvcZJZN6LQlv58/IvzQeiHd7n5+A92HXzjkOilbrfuRh3zd/bk8coN1/+Ii+jCPOqL7xKg+TH++j9rAbl4/y78JMdRWU5Z9/l7rrnFSqxMMrPXGPqZpak1KKrK9ZbB35GapnPDUR7nknj6MUVHq6FQhr6VwIZpmHekuPcO/ZVI1LoVcsmsuFKGiK9Jk/lVrQkzJIfVh/m5af6DNvg8akOTFVlt9EpaXVZy3wZRIOpENqcgklPCCV1zJBZcNdSGPKnf1YUa1epD6MG+YZX+Dmjh7+jCDWjNIfZg3zrK/QU2cPX2YQa0ZpD7Mm2bxG9TE2dWHGdWaQerD/P0sfoOaOLv6MKNaM0h9mDNn7X+Dmji7+jCjWjNIfZh/mDbfMKaJs6sPM6o1g9SHefOs+eBBTZw9fZhBrRmkPsw/zuI3qImzqw8zqjWD1Ic5a9b7O6iJs6cPM6g1g9SHecu0+bgxTZxdfZhRrRmkPsxbp81Xj2ni7OnDDGrNIPVh3jbNfx7TxNnThxnUmkHqw7x9mj7bmCbOrj7MqNYMUh/mHdPqS2OaOLv6MKNaM0h9mHdO04cZ08TZ1YcZ1ZpB6sO8a5o+5Zgmzq4+zKjWDFIf5t3T9CXGNHH29GEGtWaQ+jDvmWV/g5o4+/owY1ozSH2Y907z/8Y0cXb1YUa1ZpD6MO+bdX4MauLs6sOMas0g9WHeP4vfoCbOrj7MqNYMUh/mA9P85zFNnD19mEGtGaQ+zAfnnR9Dmji7+jCjWjNIfZgPzbK/QU2cXX2YUa0ZpD7MhxfprwT2SdDfAfl9ZBF+wDo/vRHI76OL8APWqenvgfw+tgg/YJ2V/gHI7+OL8APWCekfgfw+sQg/YJ2L3gLkd/Yi/IB1GnobkN8nF+EHrDPQO4D8zlmEHzBPTu8C8vvUIvyAeV56D5DfpxfhB8xT0vuA/D6zCD9gno0+AOT32UX4AfNE9CEgv88twg+Y56CPAPmduwg/YJxOHwPy+/wi/IBxJn0CyO8Li/ADxkn0SSC/Ly7CD+jn06eA/L60CD+gn0qfAfL78iL8gH4WfQ7I77xF+AH9BPo8kN9XFuEHPOfoi0B+X12EH3Cfpi8D+X1tEX7AfYa+AuT39UX4Ad8T+hqQ3zcW0dd5NFD3AWgztMtP5uJbIuVyjKIWkazxkX9FJWf6Qk0NvD4S1ccYtaiiJCGjU7oKlbWsW/J7zBHhh9Zb6Xb3mA10Mx57yHVmtlr34w75uvtzedwG6378Ivo6Tzii+8Sovk5/vk/YwG6ufok5dkNFOP4ouk9M15CUbY0/V/aOVKjOBf7NRJGsMNFFq0+OdcTQO0u1MVXu6ev0rn7blLIyGsOrFIVIxFasSSnnUmtMwlvvi6begq1bJqtCDkHUaq0OSH2dH53Ejz9akEU6/nBGOmtIpeptti7FUjxblKhEwZs+lt9lKJJVIlJJxilTvIq7+jqjWkdIfZ1rzLK/QU2hXX2dUa0epL7Oj03iN6optKevM6jVg9TXueYsfoOaQrv6OqNaPUh9nR+ftf8Nagrt6uuMavUg9XWuNWv/G9QU2tXXGdXqQerr/MSs93dQU2hPX2dQqwepr3PtWe/voKbQnr7OoFYPUl/nJ2e9v4OaQnv6OoNaPUh9netM8//GNIX29HUGtXqQ+jo/Nev9HdQU2tXXGdXqQerriFn2N6gptKevM6jVg9TXoVnn76Cm0K6+zqhWD1JfR86yv0FNoV19nVGtHqS+jpplf4OaQmftrXlMqwepr6Onxb9jmkL7+jpjWj1IfR0z6/0d1BTa09cZ1OpB6uvYWf7LoKbQrr7OqFYPUl/HzeI3qCm0q68zqtWD1Nfxs/a/QU2hXX2dUa0epL5OmJf/G9IU2tXXGdXqQerrXHea/zymKbSrrzOq1YPU17netPrbmKbQrr7OqFYPUl/n+tPOjzFNoT19nUGtHqS+zg1m8RvUFNrV1xnV6kHq69xwWv5+TFMIqa+z23Mxyu9G0/J/Qz8I2CdB1wDyu/Ei/IB1fromkN9NFuEHrFPTtYD8broIP2Cdla4N5HezRfgB64R0HSC/my/CD1jnIgHk99OL8APWaUgC+d1iEX7AOgNpIL+fWYQfME9OFsjvlovwA+Z5yQP5/ewi/IB5SroukN+tFuEHzLPR9YH8br0IP2CeiG4I5HebRfgB8xx0YyC/2y7CDxin002B/G63CD9gnEk3B/K7/SL8gHES3QLI79RF+AH9fLolkN8dFuEH9FPpVkB+d1yEH9DPotsA+d1pEX5AP4FuB+R350X4Ac85OhXI7y6L8APu03RHIL+7LsIPuM/QnYH87rYIP+B7QncF8rv7JH6jn/OJQN0MoM3QHj+pjZUtuxBckFXyQnPQOSXvK0WtkuRf1743FdeTozCuN+owDF9cUMlvye/4EeGH1qvpdnd8A92RJx1ynZ6t1v3kQ77u/lyevMG6n7KIPtFTj+g+MapP1J/vUzewm2dP64/WVKMquivEOCN9q9UVr3zTzeoSXNIxSKGyd32kNVCwNVIf388mmBbuu6cPo4xIMSpepU1dMsJo05pIZKJzNcSqbJU59F5rGQuvnpQMxurm+C90hNQnes68+dYcoudPYZ2vund7B/KtGCOiU6kEytqQtyWwpWbSsiZiKEWkyiha2NUnGtWKQuoTPXeWfz2oybSrTzSqdYTUJ3reLH6Dmkx7+kSDWkdIfaLTZ+1/g5pMe/pEg1pHSH2i58/iN6jJtKtPNKp1hNQnesEsfoOaTLv6RKNaR0h9ohfO2v8GNZl29YlGtY6Q+kQvmjZfM6bJtKtPNKp1hNQnevEs/29Qk2lPn2hQ6wipT3RiFr9BTaZdfaJRrSOkPtFLZr2/g5pMe/pEg1pHSH2il06bzxzTZNrVJxrVOkLqE71s2nz/mCbTnj7RoNYRUp/o5dP85zFNpj19okGtI6Q+0Sum6QOOaTLt6hONah0h9YleOa0+N6bJtKtPNKp1hNQnetU0faIxTaYz9/SdxrSOkPpEr56mjzqmybSrTzSqdYTUJ/r1afn7MU2mPX2iQa0jpD7Rb8yyv0FNpn19ojGtI6Q+0W9O8//GNJl29YlGtY6Q+kS/Nev8GNRk2tUnGtU6QuoT/fYsfoOaTLv6RKNaR0h9ot+Z5j+PaTLt6RMNah0h9Yl+d975MaTJtKtPNKp1hNQn+r1Z9jeoybSrTzSqdYTUJ/r9RfpTgX0m9Bwgv9cswg/YJ0HPA/L7g0X4Aev89Hwgvz9chB+wTk0vBPL7o0X4Aeus9GIgvz9ehB+wTkgvAfL7k0X4Aetc9DIgvz9dhB+wTkOvAPL7s0X4AesM9Cogvz9fhB8wT06/DuT3F4vwA+Z56TeB/P5yEX7APCX9NpDfXy3CD5hno98F8nvtIvyAeSL6fSC/v16EHzDPQX8A5Pe6RfgB43T6IyC/v1mEHzDOpD8B8jtjEX7AOIn+DMjvbxfhB/Tz6S+A/F6/CD+gn0p/BeT3d4vwA/pZ9NdAfm9YhB/QT6C/AfJ74yL8gOcc/S2Q35sW4Qfcp+nvgPz+fhF+wH2G3gjkd+Yi/IDvCf09kN8/LKLv9DSg7gjQZmiXn3Qi1mwbJdf1F6LUlGQSyfnmSDUZ+2SyNDnlVPukeI01qOCcadnJYPKW/J5+RPih9X663T19A92WXzrkOkdbrfsZh3zd/bk8Y4N1//Ii+k6nHdF9YlTfqT/f0zawm29Omw+OfYwh+C6QRaRyi8XY2nVhQuszwsnWGPvwdYpKOYohBi+DFJ5/xzq3p+8UGL7xvkbXh6+rKtlpUXqTsIuaZGMUztZaqhWeH1XyyhZ+RtH40Mc5kfpO/zNNn6idFBCLvpreK1qrFrbwSrUNUnpXrDLJWV1caMYXZixDjb312dkuR7Sr7zSqtYXUd/rWtP7eMU2rY3v2N6YVhdR3+vYsfoOaVsf39NnGtKKQ+k7fmTWfNKhptafvNKgVhdR3+u4sfoOaVrv6TqNaUUh9p4NLTjo/BjWtdvWdRrWikPpO55vEb1TTalffaVQrCqnvdMokfqOaVnv6ToNaUUh9p++Z9f4Oalrt6TsNakUh9Z3OP+v9HdS02tN3GtSKQuo7XWAWv0FNqz19p0GtKKS+0wVnvb+Dmla7+k6jWlFIfacLzbK/QU2rPX2nQa0opL7ThWedv4OaVrv6TqNaUUh9p++dZX+Dmla7+k6jWlFIfaeLzLK/QU2rG++teUwrCqnv9H2z+A1qWu3rO41pRSH1nS466/0d1LTa03ca1IpC6jtdbJb/MqhptavvNKoVhdR3uvgsfoOaVrv6TqNaUUh9p0vM2v8GNa129Z1GtaKQ+k6XnJf/G9K02tV3GtWKQuo7ff80/3lM02pX32lUKwqp73SpWfY3qGm1q+80qhWF1He69LTzY0zTak/faVArCqnvdJlZ/AY1rXb1nUa1opD6Tj8wLX8/pmmF1Hf6JpDfZafl/4Z+ELDPhL4F5PeDi/AD9knQd4D8LrcIP2Cdn3Zr3qP8fmgRfsA6NZ0C5Hf5RfgB66x0fiC/H16EH7BOSBcE8rvCIvyAdS66MJDfFRfhB6zT0EWA/K60CD9gnYEuCuR35UX4AfPkdHEgv6sswg+Y56VLAvlddRF+wDwlXQrI72qL8APm2egyQH4/sgg/YJ6ILgvkd/VF+AHzHHQ5IL8fXYQfME6nywP5XWMRfsA4k64A5Pdji/ADxkl0JSC/ay7CD+jn01WA/H58EX5AP5WuBuR3rUX4Af0sujqQ308swg/oJ9A1gPyuvQg/4DlH1wTy+8lF+AH3aboWkN91FuEH3Gfo2kB+P7UIP+B7QtcB8hOT+I1+zl8B6rYAbYZ2+fHCgupts5q0S02kmHVVOZDLyvZh2+bCyXmV3jiqQ83Z5upasMUJ76rdkt8zjwg/tF5St7tnbqB786uHXCdqq3U/65Cvuz+XZ22w7l9bRB/r2Ud0nxjVx+rP99kb2M0DJ53PvRFa21xMrNo678n5WEOK/DlaEqGP7uYcvbOFdJBFklPWkGhRi2r4GezpY/UvSiKbwCB9b8b3VUtDlWlp72PooyC+8HNKUrtiS/KCn5+szlKQviL1sR40yz+sKuRSaspktShCEYneNs7mRCIlL1sfP1BWqyBypWxcUVYqX2IsbG/i/nv8xrTKkPpYD5423zCmCbarjzWqtYXUx3rILPsb1ATb1cca1dpC6mMdm8VvUBNsTx9rUGsLqY/10Fnv76Am2J4+1qDWFlIf62Gz+A1qgu3qY41qbSH1sR4+i9+gJtiuPtao1hZSH+sRs/a/QU2wXX2sUa0tpD7Wz83iN6gJtquPNaq1hdTH+vlZ8cegJtiePtag1hZSH+sXZvEb1ATb1cca1dpC6mM9ctb7O6gJtqePNai1hdTH+sVZ/AY1wXb1sUa1tpD6WI+a5b8MaoLt6WMNam0h9bEePc1/HtME29PHGtTaQupjPWbW+TGoCbarjzWqtYXUx3rstPrmmCbYrj7WqNYWUh/rcbPsb1ATbFcfa1RrC6mP9fhZ5++gJtiuPtao1hZSH+sJ0/LPY5pge/pYg1pbSH2sJ86yv0FNsH19rDGtLaQ+1vFp/t+YJtiuPtao1hZSH+tJs86PQU2wXX2sUa0tpD7Wk2fxG9QE29XHGtXaQupjPWWa/zymCbanjzWotYXUx3rqvPNjSBNsVx9rVGsLqY/1tFn2N6gJtquPNaq1hdTHevoi/b3APh16ELC/95cW4QfsM6GHAPk9YxF+wD4JeiiQ3y8vwg9Y56eHA/mdtgg/YJ2afg7I71cW4Qess9IvAPk9cxF+wDoh/SKQ368uwg9Y56JHA/k9axF+wDoNPRbI79cW4QesM9DjgfyevQg/YJ6cngjk95xF+AHzvPQkIL/nLsIPmKekpwD5PW8RfsA8Gz0NyO/0RfgB80T0S0B+z1+EHzDPQb8M5PeCRfgB43T6FSC/Fy7CDxhn0q8C+b1oEX7AOIl+DcjvxYvwA/r59BwgvxOL8AP6qfQ8IL+XLMIP6GfR84H8XroIP6CfQC8E8nvZIvyA5xy9GMjv5YvwA+7T9BIgv1cswg+4z9DLgPxeuQg/4HtCrwDye9UkfsN5SqDuDdBmaI9fn3RsIvLCTBZFJpeb7F3/TkvjY9O6zzqnqiJZ6YKpRYWgPAWVXGhiU32x5x4Rfmi9qW53z91AN+h5h1xna6t1n37I192fy+kbrPv5i+iLveCI7hOj+mL9+b5gA7v56Cz/phnHdGSJUZakRfQyFOoD487mYlsTpYraWnEuh1i7dlPIXvUh6uqo5T19sZKd6BPBXVgnuxRtbJEKERnbQh+ItUV00SjykZ+JNCn3UWNbmLDXWiD1xT42iZ9Uxff+Zyt06SoGJLMm31vOA/+va0ro0tU4WkhW5+Z10n2SrsnS9bNq2NUXG9V6Q+qLfXyW/Q1qqu3qi41qlSH1xT4xid+optquvtioVhlSX+zsWfwGNdV29cVGtcqQ+mKfnLX/DWqq7emLDWqVIfXFzpnFb1BTbVdfbFSrDKkv9qlZ58egptquvtioVhlSX+zTs/a/QU21XX2xUa0ypL7YZ2a9v4Oaanv6YoNaZUh9sc/Oen8HNdX29MUGtcqQ+mKfm/X+Dmqq7emLDWqVIfXFzp3m/41pqu3piw1qlSH1xT4/rT4ypqm2qy82qlWG1Bf7wiz7G9RU29MXG9QqQ+qLfXHW+TuoqbarLzaqVYbUF/vSLPsb1FTb1Rcb1SpD6ot9eZb9DWqqnbm35jGtMqS+2HnT4t8xTbV9fbExrTKkvthXZr2/g5pqe/pig1plSH2xr87yXwY11Xb1xUa1ypD6Yl+bxW9QU21XX2xUqwypL/b1WfvfoKbam/f02ca0ypD6Yt+Yl/8b0lTb1Rcb1SpD6ov90zT/eUxTbVdfbFSrDKkv9s+z7G9QU21XX2xUqwypL/Yv086PMU21PX2xQa0ypL7Yv07r3xjTVNvVFxvVKkPqi/3btPz9mKYaUl/so8D+3n9fpD8a2KdDHwfy+49F+AH7TOhsIL//XIQfsE+CzgHy+69F+AHr/PRpIL//XoQfsE5NnwXy++Yi/IB1VjoXyO9/FuEHrBPSF4D8vrUIP2Cdi74E5PftRfgB6zR0HpDfdxbhB6wz0FeB/L67CD9gnpy+DuR38P1r8APmeemfgPzOtwg/YJ6S/gXI75RF+AHzbPRvQH7fswg/YJ6I/gPI7/yL8APmOei/gPwusAg/YJxO3wTyu+Ai/IBxJn0LyO9Ci/ADxkn0HSC/Cy/CD+jn067PO8rvexfhB/RT6RQgv4sswg/oZ9H5gfy+bxF+QD+BLgjkd9FF+AHPObowkN/FFuEH3KfpIkB+F1+EH3CfoYsC+V1iEX7A94QuDuR3yUn8hnWsgbpBQJuhPX6BRCypOkMpBaF8Cl4YXZOQLvrkTnYtF2/5f1lYaUyhLLIvzkWtffNb8nvREeGH1uvqdveiDXSXXnzIdcq2WveJQ77u/lxObLDulyyiz/bSI7pPjOqz9ef70g3s5laTzmcyqcUkpY7axaa0sVn2GS8teKVOJZUEg1VUXKpEwrVG1YjQRSZ8ky7cd08fpoWsa4yqSuO0oxq06bowJTgfk4lVBBEpGB+D063rtaWuiCJ96cMkCanPdutZ/PqcfsuNF2hszdI5XZpLXlLXfmixtdhnYJpnEzX8kYMxokRfW2IwseVdfbZRrTykPtttZvEb1KTb1Wcb1XpD6rPddhK/UU26XX22Ua03pD7b7WbFd4OadLv6bKNab0h9ttvP4jeoSbenzzao9YbUZzt11vs7qEm3p882qPWG1Ge7wyx+g5p0u/pso1pvSH22O87iN6hJt6vPNqr1htRnu9Os/W9Qk25Xn21U6w2pz3bnWfwGNel29dlGtd6Q+mx3meU/D2rS7emzDWq9IfXZ7jqL36Am3a4+26jWG1Kf7W6z3t9BTbo9fbZBrTekPtvdZ/Eb1KTb1Wcb1XpD6rPdY5b/MqhJt6fPNqj1htRnu+c0/3lMk25Pn21Q6w2pz3avWefHoCbdrj7bqNYbUp/t3tPqw2OadLv6bKNab0h9tvtMy9+PadKds6dvN6b1htRnu++s83dQk25Xn21U6w2pz3a/afnnMU26PX22Qa03pD7b/WfZ36Am3b4+25jWG1KfLU7z/8Y06Xb12Ua13pD6bGnW+TGoSberzzaq9YbUZ8uz+A1q0u3qs41qvSH12co0/3lMk25Pn21Q6w2pz1bnnR9DmnS7+myjWm9IfbY2y/4GNel29dlGtd6Q+mwPWKQ/GtjnRLcG9kc/cBF+wD4dui2Q34MW4QfsM6HbA/k9eBF+wD4JugOQ30MW4Qes89OdgPyOLcIPWKemuwD5PXQRfsA6K90NyO9hi/AD1gnpHkB+D1+EH7DORfcC8nvEIvyAdRq6D5Dfzy3CD1hnoPsB+f38IvyAeXKKQH6/sAg/YJ6XMpDfIxfhB8xTUgXy+8VF+AHzbPQAIL9HLcIPmCeiBwH5PXoRfsA8Bz0EyO8xi/ADxun0UCC/xy7CDxhn0sOB/B63CD9gnEQ/B+T3+EX4Af18+gUgvycswg/op9IvAvk9cRF+QD+LHg3kd3wRfkA/gR4L5PekRfgBzzl6PJDfkxfhB9yn6YlAfk9ZhB9wn6EnAfk9dRF+wPeEngLk97RF9O1eBtRdAtoM7fKTIkSTpeqj9kn2GZ+Q+6S9qLzUWpKzOWmbVfLeNlOa4qUG63UXvtDRty35vfyI8EPrnXW7e/kGulWvOOQ6b1ut+5WHfN39ubxyg3W/ahF9u1cf0X1iVN+uP99Xb2A3b5g1H5KCYZLKMCcXVRXeCeVFTUKZ2ESqoXhFThhG72r/1DbWVLv6kG2x5D19Oxt4nQw7lS7x1AdnbMwtSJW10pQpBxezbFkX/hoZre/N/0lL7WMg25D6dm+c1R9dyRY2u+h1zGwS/F+mqUNJJRvRpZiiUaFkm7yVTZrmrRK+sCUFMmyhu/p2o1qDSH27N03TNxnT9NvVtxvVykPq2/39NH2JMU2/43vv75hWHlLf7sxp8w1jmn67+najWnlIfbt/mKbvOabpt6tvN6qVh9S3e/Os83dQ029P325QKw+pb/ePs/gNavrt6tuNauUh9e3OmnV+DGr67erbjWrlIfXt3jJr/xvU9NvVtxvVykPq27111vs7qOm3p283qJWH1Ld72zR9jjFNvz19u0GtPKS+3dunzVePafrt6dsNauUh9e3eMc3/G9P029O3G9TKQ+rbvXNafWlM029X325UKw+pb/euWfY3qOm3p283qJWH1Ld79zR9ojFNv119u1GtPKS+3Xtm2d+gpt+uvt2oVh5S3+69s+xvUNPvNntrHtPKQ+rbvW9a/Dum6bevbzemlYfUt3v/NH3AMU2/PX27Qa08pL7dB2b5L4Oafrv6dqNaeUh9uw/O4jeo6berbzeqlYfUt/vQNH27MU2/XX27Ua08pL7dh+fl/4Y0/Xb17Ua18pD6dh+Z5j+Pafrt6tuNauUh9e0+Osv+BjX9dvXtRrXykPp2H5t2foxp+u3p2w1q5SH17T4+rf9gTNNvV99uVCsPqW/3iWn5+zFNP6S+3RuA/dFnL9JfDuxzojcB+X1yEX7APh06E8jvnEX4AftM6M1Afp9ahB+wT4LOAvL79CL8gHV+eiuQ32cW4QesU9Pbgfw+uwg/YJ2V3gnk97lF+AHrhPRuIL9zF+EHrHPRe4H8Pr8IP2Cdht4P5PeFRfgB6wz0QSC/Ly7CD5gnpw8D+X1pEX7APC99FMjvy4vwA+Yp6eNAfuctwg+YZ6Ozgfy+sgg/YJ6IzgHy++oi/IB5Dvo0kN/XFuEHjNPps0B+X1+EHzDOpHOB/L6xCD9gnERfAPL7p0X4Af18+hKQ3z8vwg/op9J5QH7/sgg/oJ9FXwXy+9dF+AH9BPo6kN+/LcIPeM7RPwH5/fsi/ID7NP0LkN9/LMIPuM/QvwH5/eci/IDvCf0HkN9/TeI3+jl/HahbBbQZ2uVHvlDhhaXmPMkic7bVWcrVJ+d81X04PNlSu8SFFjbIqoLTvlbyxuUUt+T3G0eEH1ovrtvdb2yg+/Wbh1wnb6t1/9YhX3d/Lr+1wbp/exF9wN854vusPDnXoIrS/OV92DhWLYIXzUdDpuuISaVVqaF/3yBzn8QOJgdJVodEelcnT4jgmjDK+N7vH3yfks/e+6arr8X2T9iMk6WaLj9Q+ii8MDq6LpTS+7qROnn6UnPsj5Qs/In6qAKvOyhvyEkvtSlVMC4jlC9ZV5FbM61m0kGYPo9CmZ+dU2pXJ0+4lGPxwXUtrmbYCkIthTnlloM1NXdpAd/lAmyoolDMwWiKobEVpNQaUifPTOInUjeQLibmWgpdKI8/blfrCE14oURlSCZVNhqbQ2rZOR2Fykllan2++9iezhtl6YUWSsfsJSWlksjVejZhy8/GCNuiCMUaR2zl2kTjYmuKVMpdiwapk2dn2Z8rio1Bssk4z5uCrDVVFXkvoFR87buGSzalLPj/asrOOhlMsWw+/Gea2tXJIxI65yZbkIwq9Bdd6dQnSPgP+xSTiDbWog3xFiP47ZVZ8Kutnc/axQLVyXOz7I9a6I8/O4q8+Np3qhZTUoZtqZ1UlZEyeKf4ba4lOCkMaZ94tyxJ8H62p5NnG38r3jaJ97QUSu1D8TFKldTJKbTqFfFL2/fBwA8iSx1bVD7Z2KT00SN18vwsfk4F6RR/EH6jTNCN3yzlqU98ytJHQIzUvvBbmwR/Uj4WqiJJjo2x5cj2tK+Tl3NXIoz8HUwJQWjH38gr3vj4vfYqyQ5QVfF/dG9L4C/Omo8rafkbBoXUyQuz+DXRouPj3YU+UdJ3LyOkFv2kyMnkVHiH6mYk+FipVsa+WKGLJpOd121XJ0+Ylopi85SmidCs5He/URG8eYqYlWsx8r90pRTPf1fibZVPdm9D0JbYpC1SJ++6k/hJWXUfbOINjj+eFOQqOeMt8RnBL3HwobbIx7J0jsG03AWy2E2pyqnCx3Db08kT0Rl+PZPxyZTUJ3pMU9kwVD6jDFUfkutnck4yKH4+/L5rPkxE5vM4S4PUybveLH5WO9GMzi52xeLq80nZWt7BCvssmT3DyqtlCqkGfm2l5mXy+xtDTOzgBL+rkyfYBUqe39uU2aYiOfJ8qEfe6vhtpZNzdvxHu2yj5bPHZdWFZwp/dYy5i34gdfKuP+v8pdRMZacvZcuvce3yO/0UyLHVYALvTa6PwHfR2qSzYEdGqda6ugq/cL6GXZ28rlPr2fe2lfdAx18rCltvKXxEldyVtmrig90LZ5TsGt2mD4CKPgtpNccGEqmTd4NZ9pe0CqHw3s7+q6BaTNKBjcGVPuTvpCrFcqgRVSp8hqoacqn15BCsZd9Xh12dPOrCMUYEzV9Z9Mk91IQoug4LH0m2sBWL2AUNmYrjzVIFPuzdSZmlQlVopE7eDWfx6y9od/J8C+wSs920WCO/fJbf1Oo49LBsm+yZBJF9LkJLjho4iGCALemW93XyGp+uRabGu2bXJewKC8kJsqp0QcFGPivZXFDCZNGVBTnw5GO/S4kwVIXUybvRLH6OvRNjq2I2bASVupiHjpX3Jltk3+IDnx1FEFtb8LzpR5HZsDjkLlK5EHZ18jjqPKnGk9lB4V2VF9N9x8g7RFa22db4RS1V8p82jLlLhlrNr7Xvepcc9QmkTt6NZ+1/iVMSkUM1L/sAdZO5skdb2EdxVllOXLBPx2FC4SwDh8PJdlUnxy9ztUJ1Kb09nTwtVdca5G9pIj8Ky4kMFY3pWt98MkWfcpe4rBxdafZiOPtBfZI++cKnSEgGqZN3k1n+H3t2/DkyRzyuScv7VOWDliMuhmH59SMOxzgaZysxpsucaH7Xo7S1Nn1SD2lXJ0/ywjjFEPkUsrmrZHIwLDijU3qkx+9tTV13WVSOqjniKF0Kl13MrsGQAvuGFamTd9NZ769uLXcF1ch+bGMHMDvDyRdOKpTuAWc+WWxUvOezjSTFTNhd6yErH9ZsSsbt6uSREaawm5cD570kL19wyBdTv6EgRxeJnXNXmua/MlHko5itk/NZbIcmGENCIXXybjbr/dWW006V031N+dqTd/12i67MLSwl/j02tx60ucb/SXxsuKYiH8+cR8majWxPJ49TgnzGBA6BORMZu0xmTpxxyYzLdrXQEqiR5Vj65NaaTI2eQ73UhOTHIyJSJ+/m0/J/0XrFe7jX7K3xF+skE6+WtDaK7a50kW3e69n76wcNR3GusgddDEd9LZPZ08mLrh+7QvHBIlxkJ6ckKj7yy88vdeyCb7zhcQjIxsZxjOIEou5rLpk9GcoWqZP309P8534ZSBJ8RtrujeWutU19ew+83bOx/J8F9EsuAp2MOLLhNJ8PHJu00PSuTp4wNRTK7ODw2Z1tqk6zz8M7Jrsp7FpyMJObZecyq9blbNgf51VH9pyZLOd9BFIn7xbT8n/VqMzZ0MhWyJ8v9kwVxwTsjmXeq6Lkc0BoK2UKIakufJc4ukvBeIbAm9yuTp7UxIlEtkIjSmZmql8u4jldz0d85YQNb6gMVCb+qU5d5ofzh5VjZP4LSs8VInXyfmbW+Rt4iYLzo5xKsk4XfmOV14Gtjc2LvQ/O/PXcp+gSjZX/4Xg75B2QvZnYioxtVydPskvD/qHwHHEUtrTQRctSV/MtvuhkeJfjiJAD5K6CW/rNG4Hdd66mRG17wIfUybvltPxB6ppuFFW/EIP4TPAculXpIm/v7OlxrYLrU9Tvo+FzpnHJinOEvOISLb+bSu3q5HH4li0nDGvmBEzsOt0mF84B2sCpPsXBrk18OHUlOctHNxdXTOIaCcc57A55kQtSJ+9nZ9mf5lCLT4gia7/rJnDiwBXDq+Y31vbbHjhnykmTXsvg15OjCfZAAvmTGa3K5+uuTh4l9haN7fKf7IELTpVyXYoTz5zw50xs1NJxpaCxl5lK6Acvb4m8NYqoTkbSSiF18m41LX/v+S3kDcom16+XosolUF8jcY5P8DF68r6BfuUKF0NUpI7IhJMYOM9ipdjTyYucf+mq0V0prwuoSg6BOeLIkV9kfm297CL8XZw2cD2U316On9lbZxNUWXO+AqmTd+tZ50c3Dk4UcDaYk6WuS5xrPmz5ELW6BWu5Dsexf3c+pNScK+TXvOfyI9shv40i7urkCa15DclysotDaT6BZOpKjJzEZ4+culdJkc+hpnmTKLr0uKPH25G3Q3aSrEHq5N1mFj8rRK/OUk+ys2/GtbEu7G6pC21xftj2ynbgUk/q2oFdvJw/Jhc6OPoKfF7Tnk4e8cHR60d8dIjCJwS/lVy95JjZcerBMgB2VTiznRwnmznAYd+a/+P7oZSIvSakTt5t59XPHWfY2ZN1nGJxprLJ8OvJAZfinS7yaVrY0+vZVXZXVHE9Cc1eTa9h+B6p7OrkycbnsuDineCDR3I+25+UIUvCc8xRuALCpVFO81hOjbEPHWOyPY3DePjs8PyMkDp5t5t1/mbPvnDsEUWqvGXVfktS39gVZzlrrxFZDvf7nT78tpbGji67KNX2t9pxEqHt6eQlxSViTufp1m8GS+ytcALCcODHCWw2VnPyiqHW9af5hGELVRwCW361OSHIn0EhdfJuPy3+aOy2sCvWOMku2eftSr1cOeMdK/eEXeGdTvGpbPoNnYyET+qWeediQp6zy3s6eXzecBzBJXFekpVd8JzdFA6eNdcFDGcSNMd1zlUOGLtEfN8EOEjkKhQ7205wfIjUyTt1Fr/CtYd+xw0nNhN7gB0bb0a8y/GLlfgY7beWSi5VJPZJimNfhrPwqithcmaZQ5A9nbzAh6ji/ApnHYrOHOLlfkhzJZ2dPs489zvCPP/Pdg3SnDl1xiUU6/svcmnPKaRO3h1m+S9jPwjY50S7PT+j/O64CD9gnw45IL87LcIP2GdCAcjvzovwA/ZJ0PWA/O6yCD9gnZ9uAOR310X4AevUdCMgv7stwg9YZ6WbAPndfRF+wDoh3QzI7x6L8APWueingfzuuQg/YJ2GfgbI716L8APWGehngfzuvQg/YJ6cbg3kd59F+AHzvHRbIL/7LsIPmKek2wP53W8RfsA8G90ByO/+i/AD5onoTkB+cRF+wDwH3QXILy3CDxin092A/PIi/IBxJt0DyK8swg8YJ9G9gPzqIvyAfj7dB8ivLcIP6KfS/YD8HrAIP6CfRRHI74GL8AP6CZSB/B60CD/gOUcVyO/Bi/AD7tP0ACC/hyzCD7jP0IOA/I4twg/4ntBDgPweOonf6Of8XaB+E9BmaI+fk5lSqiZJarG4UGMwfbi7OOtEn0RL5FRykpcVsqKaTPVd2ylbbWWQW/L7vSPCD62b1u3u9zbQTfv9Q64Xt9W6X3PI192fy2s2WPcfLKKT94dHfJ/tE5veeSZnlbNF5qiNlv2udldS1q6mFnWythqfQ2klRpEj/1zYWERTdlcnT8qsa5RGuyBbqrmarrXC/6dFjNFWx9/ZChWyLC6LUnJoqUvNBO9l5A+N1Mn7vWk6CzpqqQ1HGVEkRTowFFWyVYEXqHTtEzQcDnZZQe2rKClRKFUaXxV/Ae3p5GnpI39JbNXWaqmKyL+g+zhd9Awt9NFa64LhBZfgc7Wij8pGG1X0SRqkTt7vz/Izo9PGqUix6lY8r48/h3a58AfSKjupgnA1xxBDaikG60+qCMRWii1Klj2dvKT5T5tGwqaqnXe8Iq002ZhLsFHy8yhdNSqpyH9FzE7Z3JSISlIXKExInbzXzLK/oJIxXTvCuMDvWCMXlE9eldCMJVNFF63MVSdRVLE1SN3VpEzytRZmeXxP542c4bUaErLT1zm6nHg/CEyh9MHZIg05HQRvRLJWn70umjcJ3UxSviB18v5gmk5PUDLwblRbnz/yXTwr9A1XZWt9V4cqvBMG6WoIdFKqQ8nku4hFqUTJ7urkyT4AliXZYPvsaB8Z9ZLXXry2fcRMKf4FT6RUqMF0c7f9C9gWXWq6ZKRO3h/O4ieqzI5PJW/6MVF4c3eZzxLekviMkC7GPt3AVtrVdYTWrnUFGmP5xKox5j2dPHLZ2BJzrGyoqVR+TUWIWtTYh8yy5yMjWiErv8/NJVH7ZumcicJp4n2kIXXy/mjW/qdMckry5m3Ja36pSnPe8unL6+1Kg0Y0F6zh07+PxukgrRdOia4ToLzNclcnj/i3spTNNmJDi6IYK33SpFtQVfAZUfnQcLxXUONv7/j7KmFSC3wAR+2lQurk/fGsOR32G3LrWnmBKr/JzfKCpbK8Ov7Ano2nq6uKyBwbf0DKxEdHJK94HY4Nck8nL8i+NRbSRgXF2yB/URbB5GJ0F2/NWklnAz8mikqQ86FrsjCVqLq2l0Lq5P3JtDnZ5Hx1/LFqZJPqghvN9yGmaKzvhkm8dN0so6mmSt7DjBDs9LQYNLuXcVcnT6ZcSWZ2RGskLXISDJ4ceyaK39Lax+T7H5eaX1txUg0kSW0Lv9+iON4lkDp5fzrr/a2Vz1NrYmB7cK0lV9hDy/w5pGu2ZPae+fSwOctWRd8s+8up2EVJrhoR/K5OXp/Y5HNC+kqlK0V1nUJ2hvh9J11aJnaeyUrj+NlIS+xN9sM69TE+x6e1yUidvD+blmcko7WhomLpo4g5sf3UPjOb2Mktqprspc5C+UjBB+nZexYm8pZW2Z2zaVcnj+MR9pONCf0dZo+PFJ8Ylr0aq/i58GnEv6Q5qinJ8l+hGHXmHaBQYrAhKofUyfvzaTofxRHv4JE/FVti4WiL/cHusnnXR2JF4vCNI4coZTLszumTW3/rKoFZMIA9nTz27hrvcZ6/A7+eqipSUnX/hJ1K/pfUXNeT7kdW4IMq1Mx+DO+FXQM8hQTVyfuLWf5L5MCjuOYq7+m172leNz5kSxaVoy3NvkyRbIDGdhcm89HMXh6lfnCmrgC3q5Mn2YfjwIzDi2BC4+M3uq78E05q8/AOaLVKXX2KXGQnkD3AkPtsszOulWZNRurk/eUsfq1YXglbSDopMxYSh/Teik6Ij0UvEicAupyi43OzaRtStOxmB/5SH3Jwuzp5UvH2Vk6KCRrLgWBiPrrHt4U32S6AmWXieIb5deFGIVNylkSX+yj87YNH6uT91azz1xiXY+yhQRNdyFdzIFpUylZ4Z1QXaONEgOI3jQ9pPmWSZWvh6Jjf6pyDV7s6eYIPX8WoiJM17qQ6WZKV48OuXh0Skcn888qbAGnbnO73FPAjahzQSLY+05A6ea+d5v/xMdm6DHnsYkeKA9KuG8Bhbj8s+GCRHESUKiqnBHjL6lPYnJLis9OxJ1dq2NPJ6xI8jQ/apNlkOfPAL7AXHBKGzI+JOBwh9h356DFs7hz8dnFDLx3vBCppDg+ROnl/Pev84JQdb1HshDXe2D1HVZycou55dI1azScyGxH/qu7iMjIqDh26SCjHXJWzeTrt6eSJGPrNF61Lk7H32IrWMZmu7eb4UPchNPaFGvGvpEItc0gdUzYcHBt+hImQOnmvm7X/sa9ho3OxO3x9j9Ps3PnmJL/M7J8ofhs5P2u6Z8PJJsc5KN7u+WSV/NNuM7s6eYLdFD6p2eOJbMCt36/R2FxVlpU97kzUlVmVKpzy5bRENj0BQ4ZDEs4vSM78IHXy/mYWP45zDfsZnNyuvPFH09UoreUUM2dmauJzmI8O06VspeaYKzFtxVknUTxx6jj7PZ08PoJINU6MCmV9YrqJjdqabtwcifD5kzmzRYlDQ5XYDDk8YYtUjl9fduOtROrknTFNp4J3cE4u8ylbtOsSRVHx0ZELv6CVT1nOvJNx7ORyMpSrA81wqNw48SKYJptO2dXJ47c8+tIVzIPWHBZKyZbKudPG7z5nDjhxyEcUxyKO+h8NvnpOnhbfE/6k+ehB6uT97az9ryXD3hcvlJNxiVMwuvBK2X3hfFKxnEyJHKCYzK8kZ1QTW6vOXaKtp15O/u6uTh6nDY0ypXEkTbxh8oEkm+oX3LCPyTl7Tuc0LuR4fgKcse33wWTf+IRmj9tEjp2hOnmvn2V/vMk5yz5dtI0th989Np5c+CRJooUu5W4c73Zcz+D4nw8ATrI2x7/mvE68+ds9nbxYrLVBsBW2QII3BXbFeUfgCJAD7MoHEJNTgm2SnRql+SBuMfebXUTyvP9qpE7e383rs+EXjFN9gkLgfa4fh46PEFttD7C4+tGvduAd30Xfb/fRnCN02fExwl4j+4dv3lszp1IKnz6c9+Kyk8m82QXeJQMvnCM0apWDmtTdvcIxjeKSYeQcTZfrCcLzhovUyXvDtPiXOAvHb10SXOmIXZbMJ94OeY8jK3qane2GnWbRZY058SK7el7h9F2v0gXndnXyhGyGzU102UfO07TaBc35O4euHce1EWd7CoezMUWetHiOB3Pi152PalekMkidvDfOOn+7nm/ht42dGE6dcHQbdI/xRc85CS7xJvaX2XMJ7IDwLtgEFf6YfHh4z9l9ju92dd4il436fWG88bHbzei5nBz6rUK8xVHXMuTvwNttY0eJQx6uSAneEX3XdeXisk9Inbw3zbK/fhGB4BSIqOygcRoksyHoLn8vuiIqx8LRGs/F4Oy4qMYVOC77lG5UnE3m193u6uRJtlMu/nLegDiP3cNkjgc5c6XZD+I8RdAcknBAndkh4qJf1wLO/PXsb1vbb4RwSJ28v5+m86a6I8bnqebj0fSbfXLsNcec+w1SnL/nhAAvgbMmgTimiFwrZluRXcOcd0azq5PX7/bS1TdOWVvOWxOHuVz3LL7w5sq7omeXpqe0+dcpG35MXFfPhfqX9DSN1UidvDNnnb+cq/Mc4PN7xUVJrs5ypo+zCbyjKw6zdOL3i6l2BX6O40rigIIJanY7HP+71HFXJ4+rT6Jr53Eahgu9/fYh6sKC7AVyaYBfXY5YBKcajeTMRGSvWcZ+Z0vig0ScvE8CqZP3D7Pe35MFbc7tST4yKodWyfTLozgRpbkQwlksfuV4/xOJgwiu/zBWPjw5iexFjsQVzl2dPGqpK4hyBqeoXrLjaLgnVF3XuDVK29wvYHKuF0O8MarfWxI4UVN6KYoTWg2pk/fmWfy4Nta4yJN5VXyAEP+76heNlBa778fvapeGZzNMnEjgbEDXO+bME7vYuruLaVcnT7LDHXq/keawLPebSDg7kPiY5cQVFzH5AAmcsU/9asXqCie7OCKmnumSXD+1HqqT94+L9FkD+5zo94F91mctwg/Yp0N/AOT3lkX4AftM6I+A/N66CD9gnwT9CZDf2xbhB6zz058B+b19EX7AOjX9BZDfOxbhB6yz0l8B+b1zEX7AOiH9NZDfuxbhB6xz0d8A+b17EX7AOg39LZDfexbhB6wz0N8B+b13EX7APDm9EcjvfYvwA+Z56e+B/N6/CD9gnpL+AcjvA4vwA+bZ6B+B/D64CD9gnojeAuT3oUX4AfMc9DYgvw8vwg8Yp9M7gPw+sgg/YJxJ7wLy++gi/IBxEr0HyO9ji/AD+vn0PiC/jy/CD+in0geA/D6xCD+gn0UfAvI7exF+QD+BPgLk98lF+AHPOfoYkN85i/AD7tP0CSC/Ty3CD7jP0CeB/D69CD/ge0KfAvL7zCR+o5/zj4D6TUCboT1+lpcVfLLKNiU9FVN1KLqarnFDfQJPe1GtzD5KUXT22pYkbGyxRheV3pLfHx8RfmjdtG53f7yBbtqfHHK9uK3W/aeHfN39ufzpBuv+s0V08v78iO4TJEJyTROlKKrOIcnkRI7NZGWjS9SnJVwmikVq5XxqtTBUE2SKnsin3+Zv+Dsb2M0VLr3t+0K2Fk386VIKWWRrYyVerOzjCymnHPp8SO7XrZdaozHFZqt763Turef1pP7jH26w7ituvG6Zgkj8rEXLURgfmiVXXcn8YPvQQWmODabPJeSapHbJBerTaE5XZZ2ypb/Pf77Buq906Tn7hBj7QUC7pN1nPcrvypdeY5/9C+A+C7QZ2uVHuSVjraw+t97hL6WNvLFWcok3xVRzciqmritayVKQLmnVNQRFH7Vpwm/J7y+PCD+0f9Pt7i832Lf+6pD7dVut+7WHfN39ubx2g3X/9SL+7OuO+D4rQrG2q+EIZ9gVDi1nL6xNoRSvspJdtdPz/ywpF3OXe9bWW99/Ufvm1N453wJ/N8EekPJepeZLV1arQrIHKZyrVXuKXZBISeeKNsGz4+wctSQpSumQ5/zVFznn/2bH/qQOsWZbfXFB+o5Hy2ysClV45Sgk5aruD5iqTSKWYIKjwr43u6Bea4O0vz1+TRI/p6qEjPy42C2utvhCbHhdPIADqRAiB1W2CzJnQTJko5q1trvGtC2/M44IP/S+3+3ujA32/b895OfdVut+/SFfd38ur99g3X+3yDn/hiO+z47OVO/H8zlbqW1LpFpktyMHYfnLG7FXorrgfk+OxMyuCfsWyXdNeOr/UF1FLhXkOX+NRc75N55vN5fIllS71E5ulSmbnqfkx1u16pKq/FiEk+zaZZml9y21XEKwlbNuRWQjJdL+dvmRdWS6IJC2nEINMraWROmiqJRIsp+pJfubtXDqNAijbcq166U2QyZLJTfl96Yjwg+973e7e9MG+/7fH/Lzbqt1n3nI192fy5kbrPsfFjnn33xE94nR+lTP17xuA7u55iGvT3X/9Q0brPvHD3l9qr/Pb95g3ddapD4FtEv6caA/+xOL+LP/CMybAm2G9vi1qCpHOUF7L03IsnYRw5OXtHEkVEKqsl9d0IM/znrmzBtJKJzqDDLHwrHPlvzOOiL80P5Nt7uzNti33nLI/bqt1v3WQ77u/lzeusG637aIP/v2I77PjtanrgmsTyHPebHIOf8OYN4UaX+7/Cio/hh1FanI4JVxOUlrMxlhBacki+IgIVdv2PVn8+OAkCupxvV7UYxmJ3pLfu88IvzQ+363u3dusO+/65Cfd1ut+92HfN39ubx7g3W/Z5Fz/r1HfJ8drU9dE1ifQp7zcpFz/n3AvCnS/nb5EddFS/P15J1lJva7mInXJSynvbLi4mizzclA7GAKa/odJNTvoY8lpmh927Tf9P1HhB963+929/4N9v0PHPLzbqt1f/CQr7s/lw9usO4PLXLOf/iI7hOj9amer3n7BnajD3l9qvuv791g3eaQ16f6+/zhDdZtF6lPAe2SDNCfdYv4sx8B5k2BNkN7/FoVsTne/6sOvNdVGY0utvEm2K9q45VzlCJ1aqkUqWLVIlre+fvGqWpMtCW/jx4Rfmj/ptvdRzfYtz52yP26rdb98UO+7v5cPr7Buj+xiD979hHfZ0frUxpYn0Ke89df5Jz/JDBvirS/XX6SbLOOXErZFY5rRI/0+IFJ4bVqusoSTaMSY6gcBfDH8dHUfj2fdoEToXJLfuccEX7ofb/b3Tkb7PufOuTn3Vbr/vQhX3d/Lp/eYN2fWeSc/+wR32dH61MaWJ9CnvM3XOSc/xwwb4q0v11+bFrGZH6YoonCj1NHVW3QKlAgHynx41NJxuycyjap2thW+ENLXrs0ZDeN5889IvzQ+363u3M32Pc/f8jPu63W/YVDvu7+XL6wwbq/uMg5/6Ujuk+M1qd6vubsDezmxoe8PtX9189usO6bHPL6VH+fv7TBum+6iD/2PQe4d/vGQH/2ZovU94D2TTcF8rv5Ivb3ZWDeGWgzhOTXmZ3v4P//B9rnAbIUu5/3vJ1/Of///vOU/xebuOAGazr4f/w9/0+OF/9/+TXoX77FQzrvfPjv+5Xz4V7Krdb9lfPBn9He5nTYmf7fH6eAP+f5D3Cf86u7m4jh+hp7SYpM8tbKJiQ7kNEV/kXXUo4UXKyJZI1WO/Y9OQmnGucGnSHpc1plzV8Drxlth/2ZfG0DJ/XrhzyI32rd3zjk6+7P5RsbrPufNkpeHOZ3+58X2c8uAFzzv+wWeZpXKZQmTc+FWJ9ycdoLLvMIl5VzhuN/V5rIoiUhlGlGcCHD+NKHfmTRq6z5X8FrRr/T/Zn86wbv9L8d8r1sq3X/+yFfd38u/77Buv9jkT0c+W7/5yL72QWBa/6v3TXn6ASnvrlQ31SIJLnSHbNXwkhtKHGNvpFpPmmKztSmOH9uuFjeTEwxcNF6lTX/N3jN6He6P5P/3uCd/uYh38u2Wvf/HPJ19+fyPxus+1uL7OHId/vbi+xnFwKu+Tu7RdicTOMqXEjVRm1qoCQ4GJH8w1EOOgRNwTaOPYqU2RRds6OQk1eVq7YxrLLm74LXjH6n+zP57gbvdH8ooM8oVlr3+Q75uvtz6Z8Rve5TTlljD0e+299zyrbvtjQtGZGsiblpdt+1y6moRJlcCS67VqXlP5qjVL7YqrQ3vABv+S/PzlnT81v/vIGN32rrJoagiuU1uhKdJCGVMXwu1tQ4RdW52lKTUUxHWcesDUOgqqgW46zjz95jwv/cYN233rpphS2GPxYf60JkzzZkBRHFLE2J2mllrQmhGmdiSK6WZkmbRjpFW1SmrLsf9e0N1n2bjdctYozKVJk9r6URP/kaVVXK5hJsVMEFmZQnFYxuNaSm+EmnIJpsNuTgXN97vmeDPe22izRdAN9HujWw6eJ2i/AD2jfdFsjv9os0rZwfd/YT0Gbo9nviH6WfFuSDVE6onIkjqMgRViKTOUmWVVa89QSpIyltdWy82MyL1F0erJkt+V3giPBD+7Ld7i6wwb5/wUPuw2+17gsd8nX353KhDdZ94VPW2Ge/94jvsySCkKLkWouoWvE/dSYrpFQcA3lyxJFP8RxV5Si4rC2tLakarYzkdFptes9PMtbJJE3s8VOtzZrsVHT8hVr1T6aVqypGGckqnVKfY+OSeHLRCKFV0kg/6a6TznnS/CmENcpHw6X9ytWimpUU1VAx/BBIy8DFI8+hRHYcU/oWm6uCGIJR1NSen1S5pmQdryv5lhUDzylWDkmdD6byqpuuHNcqmfnJc+jiODjWbA3JWdUaKaSfdLdF/KSLAN9foM3QLj9ySXOeucdjHIppn7lOKDgZzcuxuhjpeZHV1UaRbYWTGYZtSHnjQpQlJeG25Pd9R4Qf+tzsdvd9G5ybFz3k/sJW677YIV93fy4X22DdF1/ET7rEEd9nheYMKSdIreGv53PdVqGsSo1EpWhSqVZU/jalisgp1hAEn9CZtDWkGv+y3POTEhcg+YMUz5nVIKpoKikXQ8muJvaJUjOcmROJf10pYh+vWKmF6pOMJZiUkH7SPaf5SYJicEURZyGjThTYu+G8umB/KLF7RNp1T4crta7GYnM2OaWqrWUvk3OXYddP4sxlVtWEmIooydsms+BcvUhJ58DPlTO5iayRMVqtRFTK+BJFFMVLm2OOSD/pXov4SZcEvr9Am6E9fr5HAVzfMaJWKsWHYkvj6kwqzma2lcDvReJKj1SFU9hdL4uEST7n/uBj2ZLf9x8Rfuhzs9vd929wbl7qkPsLW6370od83f25XHqDdV9mET/pB474PksMoiSuMzIx5RWlQjWxn8SJC0rswbCfxcX7VnNJ2ZlK/GWlamH479M2O3urvbwXVaFj9UEr4gK2sN7plq0OruVWQm2FCp/4jVNf0gTiGr0ny8kvzw5fiw7pJ9130jkvTZeaajpIz74epcYOjtG6c2d/pkiRddWUqy3GeMm5tUoya8kpQV4154n2/CTFxe3GK5dRc/Vbx6x8LTawoyXYEWbHMvL3YPhN+WybrWRiaSL44Bmlckg/6X6L+EmXBb6/QJuhXX7SyWx7f3pzJ+OQooLXVtmWONPKucXYOEkrZSjCJbYZjk5K4Vo/OVt983JT8agfPCL80Odmt7sf3ODcvNwh9xe2WvcPHfJ19+fyQxus+/KL+Ek/fMT3WcEOlYlOidaa4yKd9FxNazIJ64ROnO1JNivDLk0uPcHhS+/csq6S5v9w9mrPT+KsSvOC010mcCmKPSaR2UOoIRilqwpcZbNBKa4J5kbespOnOHHCmSWu1pXoLNJPSrP6k6zKJftIMQuj2ZOpKgftomJHxshmvRIhiah7V39ONurAuSBvujxmFcXt+Un8vYziklx2TJipCCNa/y6GWohBKC2kjTFx4ir55BSVwOtXUWpTDHuzBukn5UX8pCsA31+gzdAev9Ir5rJFfk5cyKbKeUfNNVdOB2aRHMchWsvEEQnHEJErqPw7xkrZE44cD5m2Jb8rHhF+6HOz290VNzg3r3TI/YWt1n3lQ77u/lyuvMG6r7KIn3TVI7pP8OHLaYrS2IcJJLzg//Jx3qi7MVUrG5qU1fQeJPYD2L/peSHOlWROZfQZB+r9Z9+7gd20rec0BudTej35Ehus+wGHfD6l54d/YIN1P/CQz6f0eO+HN1j3gw75fErfv6+6wbofvMh8BXAfogcA45eHLMIP+F7Tg4D8ji3CD/ie0EOA/B66SPx8NaBfB7QZ2uPnnefKnM68Jwvlhfeu9Dt8+fg1PdfEaatqZI1Jp8ApmC7uXk72WbWkGvtlW/L7kSPCDx1Pdbv7kQ3Ozasf8jhyq3X/6CFfd38uP7rBuq9xyhr77I8d8X2WQqNGKTIoo5Mk22/iaM1am52qUjofak4y9r+df8t7LTisCiF64jS5tW2vH2NsVgjpZz5qlp80ONO062eOzgoh/cxHz+I3ONOE9DMfBeT3mEX8zGsC9z+gzdBj9uusOrB11GI9b0sxe9KhcabQ9Qt5eLfj39CO+EXjvE8x0YQ+7dhv2ctdIWZTP/PHjwg/tN/R7e7HN/A7rnXI/a2t1v0Th3zd/bn8xAbrvvYifuZPHvF9VjrDzmFKZKIo0liuw3CennLOgr3D2id7OJevdOyNLZXTvVlyZr8YipzhFjXs5TMHZ62QfuYTZvlJgzNh+37m2KwV0s984qy+6cGZMKSf+QQgv+OL+JnXAe5/QJuhPX7E21wLpbgcOGbLOnEw4kXg16oIWxOvtyjDVebW4xLebRTHuc1H52VtrmzaD/RTR4Qf2u/odvdTG/gd4pD7W1utmw75uvtzoQ3WLRfxM9UR32el8dJXGTkP1+fXSlI2ZRN0LZWTm6FqyUk5csELrZ0QnGOznj0Cm6wriaTcy2cOzqoh/cynzprDH5yp2/UzR2fVkH7m02b5mYMzdUg/86lAfk9fxM/UwP0PaDO0x48XFPhDJzYVU22/FVv4JqVM2obEW0313larU1NZC64scBgmOCluNOe+i9qUnzki/NB+R7c7s4HfYQ+5v7XVut0hX3d/Lm6DdftF/MxwxPdZUZqJrcSiUq2cVqxcoYxVpkjVmJhLS9ordnikUypwHd3HFrtWgvaGjPb/j/7MsVk/pJ952iw/c3Am8YH783lDs35IP/NX5s03Ds0kIv3M04D8nrmIn3ld4P4HtBna4xdzj8+ycSVwHYRCK2wiofTQpDXfG+o1Van5v/yycD2mX2notQymWMrWbsnvekeEH9rv6HZ3vQ38jusfcn9rq3Xf4JCvuz+XG2yw7hsu4mfe6IjuE6Pzjb3/9sc2sJtnH/L5xt4P8pMbrPs5h3y+sdcn1Abrfu4hn2/s8XLYYN3PO+TzjX3/vtEG6z59kfky4D5EzwHGL89fhB/wvabnAfm9YBF+wPeEng/k98JF4ucbA/06oM3QHj/O2pGVFAPX63QS7H2E2AvIhn0uH4pgP88JS7Fy2op37EKS68lN6Gpl4TLzlvxuckT4oeOpbnc32eDcvOkhjyO3WvfNDvm6+3O52Qbrvvkpa+yzP33E99nR+cZnA+cbkX7mKxeZb3wucL4R6We+apH5RqSf+Uogv1cv4mfeArj/AW2GdvlJmzR5IbNwXRstB6uk1ZztECZIZasRmTcV1RKXNW0RvCHKyLXmyFsRJxzTpvONP3NE+KH9jm53P7OB33HLQ+5vbbXunz3k6+7P5Wc3WPetFvEzb33E99nR+cZnA+cbkX7mby0y3/hc4Hwj0s/87UXmG5F+5m8B+f3OIn7mbYD7H9BmaJef5NJqKdELjuiSkxyIcJ2NNyU2fS/JVGFy4E3FOraNZDkaj01p5XWsJWkr05b8bntE+KH9jm53t93A77jdIfe3tlr37Q/5uvtzuf0G6z51ET/zDkd8nx2db3w2cL4R6We+ZpH5xucC5xuRfuYfLDLfiPQzXwPk94eL+Jl3BO5/QJuhXX5Skiyc6m6mcSmkSa37lQ7aNQ42lNQhFh+TT71o4AtvPIUD8B7l9peyMI8t+d3piPBD+x3d7u60gd9x50Pub2217rsc8nX353KXDdZ910X8zLsd8X12dL7x2cD5RqSf+aeLzDc+FzjfiPQz/2yR+Uakn/mnQH5/voifeXfg/ge0GdrlR0lo6veqysZhnObQuOrSYq2R34dqbFTS9aEYCo2DMtGLBoLLCbVwqaTyjrYlv3scEX5ov6Pb3T028Dvuecj9ra3Wfa9Dvu7+XO61wbrvvYifeZ8juk+Mzjf2/tuf3sBuXnvI5xt7P8itN1j3Xx/y+cZen7jDBut+3SGfb+zx8t02WPffHPL5xr5/32eDdZ+xyHwZcB+ivwbGL3+7CD/ge01/A+T3+kX4Ad8T+lsgv79bJH6+L9CvA9oM7fGLgtinSEnKppNNvnIyqvG6ujdXORnFCcXUxzvyyckNrlRTtVysTmS4stw21Tu/3xHhh46nut3db4Nz8/6HPI7cat3xkK+7P5e4wbrTKWvss/mI7hOj8XN/vnkDuzlrVn2lD386TvzzmkummLLxlFwx1nvOOvjWG3KS943D7EzeGRWKzFppbYItSe361zJqGay1pfHXuZK4DmMtlxZS5WdmuYijCzUlsgw9o8HlBQ7NuOaQuZhWYwsS6V+/ZRY/6VqSqUnB8Vef3cySK3f8KXjp1mXO5PhsXDKWcuVKk7BSq16aMqp4Rht2/WspRBFsiVkEyfkfn7gaWXI5aYmSozsqhbEr31p2tjft8/tAvbaTpE5NNKR//dZZ/nWWNnAJilLwnviDGH7LlOfEjlG1J8G42KkqZzOscKJ/MVfschOFf6txQJyQ/vVZQH5vWyQ+Ab4n9FYgv7cvEp8U4LkJtBna4xeK56xyJWFUbz7VwsXYa8BVUKy5pcRHnhS1D5IbTrHx/uR8zk5yoT06VbfkV48IP7S/2u2ubuB3tEPup2+17gcc8nX35/KADdb9wEXikwcd0X1iND7pz/dBG9jNe2f5N8p6jiuqNS0UDlJ6CMFuognO90pI8oE/kauNfCnOSPaytbSC4cSmEoeCr92rv8bkpXKmxdacZ9/aOvacZXNJuy4kyw/LBK4maWcL8Z/uT04a6XQPMHVGxifvmzVn4ENQKUottGBWygtfgmePmlmIEGyyJSoVXTRBCMPlZg49AkdmRtaqqnC78QnZWjLbtFVcTeSKFKNyfcFcW40cOHo21KBLSOS7KVb24Rt/IRdhm4mWHXZkfPL+WfEdf0Sur1G3lcR1ZimKLJXjOg7ystVcmZMchvVqvg+V32jXTg5Wq5y59pq8OuPSuFgbGZ98YJH4BLjP0PuA/D64CD/ge0IfAPL70CLx3YOBfgfQZmiXH7GPwEkoxydfLIaK8k7z5qJzFXzU8T7s+HRLSSlnBe9Zurez87dIIWiynGbakt9Djgg/tL/f7e4hG/htxw55nLPVuh96yNfdn8tDN1j3w05ZY599+BHdJ0bju/58H76B3Zw9TW8nyGyUNpGicbWY4tk3jsoWm3spzwkluJ4kEhXRQ43S53X6sD/pqGi/v0s2jrsN12BUbxR0jID/oWrM+qQaqeZSii5FRY7DfSs9sPTSZa7NqNYHsQoyvvvkLH4mVcnhaokhZg46eBlFOIo+c4xXRJchcCIZX6nqVF0QLZrMgYcovYqS9uO77Lng5E22dHJMqskuu1o4aGmZKJgkgzo5fc78gg3alpBrrl5FwcabAjK+O2fifJTj+pm3MRHH/L5y/VIKH/ldzszDZM45BFMCGyV/5KKC5iwPf1pjOVSOcq/+NJirQMZ3n1qkfoyM784G8vv0IvEdcJ+hc4D8PrMIP+B7Qp8G8vvsIvHxI4B+G9BmaJef7AlIQ/87yxtDYWdMstvho079v802ZboyOucuWyw2Bdtluk1lJ6vFuOn9Ez93RPih46Vudz+3gd/784c8Ttxq3b9wyNfdn8svbLDuR56yxj77i0d0nxiNj/vz/cUN7Oa8afFxKoaj48b14VT47+e4ODjn+4RfNV0Kg6OWUtmTjq5qkbgQpTgQ5KA5m5Kz3a9/dv06Dj68JS5GB2NSUa7fumk0h4lcq6NAXbotisKRiZT8wKQpRVL/q6RBxsdfmRWfeC7RWUnOkSYSKqeWXeafBF2ZEsfDTfeafBCFDYjTOCr2nI6wsVdAvd2bf2I6NunIIbDmjE5y2QqXHD+IzHkerwIbtzKhKqsCyeCDcr04ymXSxDXVaJHx8Vdn+dfBctqEPxrbQOJCJ4e2XELObC9ZRSua90lJSrkmLi73gDhzgOytDU5TrTbvxsejuR5kfPy1RfoX3gusHyPj468vEt8B92n6CpDfNxbhB9xn6GtAfv+0CD/ge0LfAPL750XyC48C+r1Am6F/3tuXs3A6dW04YftFaJWs5o2Xso7RtCZr6ldUsbPbHFlnYy1VhMwkMufnU9mS36OPCD90vNnt7tEbxA2POeRx9lbrfuwhX3d/Lo/dYN2PO2WNffbxR3SfGM0v9Of7+A3s5pvT4mOlHBc7kyocFitXyYvWpcl9iDZw1JWsNIZ5E+dsAlebdcmCS75FyZ422Jv/JBmDqhz6cUrH1xJ4jcWn3lMdszl5GWNuTkthnOfougu+k+Ov6QF5EkZYZH7hf6bxc1SloN5vEJXj0rHUnIdhcsUYxhltLJxpqK0VtipT+tWmxCkarjJzGqzKvfo7B9Zcee5CVUxNWf6ru7ArfxuO4YgX57XIpTZtg9GSQzsZCpsiZeIkkDIZmV/41jT/UIaWdeAAOArvlBKJ6+yZUzU5eVtUZEuSLWmtlKmqGeKcF68kWMnrUEnv5xfGcmXI/MK3F+mfeS+wfwGZX/jOIv0LyPzCN4H8vrtIfAzcp+lbQH4Hl1mDH3Cfoe8A+Z1vEX7A94R2bWaU3ymXmXX+jn3OJwDjBqDN0C4//tC6sj/a/YHcknX9CvbQw4iWInFo0L0rG7RP2lXB/inXyFIVxI6DVsFuyu+JR4QfOl7vdvfEDeKu44c8T7HVup90yNfdn8uTNlj3k09ZY599yhHdJ0bzM/35PmUDu7nopPNZavLMKXBmRfQbOxQnvUoJpXJSwLgsZW/4r1Vb0zWmYotkORaTUpWq+80ve/q3UcYmvVZGNZv7apRwPd/DQbHsQmlZG44glREqUOByfx9pSQwlMAJ+lMj8zMVm+Yccq1EyzeQYAodxHLVyWOtCi7FfHchJGitCZfOSpRoGSrZGw7/M2Rnna4z7/R+yeQZjmHUyTlRTed2Zswct8tPQDDKrnkfjxEW38eg5gBRatsjJL5cKMj9z8Vn2l6SqLXKMLJzlLKCymXMKsV+w6ZpMlLtagoqcqHHZSpWa6KnB4lQxQtjg9+bfB3ONyPzMJabxG8tJvRfYP4PMz1xy1vs7mJM6D9g/g8zPfP8i8THwnKOLAePjSy3CD7hP0yWA/C69CD/gPkPfD+R3mUX4Ad8TujSQ3w8skt96KjDuAtoM7fIjdm0rV8O5RsZev3d9Lrc0pYtVkivkTkrva+gFNOnY3+jiRYW9Di+rcKFmtyW/px0Rfuh8R7e7p20Qtz79kOd5tlr3Lx3ydffn8ksbrPsZp6yxz/7yEd0nRvNb/fn+8gZ2c5VZ8bEMxDlAoSnEZAzZ6IlC6PdY/f/Ie8u4z47y/v/XpEIppbhLcIe5xgen7i6U6mhTx4sT3C24BQgQCBCkFC8FqjiLlTaUYsEW11Kj/2v2/+Scx/P5zmvndS+Sze69937nfebMmbnkfQKfXo3kqIrgKJQTSbVsRJJFWWbStRbGq7rzf/C5OQidk9Y2uNJy7eViPdZAHO0SMjsrNZ8mVX/Xr218ghQl8RULfI4sEdvfdLVJ/Ig5pRo5CMhxPWE5/kLacezVB2k5cpg5XuOZbRKZwyrVcKiBo3s84/jk7KKIfu939D5Xp7QspER/VTUHAKuLQTrrZNPR84gDB7pUto6jXE54DkLYUHhKJqc8Mr519Vn8qHgOs/A0yVEUjjnF0F8FLXsPXEu1NeNjCxyt9hyVaUGkSjH3ZkWXgvUm7uqPBmO1yPjWNWbxG4zpHQPWbyHjW9ecFh8ci+kdB9ZvIeNb15o1/wZjesj41mnA8/G1F4kvAJ9zdHUgv+sswg+4TtM1gfyuuwg/4DpD1wbyu94i/ID3CV0XyO/6i8QHHwo8twLnDG35UeFnonKtBt3fJex8KjxQ3rBnzk7zpiw1Pl7qzGM20SdiHlmaoKkQb8Oq04fk97Ajwg8dL+rz7mEHOPc//CSPkx1q3I84ycfdr8sjDjDuR56yxjr7qCO6TozGB/v1fdQB5o2dFh9USXiOAogqm2utUOYwljAcDHBN69jfwaF841Mshw8df1yvdG/75C/TwmWzfz9lshy6qVGEkgRHXfjg3XT/xhwE9NXy/5nCZ0ITODrBNIJwwknLAZtEggO7yPigm8UvVCNFNBQtR0AlkyyFCUUTKgewXdI2G91q5OiXt8xPq9ROqH04gFCLTLv3UyYOCnrVQuOQoHZacPSg5P6vurku/1Laqv6ymcCXQpmiK3EIgwO3psnqbEXGB/00fr0asinVY9H8v5Zy5FiJkprD05UjM0ryZ/LFJB6G52RAdj4n4tieM961nR94NNaNjA+GRepXjwHrB5HxwZsuUj94HFg/iIwP3myR+sGLXAoXa0TGB2++SHwBuE8gB+R3i0X4AZ9zFID8brkIP+A6TTcD8rvVIvyA6wzdAsjv1ovwA94ndCsgv9ssEl99NPDcD5wztOXHD/3aMp8m+dwjVeY9mjJJ1r7v5A0rb2yj1Ta2ZE3smpteFVSL5l0d7ycsPyIPye8xR4QfOt7W591jDhA3eexJHmc81Lgfd5KPu1+Xxx1g3GeessY6+/gjuk6Mxlf79X38AebNz8/a3zjPH9BLPrFaPv9yjNUqPhvrxsED7TmWYptyxVb+0C1UDgvaalQqLpqaydrd+9eo9I5Yp/urs8lxtCwKDgg6wZflxLuzfLK2d4ZTjo4DNU5bkhy85bhN8xzX0cj46i/Mis8IF0KOHNjiGAoHVSVHBpyPKQgbapAhWw7j9cBe5Cgyj4eSEByn0YqnXNZ1F18lbYWuVXBUW/K4lKytBFkCZckxiqhDFP2bKQ5h8/coPRYUk6OcOOdgbVHI+Oovzpp/rfHHV8YKDnA1nnrZ+z4NGUQiyXdc5ki0lDnF0hzHo0yzQhJnUXT/V7P3vw3mCpDx1V9apH76GLB+FRlf/eVF6lePA+tXkfHVX1mkfnVXfzkYq0XGV391kfpVZHz154H8fm2R+Axwn0C/COT364vwAz7n6JeB/H5jEX7AdZp+FcjvtovwA64z9OtAfr+5CD/gfUK3BfK73SLx6ScA4ybAOUM7foYDJNEkV02MvLetfGRwzZlYUj8D8MGA91hV8GFI8FdoElL75LwvvOFvyspD8nviEeGHjlf2effEA8SdnnSSx2kPNe4nn+Tj7tflyQcY91NOWWOdfeoRXSdG49P9+j71APPm9FnxBZs5WMrhQG1LDkLYyIEGycEoKq0p8tJxEMVY2UNUiviMnBgsx8E4EtNDL7v3nwr+Kg4Oypp7k3eUqaaQSpYcHuNB21qjKByhSHzEFqY0WUTg8Jmh0IyvLkZkfPoPZ8UXrMmeFAePOUAYmB0HpHk4PKM4osohG5EdcZilhKiUETJxsEaa2uNWqvsB2s5/qZPKwXNEunAcTPjoLCmOIfL4edjCc2A6aI4Sht44z7FVlyrHgBKHLKrk2CvUD/BH0/IjPFwdOeTnBA9ZeV/5pxyg4sCNCLbf261nQiQnnjwHDa3ijABTDTFK/oWdH2A014KMT//xIvX7x4D108j49J8sUj99HFg/jYxP/+ki9dPb+PRorBsZn/6zReqnLbB+Ghmf/vNF4jPAfRb9IZDf7RfhB9wn0B8D+d1hEX7A5xz9KZDfHRfhB1yn6c+B/O60CD/gOkN3APK78yL8gPcJ3QnI7y6LxPefBow7AecMbfnxgUpJHosqKfE+1vNh3vKJKBBHoXwuWsjC+zdleXvP+6rmgk686zpRWqb6JveQ/J5+RPih47193j39AHG7Z5zkce5DjfuZJ/m4+3V55gHGfdYpa6yzzzqi68RofL9f32cdYN48cFp8MLceCaBkuoXXytaMZO7aEAeiiUOp/LGa1K3X/HtHTmWOwspSOKbH8ZWwi+8XG0yX30qONnK0jFSIHM5OmuOomWNaDJOy4v+IytkW3V8jbzpRFSyHq6NDxvcfNK1+unKAVXCMJnC0qmgOqXJw3hZmwwNrFHJswjvtLIereCQ8XFmrDJo/uilF7OL7KpHVQQpbOKRqnSRDnkPSnCDwWbTMAVoOIfJoA8/tXtvPmRfDrDmt4DOHCJHx/QfPyo8IvmWTk1ryLIycDOG7jGl5wVkQjgXG3k/SA/r97V6e49FWif6a++yjLjb5sqs/H8xVIeP7D1mkf+QYsH4fGd9/6CL1+8eB9fvI+P7DFqnf38f3x3IFyPj+wxep37fA+n1kfP8Ri9TvI+P7DwTye+Qi8S3gPoseDOT3qEX4AfcJ9FAgv0cvwg/4nKOHA/k9ZhF+wHWaHgnk99hF+AHXGXo0kN/jFuEHvE/osUB+Zy6SH3k2MG4HnDO048cxIR9kbXx2rMV7z4dzxWE6E0WQtiXFJ3HejDnevvJ4fUu6b/p5B8wxKD7ZHrT/4TlHhB86Xt7n3XMOEPc8+yTPExxq3M89ycfdr8tzDzDu552yxjr7/CO6TozmR/r1ff4h1olZ+xvDEVWhI0ek+2sKqVmOt1oOx7Se0zDGJg5wFccB6RI4rEdkouG4g+vRQw5NtF1+hIPbHEK0nLGqSUkbGS5nSTiUpbyPQhQffWucZ+FoluvhjBMBIOuyllIUEsj8yHNnxWcM/9WNTCrSWQ51CaYns+d5wz81mecOB2ZUlb7yaDg2yMNthb8yuhY5rJx3/vPAfyaJ0DTHpjmGmHwS3Z0eldSas0o8k/mvMS6EHnptuUcbrU2cwXLdiu6Q+ZHnzZp/HKwyiqegiZxA80UYmZWTQfpYTSy+9JSR5W+SkmkcZyXiiRUYTW9y4sm69/OM5fqQ+ZHnL9K/dAzYP4LMj5yzSP/IcWD/CDI/8oJF+kd2/vPBXAsyP/LCRfpHLLB/BJkfOXeR/pHTgf0jyPzIixaJbwH3qfRcIL8XL8IPuM+i5wP5vWQRfsB9Ar0AyO+8RfgBn3N0LpDfSxfhB1yn6cVAfi9bhB9wnaHzgPxevgg/4H1CLwPye8Ui+aVzgHFP4JyhHT+Ou/VQT7dcO97jew4T9YLRnHkfL73lkIjMRWcO1nHMjvhI4WuLVnFoqpeMH7T/5gVHhB8639Dn3QsOEDd+4UmeZznUuM89ycfdr8u5Bxj3i05ZY5198RFdJ0bzS/36vvgA8+Zvp/mhkncc5TRVmsphJt10rSnkmnzzzvVckJNWNV9F5CieJutU4IA2Zz18s2LXf0ORKXKQJ1eS/GWcAfAc7uZID18OLyTjLXxBfOZImrKSLxKHHjkXJYPn7FVqBZlf+rtp8UGpOU6cKqd4mkjORA5aKc76cAw6cCifc579jRccQrQcZW2cOVE8HI4qO55TotVd/w3/CaM5JMbXhJNUgcPdmfr35KiYZfI6uUQ6tcYQu3iLJz3l/lYJjrtyGFYg80t/P63/RpuSeIb19hoOTguOCXJ+SbWo+DaMWfZX73qOSPMUSpHDeS5p6TmD5zhRYqza+bUGc6XI/NI/LNI/dwzYv4TML/3jIv1Lx4H9S8j80j8t0r+0678ZzFUh80tvXaR/yQL7l5D5pbct0r90OrB/CZlfevsi/UvI/NLfAvm9Y5H4IHCfSn8P5PfORfgB91n0j0B+71qEH3CfQG8F8nv3IvyAzzl6O5DfexbhB1yn6Z1AfscW4QdcZ+jdQH7vXYQf8D6hY0B+71skP/cSYNwYOGdoy09mG4vIISceFJ9U+ZhgeaPLpwCvoxWWw5SGIpXAMSA+LfSXODALPplHRxwHOWj/13lHhB86X9Pn3XkHiLu/9CTPUx1q3C87ycfdr8vLDjDul5+yxjr7iiO6Tozm5/r1fcUB5s0Fs+IzWUtOXgrBg0qOg/2JI6scDWxZycQxO8oc+XImiUKOA1O2kG05xsIx5qCS3Pvxas9GcZYkSeFS6zEdzpBwTDW4/iL2ZnvmrjaO73AawSbd3wrjODRdOOqviyRkfu5Ts+KDlSmFXBhj4VB0IuNs4v8yScV5kRQ5YaIiR0edKro0VXoIsAfxhedAqaB9/1d1/KteJ+1MCUlwntNYywmq4n3l+KCh4JPiMaveC8b5pyr5jpA1SklOJ2R+7tPz8pvVc/xZ99u4Numr48/IeUlde3xecR5IxlJEd+a1wglN2bpLz2cKRVSbt/m50VwzMj/3mUX6N48B++eQ+bnPLtI/dxzYP4fMz31ukf65XX5uMNeHzM8dX6R/zgL755D5uc8v0j93OrB/Dpmf+8Ii/XNnA/vnkPm5Ly4SHwTu8+lTQH5fWoQfcJ9KnwHy+/Ii/ID7LPockN9XFuEH3CfQ54H8vroIP+Bzjr4I5Pe1RfgB12n6MpDf1xfhB1xn6KtAft9YhB/wPqGvA/l9c5H85l8C4+7AOUNbfsTBHo5e2hI8RzasJD4sUMhSySYMxyNJGMnbfD44cICXj+9J81AbaZn5POUoHJLfK48IP3S+q8+7Vx4gb/FXJ3me71DjftVJPu5+XV51gHG/+pQ11tnXHNF1YjS/2a/vaw4wby506Un5zZI4XVSE5lA8x7OUsz1GJTjamTg4qkrP1XFWiDisxXhk4mh20gyh9eY3oXZ+S8mhVNkj+hzeIpmMKibLYjhWxvkQzq347Dj8FaLn3Ccz5mCXNVoEX63KXQqJzG9+/yR+/RVcMRgO2ffIquAAdew9dByLThzoIx04IioUR0ajyJzk1By55xxA0hxVbJwnUbv8po/O8tdZ7XUIVnkVOdbKk7vxVeC8chWph6s5Ti0t52USWRk42cR5rWC18hqZ37zwLH7Oc67MeM4/BukaB5QV50VIun6fxxhVjDo2W/izEjlOT3qO4HM6ypfGy0FMu/zmYK4emd/8gVn372BO9xiwfxOZ37zIrPk3mNM9DuzfROY3f3ASv9Gc7j6/OZYrReY3Lzpt/o3ldC2wfxOZ3/yhWevfYE73dGD/JjK/ebFZ828wp3s2sH8Tmd+8+Kz5N5jTReY3t2eGUX6XmPX8GPtBwH0+XRjI75KL8APuU+kiQH6XWoQfcJ9FFwXyu/Qi/ID7BLoYkN9lFuEHfM7RJYD8LrsIP+A6TZcC8rvcIvyA6wxdBsjv8ovwA94ndDkgvytM4jf6OV8LzFsA5wxdYXctyGVvLUcwczVBR5t1k4JEFNYopUXMnKLg+KTgQHlMWuXAQ44u9vf9RBEPye91R4QfOl/Y593rDpD3ef1Jnic91LjfcJKPu1+XNxxg3H99yhrr7BuP6Doxmh/u1/eNB5g3N54W3zI258xJX47UcS7J99ftaQ6cZk5PkrHNqiJKNV2J6hqH/imQiikUpkEci93lhzn9mTi5ySmokvi61Hgiqth0TJzD5wSCNE5q463qYemUKBcOdXO2ODF5jmkj88M3mRVf5TwSp85Dd/IqnpXkI/+cc0yJE46JY6iucdTfFxI8OzmRS8Fz0DSX6jyn0It47T6/xClL3y9JSByC5qR8ybYo/nJRQ2+wdTVwRr1ETnRygiRmnvecFOVkKfGEVMj8sJi1vybOp3FWRCdOG1nriKeMain20oJcC4OoTVIrnLLscWzlMucAVEjKp8ATUu7yw4O1Dsj8MM26fwdz4seA/cPI/LCcNf8Gc+LHgf3DyPywmrX+DebEt/nh0VwzMj+sp+WHx3LiFtg/jMwPm1n8BnPipwP7h5H5YTstPzyWEz8b2D+MzA+7Wc+PwZz4BcD+YWR+2C8SXwWek+gmQH5hEX7AfT4RkN9NF+EH3KeSAvK72SL8gPssMkB+N1+EH3CfQA7I7xaL8AM+5ygA+d1yEX7AdZpuBuR3q0X4AdcZugWQ360X4Qe8T+hWQH63WSS//jfAvA9wztCWH5+EOF4h+BiuOMJZqyl82DFRchwkhBxt5dSE5GBkDjZaTmdwlJJTPoozNhy/rOQOye9NR4QfOt/a592bDpA3e/NJnmc+1LjfcpKPu1+Xtxxg3H97yhrr7N8d0XViNL/er+/fHWDe/Pq0/jnJUXtjJOfCLWeFOTEXSuFwaBLOassZSo6Zcg6c8UpOiVSO8XGuM2pmrzmF5Hb5dRkkR/CT4DBgVJwA4FSTDCVyqsCXZDkzGoPvCQJhQmbwSWYROYTd9cy+SIXMr//GtPyccbp66SN/PCsjJ5gEx6w5Js9pcKoclY88UzjrKfirTCNqgScjT7ceV47SbPPrFDjLzPnmFvmqcMq3JM6+5RxrsBzRbjU5x5lmYRXHq31u0otcfOEYmfdB83+Q+fXbTssPc6KDk+W6JMM5kcafhHPsRQupLLnAyaDgOdlGMlXOs1Xpi+neBcGzKXKOiXb59cFaEWR+/TcX8SccA/avI/Prt1ukf/04sH8dmV//rUX613f914O5emR+/bcX6V+3wP51ZH79dxbpXz8d2L+OzK//7iL962cD+9eR+fXfW6R//QJg/zoyv/77i/SvI/Prvw7kFxeJTwPPSXRbIL+0CD/gPp9uB+SXF+EH3KfSbwP5lUX4AfdZ9LtAfnURfsB9Av0+kF9bhB/wOUcJyO8PFuEHXKepAPmdvgg/4DpDDcjvDxfhB7xP6HQgvz9apD7h74F5M+CcoS0/KTh7IIg4pN6FxL5m72PjOIasijg7IWvtQU4dQhUcdDIcZheVv4jju8E1kw7J7x+OCD90vrrPu384QN7xH0/yPP2hxv1PJ/m4+3X5pwOM+62nrLHOvu2IrhOj9Qn9+r7tAPPmjFn7m8zwbM38d3OkP7TCOSDJiWAOq3IMVQQOHjY6kVfLnNPkZHng7JNJTeXQgqD9+685MBs4R8DpOI50a84qcSbFaxK1o+MMFkfys9IuBZFSrIkSaQ60Wiqa0+sJWp9wv1nxVeq5W44SW2t5ZlTOKXmjKwfgOYVeOaGRODPuOM5sI4nIs9Ja/nodlCKeWKVs6xNE4wQJJ1c0M+Rki+fUMjOjWBiYK8wg8uVQnDaIJVZOH/BYY7dbODIkio3I+oT7z5p/tvAdZioHmzkVFxonw/n246h/TAyV52GgzPezit0qETgp6XjkVJPTnNvlmP3rL4mrtUHWJzxgEX/HMaA/AVmf8MBF/AnHgf4EZH3CgxbxJ+z98GO1Dsj6hAcv4k+wQH8Csj7hIYv4E04H+hOQ9QkPXcSfcDbQn4CsT3jYIv6EC4D+BGR9wsMX8Sds6xNGax2Q9QmPWCQ+DTxn0v2A/B65CD/gOYkeAOT3qEX4Aff59CAgv0cvwg+4T6WHAPk9ZhF+wH0WPQzI77GL8APuE+gRQH6PW4Qf8DlHjwLyO3MRfsB1mh4D5Pf4RfgB1xl6HJDfExbhB7xP6PFAfk9cpL7j7cC8I3DO0I6fDL4pzkZoDinxUAUf3TnyTf3XleTgt+OUoYnFZ84BmWp7BL7UYKwNKVVKh+T3jiPCD53v7/PuHQfI277zJK9zONS433WSj7tfl3cdYNzvPmWNdfY9R3SdGK3v6Nf3PQeYNy+Ztb+JnNIwxXKYNXGkPSZlremeAyE5VJqkzpXHr6wRtYec+es4Pa6l1M4SB7DLq3f+BM4wcfpDMUDTIl8mQ1JrTmv67CNnr2qrLkZOlvKfV0r5lDjjF4LmK2VcM8j6jvNm5YclJ82qL6pp33hwgTFx9pYzSymqFlttkVMjpCwn3FUL2cjirfaS0yle66R273cIhnNwsvFoU9PkquNcgcw5UeAMqfee49w2Gv4W/CWRZLKcNu4pfM2ZwFoasr7jpdP4kdWKb2SXiPPjHJi3nALud1f2JFzJKWvOkHAqLgeqtQa+B6WN/FltYez7+o7BWiVkfcfLFvHHHAP6O5D1HS9fxN9xHOjvQNZ3vGIRf8fu/Q6DtSLI+o6/XMTfYYH+DmR9xysX8XecDvR3IOs7/moRf8fZQH8Hsr7jVYv4Oy4A+juQ9R2vXsTfsfNPDNaKIOs7XrOIvwNZ3/ESIL/XLhLfB54z6aVAfq9bhB/wnEQvB/J7/SL8gPt8+ksgvzcswg+4T6W/AvL760X4AfdZ9Gogvzcuwg+4T6DXAvn9zSL8gM85ej2Q35sW4Qdcp+mvgfzevAg/4DpDfwPk95ZF+AHvE3ozkN/fLlIfcwyYtwXOGfrbXV8+Z/9MrTFzNlZxFEgrwQFxTq1q7TnWVLulXhqpOGnmc5EyetUTuI76gKU+JL/3HhF+6HqJPu/ee4C89/tO8jqRQ437/Sf5uPt1ef8Bxv2BU9ZYZz94RNeJ0fqYfn0/eIB5c/60/Y3XogrNAdTEGc6qixG5ymxDEZxi0yVZnTkgnWUzkfOZkuPwwibb333DKSna+U9icTqYxgkR63I2PWNVOV1aag6cEHCq9ffl1J5m4YC+SkqErDiW3f9Q4JQosj7mw7P4aRs4oas5b2QrZ4lNqJyAk7UnilRkUMTpdI7Ph8BTKvKnNJwLrYEHEUrmRNzu/Sy5cbqDkyPFO5kk/8NbqzjUXX1OzsRQQ2QG3gbLiargkhGR5yxnXJRLxWdkfcy/zeKXNFXKkj+MSUHXZrOOsr9tiQfegu7WmCI5p8a5kRR5xmjPOK2qjbNFssldfcxgrReyPuYji/iLjgH9Mcj6mH9fxB9zHOiPQdbHfHQRf8y2Pma01gZZH/OxRfwxFuiPQdbHfHwRf8zpQH8Msj7mE4v4Y84G+mOQ9TGfXMQfcwHQH4Osj7lgEX/Mtj5mtNYGWR/zqUX8MWcA/THI+phPLxLfB57T6cNAfp9ZhB/wnEkfAfL77CL8gOck+iiQ3+cW4Qfc59PHgfyOL8IPuE+lTwL5fX4RfsB9Fn0KyO8Li/AD7hPoM0B+X1yEH/A5R58D8vvSIvyA6zR9Hsjvy4vwA64z9EUgv68swg94n9CXgfy+ukh90T8D897AOUM7fk1mDqUpL3z2nG/UnKiwOnBQRHQXQVWKk0CcFZSc9BbecsqVx9yK4rQq5zSoHpLfh44IP3S9SZ93HzpA3cC/nOR1Noca97+e5OPu1+VfD1Encsoa6+yHj+g6MVpf1K/vhw8wby58mUn5YcuR6ShrDpzgrJE/rnGc0oj8aUlnzoyEni4iV4NRgvNEJUrOinN2KFPQIdhdfVFNPeWuNcfxc+EkCOeiOCIdZeHkUeawdhOSv4ATndXxlfOa0XC6tFUfLGfdC7K+6Acm8eOxtV4qpDWH8rOMnLqwnBCXHKFXnNSNrRd2cCbJ6l6PYDhVpJw0jE8kF8v+/UqSJzQn430QRDxY20vmarVW28hJpmQDJ5tTszVm42Tkmc8ZFr5Qqef7Sk0WWV90kVn8kuR8hXMmCBkZQPBZcEqYODdshG1G9LT6iV+qutdu8Rfwl2grStLeKLurLxqslUPWF/3gJH6jNVXHgP4iZH3RRWfxG6ypOg70FyHri35o1vNjsKZqV180WKuErC+62LTn71hNlQX6i5D1RRef9fwYrKk6HegvQtYXXWLa+jdWU3U20F+ErC+65LT5N1ZTdQHQX4SsL7rUrPVvsKZqX180VquErC+69LT981hN1RlAfxGyvugys+bfYE0Vsr5oe+Yf5XfZWc+PsR8EPKfTRYD8LrcIP+A5ky4K5Hf5RfgBz0l0MSC/KyzCD7jPp0sA+V1xEX7AfSpdCsjvSovwA+6z6DJAfldehB9wn0CXA/K7yiL8gM85ugKQ31UX4Qdcp+lKQH6nLcIPuM7QVYD8rrYIP+B9QqcB+V19Er9hDwGwbgA4Z2jLjzgizLHHaloyOYToeHhVcVorc54hcEiOB9QqRzkC53kEB5Rb5KCbrJ7Db9H7fEh+Hzki/ND1On3efeQAdRf/fpLXKR1q3B89ycfdr8tHDzDuj52yxjr78SO6TozWZ/Xr+/EDzJubz4pPK/4IynFWrqUYbSTGJbXNSVnOlGSdM2cyQ5acxdAck9ec/zW6RSn6OKRS2/osKV3jcL4OnAkWnEcPhf+gKxznz8FyNpkTMF2ExF8mnSkc++aUp+CrWJNJFCgg67NuMWt/GDhFwfF703KOImpJlTPBnC6LrXHYnxN2/G+1OU08JfvLzYKsPeEpc2Qy3u/rs5IknTgjwJdEu5ZF4Zwy589bVMLFFvr71mzgHFblDKBpVpHMpbYsOR1jUkXWZ91y2v6QZ1Oujm9sMpzj4axu1ZxDEpwo6tlHoQzzS5xPCyaKFFXQnHEXnDHnHHp0ZlufNVpriKzPutW088lYTdoxoD8LWZ9161n8BmvSjgP9Wcj6rNtMy2+O1aTt6rMGa72Q9Vk/PIvfYE2aBfqzkPVZPzLr/h2sSTsd6M9C1mf96Kz6jsGatLOB/ixkfdaPTavPGqtJuwDoz0LWZ/34LH6DNWnb+qzRWi9kfdZPTKvPGqtJOwPoz0LWZ/3krOfHYE3a+UB/FrI+66cWyY8A4xx0CyC/n16EH/CcTrcC8vuZRfgBz5l0GyC/n12EH/CcRD8C5Pdzi/AD7vPpx4D8fn4RfsB9Kv0EkN8vLMIPuM+inwLy+8VF+AH3CfQzQH6/tAg/4HOOfg7I75cX4Qdcp+kXgPx+ZRF+wHWGfgnI71cX4Qe8T+hXgPx+bZH6tk8A6y6Ac4a2/CRHhH3Opcd9NKdXybTaUtKBkwoucnK2q1hs4shI49iI5/xrapqDH8SRuBzbQevbPnlE+KHrnfq8++QB6lYuANc7rTLuT53k4+7X5VMHGPenT1ljnf3MEV0nRuvb+vX9zAHmze2n5Td1D7KHxDnz2ExWJaqQW+FcmpWim7Usp3KNdVG4KCvn55ownN21NlrF+blX7+qLasi2uhiTrzb7bJXSkaP+nPvgq+X5YtUc+bcjQ44iK84NR76SnM/KnJrxyPq2O8zaH3IuPHtOdRSmxblfoau3/HPOL2VjatKac3TBZ19jcY6M4Fnjksl9vnJSQ+/q2ygrrQonMYttJIXlmcupeckzknMj2RGjjMTJ1NyrOJk1p/VziZn/8lKtVsj6tjvOmn+cGetVUj4VXUXlOdWHH4RNxrvISfeqI8+5LLyNtXGavZEpSgVODTVf676+bbBWE1nfdqdF/IHHgP42ZH3bnRfxtx0H+tuQ9W13WcTftqtvG6yVQ9a33XURf5sF+tuQ9W1/sYi/7XSgvw1Z33a3RfxtZwP9bcj6trsv4m+7AOhvQ9a33WMRf9vOPzZYK4esb7vnIv62M4D+NmR9270W8bedD/S3Ievb7r2Ivw1Z33Z7IL/7LJJfAsY56I5AfvddhB/wnE53BvI7YxF+wHMm3RXI736L8AOek+huQH73X4QfcJ9P9wDye8Ai/ID7VLoXkN8DF+EH3GfRfYD8HrQIP+A+gc4A8nvwIvyAzzm6P5DfQxbhB1yn6YFAfg9dhB9wnaEHA/k9bBF+wPuEHgrk9/BF6gM/C6xbAc4Z2vKTnKQ/IWrh/DMJJ6Q7EWvnyKTj7JXn+FJP2FhOJ3AAyttcLKf4HecrJOf3szCH5Pe5I8IPXS/W593nDlD3c/wU7H23yrg/f5KPu1+Xzx9g3F84ZY119otHdJ0YrQ/s1/eLB5g350zzT1TOLFrO9AqO2QtO/lAKlscbdeJ0E38myzQ42q+KSdKXjptcrSHnaJPMO/+dUT3+r5s3nI3ibBxn92ItKnJiTyUpbJXJGkecvLKF+fHfFYslxWk/zkWrjKwPfMGs/IjJNnLOzeYoS+P0iOb8JeeUBGfXdGjJNZk4beRcyS1xZq46Ts7xh0+BejFD2tYHUmuN8y3FGJG14FQcZ5BUDNlpcpxR4blZSuR8i7Q8XZt0rf+dmhPNfOX6i3iR9YEvnJbfpMrpNsFp7hgSJ4lNq5w7U40HqnlKWvLJV84/Ns05N2Ob4yRT4rRnDYaz8HVbHzha64qsDzx3EX/lMaA/EFkf+KJF/IHHgf5AZH3gixfxB17kUrhaQ2R94EsW8QdaoD8QWR943iL+wNOB/kBkfeBLF/EHng30ByLrA1+2iD/wAqA/EFkf+PJF/IG7+sDBWkNkfeArFvEHngH0ByLrA/9yEX/g+UB/ILI+8JWL+AO39YGjtYbI+sC/WiS/BIwT0QuA/F61CD9gnIPOBfJ79SL8gOd0ejGQ32sW4Qc8Z9J5QH6vXYQf8JxELwPye90i/ID7fHoFkN/rF+EH3KfSK4H83rAIP+A+i14F5PfXi/AD7hPoNUB+b1yEH/A5R68D8vubRfgB12l6A5DfmxbhB1xn6I1Afm9ehB/wPqE3Afm9ZZH6yi8B636Ac4a2/KjIHuPm0akiOZHYXIwc5qyctnec5gmSg5RV6Z4K5ECvNRzA4wxtDpyMlUzioPWVXz4i/ND1dn3effkAdVNfOQV7360y7q+e5OPu1+WrBxj3105ZY539+hFdJ0brK/v1/foB5s2/z8ovBW+1DQwwcd67SiUS/5RT6j21GTgrwukkyYRVB+G1dZyN1I2a4ORIh/3q3fs1q2rJcko+1yiziPytovGZE31GBC34UuXK+eaSOYEl+lt3fU+XZFtCdYmg/sWPzuJXLecaeWpkm1XSUjdXrRZWxMi5yMYf1hntqAadpQucVG+Bc+7Vm6RCznn3fmHSvr9bmEfFw8uSU3qNE5k2G8dXxqQiiLOisnHGSudYVOZkMY+eOVj+p3cZWV/5sYn+O885Ov5EXUzpRc+ZFbKUjKg8Y/qtnGSi/pJwTp8XHotRVXJuMim+WdWuvnKwVhhZX/nxafUdYzWlx4D+SmR95ScW8VceB/orkfWVn1zEX7mrrxys1UTWV16wiL/SAv2VyPrKTy3irzwd6K9E1ld+ehF/5dlAfyWyvvIzi/grLwD6K5H1lZ9dxF+5r68cq9VE1ld+bhF/5RlAfyWyvvL4Iv7K84H+SmR95een1aeO1ZTu/IuDtZrI+sovTOuvGaspRdZX/juQ3xcXyc8B40T0MSC/Ly3CDxjnoE8A+X15EX7AczpdAOT3lUX4Ac+Z9Gkgv68uwg94TqLPAvl9bRF+wH0+HQfy+/oi/ID7VPoCkN83FuEH3GfRl4D8vrkIP+A+gb4C5PetRfgBn3P0NSC//1iEH3Cdpm8A+X17EX7AdYa+BeT3n4vwA94n9G0gv/9apD71G8C6KeCcoS0/aXuM+EQ0twXHCX6OylEKQRZfa9PWkeQcj9fRkEomFM57Kxt5sFKn/v7UQ/L75hHhh65X7PPumweoO/vWKdj7bpVx/8dJPu5+Xf7jAOP+9ilrrLP/eUTXidH61H59//MA8+Zyl501b5RLOXWLZagpxUI+CtUrtlzkz8hZcs6uJWE42+Ra5ESv6YUuPTtSazJJ7upTrekVL/r/z57rGqs3UQfO/YnM2TnOPSW+EJnTWJGzfskRpzxt4b9XlcIZfIOsT738JH489ziPaznXxp821kSSGJKTnA3ncXrL2dugbIo6VsVTjSeQUr6/JZw41WRT3dan9qIiUfgrOZcpilLZJJ6QUvEfcfz3pErOJs7BW84w12Z4+qXaOMnJifjWvNfI+tQrzOJnjTtBp3hRUs0lcxKY+shDUi777Izm1Den4JuKRsiOLdUQRAjV+ix39amDtdbI+tQrzuI3WJN7DOhPRdanXmkSv9Ga3ONAfyqyPvXKk/iN1uTu6lMHa12R9alXmcVvsCbXAv2pyPrUq866fwdrck8H+lOR9amnzeI3WJN7NtCfiqxPvdqs+3ewJvcCoD8VWZ969Wn7v7Ga3G196mitK7I+9Rqz+A3W5J4B9Kci61OvOW3/PFaTez7Qn4qsT73WLH6DNbnb+tTRWldkfeq1Zz0/BmtyzwH6U5H1qdeZdv4Y+kHAOBttY06j/K67CD9gnIiuCOR3vUX4AeMcdGUgv+svwg94TqerAvndYBF+wHMmXQ3I74aL8AOek+gaQH43WoQfcJ9P1wLyu/Ei/ID7VLoOkN9NFuEH3GfR9YD8xCL8gPsEugGQHy3CD/icoxsB+clF+AHXaboJkJ9ahB9wnSEC8tOL8APeJ6SA/My0+qHBOmRg3RlwztCWH2mbOeevnWpGSy/4n4kT/T4njtpRzN5w2JKD7ZxH42Ayp8FTCJxlVMLYyInvfEh+/31E+KHrPfu86+zQdXv/cwr2vltl3P97ko+7X5f/PcC4v3PKGuvs/x3RdWK0vrdf3/87wLz51Vn7m1YkJ5cU5960M1bLxEnyYJKowlTObSrvU+vl0bpwEt4VSiIrT5yea5mvjtvW9xInpGwNUfUKpF5Jw7llYXuRb/LZSU4CSj44kM78S7oE7/nr+e8X/A/pKFZkfe+vzaqPEZZnglDBdxlyaVE0x1lbHrPPNTXTOOspRZC99rzFoLOvNSROuXN2t1cZbet7ZTkxviClJJE5k6mIGl8JL6TynGY2gvPpnKDnbF9ORhrfq+Q4SyqUK14rQtb3/vosfilmytYJ2cjwR5LNCReCKN4rzkeGxgiijTEG3weblSFrOzzijHLW6fW7MY/VqiPre39jVn59sKb5GNDfi6zvve20+qKxmubjQH8vsr73N2fdv4M1zbv63sFaYWR97+1mPX8Ha5ot0N+LrO/9rVn8BmuaTwf6e5H1vb896/4drGk+G+jvRdb3/s609W+spvkCoL8XWd/7u9PqU8dqmnf+2cFaYWR97+9NW//GaprPAPp7kfW9vz9t/o3VNJ8P9Pci63vjrPVvsKZ5X987ViuMrO9N0+qjx2qazwH6e5H1vXlaf9dYTTOyvvdXgfm5skh+Exhno18H8quL8APGiei2QH5tEX7AOAfdDsjvDxbhBzyn028D+Z2+CD/gOZN+F8jvDxfhBzwn0e8D+f3RIvyA+3xKQH5/vAg/4D6VCpDfnyzCD7jPogbk96eL8APuE+h0IL8/W4Qf8DlHfwTk9+eL8AOu0/QnQH63X4QfcJ2hPwPyu8Mi/ID3Cd0eyO+Oi9RH92+I4gecM7Tn10wqnDLgz85hR62VEtLwwDk/yJnApr3klJmv0jfDuZ5slXaeM46lBs8x+YPy+64jwg9dL9svRGeHrns85VTsfbfKuE89ycfdr8upBxj3d5+6xjr7PUd0nRitj+7X93sOMG/OnJWfy5xhJ06CS6NTcpS8FJpHGIvhRHqmkihrTp81YbTv5UPe6V5NWIziXLlQ2/poWXWMpdiekEqc7dO9dq7KWDL/z/KYjVLBymhJyMpJ+qZspJqlVpETnlkh66MfP4ufiCaa/sGq5KSbtNREDTqYUnzINQftOAvsYrKcWtec6fXJWcoi84dW3u3qo0XP3+nKiV8qVXJCz6jGxFIovXRT80XIVcRKUXGmMwrFCejiouf0c5NBy4ysj37CtPp804XPwVXOofOH6CyZQ3Y8GYWTfINnzmTy3cmcnYhByGRDSslmpUUOZlsfPVrrj6yPfuK0/fVYTfgxoD8aWR/9pGn+u7Ga8ONAfzSyPvrJs+oTBmvCL7Lzp47VWiPro58yLb4wVhNugf5oZH30U2fxG6wJPx3oj0bWRz9tWn3RWE342UB/NLI++umz+A3WhF8A9Ecj66OfMev+HawJ39VHD9ZaI+ujnzmtv2usJvwMoD8aWR991rT66LGa8POB/mhkffSzpu2fx2rCt/XRo7XWyProZ0+rjx6rCT8H6I9G1kc/Z9bzY7Am/HI7/8JYrTWyPvrsRfKbwDglPR7I77mL8APG2eiJQH7PW4QfME5ETwbye/4i/IBxDnoqkN85i/ADntPp6UB+L1iEH/CcSc8E8nvhIvyA5yR6FpDfuYvwA+7z6TlAfi9ahB9wn0rPBfJ78SL8gPssej6Q30sW4QfcJ9ALgPzOW4Qf8DlH5wL5vXQRfsB1ml4M5PeyRfgB1xk6D8jv5YvwA94n9DIgv1csUl/+vcC6R+CcoS0/GaXy0eZkndDCc4qiKe05bS9rcpxPbT2jFbz0hgPnSSnda4A4o690iVFae0h+33dE+KHrjfu8+74D1I1e6CSvsz7UuL//JB93vy7ff4BxX3iR+vIfOKLrxGh9eb++P3CAefO+WfUxnAYPMYdimkutVlmi5sxckDx6zt0mTgzrnuLVuvnaa+CK9S5roxlYJSG39eXCVJ0zj0FKKz0PlWwT1fC35EywJ1WEC7EkYWMquTrHfzc1n4rlzLTnS4WsL3//rP2h5g9arLaNDGeBQ0rMydbEeczomiSeRYVCr13wzUeejp6nmfUqJx9rbHbn3+bhpRy6Zd6rPtdVrDYX3aIwuRepE+VMzhvPaJ3giWt0r/q10fJtYSOyvvwDs/LrRRUTgmsiJseTS5cgG991tdfLGBJO9k/G92VRQnMOnHE7Xgf4XlfEX0zb+vLRXglkffkHp9Xnj9XUHwP6y5H15f88a/4N1tQfB/rLkfXlH5pW3zZWU7+rLx+sVUfWl//LrOfvYE29BfrLkfXl/zpr/RusqT8d6C9H1pefP4vfYE392UB/ObK+/MOz7t/BmvoLgP5yZH35v01b/8Zq6rf15aO16sj68o9Mq48eq6k/A+gvR9aX//u09W+spv58oL8cWV/+0Wnzb6ymfuffHqxVR9aXf2zW+jdYU38O0F+OrC//+LT6/LGa+p1/e7BWHVlf/olp/YVjNfXI+vL3Afl9cpH8MDBOSR8A8rtgEX7AOBv9M5DfpxbhB4wT0b8A+X16EX7AOAedD+T3mUX4Ac/p9G9Afp9dhB/wnEn/DuT3uUX4Ac9J9DEgv+OL8APu8+kTQH6fX4QfcJ9KFwD5fWERfsB9Fn0ayO+Li/AD7hPos0B+X1qEH/A5R8eB/L68CD/gOk1fAPL7yiL8gOsMfQnI76uL8APeJ/QVIL+vLVKffxFg3ShwztDXdteCOOfnOKLeE6zGZC85wa9yLFFwFpGTCcGYHtLl/Db16gjKnuPjsofac5T1kPx+8IjwQ9dr93n3gweou73oSV6nfqhx/9BJPu5+XX7oAOO+2CL1+Rc/ouvEaH1+v74XP8C8udTlJuXnSDobomy2cpJT8JjJ29xyivy5OPdZJWcmA3FGvDTGYXN2SvmcWmu9dqjs6vM5XWkzp0o5GaqE4qSybIUcVf4lzhS3qFVKwhdOy2dbtK9emFQj5+D595OtyPr8S8/ix4lvpZ0UWonoSqnScG5XUu3Vf9bz1LFOJ6mb1FKSECr3qlNfcwlJ2FB39fmhpcRYdQzS8TQmlZO1OpIL1gijlKhKRSMaJ4OF0dJEnptWySKMDFYUZH3+ZSbxk8mnVmqvDKT+t1PQ3vJo+ENZvq9NSc5UnkVWRaZjXEuKaknNeibYpNrW54/2miDr8y87i99gT8IxoD8fWZ9/ucvNem6O9SQcB/rzkfX5l581/wZ7Erb1+aO1/sj6/CvMen4M9iRYoD8fWZ9/xUn8RnsSTgf685H1+VeaxW+wJ+FsoD8fWZ9/5Vn372BPwgVAfz6yPv8qs/gN9iRs6/NHa/2R9flXnXX/DvYknAH05yPr80+btX8Z7Ek4H+jPR9bnX20Wv8GehF19/mCtP7I+/+rT9s9jPQnnAP35yPr8a0yLH4z1JGzr80dr/ZH1+dec9fwY7Ek4E+jPR9bnX2va+WPoBwHjvLSNeY7yu/Yi/IBxSroskN91FuEHjLPR5YH8rrsIP2CciK4I5He9RfgB4xx0ZSC/6y/CD3hOp6sC+d1gEX7AcyZdDcjvhovwA56T6BpAfjdahB9wn0/XAvK78SL8gPtUug6Q300W4QfcZ9H1gPzEIvyA+wS6AZAfLcIP+JyjGwH5yUX4AddpugmQn1qEH3CdIQLy04vwA94npID8zLT6obHPeQlg3S1wztCWn1Qc8K21cgLQkeUhOBE5TZuDTZwhizrJrFrjpLTXvVTRctKHc4xKCakocMT8kPwueUT4oevd+7y75CHqlk/yOv9DjfvSJ/m4+3W59AHGfZlF+hsue0TXidH+hn59L3uAeXPbWfubwkngVluw2XspJOfCk8lSZeUKM666Vyxwqj26rBLFamyjkFMQnHuPPsVtfwMxKpUt55h9bjFYTpFmJ42jxN+fgSRDOQRlOD1MJkTfFCefvYrBtepFlcj+ht+cVl8konUUWq8nUtU6pcmKmr3xjpp1vaCKc+o8k6oRPBonlWbmjbLlDLpy2/4GEYS2LmTOCUdrfS2MR2RO1/cJnIKJWpjCOfrcp3nyJEsv+BL8TV3iaU7I/obbzavv+P/fUZFF5OHHmq1Omv+p+R4kHq2SPmQpXFGGf5SQObtONZbS2Xi5628Y7NVB9jf81qz6wMGejmPA9zcg+xt+e9b9O9jTcRz4/gZkf8PvzLp/B3s6dv0Ng70SyP6G351WXznW02GB729A9jf83qz1b7Cn43Tg+xuQ/Q2/P2v9G+zpOBv4/gZkf0OcxW+wp+MC4PsbkP0Nadb9O9jTsetvGOyVQPY35Gnr31hPxxnA9zcg+xvKtPr8sZ6O84Hvb0D2N9Rp699YT8e+v2GsVwLZ39Cmzb+xno5zgO9vQPY3/MGs9W+wp2Pf3zDWK4Hsbzh9Wn/IWE/HmcD3NyD7G/5wWn/rWE8Hsr/htsD88B8tkl8HxnnpdkB+f7wIP2Cckn4byO9PFuEHjLPR7wL5/eki/IBxIvp9IL8/W4QfMM5BCcjvzxfhBzynUwHyu/0i/IDnTGpAfndYhB/wnESnA/ndcRF+wH0+/RGQ350W4Qfcp9KfAPndeRF+wH0W/RmQ310W4QfcJ9Dtgfzuugg/4HOO7gjk9xeL8AOu03RnIL+7LcIPuM7QXYH87r4IP+B9QncD8rvHIv0hlwPWLQPnDG35SW9jrdlkzcF0co4Tzn14uqUkGudhu7C6euErScEpxJ5icJxQSJzEFvzb5pD8Ln9E+KH7Bfq8u/wB6r6vcJL3SRxq3Fc8ycfdr8sVDzDuKy3SH3LlI7pOjPaH9Ot75QPMm7Om7W9aysmSkDUXUzl7m1twpXDyspZeouYdp8oNyeCC01kHyWREsD6ZqoMSu/4QX6hYy+M4kWSuoXI2WSjDKftkUuJUqqrVZc7TcyraNc4da0YvrCuc0a/ZIvtDnjWvv6aXQDrllaw1eVGNSJkzxYpnpOCMefaKf8mnKn1wtjhOnjfpPMmUjDPhtTt+snfRuOb6G16CdqrJpDR/JfG0LjFor0ziK0RSpxZb5C81pkaenE2J4JH9Ic+exS+Ioj3xP2o0fF9Hb6uoUuZUvOkvuCiyeMGfVxpnm8xea5LRZkWUgtJm2x8y2uuE7A95zqz6hMGemGPA94cg+0POnlUfM9gTcxz4/hBkf8hzp53vxnpidv0hg70myP6Q503rjxvribHA94cg+0OeP2v9G+yJOR34/hBkf8g50/Z/Yz0xZwPfH4LsD3nBLH6DPTEXAN8fguwPeeG0+sqxnphdf8hgrwmyP+TcWfwGe2LOAL4/BNkf8qJp/f1jPTHnA98fguwPefG0/taxnphtf8horwmyP+Ql0/pDxnpizgG+PwTZH3LePL/EUE/Mtj9ktNcE2R/y0mn9IWM9MWcC3x+C7A952aznx2BPzLY/ZLTXBNkf8vJF8uvAODk9C8jvFYvwA8Z56TlAfn+5CD9gnJKeC+T3ykX4AeNs9Hwgv79ahB8wTkQvAPJ71SL8gHEOOhfI79WL8AOe0+nFQH6vWYQf8JxJ5wH5vXYRfsBzEr0MyO91i/AD7vPpFUB+r1+EH3CfSq8E8nvDIvyA+yx6FZDfXy/CD7hPoNcA+b1xEX7A5xy9DsjvbxbhB1yn6Q1Afm9ahB9wnaE3Avm9eRF+wPuE3gTk95ZF+muuAqz7Bs4Z2vLjgbiemSmcP1A2K867cJLQ5R5LTz5y/o/TEkbWXrLig9FN8s985kg8Jxh1U4fkd9Ujwg/db9Hn3VUPUDd/2kneZ3KocV/tJB93vy5XO8C4r75If801jug6Mdpf06/vNQ4wbz49qz6rNRcr9VqLqGIxZJgV6WJMqyq46GxVslrOvdeYhY4lNd0LLhsniSXniHf9NclWr4jzwYoCGWVVCCX0Ule+bJxLNqqUlgKnjB2n3Fuv0tKhxagkJ/AZObK/5jOz9oet8ERwledFUDwtOC1eM1XvTa+ud7LpyL/kqsv8jbTkEfvM/Eg4R9lG2r1/JfogTc1amCRbkNHIGDh93nHpXIPyVEVulpQIWbreOVFLcqpUG/h3I7K/5rOz6jtc87LX5JM0VrrKA3eRnDQpJCFs4puR+GuytiGoImqsqdcWiGCFN8HUXX/NYK8Ysr/mc/P6u4Z6io4B31+D7K85Pmv9G+wpOg58fw2yv+bz89a/oZ6ii+xq6sd6dZD9NV+Ytf4N9hRZ4PtrkP01X5xW3zvWU3Q68P01yP6aL81a/wZ7is4Gvr8G2V/z5Vnr32BP0QXA99cg+2u+MovfYE/Rrr9msFcH2V/z1Vn372BP0RnA99cg+2u+Nm39G+spOh/4/hpkf83Xp/WHjPUU7d6/Mtirg+yv+ca09W+sp+gc4PtrkP0135w2/8Z6inbvXxns1UH213xr1vo32FN0JvD9Ncj+mv+Y1p801lO0e//KYK8Osr/m29P6q8d6ipD9NZ8G8vvPReoTgHFy+iyQ338twg8Y56XjQH7/vQg/YJySvgDk9z+L8APG2ehLQH7/uwg/YJyIvgLk951F+AHjHPQ1IL//W4Qf8JxO3wDy+3+XX4Mf8JxJ3wLy+65F+AHPSfRtIL9TFuEH3OfTfwH5nboIP+A+lf4HyO+7F+EH3GfRd4D8vmcRfsB9Am2fmaP8vncRfsDnHJ0C5Pd9i/ADrtP03UB+F1qEH3Cdoe8F8vv+RfgB7xO6EJDfhSfxG/2c1wTWzQPnDG35SdmL5Tn/bFwsMafMuX3lfC7BCxmjbi1oGXy0teXCSUKKukROFYrgTUyhHZLftY4IP3S/Sp931zpA38G1T/I+nUON+zon+bj7dbnOAcZ93UX6k653RNeJ0f6kfn2vd4B5IyY9n2VwLvbCGM/5dGWVEEryR3GWbPMkQ/H82V30UUsG65pM5FVryQZy0Sjz6t37L0gnIzlX7qIMWar+4h/nTPOMMtaY+FtEL5PnC8KXMWsRkuVEfGwyN5Mqsj+JZu0Pm1WRp4/TrVTrmyvWmyyTphM1H6JX/JHX0QTttHY8aXQqgQGGUPk3d+//kUZqlVSOPnivrdeBiSlhPP8ZQzkay4RrIOJrIHyOPGSpZRG9RYlz+gbZnyRnzT9JvTDGxyJaq84wQ99ydSSqscXYpHpnh9G+tZg9Na1lTsKpXvnsaovb/qTRXjtkf5Kadj4Z68k6Bnx/ErI/SU/iN9qTdRz4/iRkf5KZdf8O9mRt+5NGe52Q/Ul22vl4rCfLAt+fhOxPcrPm32BP1unA9ych+5P8rPVvsCfrbOD7k5D9SWHa83esJ+sC4PuTkP1JN53Fb7Ana9ufNNrrhOxPutms+3ewJ+sM4PuTkP1JN5/Fb7An63zg+5OQ/Um3mHX/DvZk7fqTBnudkP1Jt5y1fxnsyToH+P4kZH/SrabFD8Z6snb9SYO9Tsj+pFtP2z+P9WSdCXx/ErI/6Taz+A32ZG37k0Z7nZD9ST886/kx2JN1FvD9Scj+pB9ZpD4BmGcgAtYn/Ogi/IBxclJAfj+2CD9gnJcMkN+PL8IPGKckB+T3E4vwA8bZKAD5/eQi/IBxIroZkN9PLcIPGOegWwD5/fQi/IDndLoVkN/PLMIPeM6k2wD5/ewi/IDnJPoRIL+fW4QfcJ9PPwbk9/OL8APuU+kngPx+YRF+wH0W/RSQ3y8uwg+4T6CfAfL7pUX4AZ9z9HNAfr+8CD/gOk2/AOT3K4vwA64z9EtAfr+6CD/gfUK/AuT3a4v0d10f2HcAnDO05cdJK85B5KR1L0bk/GEmzorxQG3NsknbIuf0Re1NAfwLXkfRpCJOzhinOItoD8nvBkeEH7rfp8+7Gxygb+OGJ3mf06HGfaOTfNz9utzoAOO+8SL9XTc5ouvEaH9Xv743OcC8udes+jbOpCftZDEpRddq74WTJRshffKtNqtMlCK3YG3PhFfZOE2upBalimpi2PZ3SZWDkClkHnWKPkZdam7RKMEXoqZgU+jtSL0KMXFmL8leLqOVsSHraI1H9nfde1p9R9VJJd1rOirPIR5O1UEa63TsXRxEUjutFJlmktKBqiRVY9VCZqu82/V3aeej4TlmZdBC8ASsTiRLlr8rKf7NWs2JApAYepuJ055UjIaKDZHviYrs77rPLH7KUU5Z+JglUVAxRb7zTGRCku92KzxPqRx7jwjxYEzphZIi+1SbU1mXbX/XaK8isr/rvrPu38GetmPA93ch+7vOmHW+G+xpOw58fxeyv+t+054fYz1t2/6u0V4xZH/X/af1B4/1tFng+7uQ/V0PmNafPtbTdjrw/V3I/q4HTqsvH+tpOxv4/i5kf9eDZq1/gz1tFwDf34Xs73rwrPVvsKdt19812CuG7O96yCx+gz1tZwDf34Xs73rorPt3sKftfOD7u5D9XQ+btv6N9bRt+7tGe8WQ/V0Pn9afNNbTdg7w/V3I/q5HTFv/xnra9v1dY71iyP6uR06bf2M9bWcC39+F7O961Kz1b7Cnbd/fNdYrhuzvevS0+OlYT9tZwPd3Ifu7HjOtv3+spw3Z33UvYH3CYxep7wDmGeg+QH6PW4QfME5OZwD5nbkIP2Ccl+4P5Pf4RfgB45T0QCC/JyzCDxhnowcD+T1xEX7AOBE9FMjvSYvwA8Y56OFAfk9ehB/wnE6PBPJ7yiL8gOdMejSQ31MX4Qc8J9Fjgfyetgg/4D6fzgTye/oi/ID7VHoCkN8zFuEH3GfRk4D8nrkIP+A+gZ4C5HfWIvyAzzl6GpDfsxbhB1yn6RlAfs9ehB9wnaGzgPyeswg/4H1CzwbyO3uR/jgB7NsAzhna8ZNFk+pVNiIUzvIIYUwvgeX0RPYye8d5Gl2z50xkz82KEmpqkpLllBdn1NQh+dER4Yful+rzjg7Q9yJP8j6xQ41bneTj7tdFHWDcepH+OHNE14nR/rh+fc0B5s3bZ9UnuJRLcK60yIPkj9frPGTLUkcner2VDa4J8kETRa9s9clbq10Systg7bY/joqtunA6XihLtcrQ23Z8lsWL4Mi11EySvRGpv87LhuAViSCSlr1aQSmF7I97x6z6BNGyaWS0bZbHYHlWBleclCbzQH0QMWVheMa24Ivh+Zs05d5gGKTpPWCv3b1/yupSciqBr4W0lAJ/PymaMzXwpCRddFLSNFOErXwvWM9fnw1fq9wrZKHvP3vnrP21JkM+CeuoyhSiT1mFzDNFFJmj7gV9PARJWTnZP6CU/OuVUk08b7Tb9ceN9noi++PeNa0/ZKwn8Bjw/XHI/rh3TzvfjfUEHge+Pw7ZH/eeWevfYE/gtj9utNcO2R93bNb9O9gTaIHvj0P2x713WnxhrCfwdOD745D9ce+bNf8GewLPBr4/Dtkf9/5Z699gT+AFwPfHIfvjPjDt+TvWE7jrjxvstUP2x31wFr/BnsAzgO+PQ/bH/fO0+vKxnsDzge+PQ/bHfWgWv8GewG1/3GivHbI/7l9m3b+DPYHnAN8fh+yP+9dp/f1jPYHb/rjRXjtkf9z50/rjxnoCzwS+Pw7ZH/fhafvnsZ7AbX/caK8dsj/u36b1x431BJ4FfH8csj/uI7OeH4M9gdv+uNFeO2R/3L8vUt8BzNPQO4D8ProIP2Cegd4F5PexRfgB4+T0HiC/jy/CDxjnpfcC+X1iEX7AOCW9H8jvk4vwA8bZ6INAfhcswg8YJ6IPAfl9ahF+wDgH/SuQ36cX4Qc8p9OHgfw+swg/4DmTPgLk99lF+AHPSfRRIL/PLcIPuM+njwP5HV+EH3CfSp8E8vv8IvyA+yz6FJDfFxbhB9wn0GeA/L64CD/gc44+B+T3pUX4Addp+jyQ35cX4QdcZ+iLQH5fWYQf8D6hLwP5fXWR/kIL7HsBzhna8uN8TknRB+VyKq3wIHpVTxQpRVKRjPCczuecTGnGJpF7ObFKhpNcnBHiLzzo+/fcEeGH7jfr884doG/In+R9docadzjJx92vSzjAuG+6SH/hzY7oOjHaX9iv780OMG+ucIVJ+xuK0ecSrW8+Oul9LeS90LHqZmX/hFRM6q2BQSeywUSdY8ghKxNNcHXbXyhyyqrUXmSkSZVoZGy52sw4PfMy/JeU7Km2qGMw2chkXYw1ieKSVVEg+wuvOIkfeV4zeS4yNs0DlMaVGoNUgqQOITIL2etxyeuqmWBoNjadpAtZeMoh7foLk6+VJ5WN3hhdnPBW8QhLyyo451oyrg9Sy+is57+EyDW+PErzfVKkssj+wivN4heUEVlHnmx8I2ffRPayZl1TraWQykLmIoo0JnitXBRFkOi3Y+Q51Sju3r832CuL7C+88ix+gz2Vx4DvL0T2F15lFr/BnsrjwPcXIvsLrzrr+THYU7nrLxzsVUT2F5427f4d66m0wPcXIvsLrzZr/g32VJ4OfH8hsr/w6pP4jfZUng18fyGyv/Aas/gN9lReAHx/IbK/8Jqz1r/Bnspdf+FgryKyv/Bas9a/wZ7KM4DvL0T2F157Fr/Bnsrzge8vRPYXXmfW/TvYU7nrLxzsVUT2F1532vo31lN5DvD9hcj+wuvNev4O9lTu3r832KuI7C+8/rT1b6yn8kzg+wuR/YU3mDb/xnoqd+/fG+xVRPYX3nBa/HSsp/Is4PsLkf2FN5o1/wZ7Knfv3xvsVUT2F9541vwb7KlE9hducz6j/G4y6/kx9oOAeRq6EpCfWIQfMM9AVwHyo0X4AePkdBqQn1yEHzDOS1cH8lOL8APGKemaQH56EX7AOBtdG8jPLMIPGCei6wL52UX4AeMcdH0gP7cIP+A5nW4I5OcX4Qc8Z9KNgfzCIvyA5yQSQH43XYQfcJ9PEsjvZovwA+5TSQP53XwRfsB9Flkgv1sswg+4TyAP5HfLRfgBn3N0UyC/Wy3CD7hO082B/G69CD/gOkO3BPK7zSL8gPcJ3RrI74cn8RveJwD7hoBzhrb8iPP8ynL+tQiVI+e0OPsfevuF5DxhLEFzWlXL7G0mzv6oXgdESctmtJdJqnZIfrc4IvzQ/Xp93t3iAH1XtzzJ+xQPNe5bneTj7tflVgcY960X6c+8zRFdJ0b7M/v1vc0B5s2fzNrfBOudoGyZGv+fD6barGqjDraJkH2vepG19AIg40PJMhZhVZONkSf96l1/XCi9bkGLwn+66ESxSMMXh/8gOWVNbp5hpuhzM1Zb6gU4yXlrvOQLRMj+zD+dVd+RWpO1l/oV24S2LjqeiY3IOBWoRpuy6p1txlrralFWUxatSiuoKuX8rj8zRC1CVVal3iHWfHCM05haqym9xLrl3vMaTCslN+YmersJWSWVT0I6ZH/mn83iJ12qMrZoknfFu156xpNEkrM8u1pKvYo8lSCLzsF7l2yLoVrHGZzUb9ptf+ZorzGyP/PPZ9VnDfakHgO+PxPZn3n7af1JYz2px4Hvz0T2Z95h2vl4rCd125852uuJ7M+846z1b7An1QLfn4nsz7zTrPt3sCf1dOD7M5H9mXeeFp8Z60k9G/j+TGR/5l1mzb/BntQLgO/PRPZn3nXW+jfYk7rtzxzt9UT2Z/7FtOfvWE/qGcD3ZyL7M+82i99gT+r5wPdnIvsz7z6tv2GsJ3XXnznY64nsz7zHLH6DPannAN+fiezPvOes+3ewJ3XXnznY64nsz7zXNL/EWE/qmcD3ZyL7M+89rT9zrCd115852OuJ7M+8z7T981hP6lnA92ci+zPvO60/c6wnddufOdrriezPPGPW82OwJ/XtwPdnIvsz77dIfQwwz0V/CuR3/0X4AfM09OdAfg9YhB8wz0B3APJ74CL8gHFyuhOQ34MW4QeM89JdgPwevAg/YJyS/gLI7yGL8APG2ejuQH4PXYQfME5E9wTye9gi/IBxDro3kN/DF+EHPKfTfYH8HrEIP+A5k+4H5PfIRfgBz0n0ACC/Ry3CD7jPpwcB+T16EX7AfSo9BMjvMYvwA+6z6GFAfo9dhB9wn0CPAPJ73CL8gM85ehSQ35mL8AOu0/QYIL/HL8IPuM7Q44D8nrAIP+B9Qo8H8nviIv2tPwzsuwLOGdryo8yZ/5RDq6kXJ5LhRJgtSrWoiWpqLXjBGS7P2f8UebBKW06ecX7Q1aAYyyH5/cgR4Yfud+zz7kcO0Lf2oyd5n+ehxv1jJ/m4+3X5sQOM+8cX6W/9iSO6Toz2t/br+xMHmDdvnrW/SR2Wdi2QYkpVpt5bQyRLDalSKCGmFI1vkZqPgT+osy36nJXjC2DSrr9V5Sg0GTKtFplsrL1ghHoFr2xNKFtSNaR0U05HZ3zRtdd6yXSidlhmZH/rW2bVp/LfaUnw3Oh9Qj7ZzLPOGtFrZIpRPjsdSjHJV2fIZ1WdcDynhO01a0Hu3z9qksvapkZFkdPaEX/byFOvWso1iGKT1kaImL1OpojURM1VuNaYhZAG2d/6t7Pqs0i36JJuFJ0gFbNQtRQbHDMlxdNSatI1Bs/4GGLUsUjXu2CF1tQc7fpbB3u1kf2tfzfr/h3s6T0GfH8rsr/17+fdv0M9vceB729F9rf+wyx+gz29u/7WwV5ZZH/rP866fwd7ei3w/a3I/tZ/mnb/jvX0ng58fyuyv/Wts+bfYE/v2cD3tyL7W982zY8w1tN7AfD9rcj+1rdP668Z6+nd9bcO9soi+1vfMWv9G+zpPQP4/lZkf+s7Z61/gz295wPf34rsb33XLH6DPb27/tbBXllkf+u7Z92/gz295wDf34rsb33PtPVvrKd329862iuL7G89Nq0/c6yn90zg+1uR/a3vnbb+jfX07vtbx3plkf2t75s2/8Z6es8Cvr8V2d/6/lnr32BP776/daxXFtnf+oFp/cFjPb1vB76/Fdnf+sFpfpOxnl5kf+ubgfz+eZH6ImCei/4WyO9Di/AD5mno74H8/mURfsA8A/0jkN+/LsIPGCentwL5nb8IP2Ccl94O5PfhRfgB45T0TiC/f1uEHzDORu8G8vvIIvyAcSI6BuT374vwA8Y56H1Afh9dhB/wnE4fAPL72CL8gOdM+mcgv48vwg94TqJ/AfL7xCL8gPt8Oh/I75OL8APuU+nfgPwuWIQfcJ9F/w7k96lF+AH3CfQxIL9PL8IP+JyjTwD5fWYRfsB1mi4A8vvsIvyA6wx9Gsjvc4vwA94n9Fkgv+OL9Af/JLBvDThnaMuPfK8Jqzb2qiaSQrdqKOjU65paFkJ53WIpnIPMKdTajE9SnqjF1YGqMIfk91NHhB+6X7TPu586QN/fT5/kfbKHGvfPnOTj7tflZw4w7p9dpD/4547oOjHaH9yv788dYN5c5oqT6juKz86K3Fv8stRK5WCrsKb3Yvve75sCNemkTak2b3rtpCuq93hRUkq3bX9wfx2fb0pRIlN7uWuTqfkqKRXfrOTLUPnfko7KCqNCbE6Sa82RLzmEapH9wZedxE+2oKLKtTllUrE6Np+UM171MuiUko+9ZU6IKmJ1sXgKfZbKFDxPzaTotbv+zBKkUzZLa6x15KpItqSinUy9YpXBF58YStHaKpF5xlZZs9HByv4+aGR/8OVmzT8TBUWdq7XKWc//8D40aq72GiwqMpQYe4W4CU1lLZuyxnitKHjVgpS7/uDBXndkf/DlJ/Eb7Yk+Bnx/MLI/+Aqz7t/BnujjwPcHI/uDrziL32BP9LY/eLTXGNkffKVZ9+9gT7QFvj8Y2R985VnPj8Ge6NOB7w9G9gdfZdb9O9gTfTbw/cHI/uCrTuI32hN9AfD9wcj+4NNmzb/Bnuhtf/BorzGyP/hqs9a/wZ7oM4DvD0b2B1992vN3rCf6fOD7g5H9wdeYxW+wJ3rbHzzaa4zsD77mrPt3sCf6HOD7g5H9wdeaxW+wJ3rbHzzaa4zsD772rPt3sCf6TOD7g5H9wdeZtX8Z7Ine9geP9hoj+4OvO4vfYE/0WcD3ByP7g683bf881hO97Q8e7TVG9gdffxa/wZ7otwPfH4zsD77BrOfHYE/0tj94tNcY2R98w2nnj6EfBMwT0jZnNsrvRovwA+a56PJAfjdehB8wT0NXBPK7ySL8gHkGujKQn1iEHzBOTlcF8qNF+AHjvHQ1ID+5CD9gnJKuAeSnFuEHjLPRtYD89CL8gHEiug6Qn1mEHzDOQdcD8rOL8AOe0+kGQH5uEX7AcybdCMjPL8IPeE6imwD5hUX4Aff5REB+N12EH3CfSgrI72aL8APus8gA+d18EX7AfQI5IL9bLMIP+JyjAOR3y0X4AddpuhmQ360W4QdcZ+gWQH63XoQf8D6hWwH53WZa/enY5/x5YN8fcM7Qlp9sharWiUfadOSsf6hKcCIweG84DWh9bw/SoUrvXH9/YMzCc35Wi5CqSPqg71/+hSPCD91v2+fdLxygb/IXT/I+40ON+5dO8nH36/JLBxj3Ly/SX/0rR3SdGO2v7tf3Vw4wb/5sWn+rC7LGXkIlqyy97Cq2/7/o0lirpVG6EGkZvIzGSd07KqPWmgqTEN7u3r/cOxVriaJIyrJo/t5J9pZsq7QXxlu+EhSYiJBOC2mjDUkyUwqZyGlC9lf/+bT6wBBNrxUtzRureZAh1iBCr1PtxWqMKbXseRopEsEnoUh5YWur/GU8QXfvX3YtFZFDy5qC6g0gUSdFVL1RQdTipQ46CVsySZFNZoxMVxqtS2xRS2R/9e2n9fdr5WPh6SFLTinLpKQIwUopmuP5ZvgzZmusENWYkl1KPIN0MKkJpYVS2/7qUVcAsr/6DrPOJ4M95ceA769G9lffcRa/wZ7y48D3VyP7q+807fkx1lN+kV1/4VivNrK/+s6z+A32lFvg+6uR/dV3mXX/DvaUnw58fzWyv/qu0+7fsZ7ys4Hvr0b2V//FrPk32FN+AfD91cj+6rtN83OM9ZTv+qsHe7WR/dV3n9bfNdZTfgbw/dXI/up7zFr/BnvKzwe+vxrZX33PWevfYE/5rr96sFcb2V99r1n8BnvKzwG+vxrZX33vafGDsZ7yXX/1YK82sr/6PtPWv7Ge8jOB769G9lffd1r8b6ynfPf+5cFebWR/9RnT1r+xnvKzgO+vRvZX329e/Hmop3z3/uXBXm1kf/X9Z61/gz3lbwe+vxrZX/2Aaf3pYz3lu/cvD/ZqI/urHzjNrzPWU47sr/4zYH3RgxapzwLmCen2QH4PXoQfMM9FdwTye8gi/IB5GrozkN9DF+EHzDPQXYH8HrYIP2CcnO4G5PfwRfgB47x0DyC/RyzCDxinpHsB+T1yEX7AOBvdB8jvUYvwA8aJ6Awgv0cvwg8Y56D7A/k9ZhF+wHM6PRDI77GL8AOeM+nBQH6PW4Qf8JxEDwXyO3MRfsB9Pj0cyO/xi/AD7lPpkUB+T1iEH3CfRY8G8nviIvyA+wR6LJDfkxbhB3zO0ZlAfk9ehB9wnaYnAPk9ZRF+wHWGngTk99RF+AHvE3oKkN/TFulP/1Vg3yRwztCWn3RWqd4JVEKInOtuPtXcep2iNiRbsJxabDZo3yuTTRGhNduUVbLWWESVh+T3a0eEH7pfuc+7XztA3+mvn+R92oca92+c5OPu1+U3DjDu2y7Sn/6bR3SdGO1P79f3Nw8wb946qz5GOh16Y4gUImf+SNK23LKKRpGWwmbv+tuWqcWijZDZN1llqC3nPgxhdu//7q2DPlhpXZJUvaXgZJOmBf4mqre/a6OrUd7LVGwttZFrveqVdM3CQPvT3zatP664UDLPvxosldKMsMXHmHvFm4/WmJZUNjJpkRsjCUU0otAr1XI05Hbv/06akopBBYYSfDal1yWZ/p5vnZTXvWQr19rLLTPjjDY1Hn5KShVHQQlkf/rbZ9W3UaiZWuoN1SqKJr2tOhUZFZ24bVMil0x2ukhLgofKN6O10fhCzihndv3pg64FZH/6O6bV54/15B8Dvj8d2Z/+zln372BP/nHg+9OR/envmnX/Dvbk797/PdjrjuxPf/e0/syxnnwLfH86sj/9PdPiM2M9+acD35+O7E8/Nuv5MdiTfzbw/enI/vT3zrp/B3vyLwC+Px3Zn/6+afHBsZ78XX/6YK87sj/9/bPm32BP/hnA96cj+9M/MGv9G+zJPx/4/nRkf/oHpz1/x3ryd/3pg73uyP70f57Fb7An/xzg+9OR/ekfmtbfNdaTv+tPH+x1R/an/8ssfoM9+WcC35+O7E//11n372BP/q4/fbDXHdmffv40v85YT/5ZwPenI/vTPzytP32sJ3/Xnz7Y647sT/+3afvnsZ78twPfn47sT//ItP70sZ78bX/6aK87sj/932c9PwZ78rf96aO97sj+9I8uUp8FzLPS24D8PrYIP2CekN4B5PfxRfgB81z0LiC/TyzCD5inofcA+X1yEX7APAO9F8jvgkX4AePk9H4gv08twg8Y56UPAvl9ehF+wDglfQjI7zOL8APG2ehfgfw+uwg/YJyIPgzk97lF+AHjHPQRIL/ji/ADntPpo0B+n1+EH/CcSR8H8vvCIvyA5yT6JJDfFxfhB9zn06eA/L60CD/gPpU+A+T35UX4AfdZ9Dkgv68swg+4T6DPA/l9dRF+wOccfRHI72uL8AOu0/RlIL+vL8IPuM7QV4H8vrEIP+B9Ql8H8vvmIv39twP2nQLnDO34mcpZ2UahcV5aV1HIp1qDlS1Gzmv73obSyyR4vKR741+vjaCU+TdCr+I7JL/fOiL80P3efd791gH6dn/7JO9zP9S4f+ckH3e/Lr9zgHH/7iL9/b93RNeJ0f7+fn1/7wDz5ppXmlSfZYyzTVLoHZhBOP6/HKOrMetUtC0yRBWD4LF435QKuTaqqkbriKJqbdvfT95XJ3TyjlKQQppegKRdDa652MuFfYk6JWI0OWiVOu9MVedIzWlsf/+1ZvHrHc4xeR97w1DlnzfJH1TG1ttBemOI6NVa2uUapRW1+uC8z1nLRv3F8dv+frK1aqO9NMIKvhyRYifXO+9qszIUQdIZnbMTvbdBRqclf+9kRe92DxnZ33/tSfzIy+a7SKIl7YM00vnsFDE750RLUpOsTVkZKfRGBM/3ZFVKRBW8lNaVXX//oKsC2d9/nVn8Bp0G2/7+UVcAsr//upP4jToNdv39g64AZH//9WbxG3Qa7N4/P+gKQPb3X3/a/TvmNNj294+6ApD9/TeYxW/QabDr7x90BSD7+2846/4ddBrs+vsHXQHI/v4bTbt/x5wG2/7+UVcAsr//xrPm36DT4Ma7MY+5ApD9/TeZdf4YdBrs+vsHXQHI/n4x7fw25jTY9fcPugKQ/f00a/0bdBrs+vsHXQHI/n45a/0bdBrs+vsHXQHI/n41i9+g02DX3z/oCkD29+tZ9++g02DX3z/oCkD295tp69+Y02Db3z/qCkD299tZz99Bp8Hu/fODrgBkf7+btv6NOQ32/f1jrgBkf7+fNv/GnAa7988PugKQ/f1hWvx+zGmw7+8fcwUg+/tvOmv+DToNdu+fH3QFIPv7bzZr/g06DZD9/duc7Si/m896foz9IGCela4N5HeLRfgB84R0XSC/Wy7CD5jnousD+d1qEX7APA3dEMjv1ovwA+YZ6MZAfrdZhB8wTk4CyO+HF+EHjPOSBPL7kUX4AeOUpIH8fnQRfsA4G1kgvx9bhB8wTkQeyO/HF+EHjHPQTYH8fmIRfsBzOt0cyO8nF+EHPGfSLYH8fmoRfsBzEt0ayO+nF+EH3OfTDwP5/cwi/ID7VPpRIL+fXYQfcJ9FPw7k93OL8APuE+gngfx+fhF+wOcc/TSQ3y8swg+4TtPPAvn94iL8gOsM/TyQ3y8twg94n9AvAvn98iR+o5/z94F9u8A5Q1t+UjUXfa5KtZybbD0Ja5q2iXo5fDTUnIxW5lijTybG3mpFoSQXezmzyofkF48IP3S/fJ938QB9z+kk9wQcatz5JB93vy75AOMui/gR6hFdJ0b9CP361gPMm/tPq88ioYylQqrwX065isRoY9FF1pqiY5zBSmKasmsMXAjW9RaRlHqBaXr1rj/YB0pauKQL/1klGVCXBSRThbDeBkcqumyN8qnwaH3pzf4q1ch/JIuM9CM8YFZ9Fok+D3vrry/FemFKoypaY5ZFacUTr4QcktNaCOVE7eVuxVtZJSVR7daPIJyUsVslcvbBJWn6VBeO+VdnlUmahDOiWMmzPbVqjLKxCC+LOdHoZZB+hAfO2l9nwzdvkEmbLKNLVrkme+ORrSXyHVhkYxy2hJZ7Cy8lW1uzsYbeCyGt3PoRRl0fSD/Cg2bNv0EnxM6PMOhaQPoRHjytP2TMCbHzIwy6FpB+hIfMun8HnRBbP8KoawHpR3jorOfvoBPC7t4/P+ZaQPoRHjatP3jMCbH1I4y6FpB+hIdPi2+NOSG2foRR1wLSj/CIafu/MSfEBbv7d8y1gPQjPHLW/TvohNj6EUZdC0g/wqOmxVfHnBA7P8KgawHpR3j0rPk36ITY+hFGXQtIP8JjZq1/g06IrR9h1LWA9CM8dtrzd8wJsfMjDLoWkH6Ex02LH4w5IbZ+hFHXAtKPcOa0/sIxJ8TOjzDoWkD6ER4/i9+gE2LrRxh1LSD9CE+Ydf8OOiF2foRB1wLSj/DEaX6nMSfE1o8w6lpA+hGeNM2PMOaE2PkRBl0LSD/Ck6ftn8ecEFs/wqhrAelHeMq0/NuYE2LrRxh1LSD9CE+d9fwYdEJs/QijrgWkH+Fpi9S3AfPU9AAgv6cvwg+YZ6UHAfk9YxF+wDwhPQTI75mL8APmuehhQH5nLcIPmKehRwD5PWsRfsA8Az0KyO/Zi/ADxsnpMUB+z1mEHzDOS48D8jt7EX7AOCU9HsjvuYvwA8bZ6IlAfs9bhB8wTkRPBvJ7/iL8gHEOeiqQ3zmL8AOe0+npQH4vWIQf8JxJzwTye+Ei/IDnJHoWkN+5i/AD7vPpOUB+L1qEH3CfSs8F8nvxIvyA+yx6PpDfSxbhB9wn0AuA/M5bhB/wOUfnAvm9dBF+wHWaXgzk97JF+AHXGToPyO/li/AD3if0MiC/Vyzil2jAvmfgnKEtP+msK6F6YQLxJ5c1J5+cqyRbVb0kmUclerOyk5zx1rU65XzoVaOuaKnUIfn9wRHhh/YN9Hn3BwfoGz/9JPcsHGrcf3iSj7tflz88wLj/aBG/xB8f0XVi1C/Rr+8fH2DefGJWfbQryuRmkzA6C5GT7V3oVTrjsk/NeP58ZHvDpSEfKznKIpHQQTsTpZR7vwRfiKYc6VisbzaTzDzc4oNpZA3/K5kWGHA3gZRYanSVx+6Ki8oan5B+iU/O2h9K4bUrPMkitRRbK1U3nZKXWhPPqZRN84JH4HQI1FqsWqveR2wpOx7b1i8hGauvvlCgPrdVOFFA3ms1NfXq1pZbc6kmX2otpZDg2d4k6ZyytUIopF/iglnzT+guNXE2GOdNDKRE8JlKyXzTxuCtEybbYLNLyfGks1JkFXrtfYp9Cdj5JQZdKUi/xKdm1acOOjV2folBVwXSL/HpWfNv0Kmx9UuMuiqQfonPzFr/Bp0aO7/EoKsC6Zf47Cx+g06NrV9i1FWB9Et8btr9O+bU2PolRl0VSL/E8Vn8Bp0aO7/EoKsC6Zf4/Kz7d9CpsfNLDLoqkH6JL0y7f8ecGlu/xKirAumX+OKs+Tfo1DhjN+YxVwXSL/GlaX6iMafGzi8x6KpA+iW+PK2/dcypsfNLDLoqkH6Jr8xa/wadGju/xKCrAumX+Oqs9W/QqbHzSwy6KpB+ia/N4jfo1Nj5JQZdFUi/xNen+SnHnBo7v8SgqwLpl/jGtPVvzKmx9UuMuiqQfolvTvMjjDk1tn6JUVcF0i/xrWnr35hTY++XGHNVIP0S/zFt/o05NbZ+iVFXBdIv8e1Z69+gU2PvlxhzVSD9Ev85zc8x5tTY+iVGXRVIv8R/TfOLjTk1kH6JTwD5/fci9YHAPDVdAOT3P4vwA+ZZ6dNAfv+7CD9gnpA+C+T3nUX4AfNcdBzI7/8W4QfM09AXgPz+35XX4AfMM9CXgPy+axF+wDg5fQXI75RF+AHjvPQ1IL9TF+EHjFPSN4D8vnsRfsA4G30LyO97FuEHjBPRt4H8vncRfsA4B/0XkN/3LcIPeE6n/wHyu9Ai/IDnTPoOkN/3L8IPeE6i7ZlhlN+FF+EH3OfTKUB+P7AIP+A+lb4byO8ii/AD7rPoe4H8fnARfsB9Al0IyO+ii/ADPufowkB+P7QIP+A6TRcB8rvYIvyA6wxdFMjv4ovwA94ndDEgv0tM4jf6Of8E2DcOnDO05Sd7x7jh4XHCWhoeZ6HQeDjRm9x6saM1mrPf1qreuqKN0/z/DMRJb4yI+pD8/vSI8EP7Gvq8+9MD9N3/2UnuqTjUuP/8JB93vy5/foBx334RP8cdjug6Mern6Nf3DgeYNz86a3+TYzY6WR7rCY7W+UJeq9g7OnwuhVLJRetQhVO9h915V2vtHXClazu2fg7ZC/K1aYL/PxdVhLdCuxz5ajmSWckmajZR8U+9raVV0TvEHP9lVG0VFenn+LFJ/MiX6GM1ytXoqxXRiCZ5ctje1ctDtirrGJ33ZJtQOWVffVKWhxZyb9Pc+Tl8L/oLjb+sqcBD5VEXmZpgevxdg7fZ1Bi0FzzZU41ayFS63qSRpJYb0s/x47PmX1OuOXKhGcM3tWiuf0yRmu/Nk5nv45Qj3/jVR5N0DK0Y/j++B5URndLWzzHqmkH6OX5iEr9RJ8nWzzHq+kD6OX5y1v076CTZ+TkGXR9IP8dPzeI36CTZ+TkGXR9IP8dPz1r/Bp0kWz/HqOsD6ef4mVnr36CTZOvnGHV9IP0cPzuL36CTZOvnGHV9IP0cPzctPjjmJNn6OUZdH0g/x8/Pen4MOkm2fo5R1wfSz/ELs+7fQSfJ1s8x6vpA+jl+cVp8esxJsvNzDLo+kH6OX5o1/wadJFs/x6jrA+nn+OVZ69+gk2Tr5xh1fSD9HL8y7fk75iTZ+TkGXR9IP8evTov/jTlJtn6OUdcH0s/xa7Pu30Enyc7PMej6QPo5fn0Wv0EnydbPMer6QPo5fmPW/TvoJNn5OQZdH0g/x21n7V8GnSRbP8eo6wPp5/jNWfwGnSQ7P8eg6wPp57jdtP3zmJNk6+cYdX0g/Ry/NS3/MeYkeevObzLm+kD6OX571vNj0Emy9XOMuj6Qfo7fWaQ+EJjnpx8D1gf+7iL8gHlq+gkgv99bhB8wz0o/BeT3+4vwA+YJ6WeA/OIi/IB5Lvo5IL+0CD9gnoZ+AcgvL8IPmGegXwLyK4vwA8bJ6VeA/Ooi/IBxXvo1IL+2CD9gnJJ+A8jvDxbhB4yz0W8C+Z2+CD9gnIh+C8jvDxfhB4xz0O8A+f3RIvyA53T6PSC/P16EH/CcSRHI708W4Qc8J1EG8vvTRfgB9/lUgfz+bBF+wH0q/QGQ358vwg+4z6I/BPK7/SL8gPsE+mMgvzsswg/4nKM/BfK74yL8gOs0/TmQ350W4QdcZ+gOQH53XoQf8D6hOwH53WURv8kdgX33wDlDW35US/E6eq16lU3SnLgv3jqRmsglupSKDSIaxmBskoqq6IU6JUqRok0qH5LfnY4IP7Tvos+7Ox3AW3Dnk9zzcahx3+UkH3e/Lnc5wLjvuojf5C+O6Dox6jfp1/cvDjBvXjirPvBET351vbBXWdP7HKgUmWsK5KvqUTtbY62yMUuGYo2zxQnhpOT/+rDzmxTvY2qFgnTe5BRdiLGpEDWPWLrYeo91rx1MNejsspeBr4sppWSZXA5Iv8m5s/aHSWTjm5DaJl0FIzCidW5GmlB9INNy8SkXUlJT0DwrU68N107JRrTzm1CoRfcuRZ8zf1kfmTJNN6F7QSWTkynE3GIOOpkojLeqWWkEMZMksX6TF83qbxA++F5Q7zMVX0jqUEKyvXqctNehacmg+BNG6y3/VNmq+Uty4IlDKpqt32TU1YP0m7x4Fr9Bp8vObzLoSkH6TV4ybf0bc7rs/CaDrhSk3+S8WfNv0Omy9ZuMulKQfpOXTnt+jDlddn6TQVcK0m/ysln8Bp0uW7/JqCsF6Td5+bT7d8zpsvWbjLpSkH6TV8ziN+h02flNBl0pSL/JX866fwedLju/yaArBek3eeW0+3fM6bL1m4y6UpB+k7+a5lccc7qcvxvzmCsF6Td51TQ/1pjTZec3GXSlIP0mr57WXz3mdNn5TQZdKUi/yWtmrX+DTped32TQlYL0m7x21vo36HTZ+U0GXSlIv8nrZvEbdLrs/CaDrhSk3+T10/yoY06Xnd9k0JWC9Ju8Ydr6N+Z02fpNRl0pSL/JX0/zc4w5XbZ+k1FXCtJv8sZp69+Y02XvNxlzpSD9Jn8zbf6NOV22fpNRVwrSb/Kmae8XGHO67P0mY64UpN/kzdP8MGNOl63fZNSVgvSbvGWa327M6YL0m7wQWB/4t4vUVwLz/PQiIL+/W4QfME9NLwHy+/tF+AHzrPRSIL9/WIQfME9ILwfy+8dF+AHzXPSXQH7/tAg/YJ6G/grI762L8APmGejVQH5vW4QfME5OrwXye/si/IBxXno9kN87FuEHjFPSXwP5vXMRfsA4G/0NkN+7FuEHjBPRm4H83r0IP2Ccg/4WyO89i/ADntPp74H8ji3CD3jOpH8E8nvvIvyA5yR6K5Df+xbhB9zn09uB/N6/CD/gPpXeCeT3gUX4AfdZ9G4gvw8uwg+4T6BjQH7/vAg/4HOO3gfk96FF+AHXafoAkN+/LMIPuM7QPwP5/esi/ID3Cf0LkN/5i/hh7gb0FgDnDG359UqHKINQXhjytTbfFJGVuXnbC2mtkTZLH4xqKUvtlSDnXe8iSFl4WQ/J7+5HhB/aF9Ln3d0P4H24x0nuSTnUuO95ko+7X5d7HmDc91rED3PvI7pOjPph+vW99wHmzUWvMqm+rWXRe3Z9DdXHXjHuizXZVi11osKUtY9VCx+FSU6pYGQwScmQswtRqZ0fRookYwomB8/MepWvFcyLhLG9FlNRjdWblFyp3mrfSMbA7LUNIjAspB/mhybxk7LVKHQyJbqgg3QxCsu/KBX/tH9WHlnsDhlpahBZCx0qf+4URO8OUWrrh+kdSEVZG2sfkixFCpI+UgxSOh3JatNr83t3RCy1pZaErE3JaEXxJUikH+Zik/gJnmheeOVk85lImd71l10OmpwUkpJowanUqgmO7/QsQvBS1WR7Gw0vCFs/zKjrCOmHufgsfoNOnK0fZtQ1g/TDXGLW/TvoxDm+m39jrhmkH+aSs54fg06cnR9m0DWD9MNcaha/QSfOzg8z6JpB+mEuPWv9G3TibP0wo64ZpB/mMrPWv0Enztm7+3fMNYP0w1x2Fr9BJ87WDzPqmkH6YS436/4ddOJs/TCjrhmkH+bys54fg06crR9m1DWD9MNcYdb9O+jE2fphRl0zSD/MFSfxG3Xi7Pwwg64ZpB/mSrPm36ATZ+uHGXXNIP0wV561/g06cbZ+mFHXDNIPc5Vpz98xJ87ODzPomkH6Ya46Lf4y5sTZ+mFGXTNIP8xps+7fQSfOzg8z6JpB+mGuNovfoBNn64cZdc0g/TBXn3X/Djpxdn6YQdcM0g9zjVn7l0EnztYPM+qaQfphrjktfzTmxNn5YQZdM0g/zLWm7Z/HnDhbP8yoawbph7n2tPzHmBNn64cZdc0g/TDXmfX8GHTibP0wo64ZpB/mutPOH0M/CFgnQduagVF+11uEHzDPTxcH8rv+IvyAeWq6JJDfDRbhB8yz0qWB/G64CD9gnpAuC+R3o0X4AfNcdHkgvxsvwg+Yp6ErAvndZBF+wDwDXRnITyzCDxgnp6sC+dEi/IBxXroakJ9chB8wTknXAPJTi/ADxtnoWkB+ehF+wDgRXQfIzyzCDxjnoOsB+dlF+AHP6XQDID+3CD/gOZNuBOTnF+EHPCfRTYD8wiL8gPt8IiC/my7CD7hPJQXkd7NF+AH3WWSA/G6+CD/gPoEckN8tFuEHfM5RAPK75SL8gOs03QzI71aL8AOuM3QLIL9bL8IPeJ/QrYD8bjOt/n7sc94H6H0Azhna8dOUiKxyQpLMVlbL/0daa3uiIU+56nvfHv92L5ONLsogC6XUm3q81+WQ/O57RPihfSt93t33AN6MM05yz8yhxn2/k3zc/brc7wDjvv8ifp0HHNF1YtSv06/vAw4wb+46rT6Qz/WlFssYdA3eq2QpGf5Thcn42ntjEukWep8ShV6I2Z0xsstPhK5669cRObhSgyXtyAdTkszFpxILU0uqKeecMpljT4X4L2pdRdHIOOVPVGAmj/Tr/MW0+vwinEtW2MhDijaEkLv3hUEl0YRmmDxJi1S2qqBbF03wnE2lReUN6bj160jd24mrjDpaIh6YKqa3a8cSa1DWm0hSn/Co2CJtTS0lUbUrxrmOIiD9Oneb1R/iasoyVe2pBi16T5dSVvcm1lJjMpJsEKnKoKS0wWbVmF0ViVzkSaXF1q8z6opC+nXuPqs+etApdGx3/465epB+nXtMm39jTqGdX2fQ1YP069xz2vwbcwrt/DqDrh6kX+des+bfoFNo69cZdfUg/Tr3nvX8HXQK7fw6g64epF/nPrP4DTqFtn6dUVcP0q9z32n375hTaOvXGXX1IP06Z0zze445hXZ+nUFXD9Kvc79Z9++gU2jn1xl09SD9Ovefdv+OOYW2fp1RVw/Sr/OAWfNv0Cl0892Yx1w9SL/OA6f52cacQju/zqCrB+nXedC0/v4xp9DOrzPo6kH6dR48a/0bdArt/DqDrh6kX+chs9a/QafQzq8z6OpB+nUeOovfoFNo59cZdPUg/ToPm+bnHXMK7fw6g64epF/n4dPWvzGn0NavM+rqQfp1HjHNDzPmFNr6dUZdPUi/ziOnrX9jTqG9X2fM1YP06zxq2vwbcwpt/Tqjrh6kX+fRs9a/QafQ3q8z5upB+nUeM81PNOYU2vp1Rl09SL/OY6f5FcecQki/zl2B9ZWPW6Q+FVgnQXcD8jtzEX7APD/dA8jv8YvwA+ap6V5Afk9YhB8wz0r3AfJ74iL8gHlCOgPI70mL8APmuej+QH5PXoQfME9DDwTye8oi/IB5BnowkN9TF+EHjJPTQ4H8nrYIP2Cclx4O5Pf0RfgB45T0SCC/ZyzCDxhno0cD+T1zEX7AOBE9FsjvrEX4AeMcdCaQ37MW4Qc8p9MTgPyevQg/4DmTngTk95xF+AHPSfQUIL+zF+EH3OfT04D8nrsIP+A+lZ4B5Pe8RfgB91l0FpDf8xfhB9wn0LOB/M5ZhB/wOUdnA/m9YBF+wHWangfk98JF+AHXGToHyO/cRfgB7xN6IZDfixbxEz0Q6M0Azhna8SNjTMslNyFLEKFX7AXjiVIuMpOXqlGWujTpKVEkm62vzodsazEqx0Pye9AR4Yf21fR596ADeEcefJJ7eg417oec5OPu1+UhBxj3QxfxEz3siK4To36ifn0fdoB587FZ+5vcNNlmtLfCOGVSr0H1qSXNI88kpW/a1cQfU9ssmalMNbTgjCjJNSe2fiIeZfVZxCKycUnFrlyIhcGpLiWKgVzQ2VRDvYEkm6SMJmmybsLEIktD+ok+Po1fn4pJCEbkkpEpp2hM4AnTWxCc9LWV7trxoRudnNYle55WsjBJk7Pa+Ymqrky18pVIhmdu7V120vd2h1K11kG63p7pdNHNuShSyaHGIK3TNUYtkX6iT8zi15sOgsk1STrhZSpOtWqaM5HvZxl07UW9xcQmusLDqspfkHyNHVEoOz/RqGsL6Sf65LT+/jEn09ZPNOo6QvqJLph2/445mbZ+olHXEdJP9Klp9fljTqatn2jUdYT0E3161v076GTa+YkGXUdIP9FnpvVnjjmZdn6iQdcR0k/02Vnr36CTaesnGnUdIf1En5u1/g06mS7Y3b9jriOkn+j4ND/HmJNp6ycadR0h/USfnxafHnMybf1Eo64jpJ/oC7OeH4NOpq2faNR1hPQTfXHW/TvoZNr6iUZdR0g/0Zem5UfGnEw7P9Gg6wjpJ/ryrPk36GTa+olGXUdIP9FXZq1/g06mrZ9o1HWE9BN9ddrzd8zJtPMTDbqOkH6ir82Lnw45mbZ+olHXEdJP9PVp/f1jTqadn2jQdYT0E31jFr9BJ9PWTzTqOkL6ib456/4ddDLt/ESDriOkn+hb0/yKY06mrZ9o1HWE9BP9xzQ/0ZiTaecnGnQdIf1E3562fx5zMm39RKOuI6Sf6D+n5T/GnExbP9Go6wjpJ/qvWc+PQSfT1k806jpC+on+e5H6VGCdCX0cyO9/FuEHrJOgTwL5/e8i/IB5fvoUkN93FuEHzFPTZ4D8/m8RfsA8K30OyO//XXUNfsA8IX0eyO+7FuEHzHPRF4H8TlmEHzBPQ18G8jt1EX7APAN9FcjvuxfhB4yT09eB/L5nEX7AOC99E8jvexfhB4xT0n8A+X3fIvyAcTb6TyC/Cy3CDxgnov8G8vv+RfgB4xz0v0B+F16EH/CcTv8H5PcDi/ADnjNpe+Ya5XeRRfgBz0l0KpDfDy7CD7jPp+8B8rvoIvyA+1T6PiC/H1qEH3CfRd8P5HexRfgB9wn0A0B+F1+EH/A5Rz8I5HeJRfgB12n6ISC/Sy7CD7jO0MWB/C61CD/gfUKXBPK79CR+w++hBHpHgHOGtvwoi16InZSMNcTcRNSKnI3atkzFJhd17jXetvWqqFBq6iV7QccTZVWtHJLfI44IP7Tvp8+7RxzA2/LIk9xzdKhxP+okH3e/Lo86wLgfvYjf6TFHdJ0Y9Tv16/uYA8ybn530fJY84pKl1C0Gr53JjooO3pqcsqFSG/9UKmFU0J5iN8LY3toRqTUrfTNbvxP1lrposze2NyWGXERLJjXSTRZhZNVC5d6f3pusVe5V+k04ktkx8FoK0u/0c5P4UUzFVBtKJitll46Q7m4naXJ10ZbeJ+KMiKXIYH3MVG0OQufGc1aZ4Ld+J8GTMVAspnnJE9q7lL0yvvA1cClZxd/N2NqE8tmHrtzJRflUa3UqUiSP9Dv9/Kz9tTKRL78km1KOfUzJNlFDnzlKdY1QF1tpRiC77sAaa2XNvdMwZmN92vmdBl1lSL/TL0zjN+a02vqdRl1RSL/TL85a/wadVsd382/MFYX0O/3SrPVv0Gm18zsNuqKQfqdfnjb/xpxWO7/ToCsK6Xf6lVnzb9BptfU7jbqikH6nX531/Bh0Wu38ToOuKKTf6ddm8Rt0Wm39TqOuKKTf6den3b9jTqut32nUFYX0O/3GLH6DTqud32nQFYX0O9121v076LTa+Z0GXVFIv9NvTrt/x5xWW7/TqCsK6Xe63az5N+i0Omc35jFXFNLv9Fuz9s+DTqud32nQFYX0O/32LH6DTqud32nQFYX0O/3OrPVv0Gm18zsNuqKQfqffnbX+DTqtdn6nQVcU0u/0e7P4DTqtdn6nQVcU0u/0+7Pu30Gn1c7vNOiKQvqd4rT1b8xptfU7jbqikH6nNOv5O+i02vqdRl1RSL9Tnrb+jTmt9n6nMVcU0u9Ups2/MafV1u806opC+p3qrPVv0Gm19zuNuaKQfqc2a/4NOq22fqdRVxTS7/QHs+bfoNMK6Xf6WWB96umL1PcC60zo54H8/nARfsA6CfpFIL8/WoQfMM9Pvwzk98eL8APmqelXgfz+ZBF+wDwr/TqQ358uwg+YJ6TbAvn92SL8gHkuuh2Q358vwg+Yp6HfBvK7/SL8gHkG+l0gvzsswg8YJ6ffB/K74yL8gHFeSkB+d1qEHzBOSQXI786L8APG2agB+d1lEX7AOBGdDuR310X4AeMc9EdAfn+xCD/gOZ3+BMjvbovwA54z6c+A/O6+CD/gOYluD+R3j0X4Aff5dEcgv3suwg+4T6U7A/ndaxF+wH0W3RXI796L8APuE+huQH73WYQf8DlH9wDyu+8i/IDrNN0LyO+MRfgB1xm6D5Df/RbhB7xP6Awgv/sv4sd6LNDbApwztONXlIwlOWej0iq3kKSIwfUavVDJ9p7mmo2MNUYdU47daOGEMCLpkBOpQ/J73BHhh/Yl9Xn3uAN4b848yT1Rhxr340/ycffr8vgDjPsJi/ixnnhE14lRP1a/vk88wLx5/az61Eg2Ze+SMa5G5kc65WqZgQ+lpC6Hidkq76popdtyRDQyM7JaPTGzrR9Lmt5VHLtXokQrVdDOyyZD60qK7Po3MI4Hmm3Wvb2acjW6qdaKKIFMRPqx3jCLX58IqjqjXcpGZdtNQqV3DsaoeGIpclS7OCw4/sTaMz+brYnFhVCTqls/lvS97SYUBliCsDKYGrwTWbpShCw+p9Breft0tHwVbNE8DY1rvSW+iViQfqy/nufHUka4bAsPlW/jKFPwXjKAHGLvfSElW5HKR86fuSCiy71jpDahqbXstn6sUdcb0o/1xln8Bp1gWz/WqGsL6cf6m2l+iTEn2PHd+jfm2kL6sd40bf6NOcG2fqxR1xbSj/Xmaf0hY06wrR9r1LWF9GO9Zdb9O+gE2/mxBl1bSD/W307rDx5zgu38WIOuLaQf6+9mrX+DTrCtH2vUtYX0Y/39rPVv0Am29WONuraQfqx/mOaHGXOCbf1Yo64tpB/rH6fF98ecYFs/1qhrC+nH+qdZz49BJ9jWjzXq2kL6sd466/4ddIJt/Vijri2kH+tt0/JLY06wnR9r0LWF9GO9fdb8G3SCbf1Yo64tpB/rHbPWv0En2NaPNeraQvqx3jnt+TvmBNv5sQZdW0g/1rumxV/GnGBbP9aoawvpx3r3NL/EmBNs58cadG0h/VjvmcVv0Am29WONuraQfqxjs+7fQSfYzo816NpC+rHeO83vOeYE2/qxRl1bSD/W+6b5scacYDs/1qBrC+nHev+0/fOYE2zrxxp1bSH9WB+Ylv8Yc4Jt/Vijri2kH+uD0/LnY06wrR9r1LWF9GP98yL1vcA6HXoDkN+HFuEHrDOhNwL5/csi/IB1EvQmIL9/XYQfMM9PbwHyO38RfsA8Nf0dkN+HF+EHzLPSPwD5/dsi/IB5QvonIL+PLMIPmOeitwH5/fsi/IB5GnoHkN9HF+EHzDPQu4D8PrYIP2CcnN4D5PfxRfgB47z0XiC/TyzCDxinpPcD+X1yEX7AOBt9EMjvgkX4AeNE9CEgv08twg8Y56B/BfL79CL8gOd0+jCQ32cW4Qc8Z9JHgPw+uwg/4DmJPgrk97lF+AH3+fRxIL/ji/AD7lPpk0B+n1+EH3CfRZ8C8vvCIvyA+wT6DJDfFxfhB3zO0eeA/L60CD/gOk2fB/L78iL8gOsMfRHI7yuL8APeJ/RlIL+vLuIXexLQewOcM7TlRz6WaFxLMVjho0opZiuctq5o6ZsyJcpCWUYlTO9wNFa10lr02lRlZTwkvycfEX5o31Sfd08+gDfoKWDf1CrjfupJPu5+XZ56gHE/bRG/2NOP6Dox6hfr1/fpB5g31z9tzryRJober1EMD4qK1qaYJnt3YCrVli45cV1goFsRwYgYRbK215+3nGyjtPOLBeNJaiUo8EVKVbVIzF5qWZo0/B/lyNgYtK/8PVKu3Selc7HJ9KZ3qF/sBrP4KSeLMkqImqU0WRYGGhJlJwVpR1Fa7YOzTZWoqUhpmyFRnTLNmCDz1i9GMbdEMvQmOE222zkKxVRzqQxTO5N01gzMKwasjA3aqd6CI52OJceK9IvdcBI/KtaFKL31oYXeepVEc1I7yZBKDVXwna55ngSjq+99SbnkVk5ImixPy71fbNCVh/SL3WgSv1Gn2s4vNugqQ/rFbjyJ36hTbesXG3WVIf1iNzlt1vNjzKm29YuNusqQfjExid+oU23nFxt0lSH9YnTarPk35lTb+cUGXWVIv5icxG/Uqbb1i426ypB+MTWJ36hTbecXG3SVIf1ieha/Qafa1i826ipD+sXMabPu3zGn2tYvNuoqQ/rF7Cx+g061nV9s0FWG9Iu5SfxGnWo7v9igqwzpF/Onzbp/x5xqW7/YqKsM6RcLk/iNOtUut3NajbnKkH6xm07iN+pU2/nFBl1lSL/YzWbxG3Sq7fxig64ypF/s5pP4jTrVdn6xQVcZ0i92i0n8Rp1qO7/YoKsM6Re75Sx+g061nV9s0FWG9IvdahK/Uafazi826CpD+sVuPYvfoFNt6xcbdZUh/WK3mcRv1Km29YuNusqQfrEfPm3W+jfmVNv7xcZcZUi/2I+cNmv+jTnVtn6xUVcZ0i/2o5P4jTrV9n6xMVcZ0i/2Y5P4jTrVtn6xUVcZ0i/245P4jTrVkH6xbc3PKL+fmMRPjP0gYJ0O3RDI7ycX4QesM6EbA/n91CL8gHUSJID8fnoRfsA8P0kgv59ZhB8wT00ayO9nF+EHzLOSBfL7uUX4AfOE5IH8fn4RfsA8F90UyO8XFuEHzNPQzYH8fnERfsA8A90SyO+XFuEHjJPTrYH8fnkRfrcB8vthIL9fWYQfME5JPwrk96uL8APG2ejHgfx+bRF+wDgR/SSQ368vwg8Y56CfBvL7jUX4Ac/p9LNAfrddhB/wnEk/D+T3m4vwA56T6BeB/G63CD/gPp9+GcjvtxbhB9yn0q8C+f32IvyA+yz6dSC/31mEH3CfQLcF8vvdRfgBn3N0OyC/31uEH3Cdpt8G8vv9RfgB1xn6XSC/uAg/4H1Cvw/klybxG/2czwB6g4Bzhnb8iqophqSV6UqbElpLVGUIvU7KqtxIt2qN6R0u1vJv1Saqdv2Xi3TUDsnvmUeEH9rX1efdMw/gXTrrVOx9t8q4n3WSj7tfl2cdYNzPXsTP9pwjuk6M+tn69X3OAebNM06btL8pWQQva0qqNyApJU4UL8eio7NKqxRVkslKMjziYGtkPM6oVviz6hrt1s9GQqfoYgo6SRlUbzupsaasQhPNFG21L9aSLL25PdRK0fF16V2vIcbSPNLP9sxJ/KQyxmRmwp+3td5/al2MwrnarHTB50oySu8SySp5IFVT5Q/fKMruN6lbP5tUViXL4I1P1snSNQG5VJGYu0ydUsk6GuJ5mIT1qttolBE28OT31CTSz3bWLH6ha3S89NXUnL0WwpVmRFdmZOuqKdFTkL3DXzmhsu8dH7lWm01RWoq687MNugaRfrZnzeI36KTb+tlGXW9IP9uzJ/EbddJt/Wyjrjekn+05k/iNOum2frZR1xvSz3b2abPm35iTbutnG3W9If1sz53Eb9RJd/pu/o253pB+tudN4jfqpNv52QZdb0g/2/Nn8Rt00u38bIOuN6Sf7ZxJ/EaddFs/26jrDelne8EkfqNOuq2fbdT1hvSzvXAWv0En3dbPNup6Q/rZzp3Eb9RJt/WzjbrekH62F03iN+qk2/rZRl1vSD/biyfxG3XSbf1so643pJ/tJZP4jTrpdn62Qdcb0s923iR+o066rZ9t1PWG9LO9dBK/USfd1s826npD+tleNonfqJNu52cbdL0h/Wwvn8Vv0Em39bONut6QfrZXTOI36qTb+dkGXW9IP9tfzuI36KTb+tlGXW9IP9srJ/EbddLt/GyDrjekn+2vJvEbddJt/Wyjrjekn+1Vs/gNOul2frZB1xvSz/bqWfwGnXRbP9uo6w3pZ3vNLH6DTrqP7fx2Y643pJ/ttZP4jTrptn62Udcb0s/2uln8xn4QsM6Jngnk9/pF+AHrdOhZQH5vWIQfsM6EngPk99eL8APWSdBzgfzeuAg/YJ6fng/k9zeL8APmqekFQH5vWoQfMM9K5wL5vXkRfsA8Ib0YyO8ti/AD5rnoPCC/v12EHzBPQy8D8vu7RfgB8wz0CiC/v1+EHzBOTq8E8vuHRfgB47z0KiC/f1yEHzBOSa8B8vunRfgB42z0OiC/ty7CDxgnojcA+b1tEX7AOAe9Ecjv7YvwA57T6U1Afu9YhB/wnElvAfJ75yL8gOck+jsgv3ctwg+4z6d/APJ79yL8gPtU+icgv/cswg+4z6K3AfkdW4QfcJ9A7wDye+8i/IDPOXoXkN/7FuEHXKfpPUB+71+EH3CdofcC+X1gEX7A+4TeD+T3wUn8hj0DQO8ScM7Qjl+vTxYpk6hOuxhNlC5Sd9CEZluwXqgTf6aU4qLT3f/jbfUhkOtlduGQ/J57RPihfWd93j33AN6q552Kve9WGffzT/Jx9+vy/AOM+5xF/HYvOKLrxKjfrl/fFxxg3lzsapP2N81KEsVKH3szSMtKeNli8zLmInQW2akotDTNOe+1Tq6Z1ESsNvT+Qbn124lUMv8qaakcCVOqLFYZ/pl3sZvLTLZBG+FrtaoYT8354KRz5MiXZh3Sb3fxSfwk5ZCsi9baGJLUKpJvpcRiRW/aIG9cyL1RX7Tsk/ZWxsAzp7fQuKArbf12FPgP5iqsKN5ow9/RMFBnRE0yxRBDK8Ior0TvsfHSC9uNY73BRiYjTEX67S4xi1+utkbKjUi4JKTVtQaeLTn5JpuoUtpKgWRRsvrYTX8MRMbepOW7yHLrtxt1NSL9dpecxW/Q6bfz2w268pB+u0vN4jfo9Nv57QZdeUi/3aVnPT8GnX5bv92oKw/pt7vMtPt3zOm39duNuvKQfrvLTuI36vTb+e0GXXlIv93lps2/Maffzm836MpD+u0uP2v+DTr9tn67UVce0m93hVnPj0Gn385vN+jKQ/rtrjiL36DTb+u3G3XlIf12V5p2/445/bZ+u1FXHtJvd+VZ/Aadfju/3aArD+m3u8qs+3fQ6bfz2w268pB+u6tOu3/HnH5bv92oKw/ptzttWvxvzOl35m7MY648pN/uarP2z4NOv53fbtCVh/TbXX0Wv0Gn385vN+jKQ/rtrjFr/Rt0+u38doOuPKTf7pqz1r9Bp9/ObzfoykP67a41i9+g02/ntxt05SH9dteedf8OOv12frtBVx7Sb3edaevfmNNv67cbdeUh/XbXnfX8HXT6bf12o648pN/uetPWvzGn395vN+bKQ/rtrj9t/o05/bZ+u1FXHtJvd4NZ69+g02/vtxtz5SH9djecNf8GnX5bv92oKw/pt7vRrPk36PRD+u22NVOj/G486/kx9oOAdU50CSC/myzCD1inQ5cC8hOL8APWmdBlgPxoEX7AOgm6HJCfXIQfMM9PVwDyU4vwA+ap6UpAfnoRfsA8K10FyM8swg+YJ6TTgPzsIvyAeS66OpCfW4QfME9D1wTy84vwA+YZ6NpAfmERfsA4OV0XyO+mi/ADxnnp+kB+N1uEHzBOSTcE8rv5IvyAcTa6MZDfLRbhB4wTkQDyu+Ui/IBxDpJAfrdahB/wnE4ayO/Wi/ADnjPJAvndZhF+wHMSeSC/H16EH3CfTzcF8vuRRfgB96l0cyC/H12EH3CfRbcE8vuxRfgB9wl0ayC/H1+EH/A5Rz8M5PcTi/ADrtP0o0B+P7kIP+A6Qz8O5PdTi/AD3if0k0B+Pz2J3+jnfCHQWwWcM7TjV6xONVVvHGVtlG61aalyqd5mZZIzvUPX26qIRLYqyBx17YVoJBojOSS/c48Iv+8C37d93p17AO/Xi07F3nerjPvFJ/m4+3V58QHG/ZJF/IDnHdF1YtQP2K/veQeYNw+eVR/Nw/KxdyoI/gDCVOq6O6LmVLa9ubxYE1xv5W1VVeFcYNTSJZcYTVR56weUgUqzVKpSgShqyX/Q8tfYZFNpMfP3ULbrLFJrwXufatUpm+KisKRKRvoBHzKtvjxJS7VGJ0RhLiHx5HRWylzIhxCLVl5kl1To08zxWIPOvX1ENUPJyK0fUIqUlC7NK1+NEjyRa6yqlahkVr3nqXQDRS3WCamMTL7ruAzZpH2/cAnpB3zorPpyKVOVJXWlZOQJUYILzYrmpXEuC1mlMMU2EsnJ3vBgmwip9gZgVxIPf+cHHHRdIv2AD5vmlxhzIu78gIOuQaQf8OGz7t9BJ+Lx3f075hpE+gEfMWv+DToRt37AUdcg0g/4yGl+nTEn4tYPOOoaRPoBHzVt/o05Ebd+wFHXINIP+Ohp+5cxJ+LZu/k35hpE+gEfM23/MuZE3PkBB12DSD/gY6f5EcaciDs/4KBrEOkHfNys9W/Qibj1A466BpF+wDNnrX+DTsStH3DUNYj0Az5+mh9rzIm49QOOugaRfsAnTMsvjTkRt37AUdcg0g/4xFnPj0En4tYPOOoaRPoBnzTr/h10Im79gKOuQaQf8MnT8ptjTsSdH3DQNYj0Az5l1vwbdCJu/YCjrkGkH/Cps9a/QSfi1g846hpE+gGfNu35O+ZE3PkBB12DSD/g06fFX8aciFs/4KhrEOkHfMY0v86YE3HnBxx0DSL9gM+cxW/Qibj1A466BpF+wLNm3b+DTsSdH3DQNYj0Az5r1v5l0Im49QOOugaRfsBnz+I36ETc+QEHXYNIP+Bzpu2fx5yIWz/gqGsQ6Qc8e179xpATcesHHHUNIv2Az531/Bh0Im79gKOuQaQf8HmL1JcD68ToIUB+z1+EH7DOiR4G5HfOIvyAdTr0CCC/FyzCD1hnQo8C8nvhIvyAdRL0GCC/cxfhB8zz0+OA/F60CD9gnpoeD+T34kX4AfOs9EQgv5cswg+YJ6QnA/mdtwg/YJ6Lngrk99JF+AHzNPR0IL+XLcIPmGegZwL5vXwRfsA4OT0LyO8Vi/ADxnnpOUB+f7kIP2Cckp4L5PfKRfgB42z0fCC/v1qEHzBORC8A8nvVIvyAcQ46F8jv1YvwA57T6cVAfq9ZhB/wnEnnAfm9dhF+wHMSvQzI73WL8APu8+kVQH6vX4QfcJ9KrwTye8Mi/ID7LHoVkN9fL8IPuE+g1wD5vXERfsDnHL0OyO9vFuEHXKfpDUB+b1qEH3CdoTcC+b15EX7A+4TeBOT3lmn9R4N5BqD3CzhnaMtPlpSadKZ6E3URyRaRXQsmVdMVBN5GYVVvRFE+SyVyjTzoHHvrruRBm0Pye9kR4fdd4Pu2z7uXHcCb9vJTsffdKuN+xUk+7n5dXnGAcf/lIn7FVx7RdWLUr9iv7ysPMG++M2t/461oRuXmq4mCqWrX+1xtUbXF5LIOXS1EuXYJSZcHWlVz7/LynlKStPMrJu20MqZ7UqR3Mjkle6u7MvytuqdN8Hdu0TmKUUr+tl5b4WsK/GV8HQjpV/y/aX4YbbOItmtJYi6GkvNZZXI2VeaZjWkUiT89fzKegv+/t62pqqzINpWdX5EoiKB841lmbG/oKoX56JylDFbzpBM1GNdFl8nHopOpjr+vMeR5gvNPkH7F/3f1Ofxk6cYwTbLYILwTkaKzXaSjtCddbFKNJ1Uj6v7ULHLiezM21VThm7Zas/UrjrpCkX7F75rEb9QpufUrjroakX7FU2bNv0Gn5M6vOOhqRPoVT53Fb9ApufMrDroakX7F7551/w46Jbd+xVFXI9Kv+D3T7t8xp+Tpu/k35mpE+hW/dxK/Uafkzq846GpE+hW/b9r8G3NK7vyKg65GpF/xQrPm36BTcutXHHU1Iv2K3z/r+THolNz5FQddjUi/4oVn8Rt0Sm79iqOuRqRf8Qem3b9jTsmtX3HU1Yj0K15kFr9Bp+TOrzjoakT6FX9w1v076JTc+RUHXY1Iv+JFp92/Y07JrV9x1NWI9Cv+0LT4y5hT8lI7p9+YqxHpV7zYrP3zoFNy51ccdDUi/YoXn8Vv0Cm58ysOuhqRfsVLzFr/Bp2SO7/ioKsR6Ve85Kz1b9ApufMrDroakX7FS83iN+iU3PkVB12NSL/ipWfdv4NOyZ1fcdDViPQrXmba+jfmlNz6FUddjUi/4mVnPX8HnZJbv+KoqxHpV7zctPVvzCm59yuOuRqRfsXLT5t/Y07JrV9x1NWI9CteYdb6N+iU3PsVx1yNSL/iFWfNv0Gn5NavOOpqRPoVrzRr/g06JZF+xe8A+V151vNj7AcB68RoWzM1yu8qi/AD1jnRKUB+V12EH7BOh74byO+0RfgB60zoe4H8rrYIP2CdBF0IyO/qi/AD5vnpwkB+11iEHzBPTRcB8rvmIvyAeVa6KJDftRbhB8wT0sWA/K69CD9gnosuAeR3nUX4AfM0dCkgv+suwg+YZ6DLAPldbxF+wDg5XQ7I7/qL8APGeekKQH43WIQfME5JVwLyu+Ei/IBxNroKkN+NFuEHjBPRaUB+N16EHzDOQVcH8rvJIvyA53S6JpCfWIQf8JxJ1wbyo0X4Ac9JdF0gP7kIP+A+n64P5KcW4Qfcp9INgfz0IvyA+yy6MZCfWYQfcJ9AAsjPLsIP+JwjCeTnFuEHXKdJA/n5RfgB1xmyQH5hEX7A+4Q8kN9NJ/Ebfg8H0JsGnDO05SetKDZG20hQlS5I6chUqpFiUsnUGlJvqZCJgupdz71x3jWbqxc1EIVD8nvVEeGH9hX2efeqA3jnXn0q9r5bZdyvOcnH3a/Law4w7tcu4qd83RFdJ0b9lP36vu4A8+Zus/Y3SXrbmKnwyqUqQjU1REXKiN6SmqLq6o6un9Ap83iFKNVSLM2W4GUKWz8lk4yUfS290br3UqvcikvCFv4fSdlC79OR1oT+qRKljle72G1breWK9FPefRq/2GR3QVhJtYradFTN9uaQ3shVXVKOP151wiidpVDeq95MwiCq9cXQ1k8pnBfeGZ7jviZXyfBXZmWricmGSJaM7b2bvaObdIuV+Je9oRaNV3wNG9JPeY9J/Kg03zsSBP/VvbO8hNIoO4qab8WaTYsiuSb48yuSpreP2N5MzuMNRetkt37KUdcq0k95z0n8Rp2cOz/loOsS6ae816z7d9DJufNTDroukX7Ke8+af4NOzq2fctR1ifRT3mfW/Bt0cm79lKOuS6Sf8r6znh+DTs6tn3LUdYn0U54xbf6NOTm3fspR1yXST3m/WevfoJPzgt38G3NdIv2U9591/w46OXd+ykHXJdJP+YBp++cxJ+fOTznoukT6KR84a/0bdHJu/ZSjrkukn/JBs9a/QSfn1k856rpE+ikfPIvfoJNz66ccdV0i/ZQPmXX/Djo5t37KUdcl0k/50FnPj0En59ZPOeq6RPopHzbr/h10cm79lKOuS6Sf8uHT8sNjTs6dn3LQdYn0Uz5i1vwbdHJu/ZSjrkukn/KRs9a/QSfn1k856rpE+ikfNe35O+bk3PkpB12XSD/lo6fFX8acnFs/5ajrEumnfMys+3fQybnzUw66LpF+ysfO4jfo5Nz6KUddl0g/5eNm3b+DTs6dn3LQdYn0U545a/8y6OTc+ilHXZdIP+XjZ/EbdHLu/JSDrkukn/IJ0/bPY07OrZ9y1HWJ9FM+cVr+Y8zJufVTjroukX7KJ816fgw6Obd+ylHXJdJP+eRp54+hHwSss6Ntzdkov6cswg9YJ0b3BPJ76iL8gHVOdG8gv6ctwg9Yp0P3BfJ7+iL8gHUmdD8gv2cswg9YJ0EPAPJ75iL8gHl+ehCQ31mL8APmqekhQH7PWoQfMM9KDwPye/Yi/IB5QnoEkN9zFuEHzHPRo4D8zl6EHzBPQ48B8nvuIvyAeQZ6HJDf8xbhB4yT0+OB/J6/CD9gnJeeCOR3ziL8gHFKejKQ3wsW4QeMs9FTgfxeuAg/YJyIng7kd+4i/IBxDnomkN+LFuEHPKfTs4D8XrwIP+A5k54D5PeSRfgBz0n0XCC/8xbhB9zn0/OB/F66CD/gPpVeAOT3skX4AfdZdC6Q38sX4QfcJ9CLgfxesQg/4HOOzgPy+8tF+AHXaXoZkN8rF+EHXGfoFUB+f7UIP+B9Qq8E8nvVJH6jn/P1QO8ccM7Qjl8ROsQWLJkUI5VYaiGbs0mpNHJMIGdbqHcke2eyL9EpkT3/PCpHqR2S3xuOCD+077HPuzccwNv316di77tVxv3Gk3zc/bq88QDj/ptF/J5vOqLrxKjfs1/fNx1g3nxj0vOZyPNfX5ibKKX3jTcmWPnDtlKjaKbxEGJuRZP0VihveRgxRKurstp6u/V7SsnEpS2KB1qN147hUoy5WGqqixwN5ZarCVYYzVfQGJEoU1G1yGSEQfo9vzlrf+gpy5Bb9+Z0d4v1+gSXYGL/pFWIWGTpwoje8lpM7U3VKnY9Z27a6J3f09gaoowtR5V1K/xnXGKMJQftEn/XHAIPUguvQ+avLcoV/jW+LYoK3jik3/Nbk/hJl0xyJCvftLY7cbxQyfN9RiZrWQJZ5QxjTERO8u1YeS7FkCQRBVWt3/k9B121SL/nf0ybf2NO063fc9QVivR7fnsWv0Gn6dbvOeoKRfo9/3PW/TvoNN35PQddoUi/53/N4jfoNN35PQddoUi/53/Pun8HnaZbv+eoKxTp9/yfaffvmNP07N38G3OFIv2e/ztr/zzoNN35PQddoUi/53emzb8xp+nO7znoCkX6Pf9v1vwbdJpu/Z6jrlCk3/P/XWPS82PQabrzew66QpF+z++axW/Qabr1e466QpF+z1OuMev+HXOabv2eo65QpN/z1Fn8Bp2mO7/noCsU6ff87ln376DTdOf3HHSFIv2e3zPt/h1zmm79nqOuUKTf83tnzb9Bp+lZuzGPuUKRfs/vm8Rv1Gm683sOukKRfs8LzeI36DTd+T0HXaFIv+f3z1r/Bp2mO7/noCsU6fe88Kz1b9BpuvN7DrpCkX7PH5jFb9BpuvN7DrpCkX7Pi8y6fwedpju/56ArFOn3/MFp69+Y03Tr9xx1hSL9nhed9fwddJpu/Z6jrlCk3/OHpq1/Y07Tvd9zzBWK9HtebNr8G3Oabv2eo65QpN/z4rPWv0Gn6d7vOeYKRfo9LzFr/g06Tbd+z1FXKNLveclZ82/QaYr0e25r9kb5XWrW82PsBwHr7OhbQH6XXoQfsE6Mvg3kd5lF+AHrnOi/gPwuuwg/YJ0O/Q+Q3+UW4QesM6HvAPldfhF+wDoJ2tYMjPK7wiL8gHl+OgXI74qL8APmqem7gfyutAg/YJ6VvhfI78qL8APmCelCQH5XWYQfMM9FFwbyu+oi/IB5GroIkN9pi/AD5hnookB+V1uEHzBOThcD8rv6IvyAcV66BJDfNRbhB4xT0qWA/K65CD9gnI0uA+R3rUX4AeNEdDkgv2svwg8Y56ArAPldZxF+wHM6XQnI77qL8AOeM+kqQH7XW4Qf8JxEpwH5XX8RfsB9Pl0dyO8Gi/AD7lPpmkB+N1yEH3CfRdcG8rvRIvyA+wS6LpDfjRfhB3zO0fWB/G6yCD/gOk03BPITi/ADrjN0YyA/WoQf8D4hAeQnJ/Eb/ZxvPhXHDzhnaMdPhapS7kYkZXNNqqlCLbWmpbU62mizijYUKXudcq9cLEFSrb2S1OZ8UH5vOSL80L7MPu86O7T38G9Pxd53q4z7707ycffr8ncHGPffn7rGOvsPR3SdGPWj9uv7DweYN3ectb/p7dPSN3Il+SJLTD7prhaTjWGTdp74QyaRcqZefl9FsUEHq5Lz0gra+lEpFJ2k0F66am2zriolnSylxiKbCFHUbHobXvF8QWKwpqsHvTIUtEghIf2od5rEj2yLJqYYqku2hFhE0yombWK3hNneKed4/lhdfRbSyNCVJMoZnkCumxh3ftTeDdx4ppngVeydYb2I33qbqgvUO1G6UKLJVMh6r1tMRccmedhVmkYN6Ue986z5x1yCtL27XzpH4kRvF5XsbA6pMFNfkhY8EJdK6qJdGYt22kWnqxXZbP2oo65fpB/1LrP4DTpht37UUdcq0o9610n8Rp2wOz/qoGsV6Uf9i1nzb9AJu/OjDrpWkX7Uu82af4NO2K0fddS1ivSj3n3W/Bt0wm79qKOuVaQf9R6z9i+DTtizd/fvmGsV6Ue957T5N+aE3fpRR12rSD/qvWatf4NO2K0fddS1ivSj3nvW/TvohN35UQddq0g/6n1m8Rt0wu78qIOuVaQf9b6z1r9BJ+zWjzrqWkX6Uc+Ytf4NOmG3ftRR1yrSj3q/WfwGnbBbP+qoaxXpR73/tPzmmBN260cdda0i/agPmPX8GHTCbv2oo65VpB/1gbPu30En7NaPOupaRfpRHzQtvz7mhN35UQddq0g/6oNnzb9BJ+zWjzrqWkX6UR8ya/0bdMJu/aijrlWkH/Wh056/Y07YnR910LWK9KM+bFr8ZcwJu/WjjrpWkX7Uh8+6fwedsDs/6qBrFelHfcQsfoNO2K0fddS1ivSjPnLW/TvohN35UQddq0g/6qNm7V8GnbBbP+qoaxXpR330LH6DTtidH3XQtYr0oz5m2v55zAm79aOOulaRftTHTst/jDlht37UUdcq0o/6uGn1a2NO2K0fddS1ivSjnrlIfwOwTpHuBOxvePwi/IB1dnQXIL8nLMIPWCdGfwHk98RF+AHrnOjuQH5PWoQfsE6H7gnk9+RF+AHrTOjeQH5PWYQfsE6C7gvk99RF+AHz/HQ/IL+nLcIPmKemBwD5PX0RfsA8Kz0IyO8Zi/AD5gnpIUB+z1yEHzDPRQ8D8jtrEX7APA09AsjvWYvwA+YZ6FFAfs9ehB8wTk6PAfJ7ziL8gHFeehyQ39mL8APGKenxQH7PXYQfMM5GTwTye94i/IBxInoykN/zF+EHjHPQU4H8zlmEH/CcTk8H8nvBIvyA50x6JpDfCxfhBzwn0bOA/M5dhB9wn0/PAfJ70SL8gPtUei6Q34sX4QfcZ9Hzgfxesgg/4D6BXgDkd94i/IDPOToXyO+li/ADrtP0YiC/ly3CD7jO0HlAfi9fhB/wPqGXAfm9YhK/0c/5j6fi+AHnDG35kTTCqli8JB+U0CpmEYMVriRBxmhtpOq9uGRlsCXy+GMIVvmaRVHal0Py+6cjwg/tG+3zrrNDeyPfeir2vltl3G87ycfdr8vbDjDut5+6xjr7jiO+znZPYysy6VYT6Ui9oUa5RPxzW2OjWHXiv6+cMI55kW30unkpi6dQ+bd3nlURajIhB0ulxZic87XIGKJwVQYypKTp8gC+Urn73mwNxnX/QnVF5uiRntWvTXrOyxR0sTmaZnRTWnQ/VAo2U/I8OJ9y1mRE7aqs5GISsST+QtKtS8ui9TvPquz9Dnyl+YraFpsxPCgbbO9oStm27Kgp43PU1bjgde+hSCYHRsAMmkB6Vr8+a5+pdVcPhVxC8DwZjazBWsezRQblfMy9T8Tprk3JJWsVeCjkeWqFolWqeedZ5RmfShdKVb5LmrSmSVX4P70FyHoRY1S9Y74lTUSxOy+qzo2ko26bUUjP6jem8VPaOsO3Ok+1orJOJKtLXXlZPI/dGyeL00KkrrssVjmdqTfhacdfGMXWsyqj7C7lElPmsUvG45MyIibTFwit+yrAP8uSqtQMt/reCFn5Zg5GmeqRntVvzuKXgrTSG2tM71UUOtVmBY9ckMpUW+CJlnNrJXteHJv0sbTK04aXTeZi6/EdvxY9fx+jAs9pR9V3G4Dl1VrEVrxPpd+lRuoUhGxNJF7SewduKdYqqwvSs/qtWfyoGtIMxJxY4kThaVHIpGKDK0KKLvzVfM+F6CIvZdS6xqPy1/Cjge/uuvWskreqa2p73zp/Rx5LEEV0kYdSvJYqvoO7VKsL30Lk55yKyttYhBOW/1sI6Vn9j1n8nHRdidJaX/cdT0aKrlpVpfRO6dZ4HgkpeYymaf6S1qWhlBlFV8ekuvWsEmVheQ8QAu8GGBJlV2rwJYWUBD96fZcKVi2d4snn+W9WJlGy0XQJkkoO6Vn99iR+XeTpo1SyET8T+M5MyfHcMl2qUzRvPHiN787QEFQ1yfHqlWrkzZPnh0FpzW09q/LE/ie76Fq2UhfF39EZ4u/TVReVpO1LqrcpZl5AyejMy2HJQRbNCwXWs/qfs/jxM5WfsF4J3ksGmUrJsuuxgqDSvaGihiZ4o0HdTG5lCbxIBu9M7Op8amnrWaXouzj6hECfeCfooupCM35uS61kVCV1XWaLPHFl42cSmVr5r+Q/I/gaVqhn9b9m7f+MdTbraCLvNaLhJY73ao0/K6/pvJAx3STtidcUpOz4xhROdS+htLyTdqm5nWfVtBMt391WqAvfuzL4qHmznKsOLva3FoRApZYWirCBF4pgbOGF0SjLiCLSs/rfs/hlhsBPhMyrnpN8luHdS+HHr+RP13QRXnc1oOF9tee9oegWKd4BG94o5i7Nd1vPKonUW2lFN/p0+Umjynsd03cv/TUaUjXHO28+EmUnJWWKXeeou9paM0plkZ7V/5n1/OAPooPIPovc5ceZt4I2Bt6fNd4J8mmi8BB5fyb7zq2bt1Pk1asVly1vlZ3aelZ5WvKtaRkNbyP5uKJd67Z0fkyrnJXhRdHz9+FzoGWevC4oz3Odn/H8jOIrKAXSs/q/0/YvzfLpmY8A3ucsest0863LKlR/b0Hls1gU3SsdBJ9PeNfMg1G2Jmu85OeI3nlWvefh8jEttP5Kg9bdMlFmnq98/lWyVF7wHB94kw451kh8bve8Z1cpEJ+TlUF6Vr8zbf/M+wgTUuazluubCn44yphi4kcuH4tbiN3KwaPlWAKvd9ZW73m/Ufj4YPixmbaeVeLzCs813kIH4Wz/7f42F36eUFDR267e4mNOCF2qyQ+Q7kpXXSnMf78T/LBCelb/bxY/pcnxws+hlcwHW9d84rMa70JSd1HwWUt0v47gk3AsfOfxg5UfKjyncmmZbz2186y2zLuV3AWj/fGRWuIjDO+Reb+tKx/reCvdhQ383Dixb+kxpBZl6g913nVLhfSs/r9rTtq/OM87sOwUL1399T7dGWG9lo3PCpoXu9z3zRzKahySEaYbd1TkRywfxUJ/MuStZ1XmoLNwgf8Q8ZGCf5dvS/6+J5bQxj+C4dNh4SOckHwKbFWS1V74VruDPnikZ/W7JvGTqYtKrCLe4nJwyfiaqiAdZKQeMuGNhqh9w8zHWisqP0V475E5tsKnEMdLo9p6Vim02kNcxIdpz4GIHv/r007x/eoM39ddEqI8b8QVf3fPD/rSVWa6v40kl6qQntVTZs2/mHhF8i7zkZ5DKzynlCV+ljCpesIaxedT/viag0+8nlWeUnxM5ocA72coc4x061nlA23jh1A7YeryyahcunWKF0V+7nBkgnfgPJ15U2ROeKSq5xBZf9VGN+Uyh4z0rJ56zVnPjyR0jwXw00Lm/vKoWPprQIptXePGkQRhIv/cKf6kHPLkSRRjP+T54Jmt2XpWyXF8uivbOAjbxVm8DyrN8xNERm17bLV0zWV38lnRJP8er409cGu7AI2vCNKz+t2z7l/JN2vqplOefHzG0DXy8YHPVzxviO/GqDmiLzjcZ/hAwnEA/uoeM+a51f1wzGnrCS0ku0cma77T+xuoOOIfeK9Yuh/dW34aecsrA4cUOITAccfGj2IO7/CKyfvpagXSs/o9s+Zfs7xqucxPkSpUqbytS/01ScYVjkX1vbXjWeT4AcwPXb4RfWM+vE6K2EMJJHae1Rz4lMyRet6L864lGg678j5RV+KYA2+qmRdHKvgYJ/ihZDXxc5oj2JEf5Hww5H0O0rP6vbPWv8RJnGI4xmx5H5gah5ti6S81jP2cIJu3jQ+s2sb+HjqGwesYx1QkhwY5tcTb7a1nVfBQ+ZnKtzuf1AxHsFrpL2fhrTQ/2CunV/jPclCGN9+85HUNYVfTl36hhNNKaaRn9ftm3b/8aOVBWdet0t7wBKJCfOCtHD51vIZ1XxaHkTmw0G8/zVEUDgHy4yTwscv6tves9pex8GZF9tc9cFpDBd5yd8ObExx54axHUZW/CT88OLbPQSsOEXIUpr+Wg8NaHJBBelYvNGv+MacUu06QM4uG55tKlld+nkVSd4cxKf5MigMqvCfm3V/iz5m74FdycJ4P/nLrWZW87e7S2er6S/n6UEzX5klb+fDbo7FEQatCmiOylCQHE/lIXT0vEKbrrQPSs/r90/bP6sT7RXvY05eeouXnL6eSeR/cuvCYQ9PJ82ba80aHn52e8xmaPzvPNE6qcehz61nl9DQfZ3gCO1W7p5YXgsrPhto1vhzCVvwg55Of7sfkyLmmFE68Q4xj2Zwf6dEYpGf1wtP4FT7cZ+189/maWDlE4vlpbHkB5OBB5X2tyJoDJjzpiD9f6ae8E0ZRJXrgZudZNfzQ5XNF5Inaz2ec6+THkeTkhuKoIacpeW/tOFDR/aJ8/OPQluWFgqMJkeM/vDYgPas/MIuf58OpSqoUFboZlE8ifCzreVmeM0zPF55qPBl5anHMgAH04F73WJLkT13E1rPa34lTgvBdbylJciirRL4OvNvRjLPvVDI/2BuzT6oHePjAyN8/cLKAYzP8tEJ6Vi8y6/lR+aRgW+Mtse1Sxcjxg2Z4/rjWo1e8ceEseuEojIucBuI9duXnBk8ZzgRxjNCnrWeVep2H6o5010Mz/YUtzdbMi6uTvKjq7p3nIQqOHbp44qW6zfNxR3OahA8mySI9qz84a/9n+Obth+DMTwOVfI5Wcxi5SVk4LsdD7C9gDaJHq2zPq3ueUU5xtJoD0ZoPaDvPKkekBMeUdeV4FaOWvW6H46ecTuLTL0cBieMKur/Mz1itbBGcJ+YJGzjtR43zSUjP6kVn3b/EZ1PDeZ7CiZCeFuJQDAc8ebCtGF4YeTLK/uY4wVlijuZzvjZr7UsPLnAIT9StZ1X0NaDvngvTDo6zkkkKy9+Dv7QwXM5n9n0l71yKIlH7hpOCsImXj8jnoIj0rP7QNH79JSCcWKx8TuVtbn/BCsdHOe/R3zMXOX/LqTNOKvWkSO41B5wT5wdq4gOI7e+63XpWORLLB4+WXO1Zj8Yxh8C7c07SMUsOUmXbYweScy3dUsuHYgbH+0FOyGV+VPHDCulZvdis+1fxXHDEKzg/PLVTnB1yfOivmjSvTRwk5tHzIsYniKQN83Hd0K17fVzh07GhrWdVcIDG9zSe4wWUU01ZdVd6P8ulXuXCD+7Wbem1n+/49uUzm9cnjh58XuZ8Z0R6Vi8+bf/MWVw+LvAHMjpxQDNF3vlxnL6/tqpKyXEWni8cDdQcn46ij7gq4oNsfz+NsxbpWf0asM7/ErPm39gPAtbZ0TeA/C65CD9gnRh9C8jvUovwA9Y50beB/C69CD9gnQ79F5DfZRbhB6wzof8B8rvsIvyAdRL0HSC/yy3CD5jnp23Oe5Tf5RfhB8xT0ylAfldYhB8wz0rfDeR3xUX4AfOE9L1AfldahB8wz0UXAvK78iL8gHkaujCQ31UW4QfMM9BFgPyuugg/YJycLgrkd9oi/IBxXroYkN/VFuEHjFPSJYD8rr4IP2CcjS4F5HeNRfgB40R0GSC/ay7CDxjnoMsB+V1rEX7AczpdAcjv2ovwA54z6UpAftdZhB/wnERXAfK77iL8gPt8Og3I73qL8APuU+nqQH7XX4QfcJ9F1wTyu8Ei/ID7BLo2kN8NF+EHfM7RdYH8brQIP+A6TdcH8rvxIvyA6wzdEMjvJovwA94ndGMgPzGJ3+jnfOepOH7AOUNbfqScLuRFTqWJ3hxFqZEPRUUXcu5WAUMhKRtqNdKboEsu3vX2WlNEKfWQ/N51RPihvZt93r3rAN7Nd5+Kve9WGfd7TvJx9+vyngOM+9gintX3HvF1llSOvbmh66IsZSqptw02F73SpK1rRuZEtbeWKGlN4b8wiiKE5i/KOqhX7zyDtvZvk1ULRYsT6qQgSo3O8IfrvU1SR1esd0WKIpPncbhgRbKtXyGoZ/X2s/ZJmqTyhUpUtfEIky2h+Rq7jjZaZqd6f0T/N5uLkjka4kvUnKsqZR7G1rNKoapgYleBVHK9nURWBp3oRINFFF5WvuS9/TspJVttjlyIsvsaai7JIz2rd5jW5+Szt1IWak3zh1Wp91xSc8I5rQSPTGXlqSbLk8eEJIssXnS/LA++5p1n9YSkzLXos9G5JSaShfX8X9PvCUNN50ypEy2BqAtu+MLkplUOVJQTSM/qHWf12bUkeAJ6zci0sqLPRooqEH8QxlhMblJZ1YWVMWXGGIIwPI9a7J01Km49q6IFlWzS3ZtUWq1JOlWqbtpHL3tjtzMUbV+GasjCUJEh819ZFVXNjCLSs3qnaX2yzienY2m2RV6iWvNWmFyDrbwCnjAm5xK72TP4nIwqujf/R+N0a/xF8vhu/hVe5lyJRrjcezfJO6tr6xLSLowKsrfkEi+hvEZKzzwa3+i55L6il2KRntU7z5p/vKKFGE13uPGiRbF2g5ZspVqeO9Zq5bvGlrotq0Xmmm2KxqR0olXb09azKmMtjgyl7vA2QukTDg+KstsepSfqNi2+V1PvV9au1MT/0bzyJp7K/GRCelbvMosfzw2+gaysIWnKPO2cMy1Uwct+UCrmbgDmz9v488US+lMz8zwsVnQ/epI7z6rgL41GBkfapdTbsrtpOojQe7aZua42e2/5ee6Jv5E20vlYvIpFVa0F0rN611n8fElkeE2SfHt2wWCwVgRtsohSmswj55W+8lTKXvHz1zu+/ZRLhqcO/wlBW88qP2WST12K3jWWVvOWi3dUgWeqC87X5GuVRlp++jopVHFCNa1b7yXVlpQJSM/qX0zzRAVRbW+IjbIJJ04IUCWl3Apv9LSOvGNTqrXGv1t5Vxd5q2NNbyukbmjLW8+q4EVM8tw1SkoXeXvC+yLpGu9iGLcpXpYUuoSV796+mvL+iFFHH3JtzDB4pGf1btPmn6pdpe8lP2Rr4y1v4seGi3wL8touSlC6NElUyVYed6s8R/lX+AOL2nxKW8+qdC7wk4If5kZQId6CR5VF5ofwCWVh4idIcLmpFLIUfanIIVqd+9OFp2uQSM/q3Wft/7qEyLXM27wUAs8fXpKy6I54HfjDhqyt0rbytFG8gKVarAuK988nnDStqa1nVehIfEsSk+uPBV7vtLH9Ru72Hl5heVHkb+b4QRV5T6T5r3G8pxbUrZiCN5pIz+o9ZvHLvfmVV3mlvNOZHwCOx0O8qaag+S523XDEe7gaGx8LTZKy8rxMjqeqZBZm61mVPvWDY1M5G5Uar6E6ZMcTq0qeqtYZwzhLqM4H/tP8d/Deie/33BvpmUVCelbvOc1T0aLufjw+0BbHT0L+DN1sHGI3A/AyxdtCPiLoxGuZ6GZfaYXufkDbCk+xuPWsdlUr3/LU73tteSEsFFpI2QbiBVBLSXzULYIP8zw9eTIyyWD6yZtB8QanIT2r95rFj2MBItUaDD+IveeTiOKtinKWdyLUN4Jdy5g0n7Sy4T0NPxyc0pG3bCn1xU1vPauC+fOBuaYWmit8EuGDNGXFa6Hooh5++PBRWPNJULuW+CklE89oIpF1VyhpqGf13rP4dW2C4Juzv78hecufJfF6JQRDrJofJgxS8Ak/UODDQ+SACU+nSIa3fjwJjdh5VoPhg5hrsst6+HbXmjdCgmdc7X5L5mC7Gt1bHraJvBPkRwlvz42tXSjPSJCe1fvM4mdzN/dy6IpPukR8FiHi8EsXwnSJROGzKj89kgot85GNIwbK8mLJsQM+v/WNz86zqjPvuEXiMwxvlZmitTxv+fhbhUqxP2854hIlH6Idh+MkH94Us+Dnv+AAmUwK6Vm977T4i5KKn4H9uCpV6YqT1HiS9Tey8EGCz3AcQOBwIz9VOEzHW17Gwue2E0R5r2x2nlUppeYtiSqUvYtk+ca1UguOPaQuF+VDND+uiuWDXHZe5ap5SrpuSm5S8w4U6Vk9Y56ngmecCr6/CKjxg1Dxbi16nkP9zSmt9TVMUODFkDeAzXDsQPFSz/FaF3mEwu48q54jLCJzxFBylIGXP55X/NiJ/XFh+XCjeGfTFfGp8tTt7yawfEzRVhZVurFbID2r95vmSeFP4hxHoEU3ffCD0vANavr7pXIVsvCumXfJjVf3KDm+zbvezqeb8ALvaqzbelZ5Q8MPWyJeSaUyKhr+ps1Ljh/2ezkr4hXRaO050NgSx2FInNCFGt4RqcBPHqRn9f6z5h9DUPyQ4ISA67ahqkzhWKbiuGdufDBN/JzgZU71N/5wCDTyPsTx1oQ33S3wRsZsPasiMmEOX3PgIMjCkSxFHPFTfILxfFubE3K3/gjnc4hXhi8Qh3A4xeD5LueFtkE9qw+YF7/ikfK6xwPnzUvrS5JgkHzXNt55cIyFt3mhq8w8Rw14mHwL93cK8UaZb+SUtp5VTsI03o3zRA6Z70t+VkfJ4xMcK82Zg/nZy8hxGd9j0HwzFz708DTlNaN/d6kT0rP6wGn3b21keMsn+LP0WF8PNqcumZZ89FUt8/GVTpyE+6KWY45ecDKEfy8nwXNm61ntFiQmz1+v+arwniTyRtD2N+PweaXvukVj/Byr59BD6y874DRU5K0OH1IcL5sR6Vl90DTPane6edUPY4WPV33L5jkL1APCshY+IWjPt2Ttvxpr4J2v42QQB2f46Sp4k7fzrPLkixzF5ighp/H4pMKHv8arIEddiyvdPN8Vvxz7144U5wg1cRg68qLYLZokI9Kz+uBp9y8v4paDKpyPbD0+3EwXCGqnePNCPV2mpTgR1ucNX+NgCic9dL+L+YQXeMuz9awK4nNeKF3TWJTiRCUf2DorPvkK3kpG3Wdc32Sa/m4ljmDzXSwsb284OsNZPoP0rD5kmic58l638P6lS3wjVX54cI6IIzFG8ayUjLBv33TmM1jkYJTmTUrj8fBxQnuOrG49q8IVzbk50eP8/OTm3bLur37pKv3Q+FnSz9l8x8botNOcg+trhuL7l6rwXV6G9Kw+dBY/wSE9HolnZpxvsxyYkqWroGvmnS9HQV1/raHor63i8InnmABvrANH+PqB3xi59axyZKAaPgLa/n46jns1fo5zAJXzQ/xQ53WUTxqpu2r5zuU57fmkyBeOz9dd388xRo30rD5s1vOD97yeI+qti5Bzl8VzeLO/CoP4gJCtoR64txyG6a+Z6xpBTjUpwfmPxPFqvr13nlXT+HnN4YOe3LD9FQd8N/Pk4ud4CrwTFyn0F4f5oIXi1F3rUcUQ+ms8eQPPwUKkZ/Xhs9Y/FzjVzU9Be2Ix52dE3354z+fhxuQ0P3Q5Tp9T97jzo4UjKIUZRw4/81fxhnDrWRVdusdZp34I4e11qJycKobzoPxsVbz3dkyKEfRgBN/QvHjSiSw8B+8LEzEZ6Vl9xCx+Kuj+lOAoZg8a9HdD5tjftclHN97PcZQud3c3TzUfIx95OfxsOavLwQZO9lKirWeVH7CNY/EcOKT+7hze6GmOz1fD2x1jC51IQnFwkJMDnng7w7+fc+wOfj4u8rNYIT2rj5z2noLGT1wOsfRRak6KZcGjcSQNJ3Ntn0J84m2Jt8qed8KcES8ciRaNk5q8kU6ktp5Vyl1uzhtD12cax6x67tLw8Tf399IFV/iUyA93/v68MfT876a/NMP1l5ry00slpGf1UdPqN3rUhIcltOAp2F8ZxMcr23ohVn+M6OyrybzWxRMBLk2cqqucUec9XX/rQNx6VjkP6ksPRPRXXHPkhSMrPfth+6uoeK/Cc7qeGHtfG/hJzhmr/t4qnuj6xHtLCtKz+uhp8b+aOW1reE0SJxLBnIdIHKTr72ewfMYKKnEMMPXXD3C22yijOUTIh5Ysk5X8x7aeVdn90klYa3jnLfjRyyle8ola7cZ9xdsjxsoHaf5IvChGPsUlfsZzUorjspoTIkjP6mOmPT9MEJKRGd7nST7jcxqJF6OcOTvWE7M1cMyZs2YcsedIK/FmRPLE6pEExsQZYaRn9fbAOv/HLtInAayzozsC+T1uEX7AOjG6M5DfmYvwA9Y50V2B/B6/CD9gnQ7dDcjvCYvwA9aZ0D2A/J64CD9gnQTdC8jvSYvwA+b56T5Afk9ehB8wT01nAPk9ZRF+wDwr3R/I76mL8APmCemBQH5PW4QfMM9FDwbye/oi/IB5GnookN8zFuEHzDPQw4H8nrkIP2CcnB4J5HfWIvyAcV56NJDfsxbhB4xT0mOB/J69CD9gnI3OBPJ7ziL8gHEiegKQ39mL8APGOehJQH7PXYQf8JxOTwHye94i/IDnTHoakN/zF+EHPCfRM4D8zlmEH3CfT2cB+b1gEX7AfSo9G8jvhYvwA+6z6Gwgv3MX4QfcJ9DzgPxetAg/4HOOzgHye/Ei/IDrNL0QyO8li/ADrjP0IiC/8xbhB7xP6CVAfi+dxG/0c74P6P8Dzhna8pMlGFG85s9evE3a2ZSSl663K9dQWuneOKo6BVmMjLp0eRCRcDaGGm07JL/3HxF+aO9mn3fvP4B38wOnYu+7Vcb9wZN83P26fPAA4/7nRTyrHzri66z0lWpx/K1VSUqIJIzvjYs+OP5+ypecfOu9yE6ULE0JMiYjXU0xKEE57TyrXdrBn6jxX196FXp3jVbBH0Tm7lctzqjclSheeJt5GOR6A72rXWeRfER6Vr80rc84udS8l0pW2zLjNC4Z1VwNXftWrXFOysK/4DOTrt00U2ssugqlo4tbz6rIXuZieIjB9CawWoRWWqZqGl+JbHxWUVM0tXfUU/PJ9dE2FTJ/PTNBela/PKvOv6sBySlNxbdgYpOiRJeIB19CVk215npLJn9qntbSJkpaCiuzou5ujFvPKv9WMyloG1prsWSfe+eEyCekKhRrzrV7BjxPalNsLjwlrUxkhSTpVA5Iz+pXZs0/kic0V8rozAPPqeYkKs+h0PtkgwtFSi1Ns3zHVucq4y3dTRNStFKbtvOsuuBy0U2QE7n3zjMWm70QpclYYnQiab4QopD3zrmgo3GFr4LyvAqZaJCe1a9O86QoEyg3IZPj1VO0UrNLmZc/vj+Tsl3tFELk+8sLImujzFXZKmP2NVvtd57VwIxCXyutTjFZk7Izol+ILmK0PLmZminKuahS5L8s10InZBZFO9E80rP6tWmet8rThNc+XwQ/cLSO1fDHdJq0DKXfujw8vod1LFWmYmOsgZ9mIaqmhbV551k1JgglDT/fFK9oqSleKq1I1UYVfa25axlPtCYqxQ8f5fj+zkE5wfO5KKGRntWvz1r/fE29ITbp0nTkD5W6TL0UKqW0rPnpYnXXritevHJS1HjhcqIWvs89P/Lr1rMqeGGzXgdiyLrwbO0u9pRJe2NUjPz9urCalwaZhYjk+UmvuzSqmSqk1QrpWf3GrPvX6OYD7zO6HrpUTab/a5Zkk1VFar6BeVPTHM8QX3m++WC7/IM/s2n9CbDzrDJnUt3KqqioanjlNMbx+sAPb+IJTSlLXfiXRLEmW9P7bytviKhQV9NXpGf1m7Pu35q6Zd/ZQrz3I8/js4VXq8Zcha+e92j8aE7UsrGNpwn/rucpGLLr0gSKW88qQyu8VxX8fHZehGZ1Xwuri5I3ljHybZ9E6UJGfoRE3gbyc1pY0yVRzvBT2SE9q9+aNf94IeIHR+53aVcfy8L7lW5L0aZ7ZbTm38pR844misiPSm2Ei87xFzWZTShbz6rgyWpD4Z2Ot7Hx1oe3xbHLH0Pk/WXrqlVeayOvdvxsItIndpOlz8mSs4gF6Vn9j2n3r2pGCp94EdciJ8tHA96ZqGZV8Jn3bvy4bDmUGGw/dLTGX6C14DOO62ZvufWsUquJ73jZHxOhNtsPIif66H1MvG4KzZeH2bXqvOsHkur7Npp32LxlJFkN0rP67Vn8WuDbslbHG0E+YhibfHWZb1Lev/X3EmQevhOOdzKUu+RJOx9q1rzTDplPJXXnWWVA1QZ+WnSvkU8MRxTdLUeM3fNBxFHt4tuSnPa8S+K9kcvUNTSaL4xxSM/qf856/vJs4QO0TzxpKvEWrWW+nR3xg5T3uJFv4G6l9KpLZmMjvtmS9PyENt0x4bzfeVaj5WNEFpLHkiRvEm31vMJF70oIOSb+8mB4M5m6tIKfTbzjbN2xyncvLxcxID2r/zXt/s21P3wrRxoizxP+KP1wxbtcq4xKKhtdrOfnLX9SUv0GrZZnl+LTHEcKzM6zykeJLvuWLnYLnuB9nbKyddEHHy74ocMXqWsXfLLUPXCm8u0bTujneTrHIpCe1f+exc+KKnUUzvOM0kE0PrBZ7/g5249bvPPjacM7EaU173QD33bRSaty9fyHeHMst55VkftbePiOj6p2xVboakKOFmjdX9bCYA1vuwuz551R307nwOsBcxCK1wuXBNKz+j/TPAF9l9uNoBwp6MYwxec0vrV46vjWvZ5KRcvD8y2dsMvwvlB6BsPT0iuePjvParVUWuQDtHXddJYadXj9FMy7Gp7mWRjFf4inZ38dDi8Q/MjihUPyubqVXJCe1f+dxY8PcJl4QeencOxmZF4G+3LYOJwQbO3e6ag5vtDt2n2t5PuQ1zLi52iJUlq59axKmbsw3xD/CacdR1qUVHxm5qlYa6DkfdTNKQ5PdM1b5SWvdGsSP4ddt+8FpGf1O7P48XaYo3yKquDzgePbqliKHGLqgb6+D0yBV6vAq9kJ1Uxw3URDfHgThinYvPWskuSY6v9X3pl965pdZb2SVCqVvu/7piqVBJLVN5UKibfoBXqBXqBjrFZ0ICIiIiIiIiIiIiIiIiIion+K3uiNioiIiEhiSEJPEgi/uTMYfDtwt+f7jf2OfUZG5dQ5u/b+1vPONeczn/muZ9HEuYwgtWF6I8ltVtPEbL3cT0CnMSNJIoYUiMi6AqIs1Z8mEikwaPqsfu5a/UeQ2y4IC7iFGURMoFMg96EPwHun1Me9fCbfDRizcA3X6qYXiVJZSrnls1rpZkluRgx+UF5p3DoNINu21E5LTXNnTIDoiYM3AjqMaHnRyT3sqMWh6bP6yBNXqh/LkfBdqAVVShxR/eqonHlGmgI+/kStN7YOhzTdRWSC/MFnEFjluoG1L31W5c41WM0k063tFo11ZJggDjxoBQwCBozHLBLglssxDErPnoXUS0ct7ulF02f1WU9cq35ASVK0xlQWJBZltHM3Ouek2+dvSyLvZToSGi3ylJP7u9y0VIHomX9c+qzyNcXPKYa3wUinwozD2oLSGkOkuWGUQh9cndQNVIab6zICu90kdFfKjqbP6rOvhR9DIkR0Cisap1zTMDJCFpts+CX2V7Rd1tRBqmffUY+d3N2XXGUGtJGvbvuseuOcoS2ebH9o3TBhiUerjFWQ/W5uCEtoEvzzxvpXcOYZpTHkcqbhNH1Wn3Ot/dtoP51cx+WFyVBOFlOxkuHVhj2HigAYpiAxlR6LXH24mJQgyEc4COrCLZ9Vy/iE1VhCK4kXFFB2wdQjUNFDo/cxBJGBH81bkGt15GehThhxUDdD02f10WvFH+MP0/kMEGLkT2YXNTsIL1W5Wnose3NZzUDAD2NHxkHisshEhBzpmHfc9ln1k8otl8nRTdiB8O/kSqrJSLUjTIQMUFRiVBfHHAXWtJujI0HVzrM3szV9Vp97tfijxTfIy10M3jyTRhkgW+Y/0NzKqMf3wu5m28ltmwwlCUvmw5kG1wUGaJc+qzYzPILmeHIkxRfRgUSZptzSElB18mCMJ20xtaVTOsQUvOcWGeZJE7maps/qY1ervykwXCMsLPuXsWMeEYnPilklEjKzHxqHNMmGQ3zbKCBQNiDfogcwtbj0WbUGXsO8vspFcrAckiSsEngykg1CWbPiFJdj4k+BBIkVmcdZJnEJBbINTZ/V510JP2QmppX8WAZs3jpG6MRNWqugniDoWyOSfREDUbHmJfnB+phdRMcYqW5bb/msircvpJmOrUVSZcieOUgxCbk0J9PEFlnqj0+pU5t3latahpVGRPT+pumz+vi18BPHVM/i4NBMORiMhWFTkGuDOrEjt9wwB6IJg/oSMnRg2UKG/TTLSDdy6bPqUP7QQUmNJAP6lE3lIbxhy43CQvD2MFYfn7+GqSBrlwHXFkUWYbG5rOmz+vxr7V+5qQed3ey2hbxt9pf498YCr6H/GDIRouVAz5pRbBvt56/PYKgme3Re+qzy15FYNuKLPlsyyIgsCEnfBE9kI1vTBjexBIcOyc2d0EzLt8+0yCgWUdNn9QXXij8a0snglkTv+cR20pbJ/cqoAEkGlks2HJ1dR19ATBlyEylqAApqzSjK7pbPakOlpx7IGB12DSIyFWIesoVdOheFSbuRGERFuTlswAOJ1Rpyo0v0SdNn9YXX4i9xg8/qhAaqHsmfHCiG3Z06S4LKdcsMjfj0Xbavlbu8JgKgOPeiod7yWaVbgeQxRJpscHkXjNAitcrbR2kKy6R9IwmOEmWkvm1x0MwWIYRyi2kYmj6rL7rW/qUkohGQ+oNIAjYNiqZcXspUHaWKDRvlppFg5cKvxUwpy3VBksaY+tC0XvqsMpwcVBUX/JAb+URkrcvJNa9oCfSHhC3QiTYR0WWQ7xHuxyDDMkEwfhdNn9UXXy3+CuoRQ8VIJxXNZFBEn1/DEhttZJTgbi6khmxQTukpUpE3PeTaHzivdU7TZ/WXFN/zf8m18t/dflnF9+zsJxXxe+lJ8FN8T8z+siJ+LzsJforvOdlfVcTv5SfBT/E9Hfvrivi94iT4Kb5nYn9TEb9XngQ/xfck7KcV8XvVSfBTnPPbzyri9+qT4Kc4p7a/o4jfa06Cn+Kc1V7OHO+K32tPgp/inNA+WxG/150EP8U5l31UEb/XnwQ/xTmNfUwRvzecBD/FOYN9XBG/N54EP0Wd3L5AEb83nQQ/RZ3XvkgRvzefBD9FndK+RBG/t5wEP0Wdzb5MEb+3ngQ/RZ3IvkIRv7edBD9FncO+ShG/t58EP8U+3b5GEb93nAQ/xT7Tvk4Rv3eeBD/FPsm+QRG/d50EP0Web9+kiN8TJ8FPkafatyji9+RJ8FPkWfZtivi9+yT4KfIE+w5F/J46CX6Kdc6+SxG/95wEP8U8bZ9UxO+9J8FPMc/YpxTxe99J8FPcJ/a9ivh90ZXwu+vn/G+K/n+KMWNv4eftaEVOnpTQwt4xOr+LuPjEnO2cK4bCOsP+/Mvu8u5jcCYMH9La09Yj8fvJB4Kftu+mxN1PHuC7+d+fo7vvzrLun7rn65bn8lMHrPt/nMRn9acfeJ41ta3lVizDND9j7KYPE3prIcZks+175z2ns7W0uauR4yHDFF/GDNbHfemzCvziz1XzbmnY7k0bOzrXawhTjs/nUPpow7Ywu/G+7cqH9zvV0FYIyWj6rH7Vtd5TrzmXXdfaye8eg5yU6EAl58Syt2UOOdbgtjN7jrz5rdt85BpyMXFOe+mzaldcPRp5y51vOFKuvvdVzfY2gv1wJfI3Oe0UsvzHO4zp4mi7ZCOub5o+q3/hWuckfGiu+e2yrzETr0A0jZlj8nlLjHnuWFZwzQ5ipozeapje9t5W7/0LfFblxG1oINg2ETtCK8H0kOuMnYXxREy20QMgz6dEH+3ItsTdhxi9Da/ps/rV18Kvzym2dnXZtN0oxo+4irFNTmzWUZonNdQQ996l8wnZx2nKeXff1s6rXPqsuuWKS93NwFd2Akx8zSYB7XtaYsGwlndr8TRc6OJjZnk4pBuX+PLsh6bP6l+82jnZBUhk0ub5oNaLJ0cZrMqGRjjGVW/26ZCDdc3UeuM9k7scPanVtvnRW/hV7+PaYnYWbE/WWRvEa3SGZtYectbTNTOWeLjenKcFWcIwW+uz70vTZ/VrrpX/mncUGx/ECNq3bNYimRfZoK0UY8KmrohJXrMmB5N9pmy45qYZlJuaL31W+couX7dYBMVHqpsYcZvd7cwx776JsxR5SqvO2XrYri/Q6MuREYrV9Fn9S9fCr4ACa7NLTlV3b52hGvPR2YvFm5pK4tOZZVoe/H2ZnlTmb2x1Vg4uXvqsuuUbKc67uYY3g8LUghxjt+zQ3mADpMU4CbZASfaEpxnbpFLET7SaPjV9Vr/2WjpFtT2mSlVMUkPYvmMTRcYkm2aDr6wlNh/ORpcGVKkHJ0bUgTQnSd9d+qy6YqcvCX41U8pbaFGd25MQwgCNsdnvznQ/mwQyEVhSilAbvnP0JARNn9W/fLVzirvZVPixfNQKbRnEyp6d2pFzKuLRSEC52goF143d+PjWEpzR5NV8vfRZZZmmFrep6JNvukJM8NWUSAMGVuRdJ8Pa7hakcrLDc21iPW1gSJkfWDV9Vr/uaucUDbluQG+T9WVRFRwkbsD3WtxwXxbRgt0wxGxZtKsVApNTjmzl5U285bPqxSO++UjmLAkG71MLEONhidyyqT9dDLcqtZ7SU8sWC4JOGoBoz+yTps/qX7maz1FKNQ4Xlh92wlVgvwa+nKaUCgOBhjjz2zTDoPUJAOdjHGP6xPbM5tJn1YinT9/0Rj7V3aDJYtkdBiFJlFWaJstPCyP2zYPaYTfjDYGXxIDZpabps/r118p/cI6bXRno5MhPS7zsbqIxjpu0NdNge5dMs0BgLfHlirsSp4U0tsKlz6r1EptyJl6qDMTEkOdCHrC8ngjfUanONDRymBkshuOHuukHbLIGMoemz+pfvVb8TWrfFCPVXbcTngIvm21DT5aVtkOsy8I0PfY2KoneBbn6YdJnUG1Xv/RZdTaxc+HGfUa3DQR5tQSKlKieCEx6EZgRFH3fNNhw6RDEUMpTmcSeStNn9RuuFX/OpUSqa4niMAEqiiYxrK3sKbtrErwGegEShstzmTxh2pkg9CFSRi59Vp1c5EAN75PWjjJUC6V2WBfERAkIqBY10SBXSned6AfUrCGGC1vMgEfR9Fn9a9fCD/a/oS5J3MfpsgyMjOo53JRbQgbbNYSagh8OXo3eIq6oo1or/LdDdy59VvliKyyRZNp9l1shiGVyp2sIMX0sKhXpcNNAw86pSa4FNxPcCKreoZKaPqvfeC38fAkBbYDOlQ9F9uKDhk1hpT7Ay0hl9GsQFxqO0vIMuY1VOvSQ3Uc/Zi99Vm3NfQwkKsCBEqcGKKWlPA1lAxRyiiuKS3K21JMgXZ0vcjVHilLLh6bP6l+/mk8Kip/tNm7irFhjacuIkbCiSC1sw07/X3ZDOEDD45OK7cSSS0mklTX7ls8q1YbCQVUJOxNkdIZtjy7u/BuZyt98p16k50WDiLMLxyQot6lUpRY0fVa/6Wo+b1vuC6jRodtVmqpNm8qeY/cK+RD/RMQmSwbcBSW1i0cvZJDubQThMbd8Vm1dngYuw37EyXsI1WF3eu9iaylSmxBvUiLWyiJIkXgWdCi5NsdKu2j6rP6Na/Ufm40GHxZ7KM9uLbNa5Ow6B+EVKbg9Vzq5vPmQmdqRV6TKOLPEM5RSc+mzauQiK9NbLmgqy4owCw2voU83smnIqLsh4HgqE9WWHNqGr/DF7KJHXw2aPqvffLX+w+6cSOB8TGASE8ou1K/OStLPpVcnN/1QnGtMjAUIVvZol8bEJeC+9Fl1I8k0oZvoKLGL7U3Tls30UxhRYMEzFdYLw6Qyr+Ryk9vAhvjNGPKBps/q37xW/E0xvQujys1TxBqbT4woadlydYXI6UY8K3ukm5DxBhtbXG3544nW1+qlz6qRm7vyHnDJUlatUiDQ/zIkGSm1lCESBWHHRARZEVYIVeTj0aqgxVCpNX1Wv+Va+CXUTSvOqKghEdUUTd2Ik7ZLheK5PMMQ+JzcRdLqTcOwEKtRtNBCGVGVS59VChEVw3UYjJFbwwL/5V4FmWrUm6skoJU78SQcCpe3My65xoQCFkcS11pNn9W/dTX9nnEarSyq1axBXGszLUY12cl9Z6Q4Wqu66XqzFf/4GGxCaYUzUinYlP7SZ9XJDC+6xngpod+LbIqkT6FFt6fjk2KSZt10wQv+M5EneEaU+YHmRYKtmj6r33qt/CdXgOSR1nQb6uFRq2jCjOSrSY+xbCfxMwhCgp5OrjTLdK9iGY9omJ1Plz6rKKN1IHYZQoxJCf8kmIvYBg+PqO+dN5uoFAU2Z1IkxWj5Qm71m0ndipo+q3/7WvyPnePXQjG1ZP/aR5yiZMlIbjJbZg4p/rIhIiCItgdjDnKFRhfO2/jAlz6rLAOWyLZFqmLIQbUR9V6+zmQ02Ml8TibYhCVUZtaeiUlkHct8O8m1Q5o+q992Nf7H7DyUkJChLSoCPQe5H9lAXLTtzf1V6NErRYbl0Yg7Ms0ZM3YUaGj0Dpc+q4DO6C6IU22zCIsM0pET86RfgR4jbU+/gty5JJaGFjiYtFDCC2NntJ9eNX1W/8618DO7Im8SYvRodc8q9+ct4oTtiS5SBuoVtVFiCmYdvHh3Q3gMiuqgNVuXPqsEW+pyZYg1fPGSdyO2mVXuLeGPIUF1oGZBHRcD4SLmkDyWmkMibyBbbE2f1W+/Wv2wdPNJ2EaCxNDTItqXKdbwNzf1EWo+QA2JS08FKbkZuSnOmkFWo67e8lkV5cYXQgkNe99MlJNfYsAX+mDYDlWXO3PE13zWm5auy3UtVK+EtjO6ps/q372a/gflSMw7Wme2SEtm0Jpji0PsysVudTH8RcWqowr9M6bkaGQoxwdH8gqXPquQ7NVbZL8ySJJZZRcWTY1t6IaybshL8yYzv5OrE6nD7PMtV7QwmTPVaPqsfsfV9BfT60RN7zK3hdpZhttb+qmClIUaCimW+wam3KMBZ0tSWdHaR4wMgkK85bMqqsOOC8XZwlhkezOJT3IryZ6S9BASnXNe7GmJaZSsVqkq8pJSW9RlTZ/Vv3e1+S+4MJdtUcxp0UeRoGmAqScNJUpsoaU/gKSFSdYq8iZLWSVD6+TWluJu+axKSwvFC0ASmB7zPIJIVSkyAyAVICQW6Z+bgyahy0a5ARD9rzhLITZb02f1O6+Fn1ybKS++5SD6ACwaWhHlfqWc5EbvKr7IUSbAJVJdyPu0JGxBI7cXwBMvfVYhdGhRrghsDCkHCr1ngE4GZYgkDTMrpwhbCjNooEGnNoGJNq6GMVfV9Fn9+1fT/7a8LdUQBSCz2y3obEPfa3bFyFhxy01czIOZrXtUOlfabox9GWRE0Wmsps/qVym+5/9dJzknofienf1qRfz+wUnwU3xPzH6NIn7ffRL8FN9zsl+riN8/PAl+iu/p2K9TxO97ToKf4nsm9usV8ftHJ8FP8T0J+w2K+H3vSfBTnPPbb1TE7x+fBD/FObX9JkX8vu8k+CnOWe03K+L3T06Cn+Kc0H6LIn7ffxL8FOdc9lsV8funJ8FPcU5jv00Rvx84CX6Kcwb77Yr4/bOT4Keok9vvUMTvB0+Cn6LOa79TEb9/fhL8FHVK+12K+P3QSfBT1Nnsdyvi9y9Ogp+iTmS/RxG/Hz4Jfoo6h/1eRfz+5UnwU+zT7fcp4vcjJ8FPsc+036+I3786CX6KfZL9AUX8fvQk+CnyfPuDivj965Pgp8hT7Q8p4vdjJ8FPkWfZH1bE79+cBD9FnmB/RBG/Hz8Jfop1zv6oIn7/9iT4KeZp+2OK+P3ESfBTzDP2xxXx+3cnwU9xn9ifUMTv318Jv7t+zv+p6P+nGDP2Ej87qnMti7VflANU/D7lMowPJSbb97T8yrGmueKKPtdUbw6vrJ2mD3keid/PPBD8tH03Je5+5gDfzf/1HN19d5Z1/+w9X7c8l589YN3/+yQ+qz/3QPOEi1be69+1xmpNMfxPTiRa73tdQXyK5ASZuFL4MfNOYY+0Zx/bl5lns/8B3P7jAXHz0SeO3S8u7h6NuPWNHXY3IY8+fbfD5lnzEHe1tFodzbHQtARiMfxMq1oxHov/iTX/5wPW/bGj1139TKxRrAqcNc7HuH1dfSe3q+2G2OnRg45P+cZjdzW7vF0zSqx5/19Y8389YN3//+B1WxPE3Sy2bsTPbdVk2CxtuDhbyAR6irUS6LHVntdk14S4beiNrTPsCOIX/dMHrPvjB6/btNZ8XG4U1rJJD3M1v7xYOtXU5Ni1675YX2PYS8wm5OxhNdvtVEfNWfL3zx2w7l86Sf+imIfsxxT7l0+cBD/FfW0/rojfJ0+Cn+I+sZ9QxO9TJ+mf/48ir1OMGXuJn82DCsvqdh+eIuvMLGnvNdPIo7FM35MtIw7bUsmsfAZTqM6VMu5DPRS/n38g+Gn3UxJ3P39A3fy/97yPPGrdv3DP1y3P5RcOWPf/O0n//IsPPM/auu22vU25BKM7m3ozee8kXm5+OSc3IIwufq1jdDnaHQxtVa2tWDNzSpc805pq+GxjrWnowfn/MGwyznn60WKzpQudxdYx+Bk+uZRmXzH46KRP30GTZ376Wjwppuy6+AiyRrmtJIJbyywo+GZ9CD4v3xoAJh/6zd0FefeeWzQm+B4ueaYNrMik6IvYQuaVSl+Dp72ivTlqb4OrOZRCWzcy/X3ZbedlLN88eru9Js/8zLXwW9uMRKiVXvbwBAZhhrIjbmaIQSXusDatnxuu8yFT3tUTirbn5DdyjybP/LQifp89Cc/8qGL+U4wZewu/2Esa7J6ytrelJyQgl1ew1U0bqggdudWciIuZkpkrzGia3HFRXUMcOhK/jz0Q/LR5h8Tdx47Q4+453zpq3R+/5+uW5/LxI/S4k/DMTzzwPOvEPMj1bmMz08XEHAaGasdgDFQhf6s2tHwfGlx2LOTe4VD2Z4TSpmhWvaVnBpkUeZdizBVelJYR68RtzbIt9rmSWc3NKZf7zFargTkMG8QrcPPHTpNnPvLklXhStz2Iwx4E31ezzPbd8zTmyAvanvuOqOHMwLb33trIE3LB+Bb5XY293+aZxvIcp7co6i10W2FdzIgMfLJDL20QzyyeiM2r0WTQWfS+QkriPjlX1eSZz7oSfkwLhl+RKJtmEubbDcN8TC62Yzq5xDWz2xRdayl407yPZTZDrBaXxGtck2dexsxd8Xv2k+fIf59UzH+KMWMv8SOh9FHj3KEF9kOmx840ueSSPZlE5XZj599SW6Qwn9li7AfGU5WsmVs+lGd+6oHgp807JO4+dQDv+OV7zreOWvev3PN1y3P5lQPW/asn4Zm/9sDzrIvFleVaEnvdSKn3qQ+5+ZfvbFNdwSHK2VyLCUEM9VNJBUaQesqzW+du6ZmAyjfwCfR98bZPKxcAbdgqimmEVRknjvFj9pHjsnwZnNhEuYCAT5o0eeZjV6rz1thlQlulBm9d5WOXLO9Oye3TY88qF19PGJNwfhfrzfWaVq5cFUfQ3fIlz3RxoWTuUF2Bg8qLXnKJUIBwoYfKlY8j0FyMlWbkqaGZLutGcMM6vhv6nybPfN61eKZPsW4+rWvBsMA2fEGor3KzqFxwFEdjrQQJDdBIOy0aoikW8LUApc+aPPMxRZ75+El45q8r5j/FmLGX+LmQo+sh95EG2YnNIe1V2ZHMIu8vMbwxNtMWxx176H6K932aQaInV1ePxO83Hgh+2rxD4u43DuAdv3nP+dZR6/6te75ueS6/dcC6P30SnvmZB55n7+rvffv9zNhjy95siLAf2xUE0e26SdmEjoqHJOojVGvI3B8yJW/Bpixm/WizWVXPfNG1eCbq4y5mMOOtjLxhnGbABFet0YflK1PyVOVl/jG25aEw7oWmo2wybZ8tp1vvZyY/5ijNtmFigGEtP2rIzUOwIg9a7nvvBrU5QjlRtW8u/iyM2eHz9B2qPPPF19KDk4+e0f+Qq9FAxUQjlyvJtXW1VeODcanJnZq+l569nZXP7JsLcYrFftTkmS9S5JkvOQnP/Kxi/lOMGXuJnyXPBBKSkRashSVqdlrytg0boDA0KDIk6HJjdU1Lzt4UNpx3YdYsb10cid9vPxD8tHmHxN1vH8A7fuee862j1v25e75ueS6fO2Ddjzx6jjz7rEcfZp646/lGef/2Fw+Im1c8eex+uev5Rnkf5BMHrPuVR6/7jucbZT7xawes+1UHr/uu5xulX/7MAet+9cHrvuv5Rsnfkhu11/2aa/Uvd/tlFfOQfaVi//Lak+CnuK/tqxXxe91J8FPcJ/a1ivi9/iT987MVeZ1izNhL/KyZa1dvTUaBC6xkJhNz9rlsynWxFUJSmJaiZY2NfMgQ2Pk+kF8Sy+yH+gM954Hgp91PSdw954C6+eijB/OFu/06bN3Pvefrlufy3APW/dhJ+ufnPfA8e9fzja+49Tnvdr5Rk2e+41o86Y7nG191Sye52/lGTZ75zmvhd8fzjZo88x2K+L3rJDzzccX8pxgz9l239sXOxEQ2nXCvceedTRqIiK0HUo3fzXS5U5u5cKr8u+0hVjdqSZb5ddxH4vf8B4KfNu+QuHv+AbzjBfecbx217hfe83XLc3nhAet+0Ul45osfeJ696/nGW3rmHc83avLMp05yvvE2z7zb+UZNnvmek5xv1OSZTyni996T8MyXKOY/xZixl/jZtnbkmdO45mh7rLu61DYdbzE+TlvnGqPO4MpiO5AoIzuDPyBfDVqVQ987f+kDwU+bd0jcvfQA3vGye863jlr3y+/5uuW5vPyAdb/iJDzzlQ88z971fOMtPfOO5xs1eeb7T3K+8ZJn3vV8oybP/MBJzjdq8sz3K+JnTsIzX6WY/xRjxt7CL9jqYzLZZjl9sbpkq5YMe23u5bspaTga2JinqUne/mJqEHqkK2PAE9uR+L36geCnzTsk7l59xPtm95xvHbXu197zdctzee0B637dSXjm6x94nr3r+cbb72fe7XyjJs8MJznfeOv9zDueb9TkmfEk5xs1eWZQxC+dhGe+QTH/KcaMTbd8hEryqzLxCC7SV8fsUb8ZH0RZLpOdwHo63Wzxo9hamCfYyMbsO0Q3ejkSvzc+EPy0eYfE3RsP4B1vuud866h1v/mer1uey5sPWPdbTsIz3/pA88RdzzfK+7fPOyBunr7n5xvlfZAXH7DuD97z840yn3jlAet+5p6fb5R++fUHrPtD9/x8o+Tvtx6w7i85yfkyxTxkP6jYv3z4JPgp7mv7IUX8PnIS/BT3if2wIn5/5CT989sUeZ1izNhL/Jzxae3OdFMUpBQZ/s7cUA+F3eVRt4zuIGoUI2dgcimi9pUlBxNK920fid/bHwh+2v2UxN3bD6ib77jnfeRR637nPV+3PJd3HrDud52kf37igefZu55vfFrxfKMmz/zSk5xvfEbxfKMmz/yjJznfqMkzv1QRvz92Ep75pGL+U4wZewu/kYnxmmPPYY4qaacnX2W5lW6/edNX2EggOfotacyY3QJZLRA8iANH4vfuB4KfNu+QuHv3AbzjqXvOt45a93vu+brlubzngHW/9yQ8830PPM/e9Xzj04rnGzV55ped5HzjM4rnGzV55h8/yflGTZ75ZYr4/YmT8MwvUsx/ijFjb+FXjA2zESnTppQXbekeleFSG5ZmzPCvk9Y4xBSqIx36HOXNMTJZ9CTIQ883fvEDwU+bd0jcffEBvOP995xvHbXuD9zzdctz+cAB6zYn4Zn2gefZu55vfFrxfKMmz/zyk5xvfEbxfKMmz/yTJznfqMkzv1wRvz91Ep7pFPOfYszYS/xsJeVkNtCkc27DtUKwNHKSrzM1x8JGmDNMn2n5Co1e9MbUzZJ9WKmFI/HzDwQ/bd4hcecP4B3hnvOto9Yd7/m65bnEA9adTsIz8wPPs3c93/i04vlGTZ75FSc53/iM4vlGTZ75p09yvlGTZ36FIn5/5iQ8syjmP8WYsZf4ubq6dKSuefJUoS31PbDe4BL9VfOOhXVXZ/S9V2YqW47mlDAtg5gVszsSv/pA8NPmHRJ39YhzS/ecbx217g/e83XLc/ngEeeWTsIzP/RA88RdzzfK+7dPHBA3/Z6fb5T3Qd53wLrHPT/fKPMJe8C65z0/3yj9cj5g3euen2+U/P2hA9a9T8K/H39EL5d3xf7lz57kfJ5iPrNTEb+vPAl+ivnBbkX8/txJ8FPcJ/YrFfH78yfJf1+iyIsVY8Zq4ieYPeuRP/hLu8dSxNJcft4PP/r7v/+93z77D4mJxw5Y0yNf8HO+EMeX/CF/pvrDj3hIH35U//t+5FG9TXnUuj/yqPozupWc7jOmj118Rtk8AsVzH/n8pnneI7+/oSTIH79Y0+8CtyUx2g7aGQA= diff --git a/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/target/witness.tr b/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/target/witness.tr deleted file mode 100644 index 28f73665f80..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/target/poseidonsponge_x5_254.bytecode b/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/target/poseidonsponge_x5_254.bytecode deleted file mode 100644 index b330916cba3..00000000000 --- a/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/target/poseidonsponge_x5_254.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/target/witness.tr b/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/target/witness.tr deleted file mode 100644 index a8558ca73c8..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/pred_eq/src/main.nr b/crates/nargo_cli/tests/execution_success/pred_eq/src/main.nr deleted file mode 100644 index c7986cb7af3..00000000000 --- a/crates/nargo_cli/tests/execution_success/pred_eq/src/main.nr +++ /dev/null @@ -1,6 +0,0 @@ -use dep::std; - -fn main(x: Field, y: Field) { - let p = x == y; - assert(p == true); -} diff --git a/crates/nargo_cli/tests/execution_success/pred_eq/target/pred_eq.bytecode b/crates/nargo_cli/tests/execution_success/pred_eq/target/pred_eq.bytecode deleted file mode 100644 index 16e4554e9e8..00000000000 --- a/crates/nargo_cli/tests/execution_success/pred_eq/target/pred_eq.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/81TMQ7DIAw0JGTsW2wMwWz9SlHJ/59QqaISStlipNxixHC+O9sbADj4x9Lqs1W8BjIdF+MeQk2+EtMLfS4SMcSyCwlFiW8vzFWCpFxywkyBKx0x89HIrCLXoufxy2UGWRrlLDU193rXwdsOdmKb4AlOfc45PgZ/qs1nDGmdwOtAb/ln+Xb6M8KO8taZ2k5jfzw/fADLYG+4cQUAAA== diff --git a/crates/nargo_cli/tests/execution_success/rebuild.sh b/crates/nargo_cli/tests/execution_success/rebuild.sh deleted file mode 100755 index e227b34b5ef..00000000000 --- a/crates/nargo_cli/tests/execution_success/rebuild.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -set -e - -excluded_dirs=("workspace" "workspace_default_member") - -# Loop over every directory -for dir in ./*; do - if [[ ! -d $dir ]]; then - continue - fi - - dir_name=$(basename "$dir") - if [[ ! " ${excluded_dirs[@]} " =~ " ${dir_name} " ]]; then - cd $dir - if [ -d ./target/ ]; then - rm -r ./target/ - fi - nargo compile && nargo execute witness - - # Extract bytecode field from JSON and save it to a target directory - if [ -f ./target/${dir_name}.json ]; then - jq -r '.bytecode' ./target/${dir_name}.json > ./target/${dir_name}.bytecode - fi - - # Delete the JSON file after extracting bytecode field - rm ./target/${dir_name}.json - - cd .. - fi -done diff --git a/crates/nargo_cli/tests/execution_success/references/src/main.nr b/crates/nargo_cli/tests/execution_success/references/src/main.nr deleted file mode 100644 index ec23f2f3a38..00000000000 --- a/crates/nargo_cli/tests/execution_success/references/src/main.nr +++ /dev/null @@ -1,232 +0,0 @@ -fn main(mut x: Field) { - add1(&mut x); - assert(x == 3); - - let mut s = S { y: x }; - s.add2(); - assert(s.y == 5); - - // Regression for #1946: Method resolution error when calling &mut methods with a variable of type &mut T - let s_ref = &mut s; - s_ref.add2(); - assert(s.y == 7); - - // Test that normal mutable variables are still copied - let mut a = 0; - mutate_copy(a); - assert(a == 0); - - // Test something 3 allocations deep - let mut nested_allocations = Nested { y: &mut &mut 0 }; - add1(*nested_allocations.y); - assert(**nested_allocations.y == 1); - - // Test nested struct allocations with a mutable reference to an array. - let mut c = C { - foo: 0, - bar: &mut C2 { - array: &mut [1, 2], - }, - }; - *c.bar.array = [3, 4]; - assert(*c.bar.array == [3, 4]); - - regression_1887(); - regression_2054(); - regression_2030(); - regression_2255(); - - assert(x == 3); - regression_2218_if_inner_if(x, 10); - regression_2218_if_inner_else(20, x); - regression_2218_else(x, 3); - regression_2218_loop(x, 10); -} - -fn add1(x: &mut Field) { - *x += 1; -} - -struct S { y: Field } - -struct Nested { y: &mut &mut Field } - -struct C { - foo: Field, - bar: &mut C2, -} - -struct C2 { - array: &mut [Field; 2] -} - -impl S { - fn add2(&mut self) { - self.y += 2; - } -} - -fn mutate_copy(mut a: Field) { - a = 7; -} - -// Previously the `foo.bar` in `foo.bar.mutate()` would insert an automatic dereference -// of `foo` which caused the method to wrongly be mutating a copy of bar rather than the original. -fn regression_1887() { - let foo = &mut Foo { bar: Bar { x: 0 } }; - foo.bar.mutate(); - assert(foo.bar.x == 32); -} - -struct Foo { bar: Bar } -struct Bar { x: Field } - -impl Bar { - fn mutate(&mut self) { - self.x = 32; - } -} - -// Ensure that mutating a variable does not also mutate its copy -fn regression_2054() { - let mut x = 2; - let z = x; - - x += 1; - assert(z == 2); -} - -// The compiler was still trying to convert an LValue from an array of structs to struct of arrays indexing, -// even though this conversion was mostly removed elsewhere. -fn regression_2030() { - let ref = &mut 0; - let mut array = [ref, ref]; - let _ = *array[0]; - *array[0] = 1; -} - -// The `mut x: &mut ...` caught a bug handling lvalues where a double-dereference would occur internally -// in one step rather than being tracked by two separate steps. This lead to assigning the 1 value to the -// incorrect outer `mut` reference rather than the correct `&mut` reference. -fn regression_2255() { - let x = &mut 0; - regression_2255_helper(x); - assert(*x == 1); -} - -fn regression_2255_helper(mut x: &mut Field) { - *x = 1; -} - -fn regression_2218(x: Field, y: Field) -> Field { - let q = &mut &mut 0; - let q1 = *q; - let q2 = *q; - - if x != y { - *q1 = 1; - // Make sure that we correct load reference aliases through multiple blocks - if x != 20 { - *q1 = 10; - *q2 = 2; // now we'd expect q1 == q2 == 2 - - assert(*q1 == 2); - } else { - *q2 = 15; - assert(*q1 == 15); - } - } else { - *q2 = 20; - assert(*q1 == 20); - } - // Have to assign value to return it - let value = *q1; - value -} - -fn regression_2218_if_inner_if(x: Field, y: Field) { - let value = regression_2218(x, y); - assert(value == 2); -} - -fn regression_2218_if_inner_else(x: Field, y: Field) { - let value = regression_2218(x, y); - assert(value == 15); -} - -fn regression_2218_else(x: Field, y: Field) { - let value = regression_2218(x, y); - assert(value == 20); -} - -fn regression_2218_loop(x: Field, y: Field) { - let q = &mut &mut 0; - let q1 = *q; - let q2 = *q; - - for _ in 0..1 { - if x != y { - *q1 = 10; - *q2 = 2; // now we'd expect q1 == q2 == 2 - - assert(*q1 == 2); - } else { - *q2 = 20; - assert(*q1 == 20); - } - } - assert(*q1 == 2); - - for _ in 0..1 { - for _ in 0..5 { - if x != y { - *q1 = 1; - // Make sure that we correct load reference aliases through multiple blocks - if x != 20 { - *q1 = 10; - *q2 = 2; // now we'd expect q1 == q2 == 2 - - assert(*q1 == 2); - } - } else { - *q2 = 20; - assert(*q1 == 20); - } - } - if x != y { - *q1 = 1; - for _ in 0..5 { - // Make sure that we correct load reference aliases through multiple blocks - if x != 20 { - *q1 = 10; - *q2 = 2; // now we'd expect q1 == q2 == 2 - - assert(*q1 == 2); - } - } - } else { - *q2 = 20; - assert(*q1 == 20); - } - } - assert(*q1 == 2); - - if x != y { - for _ in 0..5 { - if x != y { - *q1 = 1; - // Make sure that we correct load reference aliases through multiple blocks - if x != 20 { - *q1 = 10; - *q2 = 2; // now we'd expect q1 == q2 == 2 - - assert(*q1 == 2); - } - } - } - } else { - *q2 = 20; - assert(*q1 == 20); - } - assert(*q1 == 2); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/references/target/references.bytecode b/crates/nargo_cli/tests/execution_success/references/target/references.bytecode deleted file mode 100644 index 3e521923327..00000000000 --- a/crates/nargo_cli/tests/execution_success/references/target/references.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/references/target/witness.tr b/crates/nargo_cli/tests/execution_success/references/target/witness.tr deleted file mode 100644 index 22a1c7fe109..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/references/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/regression/target/regression.bytecode b/crates/nargo_cli/tests/execution_success/regression/target/regression.bytecode deleted file mode 100644 index 9e58970bbca..00000000000 --- a/crates/nargo_cli/tests/execution_success/regression/target/regression.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/regression/target/witness.tr b/crates/nargo_cli/tests/execution_success/regression/target/witness.tr deleted file mode 100644 index 9627511fc80..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/regression/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml new file mode 100644 index 00000000000..0361b28fd1e --- /dev/null +++ b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_mem_op_predicate" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml new file mode 100644 index 00000000000..3621f24082c --- /dev/null +++ b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml @@ -0,0 +1,2 @@ +x = [4,3,1,5,111] +idx = 12 \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr new file mode 100644 index 00000000000..a592e2b62b4 --- /dev/null +++ b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr @@ -0,0 +1,8 @@ +fn main(mut x: [u32; 5], idx: Field) { + // We should not hit out of bounds here as we have a predicate + // that should not be hit + if idx as u32 < 3 { + x[idx] = 10; + } + assert(x[4] == 111); +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/target/regression_method_cannot_be_found.bytecode b/crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/target/regression_method_cannot_be_found.bytecode deleted file mode 100644 index d3c2fd3959b..00000000000 --- a/crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/target/regression_method_cannot_be_found.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/82Y20rEMBCGU3Wbpue+SbtqFu/2QbzxdCHIIuL7446bwFBnTWBnQgZKeoD//79MaUkKpVShTnWNzqnau3G+rJa17qMbzfG4Wj0r+f3nEnFyaW6OGhun1bvcN6wey2xcj3AVZ3qkkH+JsvFkOc1hyaq5ewYNjfJ7Vp+9Qc9LNGpetqVAnl7XX2sx3+0WNKoAf0XkqBLyV2K+9rf/JsBviBwmIb8R87UPoFEH+GsiR52QvxbztW+e8T/+hsjRJORvxHztHWi0Af6WyNEm5G+Rr8T3L5ZfZ8DP63v7BBpdgL8jcnQJ+TvkK9H/WH6dAT+vr7Wg0Qf4eyJHn5C/R74S/79YfpMBP6+vvQeNIcA/EDmGhPyDmK99AY0xwD8SOcaE/CPylfj/x/I3GfBLfP9j+XUG/Ly+u1fQmAL8E5FjSsg/IV/uPQVY0/m+fn69H74/DuupgPJbRAW6j18bvFT/s521Z5ojdaZ+ACQMHzFQEwAA diff --git a/crates/nargo_cli/tests/execution_success/scalar_mul/src/main.nr b/crates/nargo_cli/tests/execution_success/scalar_mul/src/main.nr deleted file mode 100644 index d9d267f1dcd..00000000000 --- a/crates/nargo_cli/tests/execution_success/scalar_mul/src/main.nr +++ /dev/null @@ -1,22 +0,0 @@ -use dep::std; - -fn main( - a: Field, - a_pub_x: pub Field, - a_pub_y: pub Field, - b: Field, - b_pub_x: pub Field, - b_pub_y: pub Field -) { - let mut priv_key = a; - let mut pub_x: Field = a_pub_x; - let mut pub_y: Field = a_pub_y; - if a != 1 { // Change `a` in Prover.toml to test input `b` - priv_key = b; - pub_x = b_pub_x; - pub_y = b_pub_y; - } - let res = std::scalar_mul::fixed_base(priv_key); - assert(res[0] == pub_x); - assert(res[1] == pub_y); -} diff --git a/crates/nargo_cli/tests/execution_success/scalar_mul/target/scalar_mul.bytecode b/crates/nargo_cli/tests/execution_success/scalar_mul/target/scalar_mul.bytecode deleted file mode 100644 index 86642ca962a..00000000000 --- a/crates/nargo_cli/tests/execution_success/scalar_mul/target/scalar_mul.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1Yy26DMBBcIE1CkiZp0qiVaA9ppZ5tDMHc+itFJf//BVVj1QdDuHkWgRpfbHEYPLMPZvkgooSuV2j3T7sLvyUDB0uJU5bVRVpLJb9EWlY6F1lenbTUMtf5d6qVqnWmi7IqC1HKTNXynJfqbMFmQKzoghF08A/A/Gc4LOHed+6cJ63YmRXZfcrAiVrvaeu47ngGfTlHkOYMuDHhEpaLd4yPkXAgrxqKrw5ITRfEUxRD5rz8h5xXNOz+Y/DiDlxf3k+ErWk0b/PhWjDwfiaeXhaB73kP1BIYa4nUL7AxNlx/6M8cbCw2Ou4hUx0lzHXke7+7C8aSAfeF+qkj4bfkGoiVAPV7pXH0oS1QP2DOSKR+fQ18QC0bA9+Dc74NfJ6YWysoGndHwx74DO8dPkaN5jQ2TRF/kjhMx5GGbTpMo1kx4L7ROEzHBoh1BOr3TuMwHXugfsCckUj9+jIdQC0bpuPROd9Mhyfm3gqKxj3QsE2H4X3Ax4jVdCA1DZ07TqhZSCaxzfQ+dbj8AlEDKIebGwAA diff --git a/crates/nargo_cli/tests/execution_success/scalar_mul/target/witness.tr b/crates/nargo_cli/tests/execution_success/scalar_mul/target/witness.tr deleted file mode 100644 index 44c998c2e5b..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/scalar_mul/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/schnorr/Prover.toml b/crates/nargo_cli/tests/execution_success/schnorr/Prover.toml deleted file mode 100644 index c5c3ab5101a..00000000000 --- a/crates/nargo_cli/tests/execution_success/schnorr/Prover.toml +++ /dev/null @@ -1,9 +0,0 @@ -message = [0,1,2,3,4,5,6,7,8,9] -pub_key_x = "0x17cbd3ed3151ccfd170efe1d54280a6a4822640bf5c369908ad74ea21518a9c5" -pub_key_y = "0x0e0456e3795c1a31f20035b741cd6158929eeccd320d299cfcac962865a6bc74" -signature = [ - 5, 202, 31, 146, 81, 242, 246, 69, 43, 107, 249, 153, 198, 44, 14, 111, 191, 121, 137, 166, - 160, 103, 18, 181, 243, 233, 226, 95, 67, 16, 37, 128, 85, 76, 19, 253, 30, 77, 192, 53, 138, - 205, 69, 33, 236, 163, 83, 194, 84, 137, 184, 221, 176, 121, 179, 27, 63, 70, 54, 16, 176, - 250, 39, 239, -] \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/schnorr/src/main.nr b/crates/nargo_cli/tests/execution_success/schnorr/src/main.nr deleted file mode 100644 index c0933b23029..00000000000 --- a/crates/nargo_cli/tests/execution_success/schnorr/src/main.nr +++ /dev/null @@ -1,10 +0,0 @@ -use dep::std; - -// Note: If main has any unsized types, then the verifier will never be able -// to figure out the circuit instance -fn main(message: [u8; 10], pub_key_x: Field, pub_key_y: Field, signature: [u8; 64]) { - // Is there ever a situation where someone would want - // to ensure that a signature was invalid? - let valid_signature = std::schnorr::verify_signature(pub_key_x,pub_key_y,signature, message); - assert(valid_signature); -} diff --git a/crates/nargo_cli/tests/execution_success/schnorr/target/schnorr.bytecode b/crates/nargo_cli/tests/execution_success/schnorr/target/schnorr.bytecode deleted file mode 100644 index f30bcf32810..00000000000 --- a/crates/nargo_cli/tests/execution_success/schnorr/target/schnorr.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+WW6W7TQBhFJy2BpOz7DqHsux3biU0pTSmlLV3egYj0/Z8Akat8VzXnFxI/O5I1OpI1scf33MlRSukoLUZnfi3F3GvxEngZfAbcBZ8FnwP3wH3wSnA3nnMFz7scz9CN3/L6/bjX913EupfAl8FXwFfB18DXwTfAN8G3wLfBd8B3wffA98EPwA/Bj8CPwQPwE/Aq+Cn4Gfg5+AX4JfgV+DX4Dfgt+B34PfgD+CM4A+fgIbgAl+AKPAKPwTW4AX8Cr4E/g9fBX8Ab4Al4E/wVvAX+Bt4GfwfvgHfBe+Af4H3wQTrpjU68j4Z6QO7Ldzkur+Wy/JWz8lRuykc5KO/kmvySU/JI7siXQVp4sZoW+VfmlXNlW3lWhpVbZVX5VCaVQ2VPeVPGlCtlSflRZpQTZUN5UAaa+NZr8U3X49ttxDttxrfYij3fjr3diT3ci73ajz3pxJ6cn1+/59eFmNv700sn/ehedB+6B91/7j33nXvO/eZec5+5x9xf7i33lXvK/eReGsTsHnL/uHfcN+4Z94t7xX3iHnF/uDfcF+4J94N7wX3gHrD/9t6+23P7ba/tsz22v/bWvtpT+2kvJzHbQ/tn7+ybPbNf9mo3Zntkf+yNfWmfr2Kf0T73fd77nPf57nPXV7+1nubD9PfoxDyJOfu/kR+21iqyUVnOxsNZXuQ/s2EzrausrKajOq/zqq5+DeuimNVlPW6mzThr8rKY5cdVUxzHYgetZ/yX/xhySR6d9m7h+APZ/ELmYAoAAA== diff --git a/crates/nargo_cli/tests/execution_success/schnorr/target/witness.tr b/crates/nargo_cli/tests/execution_success/schnorr/target/witness.tr deleted file mode 100644 index 1af0743a935..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/schnorr/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/sha256/target/sha256.bytecode b/crates/nargo_cli/tests/execution_success/sha256/target/sha256.bytecode deleted file mode 100644 index d46b593b57a..00000000000 --- a/crates/nargo_cli/tests/execution_success/sha256/target/sha256.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/sha256/target/witness.tr b/crates/nargo_cli/tests/execution_success/sha256/target/witness.tr deleted file mode 100644 index e0ab1a7e37f..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/sha256/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/sha2_blocks/target/sha2_blocks.bytecode b/crates/nargo_cli/tests/execution_success/sha2_blocks/target/sha2_blocks.bytecode deleted file mode 100644 index 9b6380f190d..00000000000 --- a/crates/nargo_cli/tests/execution_success/sha2_blocks/target/sha2_blocks.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/sha2_blocks/target/witness.tr b/crates/nargo_cli/tests/execution_success/sha2_blocks/target/witness.tr deleted file mode 100644 index 0d52b61c540..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/sha2_blocks/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/sha2_byte/target/sha2_byte.bytecode b/crates/nargo_cli/tests/execution_success/sha2_byte/target/sha2_byte.bytecode deleted file mode 100644 index c20ca02761a..00000000000 --- a/crates/nargo_cli/tests/execution_success/sha2_byte/target/sha2_byte.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/sha2_byte/target/witness.tr b/crates/nargo_cli/tests/execution_success/sha2_byte/target/witness.tr deleted file mode 100644 index 42967e2d9e0..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/sha2_byte/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/signed_division/src/main.nr b/crates/nargo_cli/tests/execution_success/signed_division/src/main.nr deleted file mode 100644 index 22f0109ad1e..00000000000 --- a/crates/nargo_cli/tests/execution_success/signed_division/src/main.nr +++ /dev/null @@ -1,25 +0,0 @@ -use dep::std; - -// Testing signed integer division: -// 7/3 = 2 -// -7/3 = -2 -// -7/-3 = 2 -// 7/-3 = -2 -fn main(mut x: i32, mut y: i32, mut z: i32) { - // 7/3 = 2 - assert(x / y == z); - - // -7/3 = -2 - let minus_x = 0-x; - let minus_z = 0-z; - let minus_y = 0-y; - assert(x+minus_x==0); - assert(z+minus_z==0); - assert(minus_x / y == minus_z); - - // -7/-3 = 2 - assert(minus_x / minus_y == z); - - // 7/-3 = -2 - assert(x / minus_y == minus_z); -} diff --git a/crates/nargo_cli/tests/execution_success/signed_division/target/signed_division.bytecode b/crates/nargo_cli/tests/execution_success/signed_division/target/signed_division.bytecode deleted file mode 100644 index b4eee36e51f..00000000000 --- a/crates/nargo_cli/tests/execution_success/signed_division/target/signed_division.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/signed_division/target/witness.tr b/crates/nargo_cli/tests/execution_success/signed_division/target/witness.tr deleted file mode 100644 index dc3e7aee633..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/signed_division/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/target/simple_add_and_ret_arr.bytecode b/crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/target/simple_add_and_ret_arr.bytecode deleted file mode 100644 index ae6cd1f2333..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/target/simple_add_and_ret_arr.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/62QMRLAIAgE0XwIBBS6fCVO8P9PSGPhJGW8Zrudmz0AIMF3efKcxH+jtLgYq0i0EsR0YfFuiqK9Ghmp6V2MOUysefeGTsJBQ53HlOXNv+DVIC0NHsnD9V4gAQAA diff --git a/crates/nargo_cli/tests/execution_success/simple_array_param/target/simple_array_param.bytecode b/crates/nargo_cli/tests/execution_success/simple_array_param/target/simple_array_param.bytecode deleted file mode 100644 index 66e00c088c7..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_array_param/target/simple_array_param.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/12KsQkAAAjDUsX/X3awgtglDSQBMSszTPl/5/j2DZaRF3BIAAAA diff --git a/crates/nargo_cli/tests/execution_success/simple_bitwise/target/simple_bitwise.bytecode b/crates/nargo_cli/tests/execution_success/simple_bitwise/target/simple_bitwise.bytecode deleted file mode 100644 index 80835970a0e..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_bitwise/target/simple_bitwise.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1ZbW+CMBA+UBFQ8TUu2fZhWbZ9bgUUvu2vzAz+/0+YjWU5GheX9IGI4RJyabUPveeufS7hnYg+6GzO6XG1d9jYNcaD0+Oz8ZCNzbXKj7QntrZa47H/m7+NqW6u9p/ax2KfJMVhV8hYfoldfsxSkaTHfSYzmWbp9y6L4yJLskN+zA8il0lcyDLN41KcbQDE8hmWsLKybDLmIRArAMZc1Yevn0D7UNfFgHHiGJwIO5O8VpG4IxyWoAsGwZYNYp/QXYY50X7K5gLtq3tGmcfyXOVd1W3I1jnMOwwjZGsu/cf5Aydgc9X6iO2FcJwIj+C1JiKGid7w7wGZUP1yV4n0DSLR7zRxbS+tLTVzKAfg+EeAmItSmZATIH8PLfFnu88pMBfAmpFI/q4Joy2HvOFD1rZDWIFBYQFr5i4Ee6Z9xOZ6wcZgtiLYM6oLtnqpb7yzK4fb9jJ7pHaES9hZ7RKyFf4ZkL8n6obwR0CsLRDruSP1BzwnElgzEsmf2ThV5oK59IBYEfXNCW9O5tov2FzfnGAwW2lO5lRvTlQim25OmjqQtuLwQrctrlVDMQfGvADmAslfW+IwBmIBubwLcVhqv2JzvThgMFsRhyXVxUElsmlxaOpA2l6Ur9QNcVgCY14Bc4Hk77/iYBt/CIwfx2X92zQZMQsba1Ec1tpv2FwvDhjMVsRhTXVxUIm8Jg63eiBt9/VG3RCHNTDmDTAXOP7Kcqhx+HezIeO0Ohhq/z8o2eODeSUAAA== diff --git a/crates/nargo_cli/tests/execution_success/simple_bitwise/target/witness.tr b/crates/nargo_cli/tests/execution_success/simple_bitwise/target/witness.tr deleted file mode 100644 index 64d564557c8..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/simple_bitwise/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/simple_comparison/target/simple_comparison.bytecode b/crates/nargo_cli/tests/execution_success/simple_comparison/target/simple_comparison.bytecode deleted file mode 100644 index d698488f7c1..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_comparison/target/simple_comparison.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2UbW6DMAyGTaDQbhJnQD2BQ0hJ/u0qQ6PH3lU2ZTPIYtBpioP2A0vIgJLXX8nzDAA1fFtOz9Iy8i/kMc50JqeFK+nGauuE2nMMxTSnnhfs34W8oidYyebB93zAz1ll7F3RmvzBmmxD57KSZ81yAbmeYAniZw1rpimd8NdBVtSYdwqkaCjNImaeIPakZfDWdWPfjtroV2z94Cx2drg57bR19q11xoyuc70ffI9ed2bUd+vbO2nl8VqGtLCQqxH3ApKCA0gcSCfy/JIfQJLR3AVIYYAcSKGQZhFTGkj8EsUC6QRyQCohPZCUcC+L/1V/SgDtDreK/Jn9+wvcrmzfFtyu8Dvc1nQOuG3bDLeKNTN8h0E2i5jScEt1IWO1nuRqxEf9iwV6JVjzWXCuAv1bBVgm07+55kpwzorlyME42ScdpGNiExAAAA== diff --git a/crates/nargo_cli/tests/execution_success/simple_comparison/target/witness.tr b/crates/nargo_cli/tests/execution_success/simple_comparison/target/witness.tr deleted file mode 100644 index 6a8a4673e7c..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/simple_comparison/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/simple_mut/target/simple_mut.bytecode b/crates/nargo_cli/tests/execution_success/simple_mut/target/simple_mut.bytecode deleted file mode 100644 index 29543862e4e..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_mut/target/simple_mut.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/62Quw2AMAxEHVjI38TuWIUIZ/8RaIIUiRKuue7p7u0AUOCdbfYxG7+FysISrKrZOEnoRI7uhmq9OjmZ28Uukq7eokfDIJWkYSFjwrb/dvHzfXVQFgc33HLiBSABAAA= diff --git a/crates/nargo_cli/tests/execution_success/simple_not/target/simple_not.bytecode b/crates/nargo_cli/tests/execution_success/simple_not/target/simple_not.bytecode deleted file mode 100644 index c8e1c2d0470..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_not/target/simple_not.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/62QUQrAIAxDq7tQa1tt/3aVyfT+RxhDB7Lf7UFpPkIC2QAgwiBMHeatPJ59fsYs0kpqxHRg8mqKojUbGanpmYy5mVjx6gWdhBt1de44CD9mxSULv0Fh2QJe+u65AK6JrSgwAQAA diff --git a/crates/nargo_cli/tests/execution_success/simple_print/target/simple_print.bytecode b/crates/nargo_cli/tests/execution_success/simple_print/target/simple_print.bytecode deleted file mode 100644 index aa01b6ef454..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_print/target/simple_print.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2b24rbMBCGnWxjxYecnHOeIodWbu/yIL3p6aJQllL6/nRlW2WaiGpgZ8SYSLBk14H5/0/yWtZv6ylJkmHStqeXn0Fy3+yxa/d5fF07DehqHW+9fuw+M8BlWwp+vxLpp/T9cxy91Bh1taad7zekGqdj1o23a5xv+ygB+inwRuOl7cOUtGb92dRQwL9ltd4L8H0KPhUtW3Ouj5J/+9T+rdh0z2dTY+zhHzt8jAPyj9l0dTP+mYc/c/jIAvJnbLr6g6mRe/hzh488IH/Opqu/Wcb/8RcOH0VA/oJNV781NUoPf+nwUQbkL4Eux/UPy68E8NPqXj6ZGhMP/8ThYxKQfwJ0OcYfy68E8NPqam1qTD38U4ePaUD+KdDlmP+w/JkAflpd/c7UmHn4Zw4fs4D8MzZd/cXUmHv45w4f84D8c6DLMf9j+QsB/BzXfyy/EsBPq1t/NTUWHv6Fw8ciIP8C6FJnCmZNZ8f156/vz79/PN92hWk2IhqA4/C0gUv1u2jsStRHMHcbJPe5VR/yN2qPQwaPthWd2UAZ4bmfGeHlEjPCmBHGjPDeR8wIKX3EjDBmhDEjjBmhmz9mhFy6+mRq9CkjpNWtm/HvU0b26Pwc5z+WfyKAn1a3bu7/+pSRxoyQlL/JyPuUEXKMP5ZfCeCn1W2fkVQe/srhowrIX7Hpts/Ilh7+pcPHMiD/EuhyrH+x/LkAflpdXZsaKw//yuFjFZB/xaZbN+v/tYd/7fCxDsi/ZtPV702NjYd/4/CxCci/Aboc8x+WXwng58g/sPylAH5a3Usz/lsP/9bhYxuQfwt0Oe5/sfxzAfwc//9YfiWAn2P+w/KvBPBzrP+x/DMB/LS6dfNewM7Dv3P42AXk3wFdjvUPlr8SwM9x/cPyKwH8HPc/WP5SAD/H+x9Y/lQA/6Of/xzvf2D5xwL4Od7/wPJnAvg58i8sfy6An+P9Dyx/IYA/zv+Uuv2b/x99/Gl12z1iew//3uFjH5B/D3Q55j8sfyaAn2P9h+WvBPBzPP/E8i8E8HPM/1j+QgA/x/Ufy68E8NPqtnvEDh7+g8PHISD/IfL/1R3R6mL2yMHtaENwzH5/AbatPda9cnCf3ODGmGl/ABUi7knQSgAA diff --git a/crates/nargo_cli/tests/execution_success/simple_program_addition/target/simple_program_addition.bytecode b/crates/nargo_cli/tests/execution_success/simple_program_addition/target/simple_program_addition.bytecode deleted file mode 100644 index ae6cd1f2333..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_program_addition/target/simple_program_addition.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/62QMRLAIAgE0XwIBBS6fCVO8P9PSGPhJGW8Zrudmz0AIMF3efKcxH+jtLgYq0i0EsR0YfFuiqK9Ghmp6V2MOUysefeGTsJBQ53HlOXNv+DVIC0NHsnD9V4gAQAA diff --git a/crates/nargo_cli/tests/execution_success/simple_program_no_body/target/simple_program_no_body.bytecode b/crates/nargo_cli/tests/execution_success/simple_program_no_body/target/simple_program_no_body.bytecode deleted file mode 100644 index c676da0309e..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_program_no_body/target/simple_program_no_body.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/2NmQABGJBrGZkKSBwDu6/8ELAAAAA== diff --git a/crates/nargo_cli/tests/execution_success/simple_program_no_body/target/witness.tr b/crates/nargo_cli/tests/execution_success/simple_program_no_body/target/witness.tr deleted file mode 100644 index 94ea8c8f2b1..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/simple_program_no_body/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/simple_radix/src/main.nr b/crates/nargo_cli/tests/execution_success/simple_radix/src/main.nr deleted file mode 100644 index 4d07d8bd368..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_radix/src/main.nr +++ /dev/null @@ -1,10 +0,0 @@ -// Simple program to test to_radix - -use dep::std; - -fn main(x : Field) { - let bits = x.to_le_bits(3); - assert(bits[0] == 0); - assert(bits[1] == 1); - assert(bits[2] == 0); -} diff --git a/crates/nargo_cli/tests/execution_success/simple_radix/target/simple_radix.bytecode b/crates/nargo_cli/tests/execution_success/simple_radix/target/simple_radix.bytecode deleted file mode 100644 index df54a494233..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_radix/target/simple_radix.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2Z8W6CMBDGr+JEQcFsr7AHaCko/Gd8kxnxMfdqLsSynRVZXL+ymHCJOT3ler1yv3zBNyJ6p4tNzKs1YfzOeOlmSuByyYDV3LyfmveC7UOwz4H1ecr211rgcb9abvK83ma10upDZtWhLGReHDalKlVRFses1Lou83JbHaqtrFSua3UqKn0yySbAXK/Ac+jr31/rrE8XC3C5jlPguSL7F7C+dRloHQ3MreyAx7oV59GL8TMWWxjP2dV+L1hvm/M/s+sE84LlOLNrun4j7uRZsFh7fWLVujNeOtqM4GyWCd3yEArCprnNAX7SD4RnbA1ih8DXfnDwpQU79UI4cM5wPdH3Bl+47R9Zs89B/zeIhMbPWewRiOzp9qxsiOzpd4h05Rkhct++IRLStZKb0y1EUEqka4hcgRQC65qTnwFEQyjE3Qde65wA6xyVXf9aHMot+KKO2Kjs3GwQKDdN4souIv/KbkG4wY9wPRlM2TnUbA+66ij36SASG79ksVHZYXIOApGYrpXdkvwru4hwQIqBdS3Jz3CjIRTj7oNeZSfdTCGeJbZ7HpVd/1ocyivjExYblR0m5yBQbg6QK7uE/Cu7FeGGNcH1ZDBl51CzPehZR7lPB5HU+DWLjcoOk3MQiKR0rezW5F/ZJYQDUgqsa01+hhsNoRR3H3h9Zgf8Z1cKq0ZuX/x3v38qIQAA diff --git a/crates/nargo_cli/tests/execution_success/simple_radix/target/witness.tr b/crates/nargo_cli/tests/execution_success/simple_radix/target/witness.tr deleted file mode 100644 index dc1de9de1ff..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/simple_radix/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/simple_shield/src/main.nr b/crates/nargo_cli/tests/execution_success/simple_shield/src/main.nr deleted file mode 100644 index 18fccd862b5..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_shield/src/main.nr +++ /dev/null @@ -1,35 +0,0 @@ -use dep::std; - -fn main( - // Public key of note - // all notes have the same denomination - priv_key: Field, - - // Merkle membership proof - note_root: pub Field, - index: Field, - note_hash_path: [Field; 3], - - // Receiver public key - to_pubkey_x: Field, - to_pubkey_y: Field, -) -> pub [Field; 2] { - // Compute public key from private key to show ownership - let pubkey = std::scalar_mul::fixed_base(priv_key); - let pubkey_x = pubkey[0]; - let pubkey_y = pubkey[1]; - - // Compute input note commitment - let note_commitment = std::hash::pedersen([pubkey_x, pubkey_y]); - - // Compute input note nullifier - let nullifier = std::hash::pedersen([note_commitment[0], index, priv_key]); - - // Compute output note nullifier - let receiver_note_commitment = std::hash::pedersen([to_pubkey_x, to_pubkey_y]); - - // Check that the input note nullifier is in the root - assert(note_root == std::merkle::compute_merkle_root(note_commitment[0], index, note_hash_path)); - - [nullifier[0], receiver_note_commitment[0]] -} diff --git a/crates/nargo_cli/tests/execution_success/simple_shield/target/simple_shield.bytecode b/crates/nargo_cli/tests/execution_success/simple_shield/target/simple_shield.bytecode deleted file mode 100644 index 4bcc1ac6d5d..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_shield/target/simple_shield.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1bD0/TUBC/bQoMFd0GAwTZAEE2QPrWDrpEEyRqNNH4GSSMj+lHA3tydbeug+B+N2nSl7wcfW2v9/eXvh/rDyL6TDfjsciSyEeyNhPNQjTnRV5Fs6yO+XxR7inL+XmRPJ5E86m6tqTWr+T4Sunm8SyaCyn6Z+WaOXXt82i+kGvi60ju5XEq0ptsuBJOlxfHoBLNajRrYntBZEX+jo+rieOa8i8eJUN/fe84CPonnb7z3U+v0zsPu17QPT8OXei6YfeiE/p+PwzCk95578TrucDvu8tuz78UZRWgrmNgHm6L37/a2b+8GVWcrosaMK/I+JVU3NIG6Dk+ULdLLhja7TQeLYpcUmtlkRq7ZkQWaBiLr9V9BSULSse1uiftmsIYPWW1Ft+/oGwhXEy8GYJjs7dAo3gIS2IMupzAXzQA4SX1DFJJ0M++Z+N7CbBzi4QDziVcTPxxjV+YzH+kzZaN/t9ApC5yWa3dB0TOaDRXSRA5o7tBJE1PDiLjx18QqdPwm9wyjYII6k0krYkmBaQ60K5lsmlANAjVcXUwZGcRbCfyLXsFWPtZ8XkV7DN6B8oAXjGo75Cw9Y32m5mCFQO/e2TT12j8fgmMJTDXDh0/i35ZNaibdxnoFwuceE/Z6Jc1YCyBuXbI+CWZUcYIZkTXaMCMrkfzlcQ3Z2nGP0tvsDZENtRaztJgdE5lg8UJ1CxNg+xZmg3CgVcDF5OpsTQT2JxsdJdibuZApClyU63lLA1G51RApEnDLM0m2bM0DcIBUhNo1ybZNDcahJq4OjBlaapAXVvA2s+Kz9tgn9G7L/7NRNWgvk8JW99ov3m3sWXg9wey6Ws0fr8GxhKYa4eOn0W/bBvUzccH7jdjxLqB358oG/2yA4wlMNcOGb8kS8MYwezMDg1Ymt1ovqGcpbnrWUWlc09kS63lLA1G51Q2WJxAzdK0yJ6l2SMceLVwMZkaSzOBzclG76SYmzkQaYvcV2s5S4PRORUQadMwS7NP9ixNi3CA1AbatU82zY0GoTauDkxZmhpQ1wGw9rPi8yHYZ/Tui0GvZlDfXwhb32i/ebdxYOD3V7LpazR+vwXGEphrh46fRb8cGtTNtwfuN2PEroHf3ykb/XIEjCUw1w4ZvyRLwxjB7MwRDVgaDnLyf9PoL+6KwLx5QF0dnI9/vhgb2RgQvm+RNmt7NX32SGQxpSYMNlUuWXvJOJpuuqyS5BvoDQhX/FZ+B/gc3foRhDfZgMZ0VtnIhaw/NedzczTMosQNxp+F8+fevwHVd2aUtz4AAA== diff --git a/crates/nargo_cli/tests/execution_success/simple_shield/target/witness.tr b/crates/nargo_cli/tests/execution_success/simple_shield/target/witness.tr deleted file mode 100644 index 9968826cd01..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/simple_shield/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/simple_shift_left_right/src/main.nr b/crates/nargo_cli/tests/execution_success/simple_shift_left_right/src/main.nr deleted file mode 100644 index 1bcbbde2eb5..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_shift_left_right/src/main.nr +++ /dev/null @@ -1,8 +0,0 @@ -// Tests a very simple program. -// -// The features being tested are left and right shifts. -fn main(x : u32) { - let z = x >> 4; - let t = x << 4; - assert(z == t >> 8); -} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/simple_shift_left_right/target/simple_shift_left_right.bytecode b/crates/nargo_cli/tests/execution_success/simple_shift_left_right/target/simple_shift_left_right.bytecode deleted file mode 100644 index d4fb28251cb..00000000000 --- a/crates/nargo_cli/tests/execution_success/simple_shift_left_right/target/simple_shift_left_right.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2WzW6DMAzHHWhp6aQedtphh+7Qu02ghNteZWjw/o8w6JLWDXTThoNaqZGs0JD+Y/zxU54A4Bm+h+ossvOus9iaP5Sd3+2M0wYpOS0ccVdImwJqI0VM0z3z2KfsnXufsHy4vYvO3mCYK8WeI7sn/mGPuqKTsjX3/y3zBeRiggmI1xpumaa0w+QaqLdXODdUbBMDI8GTPNtpaTzkeVNmDWn6wKyqTYF5UR8MGSpM8ZkZrRuTm7KqqxIrynVDbVHppj2OYzFO1WqtY7HcN+I8QCK8cSBRQO3TGRxIrnaXbO0vQNrDMFc+kPbwO5DGdB5Auj5OQFpYc7/7RO68M2WBdNlE/4RIZiFCC5AD0hLuDUhIkj6PuCujTfMByTX3iq09bkgymrMAqXf8Bc5A6hO59s6UviHxJpp2Q0JKQA5IKwjT3NLxk7wVSsZvDbJAHxQ/yANd0mfuL4ePu7VFIzURABwE3jl+HIOCJVSS0gC6G5Ar/lDfvZHP0QWcbjmmyvORjy+tS+RfMBMAAA== diff --git a/crates/nargo_cli/tests/execution_success/simple_shift_left_right/target/witness.tr b/crates/nargo_cli/tests/execution_success/simple_shift_left_right/target/witness.tr deleted file mode 100644 index 9470bbe781a..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/simple_shift_left_right/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/slices/src/main.nr b/crates/nargo_cli/tests/execution_success/slices/src/main.nr deleted file mode 100644 index 8fbf0a19fc5..00000000000 --- a/crates/nargo_cli/tests/execution_success/slices/src/main.nr +++ /dev/null @@ -1,158 +0,0 @@ -use dep::std::slice; -use dep::std; -fn main(x : Field, y : pub Field) { - let mut slice = [0; 2]; - assert(slice[0] == 0); - assert(slice[0] != 1); - slice[0] = x; - assert(slice[0] == x); - - let slice_plus_10 = slice.push_back(y); - assert(slice_plus_10[2] == 10); - assert(slice_plus_10[2] != 8); - assert(slice_plus_10.len() == 3); - - let mut new_slice = []; - for i in 0..5 { - new_slice = new_slice.push_back(i); - } - assert(new_slice.len() == 5); - - new_slice = new_slice.push_front(20); - assert(new_slice[0] == 20); - assert(new_slice.len() == 6); - - let (popped_slice, last_elem) = new_slice.pop_back(); - assert(last_elem == 4); - assert(popped_slice.len() == 5); - - let (first_elem, rest_of_slice) = popped_slice.pop_front(); - assert(first_elem == 20); - assert(rest_of_slice.len() == 4); - - new_slice = rest_of_slice.insert(2, 100); - assert(new_slice[2] == 100); - assert(new_slice[4] == 3); - assert(new_slice.len() == 5); - - let (remove_slice, removed_elem) = new_slice.remove(3); - assert(removed_elem == 2); - assert(remove_slice[3] == 3); - assert(remove_slice.len() == 4); - - let append = [1, 2].append([3, 4, 5]); - assert(append.len() == 5); - assert(append[0] == 1); - assert(append[4] == 5); - - regression_2083(); - // The parameters to this function must come from witness values (inputs to main) - regression_merge_slices(x, y); -} - -// Ensure that slices of struct/tuple values work. -fn regression_2083() { - let y = [(1, 2)]; - let y = y.push_back((3, 4)); // [(1, 2), (3, 4)] - let y = y.push_back((5, 6)); // [(1, 2), (3, 4), (5, 6)] - assert(y[2].1 == 6); - - let y = y.push_front((10, 11)); // [(10, 11), (1, 2), (3, 4), (5, 6)] - let y = y.push_front((12, 13)); // [(12, 13), (10, 11), (1, 2), (3, 4), (5, 6)] - - assert(y[1].0 == 10); - - let y = y.insert(1, (55, 56)); // [(12, 13), (55, 56), (10, 11), (1, 2), (3, 4), (5, 6)] - assert(y[0].1 == 13); - assert(y[1].1 == 56); - assert(y[2].0 == 10); - - let (y, x) = y.remove(2); // [(12, 13), (55, 56), (1, 2), (3, 4), (5, 6)] - assert(y[2].0 == 1); - assert(x.0 == 10); - assert(x.1 == 11); - - let (x, y) = y.pop_front(); // [(55, 56), (1, 2), (3, 4), (5, 6)] - assert(y[0].0 == 55); - assert(x.0 == 12); - assert(x.1 == 13); - - let (y, x) = y.pop_back(); // [(55, 56), (1, 2), (3, 4)] - assert(y.len() == 3); - assert(x.0 == 5); - assert(x.1 == 6); -} - -// The parameters to this function must come from witness values (inputs to main) -fn regression_merge_slices(x: Field, y: Field) { - merge_slices_if(x, y); - merge_slices_else(x); -} - -fn merge_slices_if(x: Field, y: Field) { - let slice = merge_slices_return(x, y); - assert(slice[2] == 10); - assert(slice.len() == 3); - - let slice = merge_slices_mutate(x, y); - assert(slice[3] == 5); - assert(slice.len() == 4); - - let slice = merge_slices_mutate_in_loop(x, y); - assert(slice[6] == 4); - assert(slice.len() == 7); -} - -fn merge_slices_else(x: Field) { - let slice = merge_slices_return(x, 5); - assert(slice[0] == 0); - assert(slice[1] == 0); - assert(slice.len() == 2); - - let slice = merge_slices_mutate(x, 5); - assert(slice[2] == 5); - assert(slice.len() == 3); - - let slice = merge_slices_mutate_in_loop(x, 5); - assert(slice[2] == 5); - assert(slice.len() == 3); -} - -// Test returning a merged slice without a mutation -fn merge_slices_return(x: Field, y: Field) -> [Field] { - let slice = [0; 2]; - if x != y { - if x != 20 { - slice.push_back(y) - } else { - slice - } - } else { - slice - } -} - -// Test mutating a slice inside of an if statement -fn merge_slices_mutate(x: Field, y: Field) -> [Field] { - let mut slice = [0; 2]; - if x != y { - slice = slice.push_back(y); - slice = slice.push_back(x); - } else { - slice = slice.push_back(x); - } - slice -} - -// Test mutating a slice inside of a loop in an if statement -fn merge_slices_mutate_in_loop(x: Field, y: Field) -> [Field] { - let mut slice = [0; 2]; - if x != y { - for i in 0..5 { - slice = slice.push_back(i); - } - } else { - slice = slice.push_back(x); - } - slice -} diff --git a/crates/nargo_cli/tests/execution_success/slices/target/slices.bytecode b/crates/nargo_cli/tests/execution_success/slices/target/slices.bytecode deleted file mode 100644 index 72d36ee1199..00000000000 --- a/crates/nargo_cli/tests/execution_success/slices/target/slices.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/slices/target/witness.tr b/crates/nargo_cli/tests/execution_success/slices/target/witness.tr deleted file mode 100644 index 63dab2a7515..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/slices/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/strings/target/strings.bytecode b/crates/nargo_cli/tests/execution_success/strings/target/strings.bytecode deleted file mode 100644 index 220ced42668..00000000000 --- a/crates/nargo_cli/tests/execution_success/strings/target/strings.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/strings/target/witness.tr b/crates/nargo_cli/tests/execution_success/strings/target/witness.tr deleted file mode 100644 index 0c0954aa1d0..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/strings/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/struct/src/main.nr b/crates/nargo_cli/tests/execution_success/struct/src/main.nr deleted file mode 100644 index a6d3eddd8d5..00000000000 --- a/crates/nargo_cli/tests/execution_success/struct/src/main.nr +++ /dev/null @@ -1,79 +0,0 @@ -use dep::std; - -struct Foo { - bar: Field, - array: [Field; 2], -} - -struct Pair { - first: Foo, - second: Field, -} - -impl Foo { - fn default(x: Field,y: Field) -> Self { - Self { bar: 0, array: [x,y] } - } -} - -impl Pair { - fn foo(p: Self) -> Foo { - p.first - } - - fn bar(self) -> Field { - self.foo().bar - } -} - -struct Nested { - a: Field, - b: Field -} -struct MyStruct { - my_bool: bool, - my_int: u32, - my_nest: Nested, -} -fn test_struct_in_tuple(a_bool : bool,x:Field, y:Field) -> (MyStruct, bool) { - let my_struct = MyStruct { - my_bool: a_bool, - my_int: 5, - my_nest: Nested{a:x,b:y}, - }; - (my_struct, a_bool) -} - -struct Animal { - legs: Field, - eyes: u8, -} - -fn get_dog() -> Animal { - let dog = Animal { legs: 4, eyes: 2 }; - dog -} - -fn main(x: Field, y: Field) { - let first = Foo::default(x,y); - let p = Pair { first, second: 1 }; - - assert(p.bar() == x); - assert(p.second == y); - assert(p.first.array[0] != p.first.array[1]); - - // Nested structs - let (struct_from_tuple, a_bool) = test_struct_in_tuple(true,x,y); - assert(struct_from_tuple.my_bool == true); - assert(a_bool == true); - assert(struct_from_tuple.my_int == 5); - assert(struct_from_tuple.my_nest.a == 0); - - // Regression test for issue #670 - let Animal { legs, eyes } = get_dog(); - let six = legs + eyes as Field; - - assert(six == 6); - - let Animal { legs: _, eyes: _ } = get_dog(); -} diff --git a/crates/nargo_cli/tests/execution_success/struct/target/struct.bytecode b/crates/nargo_cli/tests/execution_success/struct/target/struct.bytecode deleted file mode 100644 index 1ea7684c9c8..00000000000 --- a/crates/nargo_cli/tests/execution_success/struct/target/struct.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1Wyw6CMBDcguID9eKPtLSV9uavSIT//wRDLMmKxEunBhLm0k0P09lZmOyFiK70jSyc93BqeTOmratWafWQlW+clcY2N6ecss4+K6d164yrfeNr6ZXRreqs1518QwC5csYlI9FziYn+xah/GQeF1Mz1bibqjN3l4SwS9ESjd8Y+XibuoI+nGNImAe+WcB9/qr63+BlJRjl7Tweggy8DchXgmf8j+ICaP4Jvx+o1+CI5i2AomndP8w6+vu89fkZJgw/t6YAcrBO58SFD9EDL2x6RmrneI6vXEI3kPARD0bwlzTtE+75L/Ix+hmisDyUtLwQEpQmBE6vXEIjkFMFQNO+Z5h0CPd8ZP6OkmxTS04xp5D/PgBeuN2XbaBMAAA== diff --git a/crates/nargo_cli/tests/execution_success/struct/target/witness.tr b/crates/nargo_cli/tests/execution_success/struct/target/witness.tr deleted file mode 100644 index 71a6b98c022..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/struct/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/struct_array_inputs/target/struct_array_inputs.bytecode b/crates/nargo_cli/tests/execution_success/struct_array_inputs/target/struct_array_inputs.bytecode deleted file mode 100644 index 9bcc42beeca..00000000000 --- a/crates/nargo_cli/tests/execution_success/struct_array_inputs/target/struct_array_inputs.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/62QWwqAQAhFp3fL0VEb/WsrDU37X0JFBn0GdUHOx4WjOIYQ6nClc/bOyrvmmNb7u7vTOGcnfAt2P7r6h4tgYi4pFiRcIFpWAZY8KSqKyhqVqChrsmwJDJkKbmK0uWz47y54+9/Kee7eAaHW1ZqoAQAA diff --git a/crates/nargo_cli/tests/execution_success/struct_fields_ordering/src/main.nr b/crates/nargo_cli/tests/execution_success/struct_fields_ordering/src/main.nr deleted file mode 100644 index 0d6e411addf..00000000000 --- a/crates/nargo_cli/tests/execution_success/struct_fields_ordering/src/main.nr +++ /dev/null @@ -1,14 +0,0 @@ -use dep::std; - -// Note that fields are not in alphabetical order. -// We want to check that this ordering is maintained -struct myStruct { - foo: u32, - bar: Field, -} - -fn main(y : pub myStruct) { - assert(y.foo == 5); - assert(y.bar == 7); -} - diff --git a/crates/nargo_cli/tests/execution_success/struct_fields_ordering/target/struct_fields_ordering.bytecode b/crates/nargo_cli/tests/execution_success/struct_fields_ordering/target/struct_fields_ordering.bytecode deleted file mode 100644 index 9dd336cc67f..00000000000 --- a/crates/nargo_cli/tests/execution_success/struct_fields_ordering/target/struct_fields_ordering.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1UUQ7CIAztYMMZE8/gEWDABn9eZVN2/yPotCaV7G/F7MOXkJJ+vPa18I4AcII3qucRGC/wDYHxilFvg6kIl9W9c2nokrFm1F2cgtfOT30wwfjg712wNgUXhjjFQUfjbDKzj3ZGMsnAleYXbhL156iY9Us+Lk37rVfuguQkRlVAE2R18jmeV3KsxUssqS7A2wDf4y+lu+HfkSaUu5/pB9zGJxj7VMBmfOOvjE9BGeM7kPvf+DZyKhwoN28L+za+RXfLv6Oixsc90wWC9Eo/0QP0CrogLgoAAA== diff --git a/crates/nargo_cli/tests/execution_success/struct_fields_ordering/target/witness.tr b/crates/nargo_cli/tests/execution_success/struct_fields_ordering/target/witness.tr deleted file mode 100644 index 4ca94e980e2..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/struct_fields_ordering/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/struct_inputs/src/main.nr b/crates/nargo_cli/tests/execution_success/struct_inputs/src/main.nr deleted file mode 100644 index fe77ed6eee6..00000000000 --- a/crates/nargo_cli/tests/execution_success/struct_inputs/src/main.nr +++ /dev/null @@ -1,36 +0,0 @@ -use dep::std; - -mod foo; - -struct myStruct { - foo: u32, - bar: Field, - message: str<5>, -} - -fn main(x : Field, y : pub myStruct, z: pub foo::bar::barStruct, a: pub foo::fooStruct) -> pub Field { - let struct_from_bar = foo::bar::barStruct { val: 1, array: [0, 1], message: "hello" }; - - check_inner_struct(a, z); - - for i in 0 .. struct_from_bar.array.len() { - assert(struct_from_bar.array[i] == z.array[i]); - } - assert(z.val == struct_from_bar.val); - - assert((struct_from_bar.val * x) == x); - - assert(x != y.bar); - - assert(y.message == "hello"); - assert(a.bar_struct.message == struct_from_bar.message); - - a.bar_struct.array[1] -} - -fn check_inner_struct(a: foo::fooStruct, z: foo::bar::barStruct) { - assert(a.bar_struct.val == z.val); - for i in 0.. a.bar_struct.array.len() { - assert(a.bar_struct.array[i] == z.array[i]); - } -} diff --git a/crates/nargo_cli/tests/execution_success/struct_inputs/target/struct_inputs.bytecode b/crates/nargo_cli/tests/execution_success/struct_inputs/target/struct_inputs.bytecode deleted file mode 100644 index 02a8b4a7e0a..00000000000 --- a/crates/nargo_cli/tests/execution_success/struct_inputs/target/struct_inputs.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2c/U7UUBDFh/2SLxH5VkAQBEEQ2t2WbQUEBEFAQPAJRJf4/k/gTrhNhmbjP/dMc5vcmzSdC+zpmTPLL7ts6E8i+kuPq697VMyxKPa17tEv9vXcvpHbP8vt+81RN9fJzjVTN8Rj6uJxvAa7x5D42nBO+3luP5Lbv8jtR8V1KsLLsNEaMY8ZNd+rCi9j3WNcaE3ktCdz+6ncfjq3nxFeasLLhNGaMo+Zoaeras6H5twKdqKo0252wlb4K2im90kcRPH9ThImYZzEf5pJq9VJoqSd3qftIA2jVid8iNPWQ/C4BoRWYLfCl0Bfr3G+gqrJPb/6clkGditEepZ+Z0VdM+dKj+dEQ6Enyl0nn+NIj69BL64xpFkF3TnCPfm1+p7DzygQks5nmi00RAeBPY8Bfc1T+SCK9Cz9vhG1h6il5rwJFK27QG5DlPtewM9IFaLoTLOFhugQsOdxoK9FKh9EkZ6l37ei9hC11Fw0gaJ1l8htiHLfS/gZqUIUnWm2KjmfyFeitlrLVD7wIT1Lv+9E7cFnqblsAkXrrpDb4OO+V/AzUgUfOtNsocE3BNRaBeZXFPiAnp+A772oPfgsNVdNoGjdNXIbfNz3Gn5GquBDZ5qtCtjnANDnOlCrKPCtkw74Pojag89Sc90EitbdILfBx31v4GekCj50ptmqgn32ERZWKK1NXI+FQRTpWfr9KGoPUUvNTRMoWneL3IYo972Fn9F/IWqbw5aST/Srxxqw522AVueBV5oWBb5t0gGfHJoHn6XmtgkUrRuS2+DjvkP8jFSBUgdm2iQYUH4XBZQm6QClJWoPFEvNpgkUrRuR20DhviP8jFSB0gBmGhMMKHFRQIlJByg7ovZAsdSMTaBo3Ta5DRTuu42fkYpXHnxE+Ld6CZUDpM+APadUPpCmpAPST6L2ILXUTE2gaN1dchuk3PcufkYqXhn4CeFBukflAGk/sOd9goG0WRRI90kHpJ9F7UFqqblvAkXrHpDbIOW+D/AzUvHKwN8jPEgPHe9bPoeQfQtJOPQngD6PCAb9wj4oOSId6H8RtYe+peaRCRSte0xuQ5/7PsbPSBUok8BMTwgGlMI+KDkhHaB8FbUHiqXmiQkUrXtKbgOF+z7Fz0gVKFPATM8IBpTC/r53RjpA+SZqDxRLzTMTKFr3nNwGCvd9jp+Rild+JXVK+LelF1QOkE4De76k8oH0knRA+l3UHqSWmpcmULTuFbkNUu77Cj8jFa8M/AvCg/SaygHSGWDPNwQDaWEflNyQDkh/iNqD1FLzxgSK1r0lt0HKfd/iZ6TilYF/TXiQ3jneN8/nrseMbPvOfPI5u8EsA4R/oXvdmJf/xzi7GW+vm+XyjV+zG+T2uoHtK5EN/8w/Ewu/MHlYAAA= diff --git a/crates/nargo_cli/tests/execution_success/struct_inputs/target/witness.tr b/crates/nargo_cli/tests/execution_success/struct_inputs/target/witness.tr deleted file mode 100644 index ddb708ec03b..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/struct_inputs/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/submodules/src/main.nr b/crates/nargo_cli/tests/execution_success/submodules/src/main.nr deleted file mode 100644 index 9bfe382663f..00000000000 --- a/crates/nargo_cli/tests/execution_success/submodules/src/main.nr +++ /dev/null @@ -1,17 +0,0 @@ -use mysubmodule::my_helper; - -fn main(x: u1, y: u1) { - my_helper(); - mysubmodule::my_bool_or(x, y); -} - -mod mysubmodule { - use dep::std; - - fn my_bool_or(x: u1, y: u1) { - assert(x | y == 1); - } - - fn my_helper() {} -} - diff --git a/crates/nargo_cli/tests/execution_success/submodules/target/submodules.bytecode b/crates/nargo_cli/tests/execution_success/submodules/target/submodules.bytecode deleted file mode 100644 index 2449c8f098f..00000000000 --- a/crates/nargo_cli/tests/execution_success/submodules/target/submodules.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/62QUQrAIAiGrV1IU5e+7SqLtfsfYYMaRK/rA/nQh190A4ANGuGt2B2G/pvB4KObcRepOVViOjF5MUXRshsZqemVjLmaWPbiGZ2EK93qfGNj3DHm4j8oLMyKC++N069nHoIDRpiQAQAA diff --git a/crates/nargo_cli/tests/execution_success/to_be_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/to_be_bytes/src/main.nr deleted file mode 100644 index f5831e8c524..00000000000 --- a/crates/nargo_cli/tests/execution_success/to_be_bytes/src/main.nr +++ /dev/null @@ -1,14 +0,0 @@ -use dep::std; - -fn main(x : Field) -> pub [u8; 31] { - // The result of this byte array will be big-endian - let byte_array = x.to_be_bytes(31); - let mut bytes = [0; 31]; - for i in 0..31 { - bytes[i] = byte_array[i]; - } - assert(bytes[30] == 60); - assert(bytes[29] == 33); - assert(bytes[28] == 31); - bytes -} diff --git a/crates/nargo_cli/tests/execution_success/to_be_bytes/target/to_be_bytes.bytecode b/crates/nargo_cli/tests/execution_success/to_be_bytes/target/to_be_bytes.bytecode deleted file mode 100644 index 6df0de0a3ac..00000000000 --- a/crates/nargo_cli/tests/execution_success/to_be_bytes/target/to_be_bytes.bytecode +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/crates/nargo_cli/tests/execution_success/to_be_bytes/target/witness.tr b/crates/nargo_cli/tests/execution_success/to_be_bytes/target/witness.tr deleted file mode 100644 index 7368f5c4d1c..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/to_be_bytes/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/to_bytes_integration/target/to_bytes_integration.bytecode b/crates/nargo_cli/tests/execution_success/to_bytes_integration/target/to_bytes_integration.bytecode deleted file mode 100644 index e05863295eb..00000000000 --- a/crates/nargo_cli/tests/execution_success/to_bytes_integration/target/to_bytes_integration.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1caXPbNhBdWb7kQ77vO7Zz+GiwFCWRdjN13TRN0zRN0zRN2091Iv2ETn9d/1oK1lACwpQsiQ8UmSFmdqDlWA+7D9wVnwbWP0T0N12PIWWtUVDzhZpFvMEFHJbYUThFacPSRqSNShuTNi6tJG1C2qS0KWnT0srSZqTNSpuTNi9tQdqitCVpy9JWpK1KW5O2Lm1D2qa0LWnb0oJ1d6XtKYIKirOiWrflDxv+iOGPGv6Y4Y8bfsnwJwx/0vCnDH/a8MuGP2P4s4Y/Z/jzhr9g+IuGv2T4y4a/Yvirhr9m+OuGv2H4m4a/Zfjbhr9j+LuGv6d8fRTVfKFmEW+E6qMiaq7bqDsNrvBfwvGvvKpwq1c1jz2uetX3jlepNDzXq/tXfl347FYa3Kz6laYCKwKxvsLlKDrx12+cjWYwBA+DsIK9GAHyd5F6/v6H5tH4WI7KmceA/H2dZv7cj3HyeDwsoeXMJSB/l2nlzwnFyRP9YwkjZ54E8vdNCvmrNW/EyVP9YXkROfM0kL/HaePPi4yTy71j1dvkzDNA/r5NE3/1tnHybG9YToeceQ7I35O08FfvGCfPd4/17paceQHI33dp4K9+a5y82B2W6CJnXgLy93TQ/Imu4uTl27GqXebMK0D+vh8kf27XcfJqRyy32UPOvAbk79mg+Kv3FCevt8fyesyZN4D8/TAA/vxmz3HyZjSW6CNn3gLy9zxp/kRfcfL2TSzuM2feAfL3Y5L8ve87Tt4NY1Vi5Mx7QP5eJMSfiDcY+D0bXwD5+ykj/AG/J+JLIH8vM8If8HsOfgzk7+eM8AfU6fwEyN+rjPAH1Jn8FMjfLxnhD6iT+BmQv9cZ4Q/4nM/Pgfz9mhH+gM+p/ALI35uM8Ad8zuKXQP5+ywh/wOcEfgXk721G+AN+zvFrIH+/Z4Q/YJ/mN0D+/sgIf8A+w2+B/P2ZEf6AdcLAe4aR/BU13qIGZh1uArHZvGAvbsFDGuYdNe9r10pqHqJPZz1H1VzQuA3OUn3Q3lfQ5oKG8UF7T9TfFNrglLRrrfeXtVgIx4kYJfhZVlHWMNEBc+vQYbCB/9KnQ4j72hqkbYK+dtyDM3cI1zj3CVeQ7Qq/EC9/ZMw2C31gTeRAzYfatV6ayCXd3CuziVzS7U0kCidvIu3HxyZyoJEZ+Id0s4mgTpJGFVHchnQAjOuQ7BQgugkd4O6DUJzmh4WINxh5yvwuAOv6JPi7apEiCovw/9FyF4cl9Hjvaa+Hjb0LRqteLTQlJmMdk0erTcvWJt2zgHufcDe/rbzv4/eoY+MT8QaU01wqdl5LbygP1HykXculIgYzkae8YAN1qXhE9qXiA8IV6xHhCjIpqRgj5s9SKh6r+US7lktFDGYiTeSYwlLxhOxLxSPCNaRjYFwnZKcA0U3oGHcfZEYqngKwkpaKpziskFT8QnudS8WYmKeKUDTuQ0q3VAzyfojfI6tSEclpLhU7r6U3lNZCevXnUhGDmchTXrCBulRksi8VBeGKlQlXkElJxRgxm4XOEeFmrok4LV61a7lUxGAm0kQcCkvFCtmXiky4huQA46qQneJGNyEHdx9YlYqI33Fq5ewCsK6lYkMkJRVdHFZIKla117lUjInpKkLRuDVKt1QM8q7h98iqVERymkvFzmvpDaWuZk+7lktFDGYiT3nBBupS0SP7UrFOuGL1CFeQSUnFGDGbhe5EhJu5JuKr+Uy7lktFDGYiTcSnsFQ8I/tS0SNcQ/KBcZ2RneJGNyEfdx9YlYrIn+k9B2ApqegkJRXPcVghqfil9jqXijExzxWhaNxHlG6pGOT9CL9HVqUiktMhLUa9eFrjP8uQ0n98YQAA diff --git a/crates/nargo_cli/tests/execution_success/to_bytes_integration/target/witness.tr b/crates/nargo_cli/tests/execution_success/to_bytes_integration/target/witness.tr deleted file mode 100644 index 08f5675af36..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/to_bytes_integration/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/to_le_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/to_le_bytes/src/main.nr deleted file mode 100644 index afa665923bf..00000000000 --- a/crates/nargo_cli/tests/execution_success/to_le_bytes/src/main.nr +++ /dev/null @@ -1,13 +0,0 @@ -use dep::std; - -fn main(x : Field) -> pub [u8; 31] { - // The result of this byte array will be little-endian - let byte_array = x.to_le_bytes(31); - assert(byte_array.len() == 31); - - let mut bytes = [0; 31]; - for i in 0..31 { - bytes[i] = byte_array[i]; - } - bytes -} diff --git a/crates/nargo_cli/tests/execution_success/to_le_bytes/target/to_le_bytes.bytecode b/crates/nargo_cli/tests/execution_success/to_le_bytes/target/to_le_bytes.bytecode deleted file mode 100644 index dea10ae36b5..00000000000 --- a/crates/nargo_cli/tests/execution_success/to_le_bytes/target/to_le_bytes.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+2a+5dNRxbHv+39fr/fQRCEW/26txEEQRDEO4hH000QBEEQBEEQBEGwJslkMplMJpPJZDKZmR/m35g/J1MnqmOfctrp7vOt0ier7lq19qq90rv22XW+X5/u3P8BWF2GXz5tzGr4mDRmm1jI9lFlvFqFkXjUc1u92unVXq8OenXUq5NenfXqoldXvbrp1V2vHnr11KuXXr316qNXX7366dVfrwF6DdRrkF6D9Rqi11C9huk1XK8RekVnjzIDKhNz64RH+7bWvp21b2/tO1j7jta+k7XvbO27WPuu1r6bte9u7XtY+57Wvpe1723t+1j7vta+n7Xvb+0HWPuB1n6QtR9s7YdY+6HWfpi1H27tR1j7kdZ+lNnLT1sTZ5tYyPaJ6aOiUF1ZWVcsr1MVamuhvKa2VFWorKqtLqmSqipVbS8vVVTUlSpLxZrammKhRlVW1Kn6qpqKelOsDbHW73jPWHjS/FraZ1199CmotqRa0V20I87v01Y/v19Kq/bZa5WbZ1YdiPP7rDXPr/LXPlXHbLUK4plVJ+L8Pm+t8yuP9ak6t7xWwXpm1YU4v9+3wvlV1z/Wp+raslqlhGdW3Yjz+6K1za+U2Kfq3vxaxUaeWfUgzu8PrWl+xUb7VD2bV6v8Cc+sehHn92VrmV/xiX2q3k2vtS3lmVUf4vz+2BrmV0ztU/VtWq1CE55Z9SPO76unPb9Ck/pU/dNrVTXxmdUA4vz+9DTnV9nkPtXAJ9aqrG/GM6tBxPl9/bTmV2xWn2pw47VKzXxmNYQ4vz8/hfnV1De7TzU0uVahBc+shhHn943v+RVa1Kca/ngt1cJnViOI8/uLz/ltb3GfamS8VkWGZ1ajiPP71tP8Ctk+ivh3NvUpcX5/zcn8PiPW+pw4v+9yMj/i3znUF8T5/S0n8yP+nq6+JM7v+5zMj/h7pvqKOL+/52R+xN+T1NfE+f2Qk/kROV99Q5zfP3IyPyKnqm+J8/sxJ/Mjcpb6jji/f+ZkfkROUN8T5/dTTuZH/HdO/UCc379yMj+iT6sfifP7d07mR/QZ9RNxfv/JyfyIOlHEd0Yx59dWzC3pwzlH1RNrKzvhru+CaiNqPmPiaJHrbGIbPPquZwcTy8Rso+8//Sx+rkzEMlHjZ/EzSf9NWSN1Ootcw8/3EL2AN5NCB9C/y1roIWqyG1YNXzqMLvC/ePQlxNHiDIhLkGdn/eLMM+AZ52jwBNmY8MuyPT+zZ5dCf2omMsbEsSLXHBOZg8fvyjaROUg3kaQ6wUQa//xqImPEMKP9WDxuIqxvkiaJKKshjSH2NRZuBMg2oTG89yAQU8pZ0uyeNXGcyAVi4tT0YnbRBUpiGgf3xPQseMIfB54gfRFThp5toauEdnNnIuNNnCBygZg4Nb2YyHjEiWkC3BPTOPAMaTyxrwlwI262CY3nvQeBmFLOkmb3nIkTRS4QE6emF7OLLlAS00S4J6bnwBP+RPAE6YuYMvRsC708od3cmcgkEyeLXCAmTk0vJjIJcWKaDPfENBE8Q5pE7Gsy3IibbUKTeO9BIKaUs6TZPW/iFJELxMSp6cXsoguUxDQF7onpefCEPwU8Qfoipgw920KvSGg3dyYytaGmyAVi4tT0YiJTESemAtwT0xTwDGkqsa8C3IibbUJTee9BIKaUs6TZNfzhUOJwICZOTS9mF12gJKZyuCcmBZ7wy8ETpC9iytCzLfTKhHZzZyIN/zLIhwnExKnpxUQqECemSrgnpnLwDKmC2Fcl3IibbUIVvPcgEFPKWdLsqkysFrlATJyaXswuukBJTNVwT0xV4Am/GjxB+iKmDD3bQq9KaDd3JlI0sSRygZg4Nb2YSBFxYirBPTFVg2dIRWJfJbgRN9uEirz3IBBTylnS7GpMnCZygZg4Nb2YXXSBkpimwT0x1YAn/GngCdIXMWXo2RZ6dUK7uTOR6SbOELlATJyaXkxkOuLENAPuiWkaeIY0ndjXDLgRN9uEpvPeg0BMKWdJs3vBxJkiF4iJU9OL2UUXKIlpJtwT0wvgCX8meIL0RUwZeraFXkxoN3cmMsuqHX0CMXFqejGRWYgT02y4J6aZ4BnSLGJfs+FG3GwTmsV7DwIxpZwlze5FE6XZBGLi1PRidtEFSmKaA/fE9CJ4wp8DniB9EVOGnm2hlxLazZ2JzDVxnsgFYuLU9GIicxEnpnlwT0xzwDOkucS+5sGNuNkmNJf3HgRiSjlLmt1LJs4XuUBMnJpezC66QElM8+GemF4CT/jzwROkL2LK0LMt9JqEdnNnIgtMXChygZg4Nb2YyALEiWkh3BPTfPAMaQGxr4VwI262CS3gvQeBmFLOkmb3somLRC4QE6emF7OLLlAS0yK4J6aXwRP+IvAE6YuYMvRsC31rQru5M5HFJi4RuUBMnJpeTGQx4sS0BO6JaRF4hrSY2NcSuBE324QW896DQEwpZ0mze8XEpSIXiIlT04vZRRcoiWkp3BPTK+AJfyl4gvRFTBl6toVem9Bu7kxkmYnLRS4QE6emFxNZhjgxLYd7YloKniEtI/a1HG7EzTahZbz3IBBTylnS7F41cYXIBWLi1PRidtEFSmJaAffE9Cp4wl8BniB9EVOGnm2hb0toN3cmstLEVSIXiIlT04uJrEScmFbBPTGtAM+QVhL7WgU34mab0EreexCIKeUsaXarTVwjcoGYODW9mF10gZKY1sA9Ma0GT/hrwBOkL2LK0LMt9O0J7ebORNaauE7kAjFxanoxkbWIE9M6uCemNeAZ0lpiX+vgRtxsE1rLew8CMaWcJc3uNRPXi1wgJk5NL2YXXaAkpvVwT0yvgSf89eAJ0hcxZejZFnpdQru5M5ENJm4UuUBMnJpeTGQD4sS0Ee6JaT14hrSB2NdGuBE324Q28N6DQEwpZ0mze93ETSIXiIlT04vZRRcoiWkT3BPT6+AJfxN4gvRFTBl6toX+mzCRzSZuEblATJyaXkxkM+LEtAXuiWkTeIa0mdjXFrgRN9uENvPeg0BMKWdJs9tqYq3IBWLi1PRidtEFSmKqhXti2gqe8GvBE6QvYsrQs7K3Ce3mzkQavq8h/y9EICZOTS8msg1xYtoO98RUC54hbSP2tR1uxM02oW289yAQU8pZ0uwa/nAoHyYQE6emF7OLLlASUz3cE1MdeMKvB0+QvogpQ8+2qaqEdnNnIjtM3ClygZg4Nb2YyA7EiWkn3BNTPXiGtIPY1064ETfbhHbw3oNATClnSbN7w8RdIheIiVPTi9lFFyiJaRfcE9Mb4Al/F3iC9EVMGXq2TbU8od3cmchuE/eIXCAmTk0vJrIbcWLaA/fEtAs8Q9pN7GsP3IibbUK7ee9BIKaUs6TZvWniXpELxMSp6cXsoguUxLQX7onpTfCEvxc8Qfoipgw926ZakdBu7kxkn4n7RS4QE6emFxPZhzgx7Yd7YtoLniHtI/a1H27EzTahfbz3IBBTylnS7N4y8YDIBWLi1PRidtEFSmI6APfE9BZ4wj8AniB9EVOGnm1TrUxoN3cmctDEQyIXiIlT04uJHEScmA7BPTEdAM+QDhL7OgQ34mab0EHeexCIKeUsaXZvm3hY5AIxcWp6MbvoAiUxHYZ7YnobPOEfBk+QvogpQ8+2qVYltJs7Ezli4lGRC8TEqenFRI4gTkxH4Z6YDoNnSEeIfR2FG3GzTegI7z0IxJRyljS7d0w8JnKBmDg1vZhddIGSmI7BPTG9A57wj4EnSF/ElKFn21SrE9rNnYkcN/GEyAVi4tT0YiLHESemE3BPTMfAM6TjxL5OwI242SZ0nPceBGJKOUua3bsmnhS5QEycml7MLrpASUwn4Z6Y3gVP+CfBE6QvYsrQs22qxYR2c2cip0w8LXKBmDg1vZjIKcSJ6TTcE9NJ8AzpFLGv03AjbrYJneK9B4GYUs6SZveeiWdELhATp6YXs4suUBLTGbgnpvfAE/4Z8ATpi5gy9Gybaimh3dyZyFkTz4lcICZOTS8mchZxYjoH98R0BjxDOkvs6xzciJttQmd570EgppSzpNm9b+J5kQvExKnpxeyiC5TEdB7uiel98IR/HjxB+iKmDD3bplqT0G7uTOSCiRdFLhATp6YXE7mAODFdhHtiOg+eIV0g9nURbsTNNqELvPcgEFPKWdLsPjDxksgFYuLU9GJ20QVKYroE98T0AXjCvwSeIH0RU4aebVPdmtBu7kzksolXRC4QE6emFxO5jDgxXYF7YroEniFdJvZ1BW7EzTahy7z3IBBTylnS7D408arIBWLi1PRidtEFSmK6CvfE9CF4wr8KniB9EVOGnm1TrU1oN3cmcs3E6yIXiIlT04uJXEOcmK7DPTFdBc+QrhH7ug434mab0DXeexCIKeUsaXYfmXhD5AIxcWp6MbvoAiUx3YB7YvoIPOHfAE+QvogpQ8+2qW5LaDd3JnLTxFsiF4iJU9OLidxEnJhuwT0x3QDPkG4S+7oFN+Jmm9BN3nsQiCnlLGl2H5t4W+QCMXFqejG76AIlMd2Ge2L6GDzh3wZPkL6IKUPPtqluT2g3dyZyx8S7IheIiVPTi4ncQZyY7sI9Md0Gz5DuEPu6CzfiZpvQHd57EIgp5Sxpdp+YeE/kAjFxanoxu+gCJTHdg3ti+gQ84d8DT5C+iClDz7ap1iW0mzsTuW/iA5ELxMSp6cVE7iNOTA/gnpjugWdI94l9PYAbcbNN6D7vPSiUWT1Gn5EmtjF3Hwm1PR4Kp6NenfBQXF306qpXN72646G4eurVS6/eevXRq69e/fTqr9cAvQbqNUivwXoN0WuoXsP0Gq7XCHP2KL3+D5GqaNJWRgEA diff --git a/crates/nargo_cli/tests/execution_success/to_le_bytes/target/witness.tr b/crates/nargo_cli/tests/execution_success/to_le_bytes/target/witness.tr deleted file mode 100644 index d9703f9193a..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/to_le_bytes/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/tuples/src/main.nr b/crates/nargo_cli/tests/execution_success/tuples/src/main.nr deleted file mode 100644 index 45d8380372b..00000000000 --- a/crates/nargo_cli/tests/execution_success/tuples/src/main.nr +++ /dev/null @@ -1,29 +0,0 @@ -use dep::std; - -fn main(x: Field, y: Field) { - let pair = (x, y); - assert(pair.0 == 1); - assert(pair.1 == 0); - - let (a, b) = if true { (0, 1) } else { (2, 3) }; - assert(a == 0); - assert(b == 1); - - let (u,v) = if x as u32 < 1 { - (x, x + 1) - } else { - (x + 1, x) - }; - assert(u == x+1); - assert(v == x); - - // Test mutating tuples - let mut mutable = ((0, 0), 1, 2, 3); - mutable.0 = (x, y); - mutable.2 = 7; - assert(mutable.0.0 == 1); - assert(mutable.0.1 == 0); - assert(mutable.1 == 1); - assert(mutable.2 == 7); - assert(mutable.3 == 3); -} diff --git a/crates/nargo_cli/tests/execution_success/tuples/target/tuples.bytecode b/crates/nargo_cli/tests/execution_success/tuples/target/tuples.bytecode deleted file mode 100644 index 1b3361f92ef..00000000000 --- a/crates/nargo_cli/tests/execution_success/tuples/target/tuples.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1a0U7jMBDcOFCgQOHg6HGIQ6h30r0hu0lo8savUNF+Nr8CsrSBbRpA4NnIFdkXu1Y73pm1J47V/0R0Q+thuL3j1oaFSwRWZm/zfDGbLlzm7u20mpeFzYv5belKV5TFw7TMskWZl7NqXs1s5fJs4ZZFlS0ZLAVjJS38EzD/FIdlZb5bLX0jxlJuBwqcqDFPU8dRyxh0co0ibSngbhNuwWrx3sbXyArIqDXtygQM6ZjAQPR7EwjENEpC7VDcJuB57+BrpGoCSE1Tet0omjknpKMtqG5OEftlDmlOu9zuibG6b+jVyAaiHnWdvNk90XqtEtE3/J30ne8kb+DInOrfj2jVcO+4tYGh4DlW1XwTFtcX8JEnMizadWPOVGHuGuuLG3/KG9/tEs5E9nAcOzMkRM5LjpZ0N86Qhtzui7HPGNKE1mvVNKQJfWxIbTi9Ib0dL4Y0FGL6z76Q14050YYkN1GoIQ0JZ0j7pLO5m/dDoXkiOR8A6/oeZxsW0Duxw444x1Tn0Tes8xGYs8bbzUELbijvS1yOKm/Pfl0fKvD+A+ZdRwrOE/hW6y6BeV1tiH7HQP2Aa8ZdATl2dc0K1HLlmvWH6PfXrIGYxywoGveE4r5m9bxP8DVSvWaNXVOPNyT8w3dCcR86/KY/UuD9l77foWMCzOvfhuh3CtQPuGYcUr+uDh1ALVcOHT9Fvz90BGKesqBo3DOK+wHpeZ/ha6R66EBrWkfMtztjIFZXxjcmHeP7Jfq98QVijllQNO45xW18nvc5vkaqxofUdNP/2fZb9HsTCMQ0LCga94LiNgHP+wJfI1UTQGpqRI5y89TxDN6YKq8EMAAA diff --git a/crates/nargo_cli/tests/execution_success/tuples/target/witness.tr b/crates/nargo_cli/tests/execution_success/tuples/target/witness.tr deleted file mode 100644 index 9cf062282e8..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/tuples/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/type_aliases/src/main.nr b/crates/nargo_cli/tests/execution_success/type_aliases/src/main.nr deleted file mode 100644 index 6cfafc91b7d..00000000000 --- a/crates/nargo_cli/tests/execution_success/type_aliases/src/main.nr +++ /dev/null @@ -1,31 +0,0 @@ -use dep::std; - -type Foo = [T; 2]; - -type Bar = Field; - -type Three = Two; -type Two = One; -type One = (A, B); - -struct MyStruct { - foo: Bar, -} - -fn main(x : [Field; 2]) { - let a: Foo = [1, 2]; - assert(a[0] != x[0]); - - let b: Bar = 2; - assert(x[0] == b); - - let c: u8 = 1; - let d: u32 = 2; - let e: Three = (c, d); - assert(e.0 == 1); - - let s = MyStruct { - foo: 10 - }; - assert(s.foo == 10); -} diff --git a/crates/nargo_cli/tests/execution_success/type_aliases/target/type_aliases.bytecode b/crates/nargo_cli/tests/execution_success/type_aliases/target/type_aliases.bytecode deleted file mode 100644 index c4fc8eacead..00000000000 --- a/crates/nargo_cli/tests/execution_success/type_aliases/target/type_aliases.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/+1WSQ7DIAx0FmiqSn2LHSAxt36lUcn/n1BF4YBolAum6qFzsZVIg2eMRlwB4AY7VKxtrE3SQ/bvEavBydowj4EMPXH0Czu0bpmYmBy718jGBLY8+8XP6MmaQKvzZsUdjSBXl3BhGaiL+nM0mX4sAwnOjOm8/UGf7rKLVVfQBNk5uY/3g2+ih9dYUl+BV4Hc5a+lW8nvCBPKj5lLfVCV5myFvZUMPi3AFdYd3wo+DXWC75L0/+Ar5NTRUGneAX47+Dbdg/yOToMPyyDq6dkLcMMbg2cBBTYKAAA= diff --git a/crates/nargo_cli/tests/execution_success/type_aliases/target/witness.tr b/crates/nargo_cli/tests/execution_success/type_aliases/target/witness.tr deleted file mode 100644 index 6c2ad03aa2e..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/type_aliases/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/vectors/target/vectors.bytecode b/crates/nargo_cli/tests/execution_success/vectors/target/vectors.bytecode deleted file mode 100644 index c676da0309e..00000000000 --- a/crates/nargo_cli/tests/execution_success/vectors/target/vectors.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/2NmQABGJBrGZkKSBwDu6/8ELAAAAA== diff --git a/crates/nargo_cli/tests/execution_success/vectors/target/witness.tr b/crates/nargo_cli/tests/execution_success/vectors/target/witness.tr deleted file mode 100644 index 3530c6f59c1..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/vectors/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/workspace/target/a.json b/crates/nargo_cli/tests/execution_success/workspace/target/a.json deleted file mode 100644 index 1c9071208c7..00000000000 --- a/crates/nargo_cli/tests/execution_success/workspace/target/a.json +++ /dev/null @@ -1 +0,0 @@ -{"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"public"}],"param_witnesses":{"x":[1],"y":[2]},"return_type":null,"return_witnesses":[]},"bytecode":"H4sIAAAAAAAA/82TQQ4DIQhFcWacZc8CoiPuepWaOvc/QpPGJmTqrpiUDcTFg//BHQA8fMfa871n/C3IKRbjEWPLoRHTA0OpkjCmeggJJUnPIMxNouRSS8ZCkRudqfDZYYsha7XT+Ga5gZfO2EvLmfW826BeBjexT9AElz5XH2+DN9PmM5a0TeB6sDv+Wbq9/Y5QIf/aU6dm/NT6E70AIbviMnEFAAA=","proving_key":null,"verification_key":null} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/workspace/target/b.json b/crates/nargo_cli/tests/execution_success/workspace/target/b.json deleted file mode 100644 index 5b013404f52..00000000000 --- a/crates/nargo_cli/tests/execution_success/workspace/target/b.json +++ /dev/null @@ -1 +0,0 @@ -{"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"public"}],"param_witnesses":{"x":[1],"y":[2]},"return_type":null,"return_witnesses":[]},"bytecode":"H4sIAAAAAAAA/7WTMRLEIAhFMYkp9ywgGrHbq6yz5v5H2JkdCyaxC9LgWDw+H9gBwMM91p7fPeOzIKdYjEeMLYdGTB8MpUrCmOohJJQkfYMwN4mSSy0ZC0VudKbCZ4cthqzVrsc/yw28dMZeWmrWerfBexnsxD6hJ7jUufr4GvyZFp8xpG0C14Pd8s/q29vPCBXypvmpDx7sD8opnfqIfsM1RNtxBQAA","proving_key":null,"verification_key":null} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/workspace/target/witness.tr b/crates/nargo_cli/tests/execution_success/workspace/target/witness.tr deleted file mode 100644 index 6a771b3b50f..00000000000 Binary files a/crates/nargo_cli/tests/execution_success/workspace/target/witness.tr and /dev/null differ diff --git a/crates/nargo_cli/tests/execution_success/xor/target/xor.bytecode b/crates/nargo_cli/tests/execution_success/xor/target/xor.bytecode deleted file mode 100644 index dcd84a97eed..00000000000 --- a/crates/nargo_cli/tests/execution_success/xor/target/xor.bytecode +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAA/7VTSw4CIQwt80FXnsEjtAMMZedVnAj3P4JGMak4uykvIaUlef08egKAM3xgXmeo9ir8QfhGvH/jI/xiqPZWLR4DjYLL4ep9jksmR3dc0sYBfdhWJqbA4bGwc5k9x7SliIm8y1RCcqWSTQpcubwRxzqLFka5/0mPC2W9s7hPjXYgdLUdeoImTzvHy05MNXkPkeYOvBb0Pn+vvq2+Rigo/2o+OgcL+gtlRJ1yiZ6k/dzRYQUAAA== diff --git a/crates/nargo_cli/tests/test_libraries/bin_dep/src/main.nr b/crates/nargo_cli/tests/test_libraries/bin_dep/src/main.nr deleted file mode 100644 index 882a9c70056..00000000000 --- a/crates/nargo_cli/tests/test_libraries/bin_dep/src/main.nr +++ /dev/null @@ -1,4 +0,0 @@ - -fn call_dep1_then_dep2(x : Field, y : Field) { - assert(x == y); -} diff --git a/crates/nargo_toml/Cargo.toml b/crates/nargo_toml/Cargo.toml deleted file mode 100644 index f693403cd06..00000000000 --- a/crates/nargo_toml/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "nargo_toml" -description = "Utilities for working with Nargo.toml files" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -dirs.workspace = true -fm.workspace = true -nargo.workspace = true -noirc_frontend.workspace = true -serde.workspace = true -thiserror.workspace = true -toml.workspace = true -url.workspace = true - -[dev-dependencies] diff --git a/crates/nargo_toml/src/errors.rs b/crates/nargo_toml/src/errors.rs deleted file mode 100644 index 2b68f681f92..00000000000 --- a/crates/nargo_toml/src/errors.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::path::PathBuf; - -use nargo::package::PackageType; -use noirc_frontend::graph::CrateName; -use thiserror::Error; - -/// Errors covering situations where a package is either missing or malformed. -#[derive(Debug, Error)] -pub enum ManifestError { - /// Package doesn't have a manifest file - #[error("cannot find a Nargo.toml for {0}")] - MissingFile(PathBuf), - - #[error("Cannot read file {0} - does it exist?")] - ReadFailed(PathBuf), - - #[error("Nargo.toml is missing a parent directory")] - MissingParent, - - #[error("Missing `type` field in {0}")] - MissingPackageType(PathBuf), - - #[error("Cannot use `{1}` for `type` field in {0}")] - InvalidPackageType(PathBuf, String), - - /// Package manifest is unreadable. - #[error("Nargo.toml is badly formed, could not parse.\n\n {0}")] - MalformedFile(#[from] toml::de::Error), - - #[error("Unexpected workspace definition found in {0}")] - UnexpectedWorkspace(PathBuf), - - #[error("Cannot find file {entry} which was specified as the `entry` field in {toml}")] - MissingEntryFile { toml: PathBuf, entry: PathBuf }, - - #[error( - r#"Cannot find file {entry} which is defaulted due to specifying `type = "{package_type}"` in {toml}"# - )] - MissingDefaultEntryFile { toml: PathBuf, entry: PathBuf, package_type: PackageType }, - - #[error("{} found in {toml}", if name.is_empty() { "Empty package name".into() } else { format!("Invalid package name `{name}`") })] - InvalidPackageName { toml: PathBuf, name: String }, - - #[error("{} found in {toml}", if name.is_empty() { "Empty dependency name".into() } else { format!("Invalid dependency name `{name}`") })] - InvalidDependencyName { toml: PathBuf, name: String }, - - /// Encountered error while downloading git repository. - #[error("{0}")] - GitError(String), - - #[error("Selected package `{0}` was not found")] - MissingSelectedPackage(CrateName), - - #[error("Default package was not found. Does {0} exist in your workspace?")] - MissingDefaultPackage(PathBuf), - - #[error("Package `{0}` has type `bin` but you cannot depend on binary packages")] - BinaryDependency(CrateName), - - #[error("Missing `name` field in {toml}")] - MissingNameField { toml: PathBuf }, - - #[error("No common ancestor between {root} and {current}")] - NoCommonAncestor { root: PathBuf, current: PathBuf }, -} diff --git a/crates/nargo_toml/src/lib.rs b/crates/nargo_toml/src/lib.rs deleted file mode 100644 index 8372942931b..00000000000 --- a/crates/nargo_toml/src/lib.rs +++ /dev/null @@ -1,436 +0,0 @@ -use std::{ - collections::BTreeMap, - path::{Component, Path, PathBuf}, -}; - -use fm::{NormalizePath, FILE_EXTENSION}; -use nargo::{ - package::{Dependency, Package, PackageType}, - workspace::Workspace, -}; -use noirc_frontend::graph::CrateName; -use serde::Deserialize; - -mod errors; -mod git; - -pub use errors::ManifestError; -use git::clone_git_repo; - -/// Returns the [PathBuf] of the directory containing the `Nargo.toml` by searching from `current_path` to the root of its [Path]. -/// -/// Returns a [ManifestError] if no parent directories of `current_path` contain a manifest file. -pub fn find_package_root(current_path: &Path) -> Result { - let root = path_root(current_path); - let manifest_path = find_package_manifest(&root, current_path)?; - - let package_root = - manifest_path.parent().expect("infallible: manifest file path can't be root directory"); - - Ok(package_root.to_path_buf()) -} - -// TODO(#2323): We are probably going to need a "filepath utils" crate soon -fn path_root(path: &Path) -> PathBuf { - let mut components = path.components(); - - match (components.next(), components.next()) { - // Preserve prefix if one exists - (Some(prefix @ Component::Prefix(_)), Some(root @ Component::RootDir)) => { - PathBuf::from(prefix.as_os_str()).join(root.as_os_str()) - } - (Some(root @ Component::RootDir), _) => PathBuf::from(root.as_os_str()), - _ => PathBuf::new(), - } -} - -/// Returns the [PathBuf] of the `Nargo.toml` file by searching from `current_path` and stopping at `root_path`. -/// -/// Returns a [ManifestError] if no parent directories of `current_path` contain a manifest file. -pub fn find_package_manifest( - root_path: &Path, - current_path: &Path, -) -> Result { - if current_path.starts_with(root_path) { - let mut found_toml_paths = Vec::new(); - for path in current_path.ancestors() { - if let Ok(toml_path) = get_package_manifest(path) { - found_toml_paths.push(toml_path); - } - // While traversing, break once we process the root specified - if path == root_path { - break; - } - } - - // Return the shallowest Nargo.toml, which will be the last in the list - found_toml_paths.pop().ok_or_else(|| ManifestError::MissingFile(current_path.to_path_buf())) - } else { - Err(ManifestError::NoCommonAncestor { - root: root_path.to_path_buf(), - current: current_path.to_path_buf(), - }) - } -} -/// Returns the [PathBuf] of the `Nargo.toml` file in the `current_path` directory. -/// -/// Returns a [ManifestError] if `current_path` does not contain a manifest file. -pub fn get_package_manifest(current_path: &Path) -> Result { - let toml_path = current_path.join("Nargo.toml"); - if toml_path.exists() { - Ok(toml_path) - } else { - Err(ManifestError::MissingFile(current_path.to_path_buf())) - } -} - -#[derive(Debug, Deserialize, Clone)] -struct PackageConfig { - package: PackageMetadata, - #[serde(default)] - dependencies: BTreeMap, -} - -impl PackageConfig { - fn resolve_to_package(&self, root_dir: &Path) -> Result { - let name = if let Some(name) = &self.package.name { - name.parse().map_err(|_| ManifestError::InvalidPackageName { - toml: root_dir.join("Nargo.toml"), - name: name.into(), - })? - } else { - return Err(ManifestError::MissingNameField { toml: root_dir.join("Nargo.toml") }); - }; - - let mut dependencies: BTreeMap = BTreeMap::new(); - for (name, dep_config) in self.dependencies.iter() { - let name = name.parse().map_err(|_| ManifestError::InvalidDependencyName { - toml: root_dir.join("Nargo.toml"), - name: name.into(), - })?; - let resolved_dep = dep_config.resolve_to_dependency(root_dir)?; - - dependencies.insert(name, resolved_dep); - } - - let package_type = match self.package.package_type.as_deref() { - Some("lib") => PackageType::Library, - Some("bin") => PackageType::Binary, - Some("contract") => PackageType::Contract, - Some(invalid) => { - return Err(ManifestError::InvalidPackageType( - root_dir.join("Nargo.toml"), - invalid.to_string(), - )) - } - None => return Err(ManifestError::MissingPackageType(root_dir.join("Nargo.toml"))), - }; - - let entry_path = if let Some(entry_path) = &self.package.entry { - let custom_entry_path = root_dir.join(entry_path); - if custom_entry_path.exists() { - custom_entry_path - } else { - return Err(ManifestError::MissingEntryFile { - toml: root_dir.join("Nargo.toml"), - entry: custom_entry_path, - }); - } - } else { - let default_entry_path = match package_type { - PackageType::Library => { - root_dir.join("src").join("lib").with_extension(FILE_EXTENSION) - } - PackageType::Binary | PackageType::Contract => { - root_dir.join("src").join("main").with_extension(FILE_EXTENSION) - } - }; - - if default_entry_path.exists() { - default_entry_path - } else { - return Err(ManifestError::MissingDefaultEntryFile { - toml: root_dir.join("Nargo.toml"), - entry: default_entry_path, - package_type, - }); - } - }; - - Ok(Package { - root_dir: root_dir.to_path_buf(), - entry_path, - package_type, - name, - dependencies, - }) - } -} - -/// Contains all the information about a package, as loaded from a `Nargo.toml`. -#[derive(Debug, Deserialize, Clone)] -#[serde(untagged)] -enum Config { - /// Represents a `Nargo.toml` with package fields. - Package { - #[serde(flatten)] - package_config: PackageConfig, - }, - /// Represents a `Nargo.toml` with workspace fields. - Workspace { - #[serde(alias = "workspace")] - workspace_config: WorkspaceConfig, - }, -} - -impl TryFrom for Config { - type Error = toml::de::Error; - - fn try_from(toml: String) -> Result { - toml::from_str(&toml) - } -} - -impl TryFrom<&str> for Config { - type Error = toml::de::Error; - - fn try_from(toml: &str) -> Result { - toml::from_str(toml) - } -} - -/// Tracks the root_dir of a `Nargo.toml` and the contents inside the file. -struct NargoToml { - root_dir: PathBuf, - config: Config, -} - -#[derive(Default, Debug, Deserialize, Clone)] -#[serde(rename_all = "kebab-case")] -struct WorkspaceConfig { - /// List of members in this workspace. - members: Vec, - /// Specifies the default crate to interact with in the context (similarly to how we have nargo as the default crate in this repository). - default_member: Option, -} - -#[allow(dead_code)] -#[derive(Default, Debug, Deserialize, Clone)] -struct PackageMetadata { - name: Option, - #[serde(alias = "type")] - package_type: Option, - entry: Option, - description: Option, - authors: Option>, - // If not compiler version is supplied, the latest is used - // For now, we state that all packages must be compiled under the same - // compiler version. - // We also state that ACIR and the compiler will upgrade in lockstep. - // so you will not need to supply an ACIR and compiler version - compiler_version: Option, - backend: Option, - license: Option, -} - -#[derive(Debug, Deserialize, Clone)] -#[serde(untagged)] -/// Enum representing the different types of ways to -/// supply a source for the dependency -enum DependencyConfig { - Github { git: String, tag: String }, - Path { path: String }, -} - -impl DependencyConfig { - fn resolve_to_dependency(&self, pkg_root: &Path) -> Result { - let dep = match self { - Self::Github { git, tag } => { - let dir_path = clone_git_repo(git, tag).map_err(ManifestError::GitError)?; - let toml_path = dir_path.join("Nargo.toml"); - let package = resolve_package_from_toml(&toml_path)?; - Dependency::Remote { package } - } - Self::Path { path } => { - let dir_path = pkg_root.join(path); - let toml_path = dir_path.join("Nargo.toml"); - let package = resolve_package_from_toml(&toml_path)?; - Dependency::Local { package } - } - }; - - // Cannot depend on a binary - // TODO: Can we depend upon contracts? - if dep.is_binary() { - Err(ManifestError::BinaryDependency(dep.package_name().clone())) - } else { - Ok(dep) - } - } -} - -fn toml_to_workspace( - nargo_toml: NargoToml, - package_selection: PackageSelection, -) -> Result { - let workspace = match nargo_toml.config { - Config::Package { package_config } => { - let member = package_config.resolve_to_package(&nargo_toml.root_dir)?; - match &package_selection { - PackageSelection::Selected(selected_name) if selected_name != &member.name => { - return Err(ManifestError::MissingSelectedPackage(member.name)) - } - _ => Workspace { - root_dir: nargo_toml.root_dir, - selected_package_index: Some(0), - members: vec![member], - }, - } - } - Config::Workspace { workspace_config } => { - let mut members = Vec::new(); - let mut selected_package_index = None; - for (index, member_path) in workspace_config.members.into_iter().enumerate() { - let package_root_dir = nargo_toml.root_dir.join(&member_path); - let package_toml_path = package_root_dir.join("Nargo.toml"); - let member = resolve_package_from_toml(&package_toml_path)?; - - match &package_selection { - PackageSelection::Selected(selected_name) => { - if &member.name == selected_name { - selected_package_index = Some(index); - } - } - PackageSelection::DefaultOrAll => { - if Some(&member_path) == workspace_config.default_member.as_ref() { - selected_package_index = Some(index); - } - } - PackageSelection::All => selected_package_index = None, - } - - members.push(member); - } - - // If the selected_package_index is still `None` but we have see a default_member or selected package, - // we want to present an error to users - match package_selection { - PackageSelection::Selected(selected_name) => { - if selected_package_index.is_none() { - return Err(ManifestError::MissingSelectedPackage(selected_name)); - } - } - PackageSelection::DefaultOrAll => match workspace_config.default_member { - // If `default-member` is specified but we don't have a selected_package_index, we need to fail - Some(default_path) if selected_package_index.is_none() => { - return Err(ManifestError::MissingDefaultPackage(default_path)); - } - // However, if there wasn't a `default-member`, we select All, so no error is needed - _ => (), - }, - PackageSelection::All => (), - } - - Workspace { root_dir: nargo_toml.root_dir, members, selected_package_index } - } - }; - - Ok(workspace) -} - -fn read_toml(toml_path: &Path) -> Result { - let toml_path = toml_path.normalize(); - let toml_as_string = std::fs::read_to_string(&toml_path) - .map_err(|_| ManifestError::ReadFailed(toml_path.to_path_buf()))?; - let root_dir = toml_path.parent().ok_or(ManifestError::MissingParent)?; - let nargo_toml = - NargoToml { root_dir: root_dir.to_path_buf(), config: toml_as_string.try_into()? }; - - Ok(nargo_toml) -} - -/// Resolves a Nargo.toml file into a `Package` struct as defined by our `nargo` core. -fn resolve_package_from_toml(toml_path: &Path) -> Result { - let nargo_toml = read_toml(toml_path)?; - - match nargo_toml.config { - Config::Package { package_config } => { - package_config.resolve_to_package(&nargo_toml.root_dir) - } - Config::Workspace { .. } => { - Err(ManifestError::UnexpectedWorkspace(toml_path.to_path_buf())) - } - } -} - -#[derive(Debug, PartialEq, Eq)] -pub enum PackageSelection { - Selected(CrateName), - DefaultOrAll, - All, -} - -/// Resolves a Nargo.toml file into a `Workspace` struct as defined by our `nargo` core. -pub fn resolve_workspace_from_toml( - toml_path: &Path, - package_selection: PackageSelection, -) -> Result { - let nargo_toml = read_toml(toml_path)?; - - toml_to_workspace(nargo_toml, package_selection) -} - -#[test] -fn parse_standard_toml() { - let src = r#" - - [package] - name = "test" - authors = ["kev", "foo"] - compiler_version = "0.1" - - [dependencies] - rand = { tag = "next", git = "https://github.com/rust-lang-nursery/rand"} - cool = { tag = "next", git = "https://github.com/rust-lang-nursery/rand"} - hello = {path = "./noir_driver"} - "#; - - assert!(Config::try_from(String::from(src)).is_ok()); - assert!(Config::try_from(src).is_ok()); -} - -#[test] -fn parse_package_toml_no_deps() { - let src = r#" - [package] - name = "test" - authors = ["kev", "foo"] - compiler_version = "0.1" - "#; - - assert!(Config::try_from(String::from(src)).is_ok()); - assert!(Config::try_from(src).is_ok()); -} - -#[test] -fn parse_workspace_toml() { - let src = r#" - [workspace] - members = ["a", "b"] - "#; - - assert!(Config::try_from(String::from(src)).is_ok()); - assert!(Config::try_from(src).is_ok()); -} - -#[test] -fn parse_workspace_default_member_toml() { - let src = r#" - [workspace] - members = ["a", "b"] - default-member = "a" - "#; - - assert!(Config::try_from(String::from(src)).is_ok()); - assert!(Config::try_from(src).is_ok()); -} diff --git a/crates/noirc_abi/Cargo.toml b/crates/noirc_abi/Cargo.toml deleted file mode 100644 index 45466061fde..00000000000 --- a/crates/noirc_abi/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "noirc_abi" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -acvm.workspace = true -iter-extended.workspace = true -noirc_frontend.workspace = true -toml.workspace = true -serde_json = "1.0" -serde.workspace = true -thiserror.workspace = true - -[dev-dependencies] -strum = "0.24" -strum_macros = "0.24" \ No newline at end of file diff --git a/crates/noirc_abi/src/input_parser/mod.rs b/crates/noirc_abi/src/input_parser/mod.rs deleted file mode 100644 index 11d40f338d5..00000000000 --- a/crates/noirc_abi/src/input_parser/mod.rs +++ /dev/null @@ -1,202 +0,0 @@ -mod json; -mod toml; - -use std::collections::BTreeMap; - -use acvm::FieldElement; -use serde::Serialize; - -use crate::errors::InputParserError; -use crate::{Abi, AbiType}; -/// This is what all formats eventually transform into -/// For example, a toml file will parse into TomlTypes -/// and those TomlTypes will be mapped to Value -#[derive(Debug, Clone, Serialize, PartialEq)] -pub enum InputValue { - Field(FieldElement), - String(String), - Vec(Vec), - Struct(BTreeMap), -} - -impl InputValue { - /// Checks whether the ABI type matches the InputValue type - /// and also their arity - pub fn matches_abi(&self, abi_param: &AbiType) -> bool { - match (self, abi_param) { - (InputValue::Field(_), AbiType::Field) => true, - (InputValue::Field(field_element), AbiType::Integer { width, .. }) => { - field_element.num_bits() <= *width - } - (InputValue::Field(field_element), AbiType::Boolean) => { - field_element.is_one() || field_element.is_zero() - } - - (InputValue::Vec(array_elements), AbiType::Array { length, typ, .. }) => { - if array_elements.len() != *length as usize { - return false; - } - // Check that all of the array's elements' values match the ABI as well. - array_elements.iter().all(|input_value| input_value.matches_abi(typ)) - } - - (InputValue::String(string), AbiType::String { length }) => { - string.len() == *length as usize - } - - (InputValue::Struct(map), AbiType::Struct { fields, .. }) => { - if map.len() != fields.len() { - return false; - } - - let field_types = BTreeMap::from_iter(fields.iter().cloned()); - - // Check that all of the struct's fields' values match the ABI as well. - map.iter().all(|(field_name, field_value)| { - if let Some(field_type) = field_types.get(field_name) { - field_value.matches_abi(field_type) - } else { - false - } - }) - } - - // All other InputValue-AbiType combinations are fundamentally incompatible. - _ => false, - } - } -} - -/// The different formats that are supported when parsing -/// the initial witness values -#[cfg_attr(test, derive(strum_macros::EnumIter))] -pub enum Format { - Json, - Toml, -} - -impl Format { - pub fn ext(&self) -> &'static str { - match self { - Format::Json => "json", - Format::Toml => "toml", - } - } -} - -impl Format { - pub fn parse( - &self, - input_string: &str, - abi: &Abi, - ) -> Result, InputParserError> { - match self { - Format::Json => json::parse_json(input_string, abi), - Format::Toml => toml::parse_toml(input_string, abi), - } - } - - pub fn serialize( - &self, - input_map: &BTreeMap, - abi: &Abi, - ) -> Result { - match self { - Format::Json => json::serialize_to_json(input_map, abi), - Format::Toml => toml::serialize_to_toml(input_map, abi), - } - } -} - -#[cfg(test)] -mod serialization_tests { - use std::collections::BTreeMap; - - use acvm::FieldElement; - use strum::IntoEnumIterator; - - use crate::{ - input_parser::InputValue, Abi, AbiParameter, AbiType, AbiVisibility, Sign, MAIN_RETURN_NAME, - }; - - use super::Format; - - #[test] - fn serialization_round_trip() { - let abi = Abi { - parameters: vec![ - AbiParameter { - name: "foo".into(), - typ: AbiType::Field, - visibility: AbiVisibility::Private, - }, - AbiParameter { - name: "bar".into(), - typ: AbiType::Struct { - name: "MyStruct".into(), - fields: vec![ - ("field1".into(), AbiType::Integer { sign: Sign::Unsigned, width: 8 }), - ( - "field2".into(), - AbiType::Array { length: 2, typ: Box::new(AbiType::Boolean) }, - ), - ], - }, - visibility: AbiVisibility::Private, - }, - ], - return_type: Some(AbiType::String { length: 5 }), - // These two fields are unused when serializing/deserializing to file. - param_witnesses: BTreeMap::new(), - return_witnesses: Vec::new(), - }; - - let input_map: BTreeMap = BTreeMap::from([ - ("foo".into(), InputValue::Field(FieldElement::one())), - ( - "bar".into(), - InputValue::Struct(BTreeMap::from([ - ("field1".into(), InputValue::Field(255u128.into())), - ( - "field2".into(), - InputValue::Vec(vec![ - InputValue::Field(true.into()), - InputValue::Field(false.into()), - ]), - ), - ])), - ), - (MAIN_RETURN_NAME.into(), InputValue::String("hello".to_owned())), - ]); - - for format in Format::iter() { - let serialized_inputs = format.serialize(&input_map, &abi).unwrap(); - - let reconstructed_input_map = format.parse(&serialized_inputs, &abi).unwrap(); - - assert_eq!(input_map, reconstructed_input_map); - } - } -} - -fn parse_str_to_field(value: &str) -> Result { - if value.starts_with("0x") { - FieldElement::from_hex(value).ok_or_else(|| InputParserError::ParseHexStr(value.to_owned())) - } else { - value - .parse::() - .map_err(|err_msg| InputParserError::ParseStr(err_msg.to_string())) - .map(FieldElement::from) - } -} - -#[cfg(test)] -mod test { - use super::parse_str_to_field; - - #[test] - fn parse_empty_str_fails() { - // Check that this fails appropriately rather than being treated as 0, etc. - assert!(parse_str_to_field("").is_err()); - } -} diff --git a/crates/noirc_abi/src/lib.rs b/crates/noirc_abi/src/lib.rs deleted file mode 100644 index 76ecba9bff2..00000000000 --- a/crates/noirc_abi/src/lib.rs +++ /dev/null @@ -1,532 +0,0 @@ -#![forbid(unsafe_code)] -#![warn(unused_crate_dependencies, unused_extern_crates)] -#![warn(unreachable_pub)] -#![warn(clippy::semicolon_if_nothing_returned)] - -use std::{collections::BTreeMap, str}; - -use acvm::{ - acir::native_types::{Witness, WitnessMap}, - FieldElement, -}; -use errors::AbiError; -use input_parser::InputValue; -use iter_extended::{try_btree_map, try_vecmap, vecmap}; -use noirc_frontend::{Signedness, Type, TypeBinding, TypeVariableKind, Visibility}; -use serde::{Deserialize, Serialize}; -// This is the ABI used to bridge the different TOML formats for the initial -// witness, the partial witness generator and the interpreter. -// -// This ABI has nothing to do with ACVM or ACIR. Although they implicitly have a relationship - -pub mod errors; -pub mod input_parser; -mod serialization; - -/// A map from the fields in an TOML/JSON file which correspond to some ABI to their values -pub type InputMap = BTreeMap; - -pub const MAIN_RETURN_NAME: &str = "return"; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(tag = "kind", rename_all = "lowercase")] -/// Types that are allowed in the (main function in binary) -/// -/// we use this separation so that we can have types like Strings -/// without needing to introduce this in the Noir types -/// -/// NOTE: If Strings are introduced as a native type, the translation will -/// be straightforward. Whether exotic types like String will be natively supported -/// depends on the types of programs that users want to do. I don't envision string manipulation -/// in programs, however it is possible to support, with many complications like encoding character set -/// support. -pub enum AbiType { - Field, - Array { - length: u64, - #[serde(rename = "type")] - typ: Box, - }, - Integer { - sign: Sign, - width: u32, - }, - Boolean, - Struct { - name: String, - #[serde( - serialize_with = "serialization::serialize_struct_fields", - deserialize_with = "serialization::deserialize_struct_fields" - )] - fields: Vec<(String, AbiType)>, - }, - String { - length: u64, - }, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -/// Represents whether the parameter is public or known only to the prover. -pub enum AbiVisibility { - Public, - // Constants are not allowed in the ABI for main at the moment. - // Constant, - Private, -} - -impl From for AbiVisibility { - fn from(value: Visibility) -> Self { - match value { - Visibility::Public => AbiVisibility::Public, - Visibility::Private => AbiVisibility::Private, - } - } -} - -impl From<&Visibility> for AbiVisibility { - fn from(value: &Visibility) -> Self { - match value { - Visibility::Public => AbiVisibility::Public, - Visibility::Private => AbiVisibility::Private, - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -/// Represents whether the return value should compromise of unique witness indices such that no -/// index occurs within the program's abi more than once. -/// -/// This is useful for application stacks that require an uniform abi across across multiple -/// circuits. When index duplication is allowed, the compiler may identify that a public input -/// reaches the output unaltered and is thus referenced directly, causing the input and output -/// witness indices to overlap. Similarly, repetitions of copied values in the output may be -/// optimized away. -pub enum AbiDistinctness { - Distinct, - DuplicationAllowed, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -pub enum Sign { - Unsigned, - Signed, -} - -impl AbiType { - // TODO: Add `Context` argument for resolving fully qualified struct paths - pub fn from_type(typ: &Type) -> Self { - // Note; use strict_eq instead of partial_eq when comparing field types - // in this method, you most likely want to distinguish between public and private - match typ { - Type::FieldElement => Self::Field, - Type::Array(size, typ) => { - let length = size - .evaluate_to_u64() - .expect("Cannot have variable sized arrays as a parameter to main"); - let typ = typ.as_ref(); - Self::Array { length, typ: Box::new(Self::from_type(typ)) } - } - Type::Integer(sign, bit_width) => { - let sign = match sign { - Signedness::Unsigned => Sign::Unsigned, - Signedness::Signed => Sign::Signed, - }; - - Self::Integer { sign, width: *bit_width } - } - Type::TypeVariable(binding, TypeVariableKind::IntegerOrField) => { - match &*binding.borrow() { - TypeBinding::Bound(typ) => Self::from_type(typ), - TypeBinding::Unbound(_) => Self::from_type(&Type::default_int_type()), - } - } - Type::Bool => Self::Boolean, - Type::String(size) => { - let size = size - .evaluate_to_u64() - .expect("Cannot have variable sized strings as a parameter to main"); - Self::String { length: size } - } - Type::FmtString(_, _) => unreachable!("format strings cannot be used in the abi"), - Type::Error => unreachable!(), - Type::Unit => unreachable!(), - Type::Constant(_) => unreachable!(), - Type::Struct(def, ref args) => { - let struct_type = def.borrow(); - let fields = struct_type.get_fields(args); - let fields = vecmap(fields, |(name, typ)| (name, Self::from_type(&typ))); - Self::Struct { fields, name: struct_type.name.to_string() } - } - Type::Tuple(_) => todo!("AbiType::from_type not yet implemented for tuple types"), - Type::TypeVariable(_, _) => unreachable!(), - Type::NamedGeneric(..) => unreachable!(), - Type::Forall(..) => unreachable!(), - Type::Function(_, _, _) => unreachable!(), - Type::MutableReference(_) => unreachable!("&mut cannot be used in the abi"), - Type::NotConstant => unreachable!(), - } - } - - /// Returns the number of field elements required to represent the type once encoded. - pub fn field_count(&self) -> u32 { - match self { - AbiType::Field | AbiType::Integer { .. } | AbiType::Boolean => 1, - AbiType::Array { length, typ } => typ.field_count() * (*length as u32), - AbiType::Struct { fields, .. } => { - fields.iter().fold(0, |acc, (_, field_type)| acc + field_type.field_count()) - } - AbiType::String { length } => *length as u32, - } - } -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -/// An argument or return value of the circuit's `main` function. -pub struct AbiParameter { - pub name: String, - #[serde(rename = "type")] - pub typ: AbiType, - pub visibility: AbiVisibility, -} - -impl AbiParameter { - pub fn is_public(&self) -> bool { - self.visibility == AbiVisibility::Public - } -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Abi { - /// An ordered list of the arguments to the program's `main` function, specifying their types and visibility. - pub parameters: Vec, - /// A map from the ABI's parameters to the indices they are written to in the [`WitnessMap`]. - /// This defines how to convert between the [`InputMap`] and [`WitnessMap`]. - pub param_witnesses: BTreeMap>, - pub return_type: Option, - pub return_witnesses: Vec, -} - -impl Abi { - pub fn parameter_names(&self) -> Vec<&String> { - self.parameters.iter().map(|x| &x.name).collect() - } - - pub fn num_parameters(&self) -> usize { - self.parameters.len() - } - - /// Returns the number of field elements required to represent the ABI's input once encoded. - pub fn field_count(&self) -> u32 { - self.parameters.iter().map(|param| param.typ.field_count()).sum() - } - - /// Returns whether any values are needed to be made public for verification. - pub fn has_public_inputs(&self) -> bool { - self.return_type.is_some() || self.parameters.iter().any(|param| param.is_public()) - } - - /// Returns `true` if the ABI contains no parameters or return value. - pub fn is_empty(&self) -> bool { - self.return_type.is_none() && self.parameters.is_empty() - } - - pub fn to_btree_map(&self) -> BTreeMap { - let mut map = BTreeMap::new(); - for param in self.parameters.iter() { - map.insert(param.name.clone(), param.typ.clone()); - } - map - } - - /// ABI with only the public parameters - #[must_use] - pub fn public_abi(self) -> Abi { - let parameters: Vec<_> = - self.parameters.into_iter().filter(|param| param.is_public()).collect(); - let param_witnesses = self - .param_witnesses - .into_iter() - .filter(|(param_name, _)| parameters.iter().any(|param| ¶m.name == param_name)) - .collect(); - Abi { - parameters, - param_witnesses, - return_type: self.return_type, - return_witnesses: self.return_witnesses, - } - } - - /// Encode a set of inputs as described in the ABI into a `WitnessMap`. - pub fn encode( - &self, - input_map: &InputMap, - return_value: Option, - ) -> Result { - // Check that no extra witness values have been provided. - let param_names = self.parameter_names(); - if param_names.len() < input_map.len() { - let unexpected_params: Vec = - input_map.keys().filter(|param| !param_names.contains(param)).cloned().collect(); - return Err(AbiError::UnexpectedParams(unexpected_params)); - } - - // First encode each input separately, performing any input validation. - let encoded_input_map: BTreeMap> = self - .to_btree_map() - .into_iter() - .map(|(param_name, expected_type)| { - let value = input_map - .get(¶m_name) - .ok_or_else(|| AbiError::MissingParam(param_name.clone()))? - .clone(); - - if !value.matches_abi(&expected_type) { - let param = self - .parameters - .iter() - .find(|param| param.name == param_name) - .unwrap() - .clone(); - return Err(AbiError::TypeMismatch { param, value }); - } - - Self::encode_value(value, &expected_type).map(|v| (param_name, v)) - }) - .collect::>()?; - - // Write input field elements into witness indices specified in `self.param_witnesses`. - let mut witness_map: BTreeMap = encoded_input_map - .iter() - .flat_map(|(param_name, encoded_param_fields)| { - let param_witness_indices = &self.param_witnesses[param_name]; - param_witness_indices - .iter() - .zip(encoded_param_fields.iter()) - .map(|(&witness, &field_element)| (witness, field_element)) - }) - .collect(); - - // When encoding public inputs to be passed to the verifier, the user can must provide a return value - // to be inserted into the witness map. This is not needed when generating a witness when proving the circuit. - match (&self.return_type, return_value) { - (Some(return_type), Some(return_value)) => { - if !return_value.matches_abi(return_type) { - return Err(AbiError::ReturnTypeMismatch { - return_type: return_type.clone(), - value: return_value, - }); - } - let encoded_return_fields = Self::encode_value(return_value, return_type)?; - - // We need to be more careful when writing the return value's witness values. - // This is as it may share witness indices with other public inputs so we must check that when - // this occurs the witness values are consistent with each other. - self.return_witnesses.iter().zip(encoded_return_fields.iter()).try_for_each( - |(&witness, &field_element)| match witness_map.insert(witness, field_element) { - Some(existing_value) if existing_value != field_element => { - Err(AbiError::InconsistentWitnessAssignment(witness)) - } - _ => Ok(()), - }, - )?; - } - (None, Some(return_value)) => { - return Err(AbiError::UnexpectedReturnValue(return_value)) - } - // We allow not passing a return value despite the circuit defining one - // in order to generate the initial partial witness. - (_, None) => {} - } - - Ok(witness_map.into()) - } - - fn encode_value(value: InputValue, abi_type: &AbiType) -> Result, AbiError> { - let mut encoded_value = Vec::new(); - match (value, abi_type) { - (InputValue::Field(elem), _) => encoded_value.push(elem), - - (InputValue::Vec(vec_elements), AbiType::Array { typ, .. }) => { - for elem in vec_elements { - encoded_value.extend(Self::encode_value(elem, typ)?); - } - } - - (InputValue::String(string), _) => { - let str_as_fields = - string.bytes().map(|byte| FieldElement::from_be_bytes_reduce(&[byte])); - encoded_value.extend(str_as_fields); - } - - (InputValue::Struct(object), AbiType::Struct { fields, .. }) => { - for (field, typ) in fields { - encoded_value.extend(Self::encode_value(object[field].clone(), typ)?); - } - } - _ => unreachable!("value should have already been checked to match abi type"), - } - Ok(encoded_value) - } - - /// Decode a `WitnessMap` into the types specified in the ABI. - pub fn decode( - &self, - witness_map: &WitnessMap, - ) -> Result<(InputMap, Option), AbiError> { - let public_inputs_map = - try_btree_map(self.parameters.clone(), |AbiParameter { name, typ, .. }| { - let param_witness_values = - try_vecmap(self.param_witnesses[&name].clone(), |witness_index| { - witness_map - .get(&witness_index) - .ok_or_else(|| AbiError::MissingParamWitnessValue { - name: name.clone(), - witness_index, - }) - .copied() - })?; - - decode_value(&mut param_witness_values.into_iter(), &typ) - .map(|input_value| (name.clone(), input_value)) - })?; - - // We also attempt to decode the circuit's return value from `witness_map`. - let return_value = if let Some(return_type) = &self.return_type { - if let Ok(return_witness_values) = - try_vecmap(self.return_witnesses.clone(), |witness_index| { - witness_map - .get(&witness_index) - .ok_or_else(|| AbiError::MissingParamWitnessValue { - name: MAIN_RETURN_NAME.to_string(), - witness_index, - }) - .copied() - }) - { - Some(decode_value(&mut return_witness_values.into_iter(), return_type)?) - } else { - // Unlike for the circuit inputs, we tolerate not being able to find the witness values for the return value. - // This is because the user may be decoding a partial witness map for which is hasn't been calculated yet. - // If a return value is expected, this should be checked for by the user. - None - } - } else { - None - }; - - Ok((public_inputs_map, return_value)) - } -} - -fn decode_value( - field_iterator: &mut impl Iterator, - value_type: &AbiType, -) -> Result { - // This function assumes that `field_iterator` contains enough `FieldElement`s in order to decode a `value_type` - // `Abi.decode` enforces that the encoded inputs matches the expected length defined by the ABI so this is safe. - let value = match value_type { - AbiType::Field | AbiType::Integer { .. } | AbiType::Boolean => { - let field_element = field_iterator.next().unwrap(); - - InputValue::Field(field_element) - } - AbiType::Array { length, typ } => { - let length = *length as usize; - let mut array_elements = Vec::with_capacity(length); - for _ in 0..length { - array_elements.push(decode_value(field_iterator, typ)?); - } - - InputValue::Vec(array_elements) - } - AbiType::String { length } => { - let field_elements: Vec = field_iterator.take(*length as usize).collect(); - - InputValue::String(decode_string_value(&field_elements)) - } - AbiType::Struct { fields, .. } => { - let mut struct_map = BTreeMap::new(); - - for (field_key, param_type) in fields { - let field_value = decode_value(field_iterator, param_type)?; - - struct_map.insert(field_key.to_owned(), field_value); - } - - InputValue::Struct(struct_map) - } - }; - - Ok(value) -} - -fn decode_string_value(field_elements: &[FieldElement]) -> String { - let string_as_slice = vecmap(field_elements, |e| { - let mut field_as_bytes = e.to_be_bytes(); - let char_byte = field_as_bytes.pop().unwrap(); // A character in a string is represented by a u8, thus we just want the last byte of the element - assert!(field_as_bytes.into_iter().all(|b| b == 0)); // Assert that the rest of the field element's bytes are empty - char_byte - }); - - let final_string = str::from_utf8(&string_as_slice).unwrap(); - final_string.to_owned() -} - -#[cfg(test)] -mod test { - use std::collections::BTreeMap; - - use acvm::{acir::native_types::Witness, FieldElement}; - - use crate::{input_parser::InputValue, Abi, AbiParameter, AbiType, AbiVisibility, InputMap}; - - #[test] - fn witness_encoding_roundtrip() { - let abi = Abi { - parameters: vec![ - AbiParameter { - name: "thing1".to_string(), - typ: AbiType::Array { length: 2, typ: Box::new(AbiType::Field) }, - visibility: AbiVisibility::Public, - }, - AbiParameter { - name: "thing2".to_string(), - typ: AbiType::Field, - visibility: AbiVisibility::Public, - }, - ], - // Note that the return value shares a witness with `thing2` - param_witnesses: BTreeMap::from([ - ("thing1".to_string(), vec![Witness(1), Witness(2)]), - ("thing2".to_string(), vec![Witness(3)]), - ]), - return_type: Some(AbiType::Field), - return_witnesses: vec![Witness(3)], - }; - - // Note we omit return value from inputs - let inputs: InputMap = BTreeMap::from([ - ( - "thing1".to_string(), - InputValue::Vec(vec![ - InputValue::Field(FieldElement::one()), - InputValue::Field(FieldElement::one()), - ]), - ), - ("thing2".to_string(), InputValue::Field(FieldElement::zero())), - ]); - - let witness_map = abi.encode(&inputs, None).unwrap(); - let (reconstructed_inputs, return_value) = abi.decode(&witness_map).unwrap(); - - for (key, expected_value) in inputs { - assert_eq!(reconstructed_inputs[&key], expected_value); - } - - // We also decode the return value (we can do this immediately as we know it shares a witness with an input). - assert_eq!(return_value.unwrap(), reconstructed_inputs["thing2"]); - } -} diff --git a/crates/noirc_driver/Cargo.toml b/crates/noirc_driver/Cargo.toml deleted file mode 100644 index 2afc7a4cb53..00000000000 --- a/crates/noirc_driver/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "noirc_driver" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -clap.workspace = true -noirc_errors.workspace = true -noirc_frontend.workspace = true -noirc_evaluator.workspace = true -noirc_abi.workspace = true -acvm.workspace = true -fm.workspace = true -serde.workspace = true -base64.workspace = true \ No newline at end of file diff --git a/crates/noirc_driver/src/contract.rs b/crates/noirc_driver/src/contract.rs deleted file mode 100644 index a1820ff2e47..00000000000 --- a/crates/noirc_driver/src/contract.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::program::{deserialize_circuit, serialize_circuit}; -use acvm::acir::circuit::Circuit; -use noirc_abi::Abi; -use noirc_errors::debug_info::DebugInfo; -use serde::{Deserialize, Serialize}; - -/// Describes the types of smart contract functions that are allowed. -/// Unlike the similar enum in noirc_frontend, 'open' and 'unconstrained' -/// are mutually exclusive here. In the case a function is both, 'unconstrained' -/// takes precedence. -#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] -pub enum ContractFunctionType { - /// This function will be executed in a private - /// context. - Secret, - /// This function will be executed in a public - /// context. - Open, - /// This function cannot constrain any values and can use nondeterministic features - /// like arrays of a dynamic size. - Unconstrained, -} - -#[derive(Serialize, Deserialize)] -pub struct CompiledContract { - /// The name of the contract. - pub name: String, - /// Each of the contract's functions are compiled into a separate `CompiledProgram` - /// stored in this `Vector`. - pub functions: Vec, -} - -/// Each function in the contract will be compiled -/// as a separate noir program. -/// -/// A contract function unlike a regular Noir program -/// however can have additional properties. -/// One of these being a function type. -#[derive(Debug, Serialize, Deserialize)] -pub struct ContractFunction { - pub name: String, - - pub function_type: ContractFunctionType, - - pub is_internal: bool, - - pub abi: Abi, - - #[serde(serialize_with = "serialize_circuit", deserialize_with = "deserialize_circuit")] - pub bytecode: Circuit, - - pub debug: DebugInfo, -} - -impl ContractFunctionType { - pub(super) fn new(kind: noirc_frontend::ContractFunctionType, is_unconstrained: bool) -> Self { - match (kind, is_unconstrained) { - (_, true) => Self::Unconstrained, - (noirc_frontend::ContractFunctionType::Secret, false) => Self::Secret, - (noirc_frontend::ContractFunctionType::Open, false) => Self::Open, - } - } -} diff --git a/crates/noirc_driver/src/lib.rs b/crates/noirc_driver/src/lib.rs deleted file mode 100644 index 3511fbeabb6..00000000000 --- a/crates/noirc_driver/src/lib.rs +++ /dev/null @@ -1,287 +0,0 @@ -#![forbid(unsafe_code)] -#![warn(unused_crate_dependencies, unused_extern_crates)] -#![warn(unreachable_pub)] -#![warn(clippy::semicolon_if_nothing_returned)] - -use clap::Args; -use fm::FileId; -use noirc_abi::{AbiParameter, AbiType}; -use noirc_errors::{CustomDiagnostic, FileDiagnostic}; -use noirc_evaluator::{create_circuit, into_abi_params}; -use noirc_frontend::graph::{CrateId, CrateName}; -use noirc_frontend::hir::def_map::{Contract, CrateDefMap}; -use noirc_frontend::hir::Context; -use noirc_frontend::monomorphization::monomorphize; -use noirc_frontend::node_interner::FuncId; -use serde::{Deserialize, Serialize}; -use std::path::Path; - -mod contract; -mod program; - -pub use contract::{CompiledContract, ContractFunction, ContractFunctionType}; -pub use program::CompiledProgram; - -#[derive(Args, Clone, Debug, Default, Serialize, Deserialize)] -pub struct CompileOptions { - /// Emit debug information for the intermediate SSA IR - #[arg(long, hide = true)] - pub show_ssa: bool, - - #[arg(long, hide = true)] - pub show_brillig: bool, - - /// Display the ACIR for compiled circuit - #[arg(long)] - pub print_acir: bool, - - /// Treat all warnings as errors - #[arg(long)] - pub deny_warnings: bool, -} - -/// Helper type used to signify where only warnings are expected in file diagnostics -pub type Warnings = Vec; - -/// Helper type used to signify where errors or warnings are expected in file diagnostics -pub type ErrorsAndWarnings = Vec; - -// This is here for backwards compatibility -// with the restricted version which only uses one file -pub fn compile_file( - context: &mut Context, - root_file: &Path, -) -> Result<(CompiledProgram, Warnings), ErrorsAndWarnings> { - let crate_id = prepare_crate(context, root_file); - compile_main(context, crate_id, &CompileOptions::default()) -} - -/// Adds the file from the file system at `Path` to the crate graph as a root file -pub fn prepare_crate(context: &mut Context, file_name: &Path) -> CrateId { - let root_file_id = context.file_manager.add_file(file_name).unwrap(); - - context.crate_graph.add_crate_root(root_file_id) -} - -// Adds the file from the file system at `Path` to the crate graph -pub fn prepare_dependency(context: &mut Context, file_name: &Path) -> CrateId { - let root_file_id = context.file_manager.add_file(file_name).unwrap(); - - context.crate_graph.add_crate(root_file_id) -} - -/// Adds a edge in the crate graph for two crates -pub fn add_dep( - context: &mut Context, - this_crate: CrateId, - depends_on: CrateId, - crate_name: CrateName, -) { - context - .crate_graph - .add_dep(this_crate, crate_name, depends_on) - .expect("cyclic dependency triggered"); -} - -/// Propagates a given dependency to every other crate. -pub fn propagate_dep( - context: &mut Context, - dep_to_propagate: CrateId, - dep_to_propagate_name: &CrateName, -) { - let crate_ids: Vec<_> = - context.crate_graph.iter_keys().filter(|crate_id| *crate_id != dep_to_propagate).collect(); - - for crate_id in crate_ids { - context - .crate_graph - .add_dep(crate_id, dep_to_propagate_name.clone(), dep_to_propagate) - .expect("ice: cyclic error triggered with std library"); - } -} - -/// Run the lexing, parsing, name resolution, and type checking passes. -/// -/// This returns a (possibly empty) vector of any warnings found on success. -/// On error, this returns a non-empty vector of warnings and error messages, with at least one error. -pub fn check_crate( - context: &mut Context, - crate_id: CrateId, - deny_warnings: bool, -) -> Result { - // Add the stdlib before we check the crate - // TODO: This should actually be done when constructing the driver and then propagated to each dependency when added; - // however, the `create_non_local_crate` panics if you add the stdlib as the first crate in the graph and other - // parts of the code expect the `0` FileID to be the crate root. See also #1681 - let std_crate_name = "std"; - let path_to_std_lib_file = Path::new(std_crate_name).join("lib.nr"); - let root_file_id = context.file_manager.add_file(&path_to_std_lib_file).unwrap(); - - // You can add any crate type to the crate graph - // but you cannot depend on Binaries - let std_crate = context.crate_graph.add_stdlib(root_file_id); - propagate_dep(context, std_crate, &std_crate_name.parse().unwrap()); - - let mut errors = vec![]; - CrateDefMap::collect_defs(crate_id, context, &mut errors); - - if has_errors(&errors, deny_warnings) { - Err(errors) - } else { - Ok(errors) - } -} - -pub fn compute_function_abi( - context: &Context, - crate_id: &CrateId, -) -> Option<(Vec, Option)> { - let main_function = context.get_main_function(crate_id)?; - - let func_meta = context.def_interner.function_meta(&main_function); - - let (parameters, return_type) = func_meta.into_function_signature(); - let parameters = into_abi_params(parameters, &context.def_interner); - let return_type = return_type.map(|typ| AbiType::from_type(&typ)); - Some((parameters, return_type)) -} - -/// Run the frontend to check the crate for errors then compile the main function if there were none -/// -/// On success this returns the compiled program alongside any warnings that were found. -/// On error this returns the non-empty list of warnings and errors. -pub fn compile_main( - context: &mut Context, - crate_id: CrateId, - options: &CompileOptions, -) -> Result<(CompiledProgram, Warnings), ErrorsAndWarnings> { - let warnings = check_crate(context, crate_id, options.deny_warnings)?; - - let main = match context.get_main_function(&crate_id) { - Some(m) => m, - None => { - // TODO(#2155): This error might be a better to exist in Nargo - let err = CustomDiagnostic::from_message( - "cannot compile crate into a program as it does not contain a `main` function", - ) - .in_file(FileId::default()); - return Err(vec![err]); - } - }; - - let compiled_program = compile_no_check(context, options, main)?; - - if options.print_acir { - println!("Compiled ACIR for main (unoptimized):"); - println!("{}", compiled_program.circuit); - } - - Ok((compiled_program, warnings)) -} - -/// Run the frontend to check the crate for errors then compile all contracts if there were none -pub fn compile_contracts( - context: &mut Context, - crate_id: CrateId, - options: &CompileOptions, -) -> Result<(Vec, Warnings), ErrorsAndWarnings> { - let warnings = check_crate(context, crate_id, options.deny_warnings)?; - - // TODO: We probably want to error if contracts is empty - let contracts = context.get_all_contracts(&crate_id); - let mut compiled_contracts = vec![]; - let mut errors = warnings; - - for contract in contracts { - match compile_contract(context, contract, options) { - Ok(contract) => compiled_contracts.push(contract), - Err(mut more_errors) => errors.append(&mut more_errors), - } - } - - if has_errors(&errors, options.deny_warnings) { - Err(errors) - } else { - if options.print_acir { - for compiled_contract in &compiled_contracts { - for contract_function in &compiled_contract.functions { - println!( - "Compiled ACIR for {}::{} (unoptimized):", - compiled_contract.name, contract_function.name - ); - println!("{}", contract_function.bytecode); - } - } - } - // errors here is either empty or contains only warnings - Ok((compiled_contracts, errors)) - } -} - -/// True if there are (non-warning) errors present and we should halt compilation -fn has_errors(errors: &[FileDiagnostic], deny_warnings: bool) -> bool { - if deny_warnings { - !errors.is_empty() - } else { - errors.iter().any(|error| error.diagnostic.is_error()) - } -} - -/// Compile all of the functions associated with a Noir contract. -fn compile_contract( - context: &Context, - contract: Contract, - options: &CompileOptions, -) -> Result> { - let mut functions = Vec::new(); - let mut errors = Vec::new(); - for function_id in &contract.functions { - let name = context.function_name(function_id).to_owned(); - let function = match compile_no_check(context, options, *function_id) { - Ok(function) => function, - Err(new_error) => { - errors.push(new_error); - continue; - } - }; - let func_meta = context.def_interner.function_meta(function_id); - let func_type = func_meta - .contract_function_type - .expect("Expected contract function to have a contract visibility"); - - let function_type = ContractFunctionType::new(func_type, func_meta.is_unconstrained); - - functions.push(ContractFunction { - name, - function_type, - is_internal: func_meta.is_internal.unwrap_or(false), - abi: function.abi, - bytecode: function.circuit, - debug: function.debug, - }); - } - - if errors.is_empty() { - Ok(CompiledContract { name: contract.name, functions }) - } else { - Err(errors) - } -} - -/// Compile the current crate. Assumes self.check_crate is called beforehand! -/// -/// This function also assumes all errors in experimental_create_circuit and create_circuit -/// are not warnings. -#[allow(deprecated)] -pub fn compile_no_check( - context: &Context, - options: &CompileOptions, - main_function: FuncId, -) -> Result { - let program = monomorphize(main_function, &context.def_interner); - - let (circuit, debug, abi) = - create_circuit(context, program, options.show_ssa, options.show_brillig)?; - - Ok(CompiledProgram { circuit, debug, abi }) -} diff --git a/crates/noirc_driver/src/program.rs b/crates/noirc_driver/src/program.rs deleted file mode 100644 index 9323f90d522..00000000000 --- a/crates/noirc_driver/src/program.rs +++ /dev/null @@ -1,34 +0,0 @@ -use acvm::acir::circuit::Circuit; - -use base64::Engine; -use noirc_errors::debug_info::DebugInfo; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct CompiledProgram { - #[serde(serialize_with = "serialize_circuit", deserialize_with = "deserialize_circuit")] - pub circuit: Circuit, - pub abi: noirc_abi::Abi, - pub debug: DebugInfo, -} - -pub(crate) fn serialize_circuit(circuit: &Circuit, s: S) -> Result -where - S: Serializer, -{ - let mut circuit_bytes: Vec = Vec::new(); - circuit.write(&mut circuit_bytes).unwrap(); - - let encoded_b64 = base64::engine::general_purpose::STANDARD.encode(circuit_bytes); - s.serialize_str(&encoded_b64) -} - -pub(crate) fn deserialize_circuit<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let bytecode_b64: String = serde::Deserialize::deserialize(deserializer)?; - let circuit_bytes = base64::engine::general_purpose::STANDARD.decode(bytecode_b64).unwrap(); - let circuit = Circuit::read(&*circuit_bytes).unwrap(); - Ok(circuit) -} diff --git a/crates/noirc_errors/Cargo.toml b/crates/noirc_errors/Cargo.toml deleted file mode 100644 index d6183062ff0..00000000000 --- a/crates/noirc_errors/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "noirc_errors" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -acvm.workspace = true -codespan-reporting.workspace = true -codespan.workspace = true -fm.workspace = true -chumsky.workspace = true -serde.workspace = true -serde_with = "3.2.0" diff --git a/crates/noirc_evaluator/Cargo.toml b/crates/noirc_evaluator/Cargo.toml deleted file mode 100644 index b838f936ee6..00000000000 --- a/crates/noirc_evaluator/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "noirc_evaluator" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -noirc_frontend.workspace = true -noirc_errors.workspace = true -noirc_abi.workspace = true -acvm.workspace = true -iter-extended.workspace = true -thiserror.workspace = true -num-bigint = "0.4" -im = "15.1" diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs deleted file mode 100644 index 1ee323e4c09..00000000000 --- a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ /dev/null @@ -1,152 +0,0 @@ -use acvm::acir::{ - brillig::{BlackBoxOp, HeapVector, RegisterOrMemory}, - BlackBoxFunc, -}; - -use crate::brillig::brillig_ir::BrilligContext; - -/// Transforms SSA's black box function calls into the corresponding brillig instructions -/// Extracting arguments and results from the SSA function call -/// And making any necessary type conversions to adapt noir's blackbox calls to brillig's -pub(crate) fn convert_black_box_call( - brillig_context: &mut BrilligContext, - bb_func: &BlackBoxFunc, - function_arguments: &[RegisterOrMemory], - function_results: &[RegisterOrMemory], -) { - match bb_func { - BlackBoxFunc::SHA256 => { - if let ( - [RegisterOrMemory::HeapArray(message_array)], - [RegisterOrMemory::HeapArray(result_array)], - ) = (function_arguments, function_results) - { - let message_vector = brillig_context.array_to_vector(message_array); - brillig_context.black_box_op_instruction(BlackBoxOp::Sha256 { - message: message_vector, - output: *result_array, - }); - } else { - unreachable!("ICE: SHA256 expects one array argument and one array result") - } - } - BlackBoxFunc::Blake2s => { - if let ( - [RegisterOrMemory::HeapArray(message_array)], - [RegisterOrMemory::HeapArray(result_array)], - ) = (function_arguments, function_results) - { - let message_vector = brillig_context.array_to_vector(message_array); - brillig_context.black_box_op_instruction(BlackBoxOp::Blake2s { - message: message_vector, - output: *result_array, - }); - } else { - unreachable!("ICE: Blake2s expects one array argument and one array result") - } - } - BlackBoxFunc::Keccak256 => { - if let ( - [RegisterOrMemory::HeapArray(message_array), RegisterOrMemory::RegisterIndex(array_size)], - [RegisterOrMemory::HeapArray(result_array)], - ) = (function_arguments, function_results) - { - let message_vector = - HeapVector { size: *array_size, pointer: message_array.pointer }; - brillig_context.black_box_op_instruction(BlackBoxOp::Keccak256 { - message: message_vector, - output: *result_array, - }); - } else { - unreachable!("ICE: Keccak256 expects message, message size and result array") - } - } - BlackBoxFunc::HashToField128Security => { - if let ( - [RegisterOrMemory::HeapArray(message_array)], - [RegisterOrMemory::RegisterIndex(result_register)], - ) = (function_arguments, function_results) - { - let message_vector = brillig_context.array_to_vector(message_array); - brillig_context.black_box_op_instruction(BlackBoxOp::HashToField128Security { - message: message_vector, - output: *result_register, - }); - } else { - unreachable!("ICE: HashToField128Security expects one array argument and one register result") - } - } - BlackBoxFunc::EcdsaSecp256k1 => { - if let ( - [RegisterOrMemory::HeapArray(public_key_x), RegisterOrMemory::HeapArray(public_key_y), RegisterOrMemory::HeapArray(signature), RegisterOrMemory::HeapArray(message_hash)], - [RegisterOrMemory::RegisterIndex(result_register)], - ) = (function_arguments, function_results) - { - let message_hash_vector = brillig_context.array_to_vector(message_hash); - brillig_context.black_box_op_instruction(BlackBoxOp::EcdsaSecp256k1 { - hashed_msg: message_hash_vector, - public_key_x: *public_key_x, - public_key_y: *public_key_y, - signature: *signature, - result: *result_register, - }); - } else { - unreachable!( - "ICE: EcdsaSecp256k1 expects four array arguments and one register result" - ) - } - } - BlackBoxFunc::Pedersen => { - if let ( - [RegisterOrMemory::HeapArray(message_array), RegisterOrMemory::RegisterIndex(domain_separator)], - [RegisterOrMemory::HeapArray(result_array)], - ) = (function_arguments, function_results) - { - let message_vector = brillig_context.array_to_vector(message_array); - brillig_context.black_box_op_instruction(BlackBoxOp::Pedersen { - inputs: message_vector, - domain_separator: *domain_separator, - output: *result_array, - }); - } else { - unreachable!("ICE: Pedersen expects one array argument, a register for the domain separator, and one array result") - } - } - BlackBoxFunc::SchnorrVerify => { - if let ( - [RegisterOrMemory::RegisterIndex(public_key_x), RegisterOrMemory::RegisterIndex(public_key_y), RegisterOrMemory::HeapArray(signature), RegisterOrMemory::HeapArray(message_hash)], - [RegisterOrMemory::RegisterIndex(result_register)], - ) = (function_arguments, function_results) - { - let message_hash = brillig_context.array_to_vector(message_hash); - let signature = brillig_context.array_to_vector(signature); - brillig_context.black_box_op_instruction(BlackBoxOp::SchnorrVerify { - public_key_x: *public_key_x, - public_key_y: *public_key_y, - message: message_hash, - signature, - result: *result_register, - }); - } else { - unreachable!("ICE: Schnorr verify expects two registers for the public key, an array for signature, an array for the message hash and one result register") - } - } - BlackBoxFunc::FixedBaseScalarMul => { - if let ( - [RegisterOrMemory::RegisterIndex(scalar)], - [RegisterOrMemory::HeapArray(result_array)], - ) = (function_arguments, function_results) - { - brillig_context.black_box_op_instruction(BlackBoxOp::FixedBaseScalarMul { - input: *scalar, - result: *result_array, - }); - } else { - unreachable!( - "ICE: FixedBaseScalarMul expects one register argument and one array result" - ) - } - } - _ => unimplemented!("ICE: Black box function {:?} is not implemented", bb_func), - } -} diff --git a/crates/noirc_evaluator/src/brillig/mod.rs b/crates/noirc_evaluator/src/brillig/mod.rs deleted file mode 100644 index 0c6ddd53a4e..00000000000 --- a/crates/noirc_evaluator/src/brillig/mod.rs +++ /dev/null @@ -1,104 +0,0 @@ -pub(crate) mod brillig_gen; -pub(crate) mod brillig_ir; - -use self::{ - brillig_gen::{brillig_fn::FunctionContext, convert_ssa_function}, - brillig_ir::artifact::{BrilligArtifact, Label}, -}; -use crate::ssa::{ - ir::{ - function::{Function, FunctionId, RuntimeType}, - value::Value, - }, - ssa_gen::Ssa, -}; -use std::collections::{HashMap, HashSet}; - -/// Context structure for the brillig pass. -/// It stores brillig-related data required for brillig generation. -#[derive(Default)] -pub struct Brillig { - /// Maps SSA function labels to their brillig artifact - ssa_function_to_brillig: HashMap, -} - -impl Brillig { - /// Compiles a function into brillig and store the compilation artifacts - pub(crate) fn compile(&mut self, func: &Function, enable_debug_trace: bool) { - let obj = convert_ssa_function(func, enable_debug_trace); - self.ssa_function_to_brillig.insert(func.id(), obj); - } - - /// Finds a brillig function artifact by its function label - pub(crate) fn find_by_function_label(&self, function_label: Label) -> Option<&BrilligArtifact> { - self.ssa_function_to_brillig.iter().find_map(|(function_id, obj)| { - if FunctionContext::function_id_to_function_label(*function_id) == function_label { - Some(obj) - } else { - None - } - }) - } -} - -impl std::ops::Index for Brillig { - type Output = BrilligArtifact; - fn index(&self, id: FunctionId) -> &Self::Output { - &self.ssa_function_to_brillig[&id] - } -} - -impl Ssa { - /// Compile to brillig brillig functions and ACIR functions reachable from them - pub(crate) fn to_brillig(&self, enable_debug_trace: bool) -> Brillig { - // Collect all the function ids that are reachable from brillig - // That means all the functions marked as brillig and ACIR functions called by them - let mut brillig_reachable_function_ids: HashSet = HashSet::new(); - - // Initialize the queue with all the functions marked as brillig - let mut reachability_queue: Vec = self - .functions - .iter() - .filter_map( - |(id, func)| { - if func.runtime() == RuntimeType::Brillig { - Some(*id) - } else { - None - } - }, - ) - .collect(); - - while let Some(func_id) = reachability_queue.pop() { - let func = &self.functions[&func_id]; - brillig_reachable_function_ids.insert(func.id()); - - // Explore all functions that are reachable from this function - for (_, value) in func.dfg.values_iter() { - // All reachable functions appear as literals after defunctionalization of the SSA - let reachable_function = match value { - Value::Function(function_id) => function_id, - _ => continue, - }; - - // If the function is already reachable by brillig or enqueued, skip it. - if brillig_reachable_function_ids.contains(reachable_function) - || reachability_queue.contains(reachable_function) - { - continue; - } - - reachability_queue.push(*reachable_function); - } - } - - let mut brillig = Brillig::default(); - for brillig_function_id in brillig_reachable_function_ids { - let func = &self.functions[&brillig_function_id]; - brillig.compile(func, enable_debug_trace); - } - - brillig - } -} diff --git a/crates/noirc_evaluator/src/errors.rs b/crates/noirc_evaluator/src/errors.rs deleted file mode 100644 index eab9bff043a..00000000000 --- a/crates/noirc_evaluator/src/errors.rs +++ /dev/null @@ -1,113 +0,0 @@ -//! Noir Evaluator has two types of errors -//! -//! [RuntimeError]s that should be displayed to the user -//! -//! [InternalError]s that are used for checking internal logics of the SSA -//! -//! An Error of the former is a user Error -//! -//! An Error of the latter is an error in the implementation of the compiler -use acvm::acir::native_types::Expression; -use iter_extended::vecmap; -use noirc_errors::{CustomDiagnostic as Diagnostic, FileDiagnostic}; -use thiserror::Error; - -use crate::ssa::ir::dfg::CallStack; - -#[derive(Debug, PartialEq, Eq, Clone, Error)] -pub enum RuntimeError { - // We avoid showing the actual lhs and rhs since most of the time they are just 0 - // and 1 respectively. This would confuse users if a constraint such as - // assert(foo < bar) fails with "failed constraint: 0 = 1." - #[error("Failed constraint")] - FailedConstraint { lhs: Box, rhs: Box, call_stack: CallStack }, - #[error(transparent)] - InternalError(#[from] InternalError), - #[error("Index out of bounds, array has size {index:?}, but index was {array_size:?}")] - IndexOutOfBounds { index: usize, array_size: usize, call_stack: CallStack }, - #[error("Range constraint of {num_bits} bits is too large for the Field size")] - InvalidRangeConstraint { num_bits: u32, call_stack: CallStack }, - #[error("Expected array index to fit into a u64")] - TypeConversion { from: String, into: String, call_stack: CallStack }, - #[error("{name:?} is not initialized")] - UnInitialized { name: String, call_stack: CallStack }, - #[error("Integer sized {num_bits:?} is over the max supported size of {max_num_bits:?}")] - UnsupportedIntegerSize { num_bits: u32, max_num_bits: u32, call_stack: CallStack }, - #[error("Could not determine loop bound at compile-time")] - UnknownLoopBound { call_stack: CallStack }, - #[error("Argument is not constant")] - AssertConstantFailed { call_stack: CallStack }, -} - -#[derive(Debug, PartialEq, Eq, Clone, Error)] -pub enum InternalError { - #[error("ICE: Both expressions should have degree<=1")] - DegreeNotReduced { call_stack: CallStack }, - #[error("Try to get element from empty array")] - EmptyArray { call_stack: CallStack }, - #[error("ICE: {message:?}")] - General { message: String, call_stack: CallStack }, - #[error("ICE: {name:?} missing {arg:?} arg")] - MissingArg { name: String, arg: String, call_stack: CallStack }, - #[error("ICE: {name:?} should be a constant")] - NotAConstant { name: String, call_stack: CallStack }, - #[error("ICE: Undeclared AcirVar")] - UndeclaredAcirVar { call_stack: CallStack }, - #[error("ICE: Expected {expected:?}, found {found:?}")] - UnExpected { expected: String, found: String, call_stack: CallStack }, -} - -impl RuntimeError { - fn call_stack(&self) -> &CallStack { - match self { - RuntimeError::InternalError( - InternalError::DegreeNotReduced { call_stack } - | InternalError::EmptyArray { call_stack } - | InternalError::General { call_stack, .. } - | InternalError::MissingArg { call_stack, .. } - | InternalError::NotAConstant { call_stack, .. } - | InternalError::UndeclaredAcirVar { call_stack } - | InternalError::UnExpected { call_stack, .. }, - ) - | RuntimeError::FailedConstraint { call_stack, .. } - | RuntimeError::IndexOutOfBounds { call_stack, .. } - | RuntimeError::InvalidRangeConstraint { call_stack, .. } - | RuntimeError::TypeConversion { call_stack, .. } - | RuntimeError::UnInitialized { call_stack, .. } - | RuntimeError::UnknownLoopBound { call_stack } - | RuntimeError::AssertConstantFailed { call_stack } - | RuntimeError::UnsupportedIntegerSize { call_stack, .. } => call_stack, - } - } -} - -impl From for FileDiagnostic { - fn from(error: RuntimeError) -> FileDiagnostic { - let call_stack = vecmap(error.call_stack(), |location| *location); - let diagnostic = error.into_diagnostic(); - let file_id = call_stack.last().map(|location| location.file).unwrap_or_default(); - - diagnostic.in_file(file_id).with_call_stack(call_stack) - } -} - -impl RuntimeError { - fn into_diagnostic(self) -> Diagnostic { - match self { - RuntimeError::InternalError(_) => { - Diagnostic::simple_error( - "Internal Consistency Evaluators Errors: \n - This is likely a bug. Consider Opening an issue at https://github.com/noir-lang/noir/issues".to_owned(), - "".to_string(), - noirc_errors::Span::new(0..0) - ) - } - _ => { - let message = self.to_string(); - let location = self.call_stack().back().expect("Expected RuntimeError to have a location"); - - Diagnostic::simple_error(message, String::new(), location.span) - } - } - } -} diff --git a/crates/noirc_evaluator/src/ssa.rs b/crates/noirc_evaluator/src/ssa.rs deleted file mode 100644 index 7dbd627a949..00000000000 --- a/crates/noirc_evaluator/src/ssa.rs +++ /dev/null @@ -1,135 +0,0 @@ -//! SSA stands for Single Static Assignment -//! The IR presented in this module will already -//! be in SSA form and will be used to apply -//! conventional optimizations like Common Subexpression -//! elimination and constant folding. -//! -//! This module heavily borrows from Cranelift -#![allow(dead_code)] - -use std::collections::BTreeSet; - -use crate::errors::RuntimeError; -use acvm::acir::{ - circuit::{Circuit, PublicInputs}, - native_types::Witness, -}; - -use noirc_errors::debug_info::DebugInfo; - -use noirc_abi::Abi; - -use noirc_frontend::{hir::Context, monomorphization::ast::Program}; - -use self::{abi_gen::gen_abi, acir_gen::GeneratedAcir, ir::function::RuntimeType, ssa_gen::Ssa}; - -pub mod abi_gen; -mod acir_gen; -pub mod ir; -mod opt; -mod ssa_builder; -pub mod ssa_gen; - -/// Optimize the given program by converting it into SSA -/// form and performing optimizations there. When finished, -/// convert the final SSA into ACIR and return it. -pub(crate) fn optimize_into_acir( - program: Program, - print_ssa_passes: bool, - print_brillig_trace: bool, -) -> Result { - let abi_distinctness = program.return_distinctness; - let mut ssa = ssa_gen::generate_ssa(program) - .print(print_ssa_passes, "Initial SSA:") - .defunctionalize() - .print(print_ssa_passes, "After Defunctionalization:"); - - let brillig = ssa.to_brillig(print_brillig_trace); - if let RuntimeType::Acir = ssa.main().runtime() { - ssa = ssa - .inline_functions() - .print(print_ssa_passes, "After Inlining:") - // Run mem2reg with the CFG separated into blocks - .mem2reg() - .print(print_ssa_passes, "After Mem2Reg:") - .evaluate_assert_constant()? - .unroll_loops()? - .print(print_ssa_passes, "After Unrolling:") - .simplify_cfg() - .print(print_ssa_passes, "After Simplifying:") - // Run mem2reg before flattening to handle any promotion - // of values that can be accessed after loop unrolling. - // If there are slice mergers uncovered by loop unrolling - // and this pass is missed, slice merging will fail inside of flattening. - .mem2reg() - .print(print_ssa_passes, "After Mem2Reg:") - .flatten_cfg() - .print(print_ssa_passes, "After Flattening:") - // Run mem2reg once more with the flattened CFG to catch any remaining loads/stores - .mem2reg() - .print(print_ssa_passes, "After Mem2Reg:") - .fold_constants() - .print(print_ssa_passes, "After Constant Folding:") - .dead_instruction_elimination() - .print(print_ssa_passes, "After Dead Instruction Elimination:"); - } - let last_array_uses = ssa.find_last_array_uses(); - ssa.into_acir(brillig, abi_distinctness, &last_array_uses) -} - -/// Compiles the [`Program`] into [`ACIR`][acvm::acir::circuit::Circuit]. -/// -/// The output ACIR is is backend-agnostic and so must go through a transformation pass before usage in proof generation. -pub fn create_circuit( - context: &Context, - program: Program, - enable_ssa_logging: bool, - enable_brillig_logging: bool, -) -> Result<(Circuit, DebugInfo, Abi), RuntimeError> { - let func_sig = program.main_function_signature.clone(); - let mut generated_acir = - optimize_into_acir(program, enable_ssa_logging, enable_brillig_logging)?; - let opcodes = generated_acir.take_opcodes(); - let GeneratedAcir { - current_witness_index, return_witnesses, locations, input_witnesses, .. - } = generated_acir; - - let abi = gen_abi(&context.def_interner, func_sig, &input_witnesses, return_witnesses.clone()); - let public_abi = abi.clone().public_abi(); - - let public_parameters = - PublicInputs(public_abi.param_witnesses.values().flatten().copied().collect()); - - let all_parameters: BTreeSet = - abi.param_witnesses.values().flatten().copied().collect(); - let private_parameters = all_parameters.difference(&public_parameters.0).copied().collect(); - - let return_values = PublicInputs(return_witnesses.into_iter().collect()); - - let circuit = Circuit { - current_witness_index, - opcodes, - private_parameters, - public_parameters, - return_values, - }; - - // This converts each im::Vector in the BTreeMap to a Vec - let locations = locations - .into_iter() - .map(|(index, locations)| (index, locations.into_iter().collect())) - .collect(); - - let debug_info = DebugInfo::new(locations); - - Ok((circuit, debug_info, abi)) -} - -impl Ssa { - fn print(self, print_ssa_passes: bool, msg: &str) -> Ssa { - if print_ssa_passes { - println!("{msg}\n{self}"); - } - self - } -} diff --git a/crates/noirc_evaluator/src/ssa/abi_gen/mod.rs b/crates/noirc_evaluator/src/ssa/abi_gen/mod.rs deleted file mode 100644 index f2c61715e37..00000000000 --- a/crates/noirc_evaluator/src/ssa/abi_gen/mod.rs +++ /dev/null @@ -1,67 +0,0 @@ -use std::collections::BTreeMap; - -use acvm::acir::native_types::Witness; -use iter_extended::{btree_map, vecmap}; -use noirc_abi::{Abi, AbiParameter, AbiType}; -use noirc_frontend::{ - hir_def::{ - function::{FunctionSignature, Param}, - stmt::HirPattern, - }, - node_interner::NodeInterner, -}; - -/// Attempts to retrieve the name of this parameter. Returns None -/// if this parameter is a tuple or struct pattern. -fn get_param_name<'a>(pattern: &HirPattern, interner: &'a NodeInterner) -> Option<&'a str> { - match pattern { - HirPattern::Identifier(ident) => Some(interner.definition_name(ident.id)), - HirPattern::Mutable(pattern, _) => get_param_name(pattern, interner), - HirPattern::Tuple(_, _) => None, - HirPattern::Struct(_, _, _) => None, - } -} - -pub fn into_abi_params(params: Vec, interner: &NodeInterner) -> Vec { - vecmap(params, |(pattern, typ, vis)| { - let param_name = get_param_name(&pattern, interner) - .expect("Abi for tuple and struct parameters is unimplemented") - .to_owned(); - let as_abi = AbiType::from_type(&typ); - AbiParameter { name: param_name, typ: as_abi, visibility: vis.into() } - }) -} - -/// Arranges a function signature and a generated circuit's return witnesses into a -/// `noirc_abi::Abi`. -pub(crate) fn gen_abi( - interner: &NodeInterner, - func_sig: FunctionSignature, - input_witnesses: &[Witness], - return_witnesses: Vec, -) -> Abi { - let (parameters, return_type) = func_sig; - let parameters = into_abi_params(parameters, interner); - let return_type = return_type.map(|typ| AbiType::from_type(&typ)); - let param_witnesses = param_witnesses_from_abi_param(¶meters, input_witnesses); - Abi { parameters, return_type, param_witnesses, return_witnesses } -} - -// Takes each abi parameter and shallowly maps to the expected witness range in which the -// parameter's constituent values live. -fn param_witnesses_from_abi_param( - abi_params: &Vec, - input_witnesses: &[Witness], -) -> BTreeMap> { - let mut idx = 0_usize; - - btree_map(abi_params, |param| { - let num_field_elements_needed = param.typ.field_count(); - let mut wit = Vec::new(); - for _ in 0..num_field_elements_needed { - wit.push(input_witnesses[idx]); - idx += 1; - } - (param.name.clone(), wit) - }) -} diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/mod.rs b/crates/noirc_evaluator/src/ssa/acir_gen/mod.rs deleted file mode 100644 index 92711701c76..00000000000 --- a/crates/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ /dev/null @@ -1,1182 +0,0 @@ -//! This file holds the pass to convert from Noir's SSA IR to ACIR. -mod acir_ir; - -use std::collections::{HashMap, HashSet}; -use std::fmt::Debug; -use std::ops::RangeInclusive; - -use self::acir_ir::acir_variable::{AcirContext, AcirType, AcirVar}; -use super::ir::dfg::CallStack; -use super::{ - ir::{ - dfg::DataFlowGraph, - function::{Function, RuntimeType}, - instruction::{ - Binary, BinaryOp, Instruction, InstructionId, Intrinsic, TerminatorInstruction, - }, - map::Id, - types::{NumericType, Type}, - value::{Value, ValueId}, - }, - ssa_gen::Ssa, -}; -use crate::brillig::brillig_ir::artifact::GeneratedBrillig; -use crate::brillig::brillig_ir::BrilligContext; -use crate::brillig::{brillig_gen::brillig_fn::FunctionContext as BrilligFunctionContext, Brillig}; -use crate::errors::{InternalError, RuntimeError}; -pub(crate) use acir_ir::generated_acir::GeneratedAcir; -use acvm::{ - acir::{circuit::opcodes::BlockId, native_types::Expression}, - FieldElement, -}; -use iter_extended::{try_vecmap, vecmap}; -use noirc_frontend::Distinctness; - -/// Context struct for the acir generation pass. -/// May be similar to the Evaluator struct in the current SSA IR. -struct Context { - /// Maps SSA values to `AcirVar`. - /// - /// This is needed so that we only create a single - /// AcirVar per SSA value. Before creating an `AcirVar` - /// for an SSA value, we check this map. If an `AcirVar` - /// already exists for this Value, we return the `AcirVar`. - ssa_values: HashMap, AcirValue>, - - /// The `AcirVar` that describes the condition belonging to the most recently invoked - /// `SideEffectsEnabled` instruction. - current_side_effects_enabled_var: AcirVar, - - /// Manages and builds the `AcirVar`s to which the converted SSA values refer. - acir_context: AcirContext, - - /// Track initialized acir dynamic arrays - /// - /// An acir array must start with a MemoryInit ACIR opcodes - /// and then have MemoryOp opcodes - /// This set is used to ensure that a MemoryOp opcode is only pushed to the circuit - /// if there is already a MemoryInit opcode. - initialized_arrays: HashSet, - - /// Maps SSA values to BlockId - /// A BlockId is an ACIR structure which identifies a memory block - /// Each acir memory block corresponds to a different SSA array. - memory_blocks: HashMap, BlockId>, - - /// Number of the next BlockId, it is used to construct - /// a new BlockId - max_block_id: u32, -} - -#[derive(Clone)] -pub(crate) struct AcirDynamicArray { - /// Identification for the Acir dynamic array - /// This is essentially a ACIR pointer to the array - block_id: BlockId, - /// Length of the array - len: usize, -} -impl Debug for AcirDynamicArray { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "id: {}, len: {}", self.block_id.0, self.len) - } -} - -#[derive(Debug, Clone)] -pub(crate) enum AcirValue { - Var(AcirVar, AcirType), - Array(im::Vector), - DynamicArray(AcirDynamicArray), -} - -impl AcirValue { - fn into_var(self) -> Result { - match self { - AcirValue::Var(var, _) => Ok(var), - AcirValue::DynamicArray(_) | AcirValue::Array(_) => Err(InternalError::General { - message: "Called AcirValue::into_var on an array".to_string(), - call_stack: CallStack::new(), - }), - } - } - - fn flatten(self) -> Vec<(AcirVar, AcirType)> { - match self { - AcirValue::Var(var, typ) => vec![(var, typ)], - AcirValue::Array(array) => array.into_iter().flat_map(AcirValue::flatten).collect(), - AcirValue::DynamicArray(_) => unimplemented!("Cannot flatten a dynamic array"), - } - } -} - -impl Ssa { - pub(crate) fn into_acir( - self, - brillig: Brillig, - abi_distinctness: Distinctness, - last_array_uses: &HashMap, - ) -> Result { - let context = Context::new(); - let mut generated_acir = context.convert_ssa(self, brillig, last_array_uses)?; - - match abi_distinctness { - Distinctness::Distinct => { - // Create a witness for each return witness we have - // to guarantee that the return witnesses are distinct - let distinct_return_witness: Vec<_> = generated_acir - .return_witnesses - .clone() - .into_iter() - .map(|return_witness| { - generated_acir - .create_witness_for_expression(&Expression::from(return_witness)) - }) - .collect(); - - generated_acir.return_witnesses = distinct_return_witness; - Ok(generated_acir) - } - Distinctness::DuplicationAllowed => Ok(generated_acir), - } - } -} - -impl Context { - fn new() -> Context { - let mut acir_context = AcirContext::default(); - let current_side_effects_enabled_var = acir_context.add_constant(FieldElement::one()); - - Context { - ssa_values: HashMap::new(), - current_side_effects_enabled_var, - acir_context, - initialized_arrays: HashSet::new(), - memory_blocks: HashMap::new(), - max_block_id: 0, - } - } - - /// Converts SSA into ACIR - fn convert_ssa( - self, - ssa: Ssa, - brillig: Brillig, - last_array_uses: &HashMap, - ) -> Result { - let main_func = ssa.main(); - match main_func.runtime() { - RuntimeType::Acir => self.convert_acir_main(main_func, &ssa, brillig, last_array_uses), - RuntimeType::Brillig => self.convert_brillig_main(main_func, brillig), - } - } - - fn convert_acir_main( - mut self, - main_func: &Function, - ssa: &Ssa, - brillig: Brillig, - last_array_uses: &HashMap, - ) -> Result { - let dfg = &main_func.dfg; - let entry_block = &dfg[main_func.entry_block()]; - let input_witness = self.convert_ssa_block_params(entry_block.parameters(), dfg)?; - - for instruction_id in entry_block.instructions() { - self.convert_ssa_instruction(*instruction_id, dfg, ssa, &brillig, last_array_uses)?; - } - - self.convert_ssa_return(entry_block.unwrap_terminator(), dfg)?; - - Ok(self.acir_context.finish(input_witness.collect())) - } - - fn convert_brillig_main( - mut self, - main_func: &Function, - brillig: Brillig, - ) -> Result { - let dfg = &main_func.dfg; - - let inputs = try_vecmap(dfg[main_func.entry_block()].parameters(), |param_id| { - let typ = dfg.type_of_value(*param_id); - self.create_value_from_type(&typ, &mut |this, _| Ok(this.acir_context.add_variable())) - })?; - let witness_inputs = self.acir_context.extract_witness(&inputs); - - let outputs: Vec = - vecmap(main_func.returns(), |result_id| dfg.type_of_value(*result_id).into()); - - let code = self.gen_brillig_for(main_func, &brillig)?; - - let output_values = self.acir_context.brillig( - self.current_side_effects_enabled_var, - code, - inputs, - outputs, - )?; - let output_vars: Vec<_> = output_values - .iter() - .flat_map(|value| value.clone().flatten()) - .map(|value| value.0) - .collect(); - - for acir_var in output_vars { - self.acir_context.return_var(acir_var)?; - } - - Ok(self.acir_context.finish(witness_inputs)) - } - - /// Adds and binds `AcirVar`s for each numeric block parameter or block parameter array element. - fn convert_ssa_block_params( - &mut self, - params: &[ValueId], - dfg: &DataFlowGraph, - ) -> Result, RuntimeError> { - // The first witness (if any) is the next one - let start_witness = self.acir_context.current_witness_index().0 + 1; - for param_id in params { - let typ = dfg.type_of_value(*param_id); - let value = self.convert_ssa_block_param(&typ)?; - match &value { - AcirValue::Var(_, _) => (), - AcirValue::Array(values) => { - let block_id = self.block_id(param_id); - let v = vecmap(values, |v| v.clone()); - self.initialize_array(block_id, values.len(), Some(&v))?; - } - AcirValue::DynamicArray(_) => unreachable!( - "The dynamic array type is created in Acir gen and therefore cannot be a block parameter" - ), - } - self.ssa_values.insert(*param_id, value); - } - let end_witness = self.acir_context.current_witness_index().0; - Ok(start_witness..=end_witness) - } - - fn convert_ssa_block_param(&mut self, param_type: &Type) -> Result { - self.create_value_from_type(param_type, &mut |this, typ| this.add_numeric_input_var(&typ)) - } - - fn create_value_from_type( - &mut self, - param_type: &Type, - make_var: &mut impl FnMut(&mut Self, NumericType) -> Result, - ) -> Result { - match param_type { - Type::Numeric(numeric_type) => { - let typ = AcirType::new(*numeric_type); - Ok(AcirValue::Var(make_var(self, *numeric_type)?, typ)) - } - Type::Array(element_types, length) => { - let mut elements = im::Vector::new(); - - for _ in 0..*length { - for element in element_types.iter() { - elements.push_back(self.create_value_from_type(element, make_var)?); - } - } - - Ok(AcirValue::Array(elements)) - } - _ => unreachable!("ICE: Params to the program should only contains numbers and arrays"), - } - } - - /// Get the BlockId corresponding to the ValueId - /// If there is no matching BlockId, we create a new one. - fn block_id(&mut self, value: &ValueId) -> BlockId { - if let Some(block_id) = self.memory_blocks.get(value) { - return *block_id; - } - let block_id = BlockId(self.max_block_id); - self.max_block_id += 1; - self.memory_blocks.insert(*value, block_id); - block_id - } - - /// Creates an `AcirVar` corresponding to a parameter witness to appears in the abi. A range - /// constraint is added if the numeric type requires it. - /// - /// This function is used not only for adding numeric block parameters, but also for adding - /// any array elements that belong to reference type block parameters. - fn add_numeric_input_var( - &mut self, - numeric_type: &NumericType, - ) -> Result { - let acir_var = self.acir_context.add_variable(); - if matches!(numeric_type, NumericType::Signed { .. } | NumericType::Unsigned { .. }) { - self.acir_context.range_constrain_var(acir_var, numeric_type)?; - } - Ok(acir_var) - } - - /// Converts an SSA instruction into its ACIR representation - fn convert_ssa_instruction( - &mut self, - instruction_id: InstructionId, - dfg: &DataFlowGraph, - ssa: &Ssa, - brillig: &Brillig, - last_array_uses: &HashMap, - ) -> Result<(), RuntimeError> { - let instruction = &dfg[instruction_id]; - self.acir_context.set_call_stack(dfg.get_call_stack(instruction_id)); - match instruction { - Instruction::Binary(binary) => { - let result_acir_var = self.convert_ssa_binary(binary, dfg)?; - self.define_result_var(dfg, instruction_id, result_acir_var); - } - Instruction::Constrain(value_id) => { - let constrain_condition = self.convert_numeric_value(*value_id, dfg)?; - self.acir_context.assert_eq_one(constrain_condition)?; - } - Instruction::Cast(value_id, typ) => { - let result_acir_var = self.convert_ssa_cast(value_id, typ, dfg)?; - self.define_result_var(dfg, instruction_id, result_acir_var); - } - Instruction::Call { func, arguments } => { - let result_ids = dfg.instruction_results(instruction_id); - match &dfg[*func] { - Value::Function(id) => { - let func = &ssa.functions[id]; - match func.runtime() { - RuntimeType::Acir => unimplemented!( - "expected an intrinsic/brillig call, but found {func:?}. All ACIR methods should be inlined" - ), - RuntimeType::Brillig => { - let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); - - let code = self.gen_brillig_for(func, brillig)?; - - let outputs: Vec = vecmap(result_ids, |result_id| dfg.type_of_value(*result_id).into()); - - let output_values = self.acir_context.brillig(self.current_side_effects_enabled_var, code, inputs, outputs)?; - - // Compiler sanity check - assert_eq!(result_ids.len(), output_values.len(), "ICE: The number of Brillig output values should match the result ids in SSA"); - - for result in result_ids.iter().zip(output_values) { - self.ssa_values.insert(*result.0, result.1); - } - } - } - } - Value::Intrinsic(intrinsic) => { - let outputs = self - .convert_ssa_intrinsic_call(*intrinsic, arguments, dfg, result_ids)?; - - // Issue #1438 causes this check to fail with intrinsics that return 0 - // results but the ssa form instead creates 1 unit result value. - // assert_eq!(result_ids.len(), outputs.len()); - - for (result, output) in result_ids.iter().zip(outputs) { - self.ssa_values.insert(*result, output); - } - } - Value::ForeignFunction(_) => unreachable!( - "All `oracle` methods should be wrapped in an unconstrained fn" - ), - _ => unreachable!("expected calling a function"), - } - } - Instruction::Not(value_id) => { - let (acir_var, typ) = match self.convert_value(*value_id, dfg) { - AcirValue::Var(acir_var, typ) => (acir_var, typ), - _ => unreachable!("NOT is only applied to numerics"), - }; - let result_acir_var = self.acir_context.not_var(acir_var, typ)?; - self.define_result_var(dfg, instruction_id, result_acir_var); - } - Instruction::Truncate { value, bit_size, max_bit_size } => { - let result_acir_var = - self.convert_ssa_truncate(*value, *bit_size, *max_bit_size, dfg)?; - self.define_result_var(dfg, instruction_id, result_acir_var); - } - Instruction::EnableSideEffects { condition } => { - let acir_var = self.convert_numeric_value(*condition, dfg)?; - self.current_side_effects_enabled_var = acir_var; - } - Instruction::ArrayGet { array, index } => { - self.handle_array_operation( - instruction_id, - *array, - *index, - None, - dfg, - last_array_uses, - )?; - } - Instruction::ArraySet { array, index, value } => { - self.handle_array_operation( - instruction_id, - *array, - *index, - Some(*value), - dfg, - last_array_uses, - )?; - } - Instruction::Allocate => { - unreachable!("Expected all allocate instructions to be removed before acir_gen") - } - Instruction::Store { .. } => { - unreachable!("Expected all store instructions to be removed before acir_gen") - } - Instruction::Load { .. } => { - unreachable!("Expected all load instructions to be removed before acir_gen") - } - } - self.acir_context.set_call_stack(CallStack::new()); - Ok(()) - } - - fn gen_brillig_for( - &self, - func: &Function, - brillig: &Brillig, - ) -> Result { - // Create the entry point artifact - let mut entry_point = BrilligContext::new_entry_point_artifact( - BrilligFunctionContext::parameters(func), - BrilligFunctionContext::return_values(func), - BrilligFunctionContext::function_id_to_function_label(func.id()), - ); - // Link the entry point with all dependencies - while let Some(unresolved_fn_label) = entry_point.first_unresolved_function_call() { - let artifact = &brillig.find_by_function_label(unresolved_fn_label.clone()); - let artifact = match artifact { - Some(artifact) => artifact, - None => { - return Err(InternalError::General { - message: format!("Cannot find linked fn {unresolved_fn_label}"), - call_stack: CallStack::new(), - }) - } - }; - entry_point.link_with(artifact); - } - // Generate the final bytecode - Ok(entry_point.finish()) - } - - /// Handles an ArrayGet or ArraySet instruction. - /// To set an index of the array (and create a new array in doing so), pass Some(value) for - /// store_value. To just retrieve an index of the array, pass None for store_value. - fn handle_array_operation( - &mut self, - instruction: InstructionId, - array: ValueId, - index: ValueId, - store_value: Option, - dfg: &DataFlowGraph, - last_array_uses: &HashMap, - ) -> Result<(), RuntimeError> { - let index_const = dfg.get_numeric_constant(index); - - match self.convert_value(array, dfg) { - AcirValue::Var(acir_var, _) => { - return Err(RuntimeError::InternalError(InternalError::UnExpected { - expected: "an array value".to_string(), - found: format!("{acir_var:?}"), - call_stack: self.acir_context.get_call_stack(), - })) - } - AcirValue::Array(array) => { - if let Some(index_const) = index_const { - let array_size = array.len(); - let index = match index_const.try_to_u64() { - Some(index_const) => index_const as usize, - None => { - let call_stack = self.acir_context.get_call_stack(); - return Err(RuntimeError::TypeConversion { - from: "array index".to_string(), - into: "u64".to_string(), - call_stack, - }); - } - }; - if index >= array_size { - // Ignore the error if side effects are disabled. - if self.acir_context.is_constant_one(&self.current_side_effects_enabled_var) - { - let call_stack = self.acir_context.get_call_stack(); - return Err(RuntimeError::IndexOutOfBounds { - index, - array_size, - call_stack, - }); - } - let result_type = - dfg.type_of_value(dfg.instruction_results(instruction)[0]); - let value = self.create_default_value(&result_type)?; - self.define_result(dfg, instruction, value); - return Ok(()); - } - - let value = match store_value { - Some(store_value) => { - let store_value = self.convert_value(store_value, dfg); - AcirValue::Array(array.update(index, store_value)) - } - None => array[index].clone(), - }; - - self.define_result(dfg, instruction, value); - return Ok(()); - } - } - AcirValue::DynamicArray(_) => (), - } - let resolved_array = dfg.resolve(array); - let map_array = last_array_uses.get(&resolved_array) == Some(&instruction); - if let Some(store) = store_value { - self.array_set(instruction, array, index, store, dfg, map_array)?; - } else { - self.array_get(instruction, array, index, dfg)?; - } - - Ok(()) - } - - /// Generates a read opcode for the array - fn array_get( - &mut self, - instruction: InstructionId, - array: ValueId, - index: ValueId, - dfg: &DataFlowGraph, - ) -> Result<(), RuntimeError> { - let array = dfg.resolve(array); - let block_id = self.block_id(&array); - if !self.initialized_arrays.contains(&block_id) { - match &dfg[array] { - Value::Array { array, .. } => { - let values: Vec = - array.iter().map(|i| self.convert_value(*i, dfg)).collect(); - self.initialize_array(block_id, array.len(), Some(&values))?; - } - _ => { - return Err(RuntimeError::UnInitialized { - name: "array".to_string(), - call_stack: self.acir_context.get_call_stack(), - }) - } - } - } - - let index_var = self.convert_value(index, dfg).into_var()?; - let read = self.acir_context.read_from_memory(block_id, &index_var)?; - let typ = match dfg.type_of_value(array) { - Type::Array(typ, _) => { - if typ.len() != 1 { - unimplemented!( - "Non-const array indices is not implemented for non-homogenous array" - ); - } - typ[0].clone() - } - _ => unreachable!("ICE - expected an array"), - }; - let typ = AcirType::from(typ); - self.define_result(dfg, instruction, AcirValue::Var(read, typ)); - Ok(()) - } - - /// Copy the array and generates a write opcode on the new array - /// - /// Note: Copying the array is inefficient and is not the way we want to do it in the end. - fn array_set( - &mut self, - instruction: InstructionId, - array: ValueId, - index: ValueId, - store_value: ValueId, - dfg: &DataFlowGraph, - map_array: bool, - ) -> Result<(), InternalError> { - // Fetch the internal SSA ID for the array - let array = dfg.resolve(array); - - // Use the SSA ID to get or create its block ID - let block_id = self.block_id(&array); - - // Every array has a length in its type, so we fetch that from - // the SSA IR. - let len = match dfg.type_of_value(array) { - Type::Array(_, len) => len, - _ => unreachable!("ICE - expected an array"), - }; - - // Check if the array has already been initialized in ACIR gen - // if not, we initialize it using the values from SSA - let already_initialized = self.initialized_arrays.contains(&block_id); - if !already_initialized { - match &dfg[array] { - Value::Array { array, .. } => { - let values: Vec = - array.iter().map(|i| self.convert_value(*i, dfg)).collect(); - self.initialize_array(block_id, array.len(), Some(&values))?; - } - _ => { - return Err(InternalError::General { - message: format!("Array {array} should be initialized"), - call_stack: self.acir_context.get_call_stack(), - }) - } - } - } - - // Since array_set creates a new array, we create a new block ID for this - // array, unless map_array is true. In that case, we operate directly on block_id - // and we do not create a new block ID. - let result_id = dfg - .instruction_results(instruction) - .first() - .expect("Array set does not have one result"); - let result_block_id; - if map_array { - self.memory_blocks.insert(*result_id, block_id); - result_block_id = block_id; - } else { - // Initialize the new array with the values from the old array - result_block_id = self.block_id(result_id); - let init_values = try_vecmap(0..len, |i| { - let index = AcirValue::Var( - self.acir_context.add_constant(FieldElement::from(i as u128)), - AcirType::NumericType(NumericType::NativeField), - ); - let var = index.into_var()?; - let read = self.acir_context.read_from_memory(block_id, &var)?; - Ok(AcirValue::Var(read, AcirType::NumericType(NumericType::NativeField))) - })?; - self.initialize_array(result_block_id, len, Some(&init_values))?; - } - - // Write the new value into the new array at the specified index - let index_var = self.convert_value(index, dfg).into_var()?; - let value_var = self.convert_value(store_value, dfg).into_var()?; - self.acir_context.write_to_memory(result_block_id, &index_var, &value_var)?; - - let result_value = - AcirValue::DynamicArray(AcirDynamicArray { block_id: result_block_id, len }); - self.define_result(dfg, instruction, result_value); - Ok(()) - } - - /// Initializes an array with the given values and caches the fact that we - /// have initialized this array. - fn initialize_array( - &mut self, - array: BlockId, - len: usize, - values: Option<&[AcirValue]>, - ) -> Result<(), InternalError> { - self.acir_context.initialize_array(array, len, values)?; - self.initialized_arrays.insert(array); - Ok(()) - } - - /// Remember the result of an instruction returning a single value - fn define_result( - &mut self, - dfg: &DataFlowGraph, - instruction: InstructionId, - result: AcirValue, - ) { - let result_ids = dfg.instruction_results(instruction); - self.ssa_values.insert(result_ids[0], result); - } - - /// Remember the result of instruction returning a single numeric value - fn define_result_var( - &mut self, - dfg: &DataFlowGraph, - instruction: InstructionId, - result: AcirVar, - ) { - let result_ids = dfg.instruction_results(instruction); - let typ = dfg.type_of_value(result_ids[0]).into(); - self.define_result(dfg, instruction, AcirValue::Var(result, typ)); - } - - /// Converts an SSA terminator's return values into their ACIR representations - fn convert_ssa_return( - &mut self, - terminator: &TerminatorInstruction, - dfg: &DataFlowGraph, - ) -> Result<(), InternalError> { - let return_values = match terminator { - TerminatorInstruction::Return { return_values } => return_values, - _ => unreachable!("ICE: Program must have a singular return"), - }; - - // The return value may or may not be an array reference. Calling `flatten_value_list` - // will expand the array if there is one. - let return_acir_vars = self.flatten_value_list(return_values, dfg); - for acir_var in return_acir_vars { - self.acir_context.return_var(acir_var)?; - } - Ok(()) - } - - /// Gets the cached `AcirVar` that was converted from the corresponding `ValueId`. If it does - /// not already exist in the cache, a conversion is attempted and cached for simple values - /// that require no further context such as numeric types - values requiring more context - /// should have already been cached elsewhere. - /// - /// Conversion is assumed to have already been performed for instruction results and block - /// parameters. This is because block parameters are converted before anything else, and - /// because instructions results are converted when the corresponding instruction is - /// encountered. (An instruction result cannot be referenced before the instruction occurs.) - /// - /// It is not safe to call this function on value ids that represent addresses. Instructions - /// involving such values are evaluated via a separate path and stored in - /// `ssa_value_to_array_address` instead. - fn convert_value(&mut self, value_id: ValueId, dfg: &DataFlowGraph) -> AcirValue { - let value_id = dfg.resolve(value_id); - let value = &dfg[value_id]; - if let Some(acir_value) = self.ssa_values.get(&value_id) { - return acir_value.clone(); - } - - let acir_value = match value { - Value::NumericConstant { constant, typ } => { - AcirValue::Var(self.acir_context.add_constant(*constant), typ.into()) - } - Value::Array { array, .. } => { - let elements = array.iter().map(|element| self.convert_value(*element, dfg)); - AcirValue::Array(elements.collect()) - } - Value::Intrinsic(..) => todo!(), - Value::Function(..) => unreachable!("ICE: All functions should have been inlined"), - Value::ForeignFunction(_) => unimplemented!( - "Oracle calls directly in constrained functions are not yet available." - ), - Value::Instruction { .. } | Value::Param { .. } => { - unreachable!("ICE: Should have been in cache {value_id} {value:?}") - } - }; - self.ssa_values.insert(value_id, acir_value.clone()); - acir_value - } - - fn convert_numeric_value( - &mut self, - value_id: ValueId, - dfg: &DataFlowGraph, - ) -> Result { - match self.convert_value(value_id, dfg) { - AcirValue::Var(acir_var, _) => Ok(acir_var), - AcirValue::Array(array) => Err(InternalError::UnExpected { - expected: "a numeric value".to_string(), - found: format!("{array:?}"), - call_stack: self.acir_context.get_call_stack(), - }), - AcirValue::DynamicArray(_) => Err(InternalError::UnExpected { - expected: "a numeric value".to_string(), - found: "an array".to_string(), - call_stack: self.acir_context.get_call_stack(), - }), - } - } - - /// Processes a binary operation and converts the result into an `AcirVar` - fn convert_ssa_binary( - &mut self, - binary: &Binary, - dfg: &DataFlowGraph, - ) -> Result { - let lhs = self.convert_numeric_value(binary.lhs, dfg)?; - let rhs = self.convert_numeric_value(binary.rhs, dfg)?; - - let binary_type = self.type_of_binary_operation(binary, dfg); - match &binary_type { - Type::Numeric(NumericType::Unsigned { bit_size }) - | Type::Numeric(NumericType::Signed { bit_size }) => { - // Conservative max bit size that is small enough such that two operands can be - // multiplied and still fit within the field modulus. This is necessary for the - // truncation technique: result % 2^bit_size to be valid. - let max_integer_bit_size = FieldElement::max_num_bits() / 2; - if *bit_size > max_integer_bit_size { - return Err(RuntimeError::UnsupportedIntegerSize { - num_bits: *bit_size, - max_num_bits: max_integer_bit_size, - call_stack: self.acir_context.get_call_stack(), - }); - } - } - _ => {} - } - - let binary_type = AcirType::from(binary_type); - let bit_count = binary_type.bit_size(); - - match binary.operator { - BinaryOp::Add => self.acir_context.add_var(lhs, rhs), - BinaryOp::Sub => self.acir_context.sub_var(lhs, rhs), - BinaryOp::Mul => self.acir_context.mul_var(lhs, rhs), - BinaryOp::Div => self.acir_context.div_var( - lhs, - rhs, - binary_type, - self.current_side_effects_enabled_var, - ), - // Note: that this produces unnecessary constraints when - // this Eq instruction is being used for a constrain statement - BinaryOp::Eq => self.acir_context.eq_var(lhs, rhs), - BinaryOp::Lt => self.acir_context.less_than_var( - lhs, - rhs, - bit_count, - self.current_side_effects_enabled_var, - ), - BinaryOp::Xor => self.acir_context.xor_var(lhs, rhs, binary_type), - BinaryOp::And => self.acir_context.and_var(lhs, rhs, binary_type), - BinaryOp::Or => self.acir_context.or_var(lhs, rhs, binary_type), - BinaryOp::Mod => self.acir_context.modulo_var( - lhs, - rhs, - bit_count, - self.current_side_effects_enabled_var, - ), - } - } - - /// Operands in a binary operation are checked to have the same type. - /// - /// In Noir, binary operands should have the same type due to the language - /// semantics. - /// - /// There are some edge cases to consider: - /// - Constants are not explicitly type casted, so we need to check for this and - /// return the type of the other operand, if we have a constant. - /// - 0 is not seen as `Field 0` but instead as `Unit 0` - /// TODO: The latter seems like a bug, if we cannot differentiate between a function returning - /// TODO nothing and a 0. - /// - /// TODO: This constant coercion should ideally be done in the type checker. - fn type_of_binary_operation(&self, binary: &Binary, dfg: &DataFlowGraph) -> Type { - let lhs_type = dfg.type_of_value(binary.lhs); - let rhs_type = dfg.type_of_value(binary.rhs); - - match (lhs_type, rhs_type) { - // Function type should not be possible, since all functions - // have been inlined. - (_, Type::Function) | (Type::Function, _) => { - unreachable!("all functions should be inlined") - } - (_, Type::Reference) | (Type::Reference, _) => { - unreachable!("References are invalid in binary operations") - } - (_, Type::Array(..)) | (Type::Array(..), _) => { - unreachable!("Arrays are invalid in binary operations") - } - (_, Type::Slice(..)) | (Type::Slice(..), _) => { - unreachable!("Arrays are invalid in binary operations") - } - // If either side is a Field constant then, we coerce into the type - // of the other operand - (Type::Numeric(NumericType::NativeField), typ) - | (typ, Type::Numeric(NumericType::NativeField)) => typ, - // If either side is a numeric type, then we expect their types to be - // the same. - (Type::Numeric(lhs_type), Type::Numeric(rhs_type)) => { - assert_eq!( - lhs_type, rhs_type, - "lhs and rhs types in {:?} are not the same", - binary - ); - Type::Numeric(lhs_type) - } - } - } - - /// Returns an `AcirVar` that is constrained to fit in the target type by truncating the input. - /// If the target cast is to a `NativeField`, no truncation is required so the cast becomes a - /// no-op. - fn convert_ssa_cast( - &mut self, - value_id: &ValueId, - typ: &Type, - dfg: &DataFlowGraph, - ) -> Result { - let (variable, incoming_type) = match self.convert_value(*value_id, dfg) { - AcirValue::Var(variable, typ) => (variable, typ), - AcirValue::DynamicArray(_) | AcirValue::Array(_) => { - unreachable!("Cast is only applied to numerics") - } - }; - let target_numeric = match typ { - Type::Numeric(numeric) => numeric, - _ => unreachable!("Can only cast to a numeric"), - }; - match target_numeric { - NumericType::NativeField => { - // Casting into a Field as a no-op - Ok(variable) - } - NumericType::Unsigned { bit_size } => { - if incoming_type.is_signed() { - todo!("Cast from unsigned to signed") - } - let max_bit_size = incoming_type.bit_size(); - if max_bit_size <= *bit_size { - // Incoming variable already fits into target bit size - this is a no-op - return Ok(variable); - } - self.acir_context.truncate_var(variable, *bit_size, max_bit_size) - } - NumericType::Signed { .. } => todo!("Cast into signed"), - } - } - - /// Returns an `AcirVar`that is constrained to be result of the truncation. - fn convert_ssa_truncate( - &mut self, - value_id: ValueId, - bit_size: u32, - max_bit_size: u32, - dfg: &DataFlowGraph, - ) -> Result { - let mut var = self.convert_numeric_value(value_id, dfg)?; - match &dfg[value_id] { - Value::Instruction { instruction, .. } => { - if matches!( - &dfg[*instruction], - Instruction::Binary(Binary { operator: BinaryOp::Sub, .. }) - ) { - // Subtractions must first have the integer modulus added before truncation can be - // applied. This is done in order to prevent underflow. - let integer_modulus = - self.acir_context.add_constant(FieldElement::from(2_u128.pow(bit_size))); - var = self.acir_context.add_var(var, integer_modulus)?; - } - } - Value::Param { .. } => { - // Binary operations on params may have been entirely simplified if the operation - // results in the identity of the parameter - } - _ => unreachable!( - "ICE: Truncates are only ever applied to the result of a binary op or a param" - ), - }; - - self.acir_context.truncate_var(var, bit_size, max_bit_size) - } - - /// Returns a vector of `AcirVar`s constrained to be result of the function call. - /// - /// The function being called is required to be intrinsic. - fn convert_ssa_intrinsic_call( - &mut self, - intrinsic: Intrinsic, - arguments: &[ValueId], - dfg: &DataFlowGraph, - result_ids: &[ValueId], - ) -> Result, RuntimeError> { - match intrinsic { - Intrinsic::BlackBox(black_box) => { - let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); - - let output_count = result_ids.iter().fold(0usize, |sum, result_id| { - sum + dfg.try_get_array_length(*result_id).unwrap_or(1) - }); - - let vars = self.acir_context.black_box_function(black_box, inputs, output_count)?; - - Ok(Self::convert_vars_to_values(vars, dfg, result_ids)) - } - Intrinsic::ToRadix(endian) => { - let field = self.convert_value(arguments[0], dfg).into_var()?; - let radix = self.convert_value(arguments[1], dfg).into_var()?; - let limb_size = self.convert_value(arguments[2], dfg).into_var()?; - - let result_type = Self::array_element_type(dfg, result_ids[1]); - - self.acir_context.radix_decompose(endian, field, radix, limb_size, result_type) - } - Intrinsic::ToBits(endian) => { - let field = self.convert_value(arguments[0], dfg).into_var()?; - let bit_size = self.convert_value(arguments[1], dfg).into_var()?; - - let result_type = Self::array_element_type(dfg, result_ids[1]); - - self.acir_context.bit_decompose(endian, field, bit_size, result_type) - } - Intrinsic::Sort => { - let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); - // We flatten the inputs and retrieve the bit_size of the elements - let mut input_vars = Vec::new(); - let mut bit_size = 0; - for input in inputs { - for (var, typ) in input.flatten() { - input_vars.push(var); - if bit_size == 0 { - bit_size = typ.bit_size(); - } else { - assert_eq!( - bit_size, - typ.bit_size(), - "cannot sort element of different bit size" - ); - } - } - } - // Generate the sorted output variables - let out_vars = self - .acir_context - .sort(input_vars, bit_size, self.current_side_effects_enabled_var) - .expect("Could not sort"); - - Ok(Self::convert_vars_to_values(out_vars, dfg, result_ids)) - } - Intrinsic::ArrayLen => { - let len = match self.convert_value(arguments[0], dfg) { - AcirValue::Var(_, _) => unreachable!("Non-array passed to array.len() method"), - AcirValue::Array(values) => (values.len() as u128).into(), - AcirValue::DynamicArray(array) => (array.len as u128).into(), - }; - Ok(vec![AcirValue::Var(self.acir_context.add_constant(len), AcirType::field())]) - } - _ => todo!("expected a black box function"), - } - } - - /// Given an array value, return the numerical type of its element. - /// Panics if the given value is not an array or has a non-numeric element type. - fn array_element_type(dfg: &DataFlowGraph, value: ValueId) -> AcirType { - match dfg.type_of_value(value) { - Type::Array(elements, _) => { - assert_eq!(elements.len(), 1); - (&elements[0]).into() - } - Type::Slice(elements) => { - assert_eq!(elements.len(), 1); - (&elements[0]).into() - } - _ => unreachable!("Expected array type"), - } - } - - /// Maps an ssa value list, for which some values may be references to arrays, by inlining - /// the `AcirVar`s corresponding to the contents of each array into the list of `AcirVar`s - /// that correspond to other values. - fn flatten_value_list(&mut self, arguments: &[ValueId], dfg: &DataFlowGraph) -> Vec { - let mut acir_vars = Vec::with_capacity(arguments.len()); - for value_id in arguments { - let value = self.convert_value(*value_id, dfg); - AcirContext::flatten_value(&mut acir_vars, value); - } - acir_vars - } - - fn bit_count(&self, lhs: ValueId, dfg: &DataFlowGraph) -> u32 { - match dfg.type_of_value(lhs) { - Type::Numeric(NumericType::Signed { bit_size }) => bit_size, - Type::Numeric(NumericType::Unsigned { bit_size }) => bit_size, - Type::Numeric(NumericType::NativeField) => FieldElement::max_num_bits(), - _ => 0, - } - } - - /// Convert a Vec into a Vec using the given result ids. - /// If the type of a result id is an array, several acir vars are collected into - /// a single AcirValue::Array of the same length. - fn convert_vars_to_values( - vars: Vec, - dfg: &DataFlowGraph, - result_ids: &[ValueId], - ) -> Vec { - let mut vars = vars.into_iter(); - vecmap(result_ids, |result| { - let result_type = dfg.type_of_value(*result); - Self::convert_var_type_to_values(&result_type, &mut vars) - }) - } - - /// Recursive helper for convert_vars_to_values. - /// If the given result_type is an array of length N, this will create an AcirValue::Array with - /// the first N elements of the given iterator. Otherwise, the result is a single - /// AcirValue::Var wrapping the first element of the iterator. - fn convert_var_type_to_values( - result_type: &Type, - vars: &mut impl Iterator, - ) -> AcirValue { - match result_type { - Type::Array(elements, size) => { - let mut element_values = im::Vector::new(); - for _ in 0..*size { - for element_type in elements.iter() { - let element = Self::convert_var_type_to_values(element_type, vars); - element_values.push_back(element); - } - } - AcirValue::Array(element_values) - } - typ => { - let var = vars.next().unwrap(); - AcirValue::Var(var, typ.into()) - } - } - } - - /// Creates a default, meaningless value meant only to be a valid value of the given type. - fn create_default_value(&mut self, param_type: &Type) -> Result { - self.create_value_from_type(param_type, &mut |this, _| { - Ok(this.acir_context.add_constant(FieldElement::zero())) - }) - } -} - -#[cfg(test)] -mod tests { - use std::{collections::HashMap, rc::Rc}; - - use acvm::{ - acir::{ - circuit::Opcode, - native_types::{Expression, Witness}, - }, - FieldElement, - }; - - use crate::{ - brillig::Brillig, - ssa::{ - ir::{function::RuntimeType, map::Id, types::Type}, - ssa_builder::FunctionBuilder, - }, - }; - - use super::Context; - - #[test] - fn returns_body_scoped_arrays() { - // fn main { - // b0(): - // return [Field 1] - // } - let func_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); - - let one = builder.field_constant(FieldElement::one()); - - let element_type = Rc::new(vec![Type::field()]); - let array_type = Type::Array(element_type, 1); - let array = builder.array_constant(im::Vector::unit(one), array_type); - - builder.terminate_with_return(vec![array]); - - let ssa = builder.finish(); - - let context = Context::new(); - let mut acir = context.convert_ssa(ssa, Brillig::default(), &HashMap::new()).unwrap(); - - let expected_opcodes = - vec![Opcode::Arithmetic(&Expression::one() - &Expression::from(Witness(1)))]; - assert_eq!(acir.take_opcodes(), expected_opcodes); - assert_eq!(acir.return_witnesses, vec![Witness(1)]); - } -} diff --git a/crates/noirc_evaluator/src/ssa/opt/constant_folding.rs b/crates/noirc_evaluator/src/ssa/opt/constant_folding.rs deleted file mode 100644 index 75ff92ebbf1..00000000000 --- a/crates/noirc_evaluator/src/ssa/opt/constant_folding.rs +++ /dev/null @@ -1,206 +0,0 @@ -use std::collections::HashSet; - -use iter_extended::vecmap; - -use crate::ssa::{ - ir::{ - basic_block::BasicBlockId, dfg::InsertInstructionResult, function::Function, - instruction::InstructionId, - }, - ssa_gen::Ssa, -}; - -impl Ssa { - /// Performs constant folding on each instruction. - /// - /// This is generally done automatically but this pass can become needed - /// if `DataFlowGraph::set_value` or `DataFlowGraph::set_value_from_id` are - /// used on a value which enables instructions dependent on the value to - /// now be simplified. - pub(crate) fn fold_constants(mut self) -> Ssa { - for function in self.functions.values_mut() { - constant_fold(function); - } - self - } -} - -/// The structure of this pass is simple: -/// Go through each block and re-insert all instructions. -fn constant_fold(function: &mut Function) { - let mut context = Context::default(); - context.block_queue.push(function.entry_block()); - - while let Some(block) = context.block_queue.pop() { - if context.visited_blocks.contains(&block) { - continue; - } - - context.visited_blocks.insert(block); - context.fold_constants_in_block(function, block); - } -} - -#[derive(Default)] -struct Context { - /// Maps pre-folded ValueIds to the new ValueIds obtained by re-inserting the instruction. - visited_blocks: HashSet, - block_queue: Vec, -} - -impl Context { - fn fold_constants_in_block(&mut self, function: &mut Function, block: BasicBlockId) { - let instructions = function.dfg[block].take_instructions(); - - for instruction in instructions { - self.push_instruction(function, block, instruction); - } - self.block_queue.extend(function.dfg[block].successors()); - } - - fn push_instruction( - &mut self, - function: &mut Function, - block: BasicBlockId, - id: InstructionId, - ) { - let instruction = function.dfg[id].clone(); - let old_results = function.dfg.instruction_results(id).to_vec(); - - let ctrl_typevars = instruction - .requires_ctrl_typevars() - .then(|| vecmap(&old_results, |result| function.dfg.type_of_value(*result))); - - let call_stack = function.dfg.get_call_stack(id); - let new_results = match function.dfg.insert_instruction_and_results( - instruction, - block, - ctrl_typevars, - call_stack, - ) { - InsertInstructionResult::SimplifiedTo(new_result) => vec![new_result], - InsertInstructionResult::SimplifiedToMultiple(new_results) => new_results, - InsertInstructionResult::Results(new_results) => new_results.to_vec(), - InsertInstructionResult::InstructionRemoved => vec![], - }; - assert_eq!(old_results.len(), new_results.len()); - for (old_result, new_result) in old_results.iter().zip(new_results) { - function.dfg.set_value_from_id(*old_result, new_result); - } - } -} - -#[cfg(test)] -mod test { - use std::rc::Rc; - - use crate::ssa::{ - ir::{ - function::RuntimeType, - instruction::{BinaryOp, TerminatorInstruction}, - map::Id, - types::Type, - value::Value, - }, - ssa_builder::FunctionBuilder, - }; - - #[test] - fn simple_constant_fold() { - // fn main f0 { - // b0(v0: Field): - // v1 = add v0, Field 1 - // v2 = mul v1, Field 3 - // return v2 - // } - // - // After constructing this IR, we set the value of v0 to 2. - // The expected return afterwards should be 9. - let main_id = Id::test_new(0); - - // Compiling main - let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); - let v0 = builder.add_parameter(Type::field()); - - let one = builder.field_constant(1u128); - let two = builder.field_constant(2u128); - let three = builder.field_constant(3u128); - - let v1 = builder.insert_binary(v0, BinaryOp::Add, one); - let v2 = builder.insert_binary(v1, BinaryOp::Mul, three); - builder.terminate_with_return(vec![v2]); - - let mut ssa = builder.finish(); - let main = ssa.main_mut(); - let instructions = main.dfg[main.entry_block()].instructions(); - assert_eq!(instructions.len(), 2); // The final return is not counted - - // Expected output: - // - // fn main f0 { - // b0(Field 2: Field): - // return Field 9 - // } - main.dfg.set_value_from_id(v0, two); - - let ssa = ssa.fold_constants(); - let main = ssa.main(); - let block = &main.dfg[main.entry_block()]; - assert_eq!(block.instructions().len(), 0); - - match block.terminator() { - Some(TerminatorInstruction::Return { return_values }) => { - let value = main - .dfg - .get_numeric_constant(return_values[0]) - .expect("Expected constant 9") - .to_u128(); - assert_eq!(value, 9); - } - _ => unreachable!("b0 should have a return terminator"), - } - } - - #[test] - fn arrays_elements_are_updated() { - // fn main f0 { - // b0(v0: Field): - // v1 = add v0, Field 1 - // return [v1] - // } - // - // After constructing this IR, we run constant folding with no expected benefit, but to - // ensure that all new values ids are correctly propagated. - let main_id = Id::test_new(0); - - // Compiling main - let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); - let v0 = builder.add_parameter(Type::field()); - let one = builder.field_constant(1u128); - let v1 = builder.insert_binary(v0, BinaryOp::Add, one); - - let array_type = Type::Array(Rc::new(vec![Type::field()]), 1); - let arr = builder.current_function.dfg.make_array(vec![v1].into(), array_type); - builder.terminate_with_return(vec![arr]); - - let ssa = builder.finish().fold_constants(); - let main = ssa.main(); - let entry_block_id = main.entry_block(); - let entry_block = &main.dfg[entry_block_id]; - assert_eq!(entry_block.instructions().len(), 1); - let new_add_instr = entry_block.instructions().first().unwrap(); - let new_add_instr_result = main.dfg.instruction_results(*new_add_instr)[0]; - assert_ne!(new_add_instr_result, v1); - - let return_value_id = match entry_block.unwrap_terminator() { - TerminatorInstruction::Return { return_values } => return_values[0], - _ => unreachable!(), - }; - let return_element = match &main.dfg[return_value_id] { - Value::Array { array, .. } => array[0], - _ => unreachable!(), - }; - // The return element is expected to refer to the new add instruction result. - assert_eq!(main.dfg.resolve(new_add_instr_result), main.dfg.resolve(return_element)); - } -} diff --git a/crates/noirc_evaluator/src/ssa/opt/mem2reg.rs b/crates/noirc_evaluator/src/ssa/opt/mem2reg.rs deleted file mode 100644 index d83cda4a8b1..00000000000 --- a/crates/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ /dev/null @@ -1,687 +0,0 @@ -//! mem2reg implements a pass for promoting values stored in memory to values in registers where -//! possible. This is particularly important for converting our memory-based representation of -//! mutable variables into values that are easier to manipulate. -use std::collections::{BTreeMap, HashSet}; - -use crate::ssa::{ - ir::{ - basic_block::BasicBlockId, - cfg::ControlFlowGraph, - dfg::DataFlowGraph, - dom::DominatorTree, - function::Function, - instruction::{Instruction, InstructionId, TerminatorInstruction}, - post_order::PostOrder, - value::{Value, ValueId}, - }, - ssa_gen::Ssa, -}; - -use super::unrolling::{find_all_loops, Loops}; - -impl Ssa { - /// Attempts to remove any load instructions that recover values that are already available in - /// scope, and attempts to remove stores that are subsequently redundant. - /// As long as they are not stores on memory used inside of loops - pub(crate) fn mem2reg(mut self) -> Ssa { - for function in self.functions.values_mut() { - let mut all_protected_allocations = HashSet::new(); - - let mut context = PerFunctionContext::new(function); - - for block in function.reachable_blocks() { - // Maps Load instruction id -> value to replace the result of the load with - let mut loads_to_substitute_per_block = BTreeMap::new(); - - // Maps Load result id -> value to replace the result of the load with - let mut load_values_to_substitute = BTreeMap::new(); - - let allocations_protected_by_block = context - .analyze_allocations_and_eliminate_known_loads( - &mut function.dfg, - &mut loads_to_substitute_per_block, - &mut load_values_to_substitute, - block, - ); - all_protected_allocations.extend(allocations_protected_by_block.into_iter()); - } - - for block in function.reachable_blocks() { - context.remove_unused_stores(&mut function.dfg, &all_protected_allocations, block); - } - } - self - } -} - -struct PerFunctionContext { - last_stores_with_block: BTreeMap<(AllocId, BasicBlockId), ValueId>, - // Maps Load result id -> (value, block_id) - // Used to replace the result of a load with the appropriate block - load_values_to_substitute_per_func: BTreeMap, - store_ids: Vec, - cfg: ControlFlowGraph, - post_order: PostOrder, - dom_tree: DominatorTree, - loops: Loops, -} - -impl PerFunctionContext { - fn new(function: &Function) -> Self { - let cfg = ControlFlowGraph::with_function(function); - let post_order = PostOrder::with_function(function); - let dom_tree = DominatorTree::with_cfg_and_post_order(&cfg, &post_order); - PerFunctionContext { - last_stores_with_block: BTreeMap::new(), - load_values_to_substitute_per_func: BTreeMap::new(), - store_ids: Vec::new(), - cfg, - post_order, - dom_tree, - loops: find_all_loops(function), - } - } -} - -/// An AllocId is the ValueId returned from an allocate instruction. E.g. v0 in v0 = allocate. -/// This type alias is used to help signal where the only valid ValueIds are those that are from -/// an allocate instruction. -type AllocId = ValueId; - -impl PerFunctionContext { - // Attempts to remove load instructions for which the result is already known from previous - // store instructions to the same address in the same block. - fn analyze_allocations_and_eliminate_known_loads( - &mut self, - dfg: &mut DataFlowGraph, - loads_to_substitute: &mut BTreeMap, - load_values_to_substitute_per_block: &mut BTreeMap, - block_id: BasicBlockId, - ) -> HashSet { - let mut protected_allocations = HashSet::new(); - let block = &dfg[block_id]; - - // Check whether the block has a common successor here to avoid analyzing - // the CFG for every block instruction. - let has_common_successor = self.has_common_successor(block_id); - - for instruction_id in block.instructions() { - match &dfg[*instruction_id] { - Instruction::Store { mut address, value } => { - if has_common_successor { - protected_allocations.insert(address); - } - address = self.fetch_load_value_to_substitute(block_id, address); - - self.last_stores_with_block.insert((address, block_id), *value); - self.store_ids.push(*instruction_id); - - if has_common_successor { - protected_allocations.insert(address); - } - } - Instruction::Load { mut address } => { - address = self.fetch_load_value_to_substitute(block_id, address); - - let found_last_value = self.find_load_to_substitute( - block_id, - address, - dfg, - instruction_id, - loads_to_substitute, - load_values_to_substitute_per_block, - ); - if !found_last_value { - // We want to protect allocations that do not have a load to substitute - protected_allocations.insert(address); - // We also want to check for allocations that share a value - // with the one we are protecting. - // This check prevents the pass from removing stores to a value that - // is used by reference aliases in different blocks - protected_allocations.insert(dfg.resolve(address)); - } - } - Instruction::Call { arguments, .. } => { - for arg in arguments { - if Self::value_is_from_allocation(*arg, dfg) { - protected_allocations.insert(*arg); - } - } - } - _ => { - // Nothing to do - } - } - } - - // Identify any arrays that are returned from this function - if let TerminatorInstruction::Return { return_values } = block.unwrap_terminator() { - for value in return_values { - if Self::value_is_from_allocation(*value, dfg) { - protected_allocations.insert(*value); - } - } - } - - // Substitute load result values - for (result_value, new_value) in load_values_to_substitute_per_block { - let result_value = dfg.resolve(*result_value); - dfg.set_value_from_id(result_value, *new_value); - } - - // Delete load instructions - // Even though we could let DIE handle this, doing it here makes the debug output easier - // to read. - dfg[block_id] - .instructions_mut() - .retain(|instruction| !loads_to_substitute.contains_key(instruction)); - - protected_allocations - } - - // This method will fetch already saved load values to substitute for a given address. - // The search starts at the block supplied as a parameter. If there is not a load to substitute - // the CFG is analyzed to determine whether a predecessor block has a load value to substitute. - // If there is no load value to substitute the original address is returned. - fn fetch_load_value_to_substitute( - &mut self, - block_id: BasicBlockId, - address: ValueId, - ) -> ValueId { - let mut stack = vec![block_id]; - let mut visited = HashSet::new(); - - while let Some(block) = stack.pop() { - visited.insert(block); - - // We do not want to substitute loads that take place within loops or yet to be simplified branches - // as this pass can occur before loop unrolling and flattening. - // The mem2reg pass should be ran again following all optimization passes as new values - // may be able to be promoted - for l in self.loops.yet_to_unroll.iter() { - // We do not want to substitute loads that take place within loops as this pass - // can occur before loop unrolling - // The pass should be ran again following loop unrolling as new values - if l.blocks.contains(&block) { - return address; - } - } - - // Check whether there is a load value to substitute in the current block. - // Return the value if found. - if let Some((value, load_block_id)) = - self.load_values_to_substitute_per_func.get(&address) - { - if *load_block_id == block { - return *value; - } - } - - // If no load values to substitute have been found in the current block, check the block's predecessors. - if let Some(predecessor) = self.block_has_predecessor(block, &visited) { - stack.push(predecessor); - } - } - address - } - - // This method determines which loads should be substituted and saves them - // to be substituted further in the pass. - // Starting at the block supplied as a parameter, we check whether a store has occurred with the given address. - // If no store has occurred in the supplied block, the CFG is analyzed to determine whether - // a predecessor block has a store at the given address. - fn find_load_to_substitute( - &mut self, - block_id: BasicBlockId, - address: ValueId, - dfg: &DataFlowGraph, - instruction_id: &InstructionId, - loads_to_substitute: &mut BTreeMap, - load_values_to_substitute_per_block: &mut BTreeMap, - ) -> bool { - let mut stack = vec![block_id]; - let mut visited = HashSet::new(); - - while let Some(block) = stack.pop() { - visited.insert(block); - - // We do not want to substitute loads that take place within loops or yet to be simplified branches - // as this pass can occur before loop unrolling and flattening. - // The mem2reg pass should be ran again following all optimization passes as new values - // may be able to be promoted - for l in self.loops.yet_to_unroll.iter() { - // We do not want to substitute loads that take place within loops as this pass - // can occur before loop unrolling - // The pass should be ran again following loop unrolling as new values - if l.blocks.contains(&block) { - return false; - } - } - - // Check whether there has been a store instruction in the current block - // If there has been a store, add a load to be substituted. - if let Some(last_value) = self.last_stores_with_block.get(&(address, block)) { - let result_value = *dfg - .instruction_results(*instruction_id) - .first() - .expect("ICE: Load instructions should have single result"); - - loads_to_substitute.insert(*instruction_id, *last_value); - load_values_to_substitute_per_block.insert(result_value, *last_value); - self.load_values_to_substitute_per_func.insert(result_value, (*last_value, block)); - return true; - } - - // If no load values to substitute have been found in the current block, check the block's predecessors. - if let Some(predecessor) = self.block_has_predecessor(block, &visited) { - stack.push(predecessor); - } - } - false - } - - // If no loads or stores have been found in the current block, check the block's predecessors. - // Only check blocks with one predecessor as otherwise a constant value could be propogated - // through successor blocks with multiple branches that rely on other simplification passes - // such as loop unrolling or flattening of the CFG. - fn block_has_predecessor( - &mut self, - block_id: BasicBlockId, - visited: &HashSet, - ) -> Option { - let mut predecessors = self.cfg.predecessors(block_id); - if predecessors.len() == 1 { - let predecessor = predecessors.next().unwrap(); - if self.dom_tree.is_reachable(predecessor) - && self.dom_tree.dominates(predecessor, block_id) - && !visited.contains(&predecessor) - { - return Some(predecessor); - } - } - None - } - - fn has_common_successor(&mut self, block_id: BasicBlockId) -> bool { - let mut predecessors = self.cfg.predecessors(block_id); - if let Some(predecessor) = predecessors.next() { - let pred_successors = self.find_all_successors(predecessor); - let current_successors: HashSet<_> = self.cfg.successors(block_id).collect(); - return pred_successors.into_iter().any(|b| current_successors.contains(&b)); - } - false - } - - fn find_all_successors(&self, block_id: BasicBlockId) -> HashSet { - let mut stack = vec![]; - let mut visited = HashSet::new(); - - // Fetch initial block successors - let successors = self.cfg.successors(block_id); - for successor in successors { - if !visited.contains(&successor) { - stack.push(successor); - } - } - - // Follow the CFG to fetch the remaining successors - while let Some(block) = stack.pop() { - visited.insert(block); - let successors = self.cfg.successors(block); - for successor in successors { - if !visited.contains(&successor) { - stack.push(successor); - } - } - } - visited - } - - /// Checks whether the given value id refers to an allocation. - fn value_is_from_allocation(value: ValueId, dfg: &DataFlowGraph) -> bool { - match &dfg[value] { - Value::Instruction { instruction, .. } => { - matches!(&dfg[*instruction], Instruction::Allocate) - } - _ => false, - } - } - - /// Removes all store instructions identified during analysis that aren't present in the - /// provided `protected_allocations` `HashSet`. - fn remove_unused_stores( - &self, - dfg: &mut DataFlowGraph, - protected_allocations: &HashSet, - block_id: BasicBlockId, - ) { - // Scan for unused stores - let mut stores_to_remove = HashSet::new(); - - for instruction_id in &self.store_ids { - let address = match &dfg[*instruction_id] { - Instruction::Store { address, .. } => *address, - _ => unreachable!("store_ids should contain only store instructions"), - }; - - if !protected_allocations.contains(&address) { - stores_to_remove.insert(*instruction_id); - } - } - - // Delete unused stores - dfg[block_id] - .instructions_mut() - .retain(|instruction| !stores_to_remove.contains(instruction)); - } -} - -#[cfg(test)] -mod tests { - use std::rc::Rc; - - use acvm::FieldElement; - use im::vector; - - use crate::ssa::{ - ir::{ - basic_block::BasicBlockId, - dfg::DataFlowGraph, - function::RuntimeType, - instruction::{BinaryOp, Instruction, Intrinsic, TerminatorInstruction}, - map::Id, - types::Type, - }, - ssa_builder::FunctionBuilder, - }; - - #[test] - fn test_simple() { - // fn func() { - // b0(): - // v0 = allocate - // store [Field 1, Field 2] in v0 - // v1 = load v0 - // v2 = array_get v1, index 1 - // return v2 - // } - - let func_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); - let v0 = builder.insert_allocate(); - let one = builder.field_constant(FieldElement::one()); - let two = builder.field_constant(FieldElement::one()); - - let element_type = Rc::new(vec![Type::field()]); - let array_type = Type::Array(element_type, 2); - let array = builder.array_constant(vector![one, two], array_type.clone()); - - builder.insert_store(v0, array); - let v1 = builder.insert_load(v0, array_type); - let v2 = builder.insert_array_get(v1, one, Type::field()); - builder.terminate_with_return(vec![v2]); - - let ssa = builder.finish().mem2reg().fold_constants(); - - println!("{ssa}"); - - let func = ssa.main(); - let block_id = func.entry_block(); - - assert_eq!(count_loads(block_id, &func.dfg), 0); - assert_eq!(count_stores(block_id, &func.dfg), 0); - - let ret_val_id = match func.dfg[block_id].terminator().unwrap() { - TerminatorInstruction::Return { return_values } => return_values.first().unwrap(), - _ => unreachable!(), - }; - assert_eq!(func.dfg[*ret_val_id], func.dfg[two]); - } - - #[test] - fn test_simple_with_call() { - // fn func { - // b0(): - // v0 = allocate - // store v0, Field 1 - // v1 = load v0 - // call f0(v0) - // return v1 - // } - - let func_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); - let v0 = builder.insert_allocate(); - let one = builder.field_constant(FieldElement::one()); - builder.insert_store(v0, one); - let v1 = builder.insert_load(v0, Type::field()); - let f0 = builder.import_intrinsic_id(Intrinsic::AssertConstant); - builder.insert_call(f0, vec![v0], vec![]); - builder.terminate_with_return(vec![v1]); - - let ssa = builder.finish().mem2reg(); - - let func = ssa.main(); - let block_id = func.entry_block(); - - assert_eq!(count_loads(block_id, &func.dfg), 0); - assert_eq!(count_stores(block_id, &func.dfg), 1); - - let ret_val_id = match func.dfg[block_id].terminator().unwrap() { - TerminatorInstruction::Return { return_values } => return_values.first().unwrap(), - _ => unreachable!(), - }; - assert_eq!(func.dfg[*ret_val_id], func.dfg[one]); - } - - #[test] - fn test_simple_with_return() { - // fn func { - // b0(): - // v0 = allocate - // store v0, Field 1 - // return v0 - // } - - let func_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); - let v0 = builder.insert_allocate(); - let const_one = builder.field_constant(FieldElement::one()); - builder.insert_store(v0, const_one); - builder.terminate_with_return(vec![v0]); - - let ssa = builder.finish().mem2reg(); - - let func = ssa.main(); - let block_id = func.entry_block(); - - // Store affects outcome of returned array, and can't be removed - assert_eq!(count_stores(block_id, &func.dfg), 1); - - let ret_val_id = match func.dfg[block_id].terminator().unwrap() { - TerminatorInstruction::Return { return_values } => return_values.first().unwrap(), - _ => unreachable!(), - }; - assert_eq!(func.dfg[*ret_val_id], func.dfg[v0]); - } - - fn count_stores(block: BasicBlockId, dfg: &DataFlowGraph) -> usize { - dfg[block] - .instructions() - .iter() - .filter(|instruction_id| matches!(dfg[**instruction_id], Instruction::Store { .. })) - .count() - } - - fn count_loads(block: BasicBlockId, dfg: &DataFlowGraph) -> usize { - dfg[block] - .instructions() - .iter() - .filter(|instruction_id| matches!(dfg[**instruction_id], Instruction::Load { .. })) - .count() - } - - // Test that loads across multiple blocks are removed - #[test] - fn multiple_blocks() { - // fn main { - // b0(): - // v0 = allocate - // store Field 5 in v0 - // v1 = load v0 - // jmp b1(v1): - // b1(v2: Field): - // v3 = load v0 - // store Field 6 in v0 - // v4 = load v0 - // return v2, v3, v4 - // } - let main_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); - - let v0 = builder.insert_allocate(); - - let five = builder.field_constant(5u128); - builder.insert_store(v0, five); - - let v1 = builder.insert_load(v0, Type::field()); - let b1 = builder.insert_block(); - builder.terminate_with_jmp(b1, vec![v1]); - - builder.switch_to_block(b1); - let v2 = builder.add_block_parameter(b1, Type::field()); - let v3 = builder.insert_load(v0, Type::field()); - - let six = builder.field_constant(6u128); - builder.insert_store(v0, six); - let v4 = builder.insert_load(v0, Type::field()); - - builder.terminate_with_return(vec![v2, v3, v4]); - - let ssa = builder.finish(); - assert_eq!(ssa.main().reachable_blocks().len(), 2); - - // Expected result: - // fn main { - // b0(): - // v0 = allocate - // jmp b1(Field 5) - // b1(v3: Field): - // return v3, Field 5, Field 6 // Optimized to constants 5 and 6 - // } - let ssa = ssa.mem2reg(); - - let main = ssa.main(); - assert_eq!(main.reachable_blocks().len(), 2); - - // The loads should be removed - assert_eq!(count_loads(main.entry_block(), &main.dfg), 0); - assert_eq!(count_loads(b1, &main.dfg), 0); - - // All stores should be removed - assert_eq!(count_stores(main.entry_block(), &main.dfg), 0); - assert_eq!(count_stores(b1, &main.dfg), 0); - - // The jmp to b1 should also be a constant 5 now - match main.dfg[main.entry_block()].terminator() { - Some(TerminatorInstruction::Jmp { arguments, .. }) => { - assert_eq!(arguments.len(), 1); - let argument = - main.dfg.get_numeric_constant(arguments[0]).expect("Expected constant value"); - assert_eq!(argument.to_u128(), 5); - } - _ => unreachable!(), - }; - } - - // Test that a load in a predecessor block has been removed if the value - // is later stored in a successor block - #[test] - fn store_with_load_in_predecessor_block() { - // fn main { - // b0(): - // v0 = allocate - // store Field 0 at v0 - // v2 = allocate - // store v0 at v2 - // v3 = load v2 - // v4 = load v2 - // jmp b1() - // b1(): - // store Field 1 at v3 - // store Field 2 at v4 - // v8 = load v3 - // v9 = eq v8, Field 2 - // return - // } - let main_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); - - let v0 = builder.insert_allocate(); - - let zero = builder.field_constant(0u128); - builder.insert_store(v0, zero); - - let v2 = builder.insert_allocate(); - builder.insert_store(v2, v0); - - let v3 = builder.insert_load(v2, Type::field()); - let v4 = builder.insert_load(v2, Type::field()); - let b1 = builder.insert_block(); - builder.terminate_with_jmp(b1, vec![]); - - builder.switch_to_block(b1); - - let one = builder.field_constant(1u128); - builder.insert_store(v3, one); - - let two = builder.field_constant(2u128); - builder.insert_store(v4, two); - - let v8 = builder.insert_load(v3, Type::field()); - let _ = builder.insert_binary(v8, BinaryOp::Eq, two); - - builder.terminate_with_return(vec![]); - - let ssa = builder.finish(); - assert_eq!(ssa.main().reachable_blocks().len(), 2); - - // Expected result: - // fn main { - // b0(): - // v0 = allocate - // v2 = allocate - // jmp b1() - // b1(): - // v8 = eq Field 2, Field 2 - // return - // } - let ssa = ssa.mem2reg(); - - let main = ssa.main(); - assert_eq!(main.reachable_blocks().len(), 2); - - // All loads should be removed - assert_eq!(count_loads(main.entry_block(), &main.dfg), 0); - assert_eq!(count_loads(b1, &main.dfg), 0); - - // All stores should be removed - assert_eq!(count_stores(main.entry_block(), &main.dfg), 0); - assert_eq!(count_stores(b1, &main.dfg), 0); - - let b1_instructions = main.dfg[b1].instructions(); - // The first instruction should be a binary operation - match &main.dfg[b1_instructions[0]] { - Instruction::Binary(binary) => { - let lhs = - main.dfg.get_numeric_constant(binary.lhs).expect("Expected constant value"); - let rhs = - main.dfg.get_numeric_constant(binary.rhs).expect("Expected constant value"); - - assert_eq!(lhs, rhs); - assert_eq!(lhs, FieldElement::from(2u128)); - } - _ => unreachable!(), - } - } -} diff --git a/crates/noirc_evaluator/src/ssa/ssa_builder/mod.rs b/crates/noirc_evaluator/src/ssa/ssa_builder/mod.rs deleted file mode 100644 index 6a5b24e3e9f..00000000000 --- a/crates/noirc_evaluator/src/ssa/ssa_builder/mod.rs +++ /dev/null @@ -1,418 +0,0 @@ -use std::borrow::Cow; - -use acvm::FieldElement; -use noirc_errors::Location; - -use crate::ssa::ir::{ - basic_block::BasicBlockId, - function::{Function, FunctionId}, - instruction::{Binary, BinaryOp, Instruction, TerminatorInstruction}, - types::Type, - value::{Value, ValueId}, -}; - -use super::{ - ir::{ - basic_block::BasicBlock, - dfg::{CallStack, InsertInstructionResult}, - function::RuntimeType, - instruction::{InstructionId, Intrinsic}, - }, - ssa_gen::Ssa, -}; - -/// The per-function context for each ssa function being generated. -/// -/// This is split from the global SsaBuilder context to allow each function -/// to be potentially built concurrently. -/// -/// Contrary to the name, this struct has the capacity to build as many -/// functions as needed, although it is limited to one function at a time. -pub(crate) struct FunctionBuilder { - pub(super) current_function: Function, - current_block: BasicBlockId, - finished_functions: Vec, - call_stack: CallStack, -} - -impl FunctionBuilder { - /// Creates a new FunctionBuilder to build the function with the given FunctionId. - /// - /// This creates the new function internally so there is no need to call .new_function() - /// right after constructing a new FunctionBuilder. - pub(crate) fn new( - function_name: String, - function_id: FunctionId, - runtime: RuntimeType, - ) -> Self { - let mut new_function = Function::new(function_name, function_id); - new_function.set_runtime(runtime); - let current_block = new_function.entry_block(); - - Self { - current_function: new_function, - current_block, - finished_functions: Vec::new(), - call_stack: CallStack::new(), - } - } - - /// Finish the current function and create a new function. - /// - /// A FunctionBuilder can always only work on one function at a time, so care - /// should be taken not to finish a function that is still in progress by calling - /// new_function before the current function is finished. - fn new_function_with_type( - &mut self, - name: String, - function_id: FunctionId, - runtime_type: RuntimeType, - ) { - let mut new_function = Function::new(name, function_id); - new_function.set_runtime(runtime_type); - self.current_block = new_function.entry_block(); - - let old_function = std::mem::replace(&mut self.current_function, new_function); - self.finished_functions.push(old_function); - } - - /// Finish the current function and create a new ACIR function. - pub(crate) fn new_function(&mut self, name: String, function_id: FunctionId) { - self.new_function_with_type(name, function_id, RuntimeType::Acir); - } - - /// Finish the current function and create a new unconstrained function. - pub(crate) fn new_brillig_function(&mut self, name: String, function_id: FunctionId) { - self.new_function_with_type(name, function_id, RuntimeType::Brillig); - } - - /// Consume the FunctionBuilder returning all the functions it has generated. - pub(crate) fn finish(mut self) -> Ssa { - self.finished_functions.push(self.current_function); - Ssa::new(self.finished_functions) - } - - /// Add a parameter to the current function with the given parameter type. - /// Returns the newly-added parameter. - pub(crate) fn add_parameter(&mut self, typ: Type) -> ValueId { - let entry = self.current_function.entry_block(); - self.current_function.dfg.add_block_parameter(entry, typ) - } - - /// Insert a numeric constant into the current function - pub(crate) fn numeric_constant( - &mut self, - value: impl Into, - typ: Type, - ) -> ValueId { - self.current_function.dfg.make_constant(value.into(), typ) - } - - /// Insert a numeric constant into the current function of type Field - pub(crate) fn field_constant(&mut self, value: impl Into) -> ValueId { - self.numeric_constant(value.into(), Type::field()) - } - - /// Insert an array constant into the current function with the given element values. - pub(crate) fn array_constant(&mut self, elements: im::Vector, typ: Type) -> ValueId { - self.current_function.dfg.make_array(elements, typ) - } - - /// Returns the type of the given value. - pub(crate) fn type_of_value(&self, value: ValueId) -> Type { - self.current_function.dfg.type_of_value(value) - } - - /// Insert a new block into the current function and return it. - /// Note that this block is unreachable until another block is set to jump to it. - pub(crate) fn insert_block(&mut self) -> BasicBlockId { - self.current_function.dfg.make_block() - } - - /// Adds a parameter with the given type to the given block. - /// Returns the newly-added parameter. - pub(crate) fn add_block_parameter(&mut self, block: BasicBlockId, typ: Type) -> ValueId { - self.current_function.dfg.add_block_parameter(block, typ) - } - - /// Returns the parameters of the given block in the current function. - pub(crate) fn block_parameters(&self, block: BasicBlockId) -> &[ValueId] { - self.current_function.dfg.block_parameters(block) - } - - /// Inserts a new instruction at the end of the current block and returns its results - pub(crate) fn insert_instruction( - &mut self, - instruction: Instruction, - ctrl_typevars: Option>, - ) -> InsertInstructionResult { - self.current_function.dfg.insert_instruction_and_results( - instruction, - self.current_block, - ctrl_typevars, - self.call_stack.clone(), - ) - } - - /// Switch to inserting instructions in the given block. - /// Expects the given block to be within the same function. If you want to insert - /// instructions into a new function, call new_function instead. - pub(crate) fn switch_to_block(&mut self, block: BasicBlockId) { - self.current_block = block; - } - - /// Returns the block currently being inserted into - pub(crate) fn current_block(&mut self) -> BasicBlockId { - self.current_block - } - - /// Insert an allocate instruction at the end of the current block, allocating the - /// given amount of field elements. Returns the result of the allocate instruction, - /// which is always a Reference to the allocated data. - pub(crate) fn insert_allocate(&mut self) -> ValueId { - self.insert_instruction(Instruction::Allocate, None).first() - } - - pub(crate) fn set_location(&mut self, location: Location) -> &mut FunctionBuilder { - self.call_stack = im::Vector::unit(location); - self - } - - pub(crate) fn set_call_stack(&mut self, call_stack: CallStack) -> &mut FunctionBuilder { - self.call_stack = call_stack; - self - } - - /// Insert a Load instruction at the end of the current block, loading from the given offset - /// of the given address which should point to a previous Allocate instruction. Note that - /// this is limited to loading a single value. Loading multiple values (such as a tuple) - /// will require multiple loads. - /// 'offset' is in units of FieldElements here. So loading the fourth FieldElement stored in - /// an array will have an offset of 3. - /// Returns the element that was loaded. - pub(crate) fn insert_load(&mut self, address: ValueId, type_to_load: Type) -> ValueId { - self.insert_instruction(Instruction::Load { address }, Some(vec![type_to_load])).first() - } - - /// Insert a Store instruction at the end of the current block, storing the given element - /// at the given address. Expects that the address points somewhere - /// within a previous Allocate instruction. - pub(crate) fn insert_store(&mut self, address: ValueId, value: ValueId) { - self.insert_instruction(Instruction::Store { address, value }, None); - } - - /// Insert a binary instruction at the end of the current block. - /// Returns the result of the binary instruction. - pub(crate) fn insert_binary( - &mut self, - lhs: ValueId, - operator: BinaryOp, - rhs: ValueId, - ) -> ValueId { - let instruction = Instruction::Binary(Binary { lhs, rhs, operator }); - self.insert_instruction(instruction, None).first() - } - - /// Insert a not instruction at the end of the current block. - /// Returns the result of the instruction. - pub(crate) fn insert_not(&mut self, rhs: ValueId) -> ValueId { - self.insert_instruction(Instruction::Not(rhs), None).first() - } - - /// Insert a cast instruction at the end of the current block. - /// Returns the result of the cast instruction. - pub(crate) fn insert_cast(&mut self, value: ValueId, typ: Type) -> ValueId { - self.insert_instruction(Instruction::Cast(value, typ), None).first() - } - - /// Insert a truncate instruction at the end of the current block. - /// Returns the result of the truncate instruction. - pub(crate) fn insert_truncate( - &mut self, - value: ValueId, - bit_size: u32, - max_bit_size: u32, - ) -> ValueId { - self.insert_instruction(Instruction::Truncate { value, bit_size, max_bit_size }, None) - .first() - } - - /// Insert a constrain instruction at the end of the current block. - pub(crate) fn insert_constrain(&mut self, boolean: ValueId) { - self.insert_instruction(Instruction::Constrain(boolean), None); - } - - /// Insert a call instruction at the end of the current block and return - /// the results of the call. - pub(crate) fn insert_call( - &mut self, - func: ValueId, - arguments: Vec, - result_types: Vec, - ) -> Cow<[ValueId]> { - self.insert_instruction(Instruction::Call { func, arguments }, Some(result_types)).results() - } - - /// Insert an instruction to extract an element from an array - pub(crate) fn insert_array_get( - &mut self, - array: ValueId, - index: ValueId, - element_type: Type, - ) -> ValueId { - let element_type = Some(vec![element_type]); - self.insert_instruction(Instruction::ArrayGet { array, index }, element_type).first() - } - - /// Insert an instruction to create a new array with the given index replaced with a new value - pub(crate) fn insert_array_set( - &mut self, - array: ValueId, - index: ValueId, - value: ValueId, - ) -> ValueId { - self.insert_instruction(Instruction::ArraySet { array, index, value }, None).first() - } - - /// Terminates the current block with the given terminator instruction - fn terminate_block_with(&mut self, terminator: TerminatorInstruction) { - self.current_function.dfg.set_block_terminator(self.current_block, terminator); - } - - /// Terminate the current block with a jmp instruction to jmp to the given - /// block with the given arguments. - pub(crate) fn terminate_with_jmp( - &mut self, - destination: BasicBlockId, - arguments: Vec, - ) { - let call_stack = self.call_stack.clone(); - self.terminate_block_with(TerminatorInstruction::Jmp { - destination, - arguments, - call_stack, - }); - } - - /// Terminate the current block with a jmpif instruction to jmp with the given arguments - /// block with the given arguments. - pub(crate) fn terminate_with_jmpif( - &mut self, - condition: ValueId, - then_destination: BasicBlockId, - else_destination: BasicBlockId, - ) { - self.terminate_block_with(TerminatorInstruction::JmpIf { - condition, - then_destination, - else_destination, - }); - } - - /// Terminate the current block with a return instruction - pub(crate) fn terminate_with_return(&mut self, return_values: Vec) { - self.terminate_block_with(TerminatorInstruction::Return { return_values }); - } - - /// Returns a ValueId pointing to the given function or imports the function - /// into the current function if it was not already, and returns that ID. - pub(crate) fn import_function(&mut self, function: FunctionId) -> ValueId { - self.current_function.dfg.import_function(function) - } - - /// Returns a ValueId pointing to the given oracle/foreign function or imports the oracle - /// into the current function if it was not already, and returns that ID. - pub(crate) fn import_foreign_function(&mut self, function: &str) -> ValueId { - self.current_function.dfg.import_foreign_function(function) - } - - /// Retrieve a value reference to the given intrinsic operation. - /// Returns None if there is no intrinsic matching the given name. - pub(crate) fn import_intrinsic(&mut self, name: &str) -> Option { - Intrinsic::lookup(name).map(|intrinsic| self.import_intrinsic_id(intrinsic)) - } - - /// Retrieve a value reference to the given intrinsic operation. - pub(crate) fn import_intrinsic_id(&mut self, intrinsic: Intrinsic) -> ValueId { - self.current_function.dfg.import_intrinsic(intrinsic) - } - - /// Removes the given instruction from the current block or panics otherwise. - pub(crate) fn remove_instruction_from_current_block(&mut self, instruction: InstructionId) { - self.current_function.dfg[self.current_block].remove_instruction(instruction); - } -} - -impl std::ops::Index for FunctionBuilder { - type Output = Value; - - fn index(&self, id: ValueId) -> &Self::Output { - &self.current_function.dfg[id] - } -} - -impl std::ops::Index for FunctionBuilder { - type Output = Instruction; - - fn index(&self, id: InstructionId) -> &Self::Output { - &self.current_function.dfg[id] - } -} - -impl std::ops::Index for FunctionBuilder { - type Output = BasicBlock; - - fn index(&self, id: BasicBlockId) -> &Self::Output { - &self.current_function.dfg[id] - } -} - -#[cfg(test)] -mod tests { - use std::rc::Rc; - - use acvm::FieldElement; - - use crate::ssa::ir::{ - function::RuntimeType, - instruction::{Endian, Intrinsic}, - map::Id, - types::Type, - value::Value, - }; - - use super::FunctionBuilder; - - #[test] - fn insert_constant_call() { - // `bits` should be an array of constants [1, 1, 1, 0...]: - // let x = 7; - // let bits = x.to_le_bits(8); - let func_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); - let one = builder.numeric_constant(FieldElement::one(), Type::bool()); - let zero = builder.numeric_constant(FieldElement::zero(), Type::bool()); - - let to_bits_id = builder.import_intrinsic_id(Intrinsic::ToBits(Endian::Little)); - let input = builder.numeric_constant(FieldElement::from(7_u128), Type::field()); - let length = builder.numeric_constant(FieldElement::from(8_u128), Type::field()); - let result_types = vec![Type::Array(Rc::new(vec![Type::bool()]), 8)]; - let call_results = - builder.insert_call(to_bits_id, vec![input, length], result_types).into_owned(); - - let slice_len = match &builder.current_function.dfg[call_results[0]] { - Value::NumericConstant { constant, .. } => *constant, - _ => panic!(), - }; - assert_eq!(slice_len, FieldElement::from(256u128)); - - let slice = match &builder.current_function.dfg[call_results[1]] { - Value::Array { array, .. } => array, - _ => panic!(), - }; - assert_eq!(slice[0], one); - assert_eq!(slice[1], one); - assert_eq!(slice[2], one); - assert_eq!(slice[3], zero); - } -} diff --git a/crates/noirc_evaluator/src/ssa/ssa_gen/mod.rs b/crates/noirc_evaluator/src/ssa/ssa_gen/mod.rs deleted file mode 100644 index 1367b1753af..00000000000 --- a/crates/noirc_evaluator/src/ssa/ssa_gen/mod.rs +++ /dev/null @@ -1,531 +0,0 @@ -mod context; -mod program; -mod value; - -pub(crate) use program::Ssa; - -use context::SharedContext; -use iter_extended::vecmap; -use noirc_errors::Location; -use noirc_frontend::monomorphization::ast::{self, Expression, Program}; - -use crate::ssa::ir::types::NumericType; - -use self::{ - context::FunctionContext, - value::{Tree, Values}, -}; - -use super::ir::{function::RuntimeType, instruction::BinaryOp, types::Type, value::ValueId}; - -/// Generates SSA for the given monomorphized program. -/// -/// This function will generate the SSA but does not perform any optimizations on it. -pub(crate) fn generate_ssa(program: Program) -> Ssa { - let context = SharedContext::new(program); - - let main_id = Program::main_id(); - let main = context.program.main(); - - // Queue the main function for compilation - context.get_or_queue_function(main_id); - - let mut function_context = FunctionContext::new( - main.name.clone(), - &main.parameters, - if main.unconstrained { RuntimeType::Brillig } else { RuntimeType::Acir }, - &context, - ); - function_context.codegen_function_body(&main.body); - - // Main has now been compiled and any other functions referenced within have been added to the - // function queue as they were found in codegen_ident. This queueing will happen each time a - // previously-unseen function is found so we need now only continue popping from this queue - // to generate SSA for each function used within the program. - while let Some((src_function_id, dest_id)) = context.pop_next_function_in_queue() { - let function = &context.program[src_function_id]; - function_context.new_function(dest_id, function); - function_context.codegen_function_body(&function.body); - } - - function_context.builder.finish() -} - -impl<'a> FunctionContext<'a> { - /// Codegen a function's body and set its return value to that of its last parameter. - /// For functions returning nothing, this will be an empty list. - fn codegen_function_body(&mut self, body: &Expression) { - let return_value = self.codegen_expression(body); - let results = return_value.into_value_list(self); - self.builder.terminate_with_return(results); - } - - fn codegen_expression(&mut self, expr: &Expression) -> Values { - match expr { - Expression::Ident(ident) => self.codegen_ident(ident), - Expression::Literal(literal) => self.codegen_literal(literal), - Expression::Block(block) => self.codegen_block(block), - Expression::Unary(unary) => self.codegen_unary(unary), - Expression::Binary(binary) => self.codegen_binary(binary), - Expression::Index(index) => self.codegen_index(index), - Expression::Cast(cast) => self.codegen_cast(cast), - Expression::For(for_expr) => self.codegen_for(for_expr), - Expression::If(if_expr) => self.codegen_if(if_expr), - Expression::Tuple(tuple) => self.codegen_tuple(tuple), - Expression::ExtractTupleField(tuple, index) => { - self.codegen_extract_tuple_field(tuple, *index) - } - Expression::Call(call) => self.codegen_call(call), - Expression::Let(let_expr) => self.codegen_let(let_expr), - Expression::Constrain(constrain, location) => { - self.codegen_constrain(constrain, *location) - } - Expression::Assign(assign) => self.codegen_assign(assign), - Expression::Semi(semi) => self.codegen_semi(semi), - } - } - - /// Codegen any non-tuple expression so that we can unwrap the Values - /// tree to return a single value for use with most SSA instructions. - fn codegen_non_tuple_expression(&mut self, expr: &Expression) -> ValueId { - self.codegen_expression(expr).into_leaf().eval(self) - } - - /// Codegen a reference to an ident. - /// The only difference between this and codegen_ident is that if the variable is mutable - /// as in `let mut var = ...;` the `Value::Mutable` will be returned directly instead of - /// being automatically loaded from. This is needed when taking the reference of a variable - /// to reassign to it. Note that mutable references `let x = &mut ...;` do not require this - /// since they are not automatically loaded from and must be explicitly dereferenced. - fn codegen_ident_reference(&mut self, ident: &ast::Ident) -> Values { - match &ident.definition { - ast::Definition::Local(id) => self.lookup(*id), - ast::Definition::Function(id) => self.get_or_queue_function(*id), - ast::Definition::Oracle(name) => self.builder.import_foreign_function(name).into(), - ast::Definition::Builtin(name) | ast::Definition::LowLevel(name) => { - match self.builder.import_intrinsic(name) { - Some(builtin) => builtin.into(), - None => panic!("No builtin function named '{name}' found"), - } - } - } - } - - /// Codegen an identifier, automatically loading its value if it is mutable. - fn codegen_ident(&mut self, ident: &ast::Ident) -> Values { - self.codegen_ident_reference(ident).map(|value| value.eval(self).into()) - } - - fn codegen_literal(&mut self, literal: &ast::Literal) -> Values { - match literal { - ast::Literal::Array(array) => { - let elements = vecmap(&array.contents, |element| self.codegen_expression(element)); - - let typ = Self::convert_type(&array.typ).flatten(); - match array.typ { - ast::Type::Array(_, _) => self.codegen_array(elements, typ[0].clone()), - ast::Type::Slice(_) => { - let slice_length = - self.builder.field_constant(array.contents.len() as u128); - let slice_contents = self.codegen_array(elements, typ[1].clone()); - Tree::Branch(vec![slice_length.into(), slice_contents]) - } - _ => unreachable!( - "ICE: array literal type must be an array or a slice, but got {}", - array.typ - ), - } - } - ast::Literal::Integer(value, typ) => { - let typ = Self::convert_non_tuple_type(typ); - self.builder.numeric_constant(*value, typ).into() - } - ast::Literal::Bool(value) => { - self.builder.numeric_constant(*value as u128, Type::bool()).into() - } - ast::Literal::Str(string) => { - let elements = vecmap(string.as_bytes(), |byte| { - self.builder.numeric_constant(*byte as u128, Type::field()).into() - }); - let typ = Self::convert_non_tuple_type(&ast::Type::String(elements.len() as u64)); - self.codegen_array(elements, typ) - } - ast::Literal::FmtStr(string, number_of_fields, fields) => { - // A caller needs multiple pieces of information to make use of a format string - // The message string, the number of fields to be formatted, and the fields themselves - let string = Expression::Literal(ast::Literal::Str(string.clone())); - let number_of_fields = Expression::Literal(ast::Literal::Integer( - (*number_of_fields as u128).into(), - ast::Type::Field, - )); - let fields = *fields.clone(); - let fmt_str_tuple = &[string, number_of_fields, fields]; - self.codegen_tuple(fmt_str_tuple) - } - } - } - - /// Codegen an array by allocating enough space for each element and inserting separate - /// store instructions until each element is stored. The store instructions will be separated - /// by add instructions to calculate the new offset address to store to next. - /// - /// In the case of arrays of structs, the structs are flattened such that each field will be - /// stored next to the other fields in memory. So an array such as [(1, 2), (3, 4)] is - /// stored the same as the array [1, 2, 3, 4]. - /// - /// The value returned from this function is always that of the allocate instruction. - fn codegen_array(&mut self, elements: Vec, typ: Type) -> Values { - let mut array = im::Vector::new(); - - for element in elements { - element.for_each(|element| { - let element = element.eval(self); - array.push_back(element); - }); - } - - self.builder.array_constant(array, typ).into() - } - - fn codegen_block(&mut self, block: &[Expression]) -> Values { - let mut result = Self::unit_value(); - for expr in block { - result = self.codegen_expression(expr); - } - result - } - - fn codegen_unary(&mut self, unary: &ast::Unary) -> Values { - match unary.operator { - noirc_frontend::UnaryOp::Not => { - let rhs = self.codegen_expression(&unary.rhs); - let rhs = rhs.into_leaf().eval(self); - self.builder.insert_not(rhs).into() - } - noirc_frontend::UnaryOp::Minus => { - let rhs = self.codegen_expression(&unary.rhs); - let rhs = rhs.into_leaf().eval(self); - let typ = self.builder.type_of_value(rhs); - let zero = self.builder.numeric_constant(0u128, typ); - self.builder.insert_binary(zero, BinaryOp::Sub, rhs).into() - } - noirc_frontend::UnaryOp::MutableReference => { - self.codegen_reference(&unary.rhs).map(|rhs| { - match rhs { - value::Value::Normal(value) => { - let alloc = self.builder.insert_allocate(); - self.builder.insert_store(alloc, value); - Tree::Leaf(value::Value::Normal(alloc)) - } - // NOTE: The `.into()` here converts the Value::Mutable into - // a Value::Normal so it is no longer automatically dereferenced. - value::Value::Mutable(reference, _) => reference.into(), - } - }) - } - noirc_frontend::UnaryOp::Dereference { .. } => { - let rhs = self.codegen_expression(&unary.rhs); - self.dereference(&rhs, &unary.result_type) - } - } - } - - fn dereference(&mut self, values: &Values, element_type: &ast::Type) -> Values { - let element_types = Self::convert_type(element_type); - values.map_both(element_types, |value, element_type| { - let reference = value.eval(self); - self.builder.insert_load(reference, element_type).into() - }) - } - - fn codegen_reference(&mut self, expr: &Expression) -> Values { - match expr { - Expression::Ident(ident) => self.codegen_ident_reference(ident), - Expression::ExtractTupleField(tuple, index) => { - let tuple = self.codegen_reference(tuple); - Self::get_field(tuple, *index) - } - other => self.codegen_expression(other), - } - } - - fn codegen_binary(&mut self, binary: &ast::Binary) -> Values { - let lhs = self.codegen_non_tuple_expression(&binary.lhs); - let rhs = self.codegen_non_tuple_expression(&binary.rhs); - self.insert_binary(lhs, binary.operator, rhs, binary.location) - } - - fn codegen_index(&mut self, index: &ast::Index) -> Values { - let array_or_slice = self.codegen_expression(&index.collection).into_value_list(self); - let index_value = self.codegen_non_tuple_expression(&index.index); - // Slices are represented as a tuple in the form: (length, slice contents). - // Thus, slices require two value ids for their representation. - let (array, slice_length) = if array_or_slice.len() > 1 { - (array_or_slice[1], Some(array_or_slice[0])) - } else { - (array_or_slice[0], None) - }; - self.codegen_array_index( - array, - index_value, - &index.element_type, - index.location, - slice_length, - ) - } - - /// This is broken off from codegen_index so that it can also be - /// used to codegen a LValue::Index. - /// - /// Set load_result to true to load from each relevant index of the array - /// (it may be multiple in the case of tuples). Set it to false to instead - /// return a reference to each element, for use with the store instruction. - fn codegen_array_index( - &mut self, - array: super::ir::value::ValueId, - index: super::ir::value::ValueId, - element_type: &ast::Type, - location: Location, - length: Option, - ) -> Values { - // base_index = index * type_size - let type_size = Self::convert_type(element_type).size_of_type(); - let type_size = self.builder.field_constant(type_size as u128); - let base_index = - self.builder.set_location(location).insert_binary(index, BinaryOp::Mul, type_size); - - let mut field_index = 0u128; - Self::map_type(element_type, |typ| { - let offset = self.make_offset(base_index, field_index); - field_index += 1; - - let array_type = &self.builder.type_of_value(array); - match array_type { - Type::Slice(_) => { - self.codegen_slice_access_check(index, length); - } - Type::Array(..) => { - // Nothing needs to done to prepare an array access on an array - } - _ => unreachable!("must have array or slice but got {array_type}"), - } - self.builder.insert_array_get(array, offset, typ).into() - }) - } - - /// Prepare a slice access. - /// Check that the index being used to access a slice element - /// is less than the dynamic slice length. - fn codegen_slice_access_check( - &mut self, - index: super::ir::value::ValueId, - length: Option, - ) { - let array_len = length.expect("ICE: a length must be supplied for indexing slices"); - // Check the type of the index value for valid comparisons - let array_len = match self.builder.type_of_value(index) { - Type::Numeric(numeric_type) => match numeric_type { - // If the index itself is an integer, keep the array length as a Field - NumericType::Unsigned { .. } | NumericType::Signed { .. } => array_len, - // If the index and the array length are both Fields we will not be able to perform a less than comparison on them. - // Thus, we cast the array length to a u64 before performing the less than comparison - NumericType::NativeField => self - .builder - .insert_cast(array_len, Type::Numeric(NumericType::Unsigned { bit_size: 64 })), - }, - _ => unreachable!("ICE: array index must be a numeric type"), - }; - - let is_offset_out_of_bounds = self.builder.insert_binary(index, BinaryOp::Lt, array_len); - self.builder.insert_constrain(is_offset_out_of_bounds); - } - - fn codegen_cast(&mut self, cast: &ast::Cast) -> Values { - let lhs = self.codegen_non_tuple_expression(&cast.lhs); - let typ = Self::convert_non_tuple_type(&cast.r#type); - self.builder.set_location(cast.location); - self.builder.insert_cast(lhs, typ).into() - } - - /// Codegens a for loop, creating three new blocks in the process. - /// The return value of a for loop is always a unit literal. - /// - /// For example, the loop `for i in start .. end { body }` is codegen'd as: - /// - /// v0 = ... codegen start ... - /// v1 = ... codegen end ... - /// br loop_entry(v0) - /// loop_entry(i: Field): - /// v2 = lt i v1 - /// brif v2, then: loop_body, else: loop_end - /// loop_body(): - /// v3 = ... codegen body ... - /// v4 = add 1, i - /// br loop_entry(v4) - /// loop_end(): - /// ... This is the current insert point after codegen_for finishes ... - fn codegen_for(&mut self, for_expr: &ast::For) -> Values { - let loop_entry = self.builder.insert_block(); - let loop_body = self.builder.insert_block(); - let loop_end = self.builder.insert_block(); - - // this is the 'i' in `for i in start .. end { block }` - let index_type = Self::convert_non_tuple_type(&for_expr.index_type); - let loop_index = self.builder.add_block_parameter(loop_entry, index_type); - - self.builder.set_location(for_expr.start_range_location); - let start_index = self.codegen_non_tuple_expression(&for_expr.start_range); - - self.builder.set_location(for_expr.end_range_location); - let end_index = self.codegen_non_tuple_expression(&for_expr.end_range); - - // Set the location of the initial jmp instruction to the start range. This is the location - // used to issue an error if the start range cannot be determined at compile-time. - self.builder.set_location(for_expr.start_range_location); - self.builder.terminate_with_jmp(loop_entry, vec![start_index]); - - // Compile the loop entry block - self.builder.switch_to_block(loop_entry); - - // Set the location of the ending Lt instruction and the jmpif back-edge of the loop to the - // end range. These are the instructions used to issue an error if the end of the range - // cannot be determined at compile-time. - self.builder.set_location(for_expr.end_range_location); - let jump_condition = self.builder.insert_binary(loop_index, BinaryOp::Lt, end_index); - self.builder.terminate_with_jmpif(jump_condition, loop_body, loop_end); - - // Compile the loop body - self.builder.switch_to_block(loop_body); - self.define(for_expr.index_variable, loop_index.into()); - self.codegen_expression(&for_expr.block); - let new_loop_index = self.make_offset(loop_index, 1); - self.builder.terminate_with_jmp(loop_entry, vec![new_loop_index]); - - // Finish by switching back to the end of the loop - self.builder.switch_to_block(loop_end); - Self::unit_value() - } - - /// Codegens an if expression, handling the case of what to do if there is no 'else'. - /// - /// For example, the expression `if cond { a } else { b }` is codegen'd as: - /// - /// v0 = ... codegen cond ... - /// brif v0, then: then_block, else: else_block - /// then_block(): - /// v1 = ... codegen a ... - /// br end_if(v1) - /// else_block(): - /// v2 = ... codegen b ... - /// br end_if(v2) - /// end_if(v3: ?): // Type of v3 matches the type of a and b - /// ... This is the current insert point after codegen_if finishes ... - /// - /// As another example, the expression `if cond { a }` is codegen'd as: - /// - /// v0 = ... codegen cond ... - /// brif v0, then: then_block, else: end_block - /// then_block: - /// v1 = ... codegen a ... - /// br end_if() - /// end_if: // No block parameter is needed. Without an else, the unit value is always returned. - /// ... This is the current insert point after codegen_if finishes ... - fn codegen_if(&mut self, if_expr: &ast::If) -> Values { - let condition = self.codegen_non_tuple_expression(&if_expr.condition); - - let then_block = self.builder.insert_block(); - let else_block = self.builder.insert_block(); - - self.builder.terminate_with_jmpif(condition, then_block, else_block); - - self.builder.switch_to_block(then_block); - let then_value = self.codegen_expression(&if_expr.consequence); - - let mut result = Self::unit_value(); - - if let Some(alternative) = &if_expr.alternative { - let end_block = self.builder.insert_block(); - let then_values = then_value.into_value_list(self); - self.builder.terminate_with_jmp(end_block, then_values); - - self.builder.switch_to_block(else_block); - let else_value = self.codegen_expression(alternative); - let else_values = else_value.into_value_list(self); - self.builder.terminate_with_jmp(end_block, else_values); - - // Create block arguments for the end block as needed to branch to - // with our then and else value. - result = Self::map_type(&if_expr.typ, |typ| { - self.builder.add_block_parameter(end_block, typ).into() - }); - - // Must also set the then block to jmp to the end now - self.builder.switch_to_block(end_block); - } else { - // In the case we have no 'else', the 'else' block is actually the end block. - self.builder.terminate_with_jmp(else_block, vec![]); - self.builder.switch_to_block(else_block); - } - - result - } - - fn codegen_tuple(&mut self, tuple: &[Expression]) -> Values { - Tree::Branch(vecmap(tuple, |expr| self.codegen_expression(expr))) - } - - fn codegen_extract_tuple_field(&mut self, tuple: &Expression, field_index: usize) -> Values { - let tuple = self.codegen_expression(tuple); - Self::get_field(tuple, field_index) - } - - /// Generate SSA for a function call. Note that calls to built-in functions - /// and intrinsics are also represented by the function call instruction. - fn codegen_call(&mut self, call: &ast::Call) -> Values { - let function = self.codegen_non_tuple_expression(&call.func); - let arguments = call - .arguments - .iter() - .flat_map(|argument| self.codegen_expression(argument).into_value_list(self)) - .collect(); - - self.insert_call(function, arguments, &call.return_type, call.location) - } - - /// Generate SSA for the given variable. - /// If the variable is immutable, no special handling is necessary and we can return the given - /// ValueId directly. If it is mutable, we'll need to allocate space for the value and store - /// the initial value before returning the allocate instruction. - fn codegen_let(&mut self, let_expr: &ast::Let) -> Values { - let mut values = self.codegen_expression(&let_expr.expression); - - if let_expr.mutable { - values = values.map(|value| { - let value = value.eval(self); - Tree::Leaf(self.new_mutable_variable(value)) - }); - } - - self.define(let_expr.id, values); - Self::unit_value() - } - - fn codegen_constrain(&mut self, expr: &Expression, location: Location) -> Values { - let boolean = self.codegen_non_tuple_expression(expr); - self.builder.set_location(location).insert_constrain(boolean); - Self::unit_value() - } - - fn codegen_assign(&mut self, assign: &ast::Assign) -> Values { - let lhs = self.extract_current_value(&assign.lvalue); - let rhs = self.codegen_expression(&assign.expression); - - self.assign_new_value(lhs, rhs); - Self::unit_value() - } - - fn codegen_semi(&mut self, expr: &Expression) -> Values { - self.codegen_expression(expr); - Self::unit_value() - } -} diff --git a/crates/noirc_frontend/Cargo.toml b/crates/noirc_frontend/Cargo.toml deleted file mode 100644 index 636f2e74b2a..00000000000 --- a/crates/noirc_frontend/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "noirc_frontend" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -acvm.workspace = true -noirc_errors.workspace = true -noirc_printable_type.workspace = true -fm.workspace = true -arena.workspace = true -iter-extended.workspace = true -chumsky.workspace = true -thiserror.workspace = true -smol_str.workspace = true -serde_json.workspace = true -rustc-hash = "1.1.0" -small-ord-set = "0.1.3" -regex = "1.9.1" - -[dev-dependencies] -strum = "0.24" -strum_macros = "0.24" diff --git a/crates/noirc_frontend/src/ast/function.rs b/crates/noirc_frontend/src/ast/function.rs deleted file mode 100644 index 377e6aa77ad..00000000000 --- a/crates/noirc_frontend/src/ast/function.rs +++ /dev/null @@ -1,100 +0,0 @@ -use std::fmt::Display; - -use crate::{token::Attribute, FunctionReturnType, Ident, Pattern, Visibility}; - -use super::{FunctionDefinition, UnresolvedType}; - -// A NoirFunction can be either a foreign low level function or a function definition -// A closure / function definition will be stored under a name, so we do not differentiate between their variants -// The name for function literal will be the variable it is bound to, and the name for a function definition will -// be the function name itself. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct NoirFunction { - pub kind: FunctionKind, - pub def: FunctionDefinition, -} - -/// Currently, we support three types of functions: -/// - Normal functions -/// - LowLevel/Foreign which link to an OPCODE in ACIR -/// - BuiltIn which are provided by the runtime -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum FunctionKind { - LowLevel, - Builtin, - Normal, - Oracle, -} - -impl NoirFunction { - pub fn normal(def: FunctionDefinition) -> NoirFunction { - NoirFunction { kind: FunctionKind::Normal, def } - } - pub fn builtin(def: FunctionDefinition) -> NoirFunction { - NoirFunction { kind: FunctionKind::Builtin, def } - } - pub fn low_level(def: FunctionDefinition) -> NoirFunction { - NoirFunction { kind: FunctionKind::LowLevel, def } - } - pub fn oracle(def: FunctionDefinition) -> NoirFunction { - NoirFunction { kind: FunctionKind::Oracle, def } - } - - pub fn return_type(&self) -> UnresolvedType { - match &self.def.return_type { - FunctionReturnType::Default(_) => UnresolvedType::Unit, - FunctionReturnType::Ty(ty, _) => ty.clone(), - } - } - pub fn name(&self) -> &str { - &self.name_ident().0.contents - } - pub fn name_ident(&self) -> &Ident { - &self.def.name - } - pub fn parameters(&self) -> &Vec<(Pattern, UnresolvedType, Visibility)> { - &self.def.parameters - } - pub fn attribute(&self) -> Option<&Attribute> { - self.def.attribute.as_ref() - } - pub fn def(&self) -> &FunctionDefinition { - &self.def - } - pub fn def_mut(&mut self) -> &mut FunctionDefinition { - &mut self.def - } - pub fn number_of_statements(&self) -> usize { - self.def.body.0.len() - } - - pub fn foreign(&self) -> Option<&FunctionDefinition> { - match &self.kind { - FunctionKind::LowLevel => {} - _ => return None, - } - assert!(self.attribute().unwrap().is_foreign()); - Some(&self.def) - } -} - -impl From for NoirFunction { - fn from(fd: FunctionDefinition) -> Self { - let kind = match fd.attribute { - Some(Attribute::Builtin(_)) => FunctionKind::Builtin, - Some(Attribute::Foreign(_)) => FunctionKind::LowLevel, - Some(Attribute::Test) => FunctionKind::Normal, - Some(Attribute::Oracle(_)) => FunctionKind::Oracle, - Some(Attribute::Deprecated(_)) | None => FunctionKind::Normal, - Some(Attribute::Custom(_)) => FunctionKind::Normal, - }; - - NoirFunction { def: fd, kind } - } -} - -impl Display for NoirFunction { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.def.fmt(f) - } -} diff --git a/crates/noirc_frontend/src/ast/mod.rs b/crates/noirc_frontend/src/ast/mod.rs deleted file mode 100644 index 0a4e69aa55f..00000000000 --- a/crates/noirc_frontend/src/ast/mod.rs +++ /dev/null @@ -1,271 +0,0 @@ -//! The submodules of this module define the various data types required to -//! represent Noir's Ast. Of particular importance are ExpressionKind and Statement -//! which can be found in expression.rs and statement.rs respectively. -//! -//! Noir's Ast is produced by the parser and taken as input to name resolution, -//! where it is converted into the Hir (defined in the hir_def module). -mod expression; -mod function; -mod statement; -mod structure; -mod traits; -mod type_alias; - -pub use expression::*; -pub use function::*; - -use noirc_errors::Span; -pub use statement::*; -pub use structure::*; -pub use traits::*; -pub use type_alias::*; - -use crate::{ - parser::{ParserError, ParserErrorReason}, - token::IntType, - BinaryTypeOperator, -}; -use iter_extended::vecmap; - -/// The parser parses types as 'UnresolvedType's which -/// require name resolution to resolve any type names used -/// for structs within, but are otherwise identical to Types. -#[derive(Debug, PartialEq, Eq, Clone, Hash)] -pub enum UnresolvedType { - FieldElement, - Array(Option, Box), // [4]Witness = Array(4, Witness) - Integer(Signedness, u32), // u32 = Integer(unsigned, 32) - Bool, - Expression(UnresolvedTypeExpression), - String(Option), - FormatString(UnresolvedTypeExpression, Box), - Unit, - - /// A Named UnresolvedType can be a struct type or a type variable - Named(Path, Vec), - - /// &mut T - MutableReference(Box), - - // Note: Tuples have no visibility, instead each of their elements may have one. - Tuple(Vec), - - Function( - /*args:*/ Vec, - /*ret:*/ Box, - /*env:*/ Box, - ), - - Unspecified, // This is for when the user declares a variable without specifying it's type - Error, -} - -/// The precursor to TypeExpression, this is the type that the parser allows -/// to be used in the length position of an array type. Only constants, variables, -/// and numeric binary operators are allowed here. -#[derive(Debug, PartialEq, Eq, Clone, Hash)] -pub enum UnresolvedTypeExpression { - Variable(Path), - Constant(u64, Span), - BinaryOperation( - Box, - BinaryTypeOperator, - Box, - Span, - ), -} - -impl Recoverable for UnresolvedType { - fn error(_: Span) -> Self { - UnresolvedType::Error - } -} - -impl std::fmt::Display for UnresolvedType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use UnresolvedType::*; - match self { - FieldElement => write!(f, "Field"), - Array(len, typ) => match len { - None => write!(f, "[{typ}]"), - Some(len) => write!(f, "[{typ}; {len}]"), - }, - Integer(sign, num_bits) => match sign { - Signedness::Signed => write!(f, "i{num_bits}"), - Signedness::Unsigned => write!(f, "u{num_bits}"), - }, - Named(s, args) => { - let args = vecmap(args, ToString::to_string); - if args.is_empty() { - write!(f, "{s}") - } else { - write!(f, "{}<{}>", s, args.join(", ")) - } - } - Tuple(elements) => { - let elements = vecmap(elements, ToString::to_string); - write!(f, "({})", elements.join(", ")) - } - Expression(expression) => expression.fmt(f), - Bool => write!(f, "bool"), - String(len) => match len { - None => write!(f, "str<_>"), - Some(len) => write!(f, "str<{len}>"), - }, - FormatString(len, elements) => write!(f, "fmt<{len}, {elements}"), - Function(args, ret, env) => { - let args = vecmap(args, ToString::to_string); - - match &**env { - UnresolvedType::Unit => { - write!(f, "fn({}) -> {ret}", args.join(", ")) - } - UnresolvedType::Tuple(env_types) => { - let env_types = vecmap(env_types, ToString::to_string); - write!(f, "fn[{}]({}) -> {ret}", env_types.join(", "), args.join(", ")) - } - _ => unreachable!(), - } - } - MutableReference(element) => write!(f, "&mut {element}"), - Unit => write!(f, "()"), - Error => write!(f, "error"), - Unspecified => write!(f, "unspecified"), - } - } -} - -impl std::fmt::Display for UnresolvedTypeExpression { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - UnresolvedTypeExpression::Variable(name) => name.fmt(f), - UnresolvedTypeExpression::Constant(x, _) => x.fmt(f), - UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, _) => { - write!(f, "({lhs} {op} {rhs})") - } - } - } -} - -impl UnresolvedType { - pub fn from_int_token(token: IntType) -> UnresolvedType { - use {IntType::*, UnresolvedType::Integer}; - match token { - Signed(num_bits) => Integer(Signedness::Signed, num_bits), - Unsigned(num_bits) => Integer(Signedness::Unsigned, num_bits), - } - } -} - -#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] -pub enum Signedness { - Unsigned, - Signed, -} - -impl UnresolvedTypeExpression { - // This large error size is justified because it improves parsing speeds by around 40% in - // release mode. See `ParserError` definition for further explanation. - #[allow(clippy::result_large_err)] - pub fn from_expr( - expr: Expression, - span: Span, - ) -> Result { - Self::from_expr_helper(expr).map_err(|err_expr| { - ParserError::with_reason( - ParserErrorReason::InvalidArrayLengthExpression(err_expr), - span, - ) - }) - } - - pub fn span(&self) -> Span { - match self { - UnresolvedTypeExpression::Variable(path) => path.span(), - UnresolvedTypeExpression::Constant(_, span) => *span, - UnresolvedTypeExpression::BinaryOperation(_, _, _, span) => *span, - } - } - - fn from_expr_helper(expr: Expression) -> Result { - match expr.kind { - ExpressionKind::Literal(Literal::Integer(int)) => match int.try_to_u64() { - Some(int) => Ok(UnresolvedTypeExpression::Constant(int, expr.span)), - None => Err(expr), - }, - ExpressionKind::Variable(path) => Ok(UnresolvedTypeExpression::Variable(path)), - ExpressionKind::Prefix(prefix) if prefix.operator == UnaryOp::Minus => { - let lhs = Box::new(UnresolvedTypeExpression::Constant(0, expr.span)); - let rhs = Box::new(UnresolvedTypeExpression::from_expr_helper(prefix.rhs)?); - let op = BinaryTypeOperator::Subtraction; - Ok(UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, expr.span)) - } - ExpressionKind::Infix(infix) if Self::operator_allowed(infix.operator.contents) => { - let lhs = Box::new(UnresolvedTypeExpression::from_expr_helper(infix.lhs)?); - let rhs = Box::new(UnresolvedTypeExpression::from_expr_helper(infix.rhs)?); - let op = match infix.operator.contents { - BinaryOpKind::Add => BinaryTypeOperator::Addition, - BinaryOpKind::Subtract => BinaryTypeOperator::Subtraction, - BinaryOpKind::Multiply => BinaryTypeOperator::Multiplication, - BinaryOpKind::Divide => BinaryTypeOperator::Division, - BinaryOpKind::Modulo => BinaryTypeOperator::Modulo, - _ => unreachable!(), // impossible via operator_allowed check - }; - Ok(UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, expr.span)) - } - _ => Err(expr), - } - } - - fn operator_allowed(op: BinaryOpKind) -> bool { - matches!( - op, - BinaryOpKind::Add - | BinaryOpKind::Subtract - | BinaryOpKind::Multiply - | BinaryOpKind::Divide - | BinaryOpKind::Modulo - ) - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -/// Represents whether the parameter is public or known only to the prover. -pub enum Visibility { - Public, - // Constants are not allowed in the ABI for main at the moment. - // Constant, - Private, -} - -impl std::fmt::Display for Visibility { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Public => write!(f, "pub"), - Self::Private => write!(f, "priv"), - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -/// Represents whether the return value should compromise of unique witness indices such that no -/// index occurs within the program's abi more than once. -/// -/// This is useful for application stacks that require an uniform abi across across multiple -/// circuits. When index duplication is allowed, the compiler may identify that a public input -/// reaches the output unaltered and is thus referenced directly, causing the input and output -/// witness indices to overlap. Similarly, repetitions of copied values in the output may be -/// optimized away. -pub enum Distinctness { - Distinct, - DuplicationAllowed, -} - -impl std::fmt::Display for Distinctness { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Distinct => write!(f, "distinct"), - Self::DuplicationAllowed => write!(f, "duplication-allowed"), - } - } -} diff --git a/crates/noirc_frontend/src/graph/mod.rs b/crates/noirc_frontend/src/graph/mod.rs deleted file mode 100644 index 0305854ca32..00000000000 --- a/crates/noirc_frontend/src/graph/mod.rs +++ /dev/null @@ -1,409 +0,0 @@ -// This has been taken and modified from the rust-analyzer codebase -// For the most part, everything is the same, the differences are quite subtle -// but still present. Moreover, since RA is uses incremental compilation, the usage of this component may differ. -// This version is also simpler due to not having macro_defs or proc_macros -// XXX: Edition may be reintroduced or some sort of versioning - -use std::{fmt::Display, str::FromStr}; - -use fm::FileId; -use rustc_hash::{FxHashMap, FxHashSet}; -use smol_str::SmolStr; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum CrateId { - Root(usize), - Crate(usize), - Stdlib(usize), - Dummy, -} - -impl CrateId { - pub fn dummy_id() -> CrateId { - CrateId::Dummy - } - - pub fn is_stdlib(&self) -> bool { - matches!(self, CrateId::Stdlib(_)) - } - - pub fn is_root(&self) -> bool { - matches!(self, CrateId::Root(_)) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct CrateName(SmolStr); - -impl CrateName { - fn is_valid_name(name: &str) -> bool { - !name.is_empty() && name.chars().all(|n| !CHARACTER_BLACK_LIST.contains(&n)) - } -} - -impl Display for CrateName { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} - -impl From for String { - fn from(crate_name: CrateName) -> Self { - crate_name.0.into() - } -} -impl From<&CrateName> for String { - fn from(crate_name: &CrateName) -> Self { - crate_name.0.clone().into() - } -} - -/// Creates a new CrateName rejecting any crate name that -/// has a character on the blacklist. -/// The difference between RA and this implementation is that -/// characters on the blacklist are never allowed; there is no normalization. -impl FromStr for CrateName { - type Err = String; - - fn from_str(name: &str) -> Result { - if Self::is_valid_name(name) { - Ok(Self(SmolStr::new(name))) - } else { - Err("Package names must be non-empty and cannot contain hyphens".into()) - } - } -} - -#[cfg(test)] -mod crate_name { - use super::{CrateName, CHARACTER_BLACK_LIST}; - - #[test] - fn it_rejects_empty_string() { - assert!(!CrateName::is_valid_name("")); - } - - #[test] - fn it_rejects_blacklisted_chars() { - for bad_char in CHARACTER_BLACK_LIST { - let bad_char_string = bad_char.to_string(); - assert!(!CrateName::is_valid_name(&bad_char_string)); - } - } -} - -#[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct CrateGraph { - arena: FxHashMap, -} - -/// List of characters that are not allowed in a crate name -/// For example, Hyphen(-) is disallowed as it is similar to underscore(_) -/// and we do not want names that differ by a hyphen -pub const CHARACTER_BLACK_LIST: [char; 1] = ['-']; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CrateData { - pub root_file_id: FileId, - pub dependencies: Vec, -} - -/// A dependency is a crate name and a crate_id -/// This means that the same crate can be compiled once under different names -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Dependency { - pub crate_id: CrateId, - pub name: CrateName, -} - -impl Dependency { - pub fn as_name(&self) -> String { - self.name.clone().into() - } -} - -impl CrateGraph { - pub fn root_crate_id(&self) -> &CrateId { - self.arena - .keys() - .find(|crate_id| crate_id.is_root()) - .expect("ICE: A root crate should exist in the CrateGraph") - } - - pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId { - for (crate_id, crate_data) in self.arena.iter() { - if crate_id.is_root() { - panic!("ICE: Cannot add two crate roots to a graph - use `add_crate` instead"); - } - - if crate_data.root_file_id == file_id { - panic!("ICE: This FileId was already added to the CrateGraph") - } - } - - let data = CrateData { root_file_id: file_id, dependencies: Vec::new() }; - let crate_id = CrateId::Root(self.arena.len()); - let prev = self.arena.insert(crate_id, data); - assert!(prev.is_none()); - crate_id - } - - pub fn add_crate(&mut self, file_id: FileId) -> CrateId { - let mut crates_with_file_id = self - .arena - .iter() - .filter(|(_, crate_data)| crate_data.root_file_id == file_id) - .peekable(); - - let matching_id = crates_with_file_id.next(); - if crates_with_file_id.peek().is_some() { - panic!("ICE: Found multiple crates with the same FileId"); - } - - match matching_id { - Some((crate_id @ CrateId::Crate(_), _)) => *crate_id, - Some((CrateId::Root(_), _)) => { - panic!("ICE: Tried to re-add the root crate as a regular crate") - } - Some((CrateId::Stdlib(_), _)) => { - panic!("ICE: Tried to re-add the stdlib crate as a regular crate") - } - Some((CrateId::Dummy, _)) => { - panic!("ICE: A dummy CrateId should not exist in the CrateGraph") - } - None => { - let data = CrateData { root_file_id: file_id, dependencies: Vec::new() }; - let crate_id = CrateId::Crate(self.arena.len()); - let prev = self.arena.insert(crate_id, data); - assert!(prev.is_none()); - crate_id - } - } - } - - pub fn add_stdlib(&mut self, file_id: FileId) -> CrateId { - for (crate_id, crate_data) in self.arena.iter() { - if crate_id.is_stdlib() { - panic!("ICE: Cannot add two stdlib crates to a graph - use `add_crate` instead"); - } - - if crate_data.root_file_id == file_id { - panic!("ICE: This FileId was already added to the CrateGraph") - } - } - - let data = CrateData { root_file_id: file_id, dependencies: Vec::new() }; - let crate_id = CrateId::Stdlib(self.arena.len()); - let prev = self.arena.insert(crate_id, data); - assert!(prev.is_none()); - crate_id - } - - pub fn iter_keys(&self) -> impl Iterator + '_ { - self.arena.keys().copied() - } - - pub fn crates_in_topological_order(&self) -> Vec { - let mut res = Vec::new(); - let mut visited = FxHashSet::default(); - - for krate in self.arena.keys().copied() { - go(self, &mut visited, &mut res, krate); - } - - return res; - - fn go( - graph: &CrateGraph, - visited: &mut FxHashSet, - res: &mut Vec, - source: CrateId, - ) { - if !visited.insert(source) { - return; - } - for dep in graph[source].dependencies.iter() { - go(graph, visited, res, dep.crate_id); - } - res.push(source); - } - } - - pub fn add_dep( - &mut self, - from: CrateId, - name: CrateName, - to: CrateId, - ) -> Result<(), CyclicDependenciesError> { - if self.dfs_find(from, to, &mut FxHashSet::default()) { - return Err(CyclicDependenciesError { from, to }); - } - self.arena.get_mut(&from).unwrap().add_dep(name, to); - Ok(()) - } - - fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet) -> bool { - if !visited.insert(from) { - return false; - } - - if target == from { - return true; - } - - for dep in &self[from].dependencies { - let crate_id = dep.crate_id; - if self.dfs_find(target, crate_id, visited) { - return true; - } - } - false - } - - pub fn number_of_crates(&self) -> usize { - self.arena.len() - } -} -impl CrateData { - fn add_dep(&mut self, name: CrateName, crate_id: CrateId) { - self.dependencies.push(Dependency { crate_id, name }); - } -} -impl std::ops::Index for CrateGraph { - type Output = CrateData; - fn index(&self, crate_id: CrateId) -> &CrateData { - &self.arena[&crate_id] - } -} - -/// XXX: This is bare-bone for two reasons: -// There are no display names currently -// The error would be better if it showed the full cyclic dependency, including transitives. -#[allow(dead_code)] -#[derive(Debug)] -pub struct CyclicDependenciesError { - from: CrateId, - to: CrateId, -} - -#[cfg(test)] -mod tests { - use std::path::PathBuf; - - use super::{CrateGraph, FileId}; - - fn dummy_file_ids(n: usize) -> Vec { - use fm::{FileMap, FILE_EXTENSION}; - let mut fm = FileMap::default(); - - let mut vec_ids = Vec::with_capacity(n); - for i in 0..n { - let mut pth = PathBuf::new(); - pth.push(format!("{}", i)); - pth.set_extension(FILE_EXTENSION); - vec_ids.push(fm.add_file(pth.into(), String::new())); - } - - vec_ids - } - - #[test] - fn detect_cyclic_dependency_indirect() { - let file_ids = dummy_file_ids(3); - - let mut graph = CrateGraph::default(); - let crate1 = graph.add_crate_root(file_ids[0]); - let crate2 = graph.add_crate(file_ids[1]); - let crate3 = graph.add_crate(file_ids[2]); - - assert!(graph.add_dep(crate1, "crate2".parse().unwrap(), crate2).is_ok()); - assert!(graph.add_dep(crate2, "crate3".parse().unwrap(), crate3).is_ok()); - assert!(graph.add_dep(crate3, "crate1".parse().unwrap(), crate1).is_err()); - } - - #[test] - fn it_works() { - let file_ids = dummy_file_ids(3); - let file_id_0 = file_ids[0]; - let file_id_1 = file_ids[1]; - let file_id_2 = file_ids[2]; - let mut graph = CrateGraph::default(); - let crate1 = graph.add_crate_root(file_id_0); - let crate2 = graph.add_crate(file_id_1); - let crate3 = graph.add_crate(file_id_2); - assert!(graph.add_dep(crate1, "crate2".parse().unwrap(), crate2).is_ok()); - assert!(graph.add_dep(crate2, "crate3".parse().unwrap(), crate3).is_ok()); - } - #[test] - fn it_works2() { - let file_ids = dummy_file_ids(3); - let file_id_0 = file_ids[0]; - let file_id_1 = file_ids[1]; - let file_id_2 = file_ids[2]; - let mut graph = CrateGraph::default(); - let _crate1 = graph.add_crate_root(file_id_0); - let _crate2 = graph.add_crate(file_id_1); - - // Adding the same file, so the crate should be the same. - let crate3 = graph.add_crate(file_id_2); - let crate3_2 = graph.add_crate(file_id_2); - assert_eq!(crate3, crate3_2); - } - - #[test] - #[should_panic = "ICE: Cannot add two crate roots to a graph - use `add_crate` instead"] - fn panics_if_adding_two_roots() { - let file_ids = dummy_file_ids(2); - let mut graph = CrateGraph::default(); - let _ = graph.add_crate_root(file_ids[0]); - let _ = graph.add_crate_root(file_ids[1]); - } - - #[test] - #[should_panic = "ICE: This FileId was already added to the CrateGraph"] - fn panics_if_adding_existing_file_as_root() { - let file_ids = dummy_file_ids(1); - let mut graph = CrateGraph::default(); - let file_id_0 = file_ids[0]; - let _ = graph.add_crate(file_id_0); - let _ = graph.add_crate_root(file_id_0); - } - - #[test] - #[should_panic = "ICE: Cannot add two stdlib crates to a graph - use `add_crate` instead"] - fn panics_if_adding_two_stdlib() { - let file_ids = dummy_file_ids(2); - let mut graph = CrateGraph::default(); - let _ = graph.add_stdlib(file_ids[0]); - let _ = graph.add_stdlib(file_ids[1]); - } - - #[test] - #[should_panic = "ICE: This FileId was already added to the CrateGraph"] - fn panics_if_adding_existing_file_as_stdlib() { - let file_ids = dummy_file_ids(1); - let mut graph = CrateGraph::default(); - let file_id_0 = file_ids[0]; - let _ = graph.add_crate(file_id_0); - let _ = graph.add_stdlib(file_id_0); - } - - #[test] - #[should_panic = "ICE: Tried to re-add the root crate as a regular crate"] - fn panics_if_adding_root_as_regular() { - let file_ids = dummy_file_ids(1); - let mut graph = CrateGraph::default(); - let file_id_0 = file_ids[0]; - let _ = graph.add_crate_root(file_id_0); - let _ = graph.add_crate(file_id_0); - } - #[test] - #[should_panic = "ICE: Tried to re-add the stdlib crate as a regular crate"] - fn panics_if_adding_stdlib_as_regular() { - let file_ids = dummy_file_ids(1); - let mut graph = CrateGraph::default(); - let file_id_0 = file_ids[0]; - let _ = graph.add_stdlib(file_id_0); - let _ = graph.add_crate(file_id_0); - } -} diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs deleted file mode 100644 index ac83e81ea71..00000000000 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ /dev/null @@ -1,534 +0,0 @@ -use super::dc_mod::collect_defs; -use super::errors::{DefCollectorErrorKind, DuplicateType}; -use crate::graph::CrateId; -use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleId}; -use crate::hir::resolution::errors::ResolverError; -use crate::hir::resolution::resolver::Resolver; -use crate::hir::resolution::{ - import::{resolve_imports, ImportDirective}, - path_resolver::StandardPathResolver, -}; -use crate::hir::type_check::{type_check_func, TypeChecker}; -use crate::hir::Context; -use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TypeAliasId}; -use crate::{ - ExpressionKind, Generics, Ident, LetStatement, Literal, NoirFunction, NoirStruct, - NoirTypeAlias, ParsedModule, Shared, StructType, Type, TypeBinding, UnresolvedGenerics, - UnresolvedType, -}; -use fm::FileId; -use iter_extended::vecmap; -use noirc_errors::Span; -use noirc_errors::{CustomDiagnostic, FileDiagnostic}; -use std::collections::HashMap; -use std::rc::Rc; - -/// Stores all of the unresolved functions in a particular file/mod -pub struct UnresolvedFunctions { - pub file_id: FileId, - pub functions: Vec<(LocalModuleId, FuncId, NoirFunction)>, -} - -impl UnresolvedFunctions { - pub fn push_fn(&mut self, mod_id: LocalModuleId, func_id: FuncId, func: NoirFunction) { - self.functions.push((mod_id, func_id, func)); - } -} - -pub struct UnresolvedStruct { - pub file_id: FileId, - pub module_id: LocalModuleId, - pub struct_def: NoirStruct, -} - -#[derive(Clone)] -pub struct UnresolvedTypeAlias { - pub file_id: FileId, - pub module_id: LocalModuleId, - pub type_alias_def: NoirTypeAlias, -} - -#[derive(Clone)] -pub struct UnresolvedGlobal { - pub file_id: FileId, - pub module_id: LocalModuleId, - pub stmt_id: StmtId, - pub stmt_def: LetStatement, -} - -/// Given a Crate root, collect all definitions in that crate -pub struct DefCollector { - pub(crate) def_map: CrateDefMap, - pub(crate) collected_imports: Vec, - pub(crate) collected_functions: Vec, - pub(crate) collected_types: HashMap, - pub(crate) collected_type_aliases: HashMap, - pub(crate) collected_globals: Vec, - pub(crate) collected_impls: ImplMap, -} - -/// Maps the type and the module id in which the impl is defined to the functions contained in that -/// impl along with the generics declared on the impl itself. This also contains the Span -/// of the object_type of the impl, used to issue an error if the object type fails to resolve. -type ImplMap = - HashMap<(UnresolvedType, LocalModuleId), Vec<(UnresolvedGenerics, Span, UnresolvedFunctions)>>; - -impl DefCollector { - fn new(def_map: CrateDefMap) -> DefCollector { - DefCollector { - def_map, - collected_imports: vec![], - collected_functions: vec![], - collected_types: HashMap::new(), - collected_type_aliases: HashMap::new(), - collected_impls: HashMap::new(), - collected_globals: vec![], - } - } - - /// Collect all of the definitions in a given crate into a CrateDefMap - /// Modules which are not a part of the module hierarchy starting with - /// the root module, will be ignored. - pub fn collect( - mut def_map: CrateDefMap, - context: &mut Context, - ast: ParsedModule, - root_file_id: FileId, - errors: &mut Vec, - ) { - let crate_id = def_map.krate; - - // Recursively resolve the dependencies - // - // Dependencies are fetched from the crate graph - // Then added these to the context of DefMaps once they are resolved - // - let crate_graph = &context.crate_graph[crate_id]; - - for dep in crate_graph.dependencies.clone() { - CrateDefMap::collect_defs(dep.crate_id, context, errors); - - let dep_def_root = - context.def_map(&dep.crate_id).expect("ice: def map was just created").root; - let module_id = ModuleId { krate: dep.crate_id, local_id: dep_def_root }; - // Add this crate as a dependency by linking it's root module - def_map.extern_prelude.insert(dep.as_name(), module_id); - } - - // At this point, all dependencies are resolved and type checked. - // - // It is now possible to collect all of the definitions of this crate. - let crate_root = def_map.root; - let mut def_collector = DefCollector::new(def_map); - - // Collecting module declarations with ModCollector - // and lowering the functions - // i.e. Use a mod collector to collect the nodes at the root module - // and process them - collect_defs(&mut def_collector, ast, root_file_id, crate_root, crate_id, context, errors); - - // Add the current crate to the collection of DefMaps - context.def_maps.insert(crate_id, def_collector.def_map); - - // Resolve unresolved imports collected from the crate - let (resolved, unresolved_imports) = - resolve_imports(crate_id, def_collector.collected_imports, &context.def_maps); - - let current_def_map = context.def_maps.get(&crate_id).unwrap(); - - errors.extend(vecmap(unresolved_imports, |(error, module_id)| { - let file_id = current_def_map.file_id(module_id); - let error = DefCollectorErrorKind::PathResolutionError(error); - error.into_file_diagnostic(file_id) - })); - - // Populate module namespaces according to the imports used - let current_def_map = context.def_maps.get_mut(&crate_id).unwrap(); - for resolved_import in resolved { - let name = resolved_import.name; - for ns in resolved_import.resolved_namespace.iter_defs() { - let result = current_def_map.modules[resolved_import.module_scope.0] - .import(name.clone(), ns); - - if let Err((first_def, second_def)) = result { - let err = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Import, - first_def, - second_def, - }; - errors.push(err.into_file_diagnostic(root_file_id)); - } - } - } - - // We must first resolve and intern the globals before we can resolve any stmts inside each function. - // Each function uses its own resolver with a newly created ScopeForest, and must be resolved again to be within a function's scope - // - // Additionally, we must resolve integer globals before structs since structs may refer to - // the values of integer globals as numeric generics. - let (literal_globals, other_globals) = - filter_literal_globals(def_collector.collected_globals); - - let mut file_global_ids = resolve_globals(context, literal_globals, crate_id, errors); - - resolve_type_aliases(context, def_collector.collected_type_aliases, crate_id, errors); - - // Must resolve structs before we resolve globals. - resolve_structs(context, def_collector.collected_types, crate_id, errors); - - // We must wait to resolve non-integer globals until after we resolve structs since structs - // globals will need to reference the struct type they're initialized to to ensure they are valid. - let mut more_global_ids = resolve_globals(context, other_globals, crate_id, errors); - - file_global_ids.append(&mut more_global_ids); - - // Before we resolve any function symbols we must go through our impls and - // re-collect the methods within into their proper module. This cannot be - // done before resolution since we need to be able to resolve the type of the - // impl since that determines the module we should collect into. - collect_impls(context, crate_id, &def_collector.collected_impls, errors); - - // Lower each function in the crate. This is now possible since imports have been resolved - let file_func_ids = resolve_free_functions( - &mut context.def_interner, - crate_id, - &context.def_maps, - def_collector.collected_functions, - None, - errors, - ); - - let file_method_ids = resolve_impls( - &mut context.def_interner, - crate_id, - &context.def_maps, - def_collector.collected_impls, - errors, - ); - - type_check_globals(&mut context.def_interner, file_global_ids, errors); - - // Type check all of the functions in the crate - type_check_functions(&mut context.def_interner, file_func_ids, errors); - type_check_functions(&mut context.def_interner, file_method_ids, errors); - } -} - -/// Go through the list of impls and add each function within to the scope -/// of the module defined by its type. -fn collect_impls( - context: &mut Context, - crate_id: CrateId, - collected_impls: &ImplMap, - errors: &mut Vec, -) { - let interner = &mut context.def_interner; - let def_maps = &mut context.def_maps; - - for ((unresolved_type, module_id), methods) in collected_impls { - let path_resolver = - StandardPathResolver::new(ModuleId { local_id: *module_id, krate: crate_id }); - - let file = def_maps[&crate_id].file_id(*module_id); - - for (generics, span, unresolved) in methods { - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); - resolver.add_generics(generics); - let typ = resolver.resolve_type(unresolved_type.clone()); - - extend_errors(errors, unresolved.file_id, resolver.take_errors()); - - if let Some(struct_type) = get_struct_type(&typ) { - let struct_type = struct_type.borrow(); - let type_module = struct_type.id.0.local_id; - - // `impl`s are only allowed on types defined within the current crate - if struct_type.id.0.krate != crate_id { - let span = *span; - let type_name = struct_type.name.to_string(); - let error = DefCollectorErrorKind::ForeignImpl { span, type_name }; - errors.push(error.into_file_diagnostic(unresolved.file_id)); - continue; - } - - // Grab the module defined by the struct type. Note that impls are a case - // where the module the methods are added to is not the same as the module - // they are resolved in. - let module = &mut def_maps.get_mut(&crate_id).unwrap().modules[type_module.0]; - - for (_, method_id, method) in &unresolved.functions { - let result = module.declare_function(method.name_ident().clone(), *method_id); - - if let Err((first_def, second_def)) = result { - let err = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Function, - first_def, - second_def, - }; - errors.push(err.into_file_diagnostic(unresolved.file_id)); - } - } - // Prohibit defining impls for primitive types if we're not in the stdlib - } else if typ != Type::Error && !crate_id.is_stdlib() { - let span = *span; - let error = DefCollectorErrorKind::NonStructTypeInImpl { span }; - errors.push(error.into_file_diagnostic(unresolved.file_id)); - } - } - } -} - -fn get_struct_type(typ: &Type) -> Option<&Shared> { - match typ { - Type::Struct(definition, _) => Some(definition), - _ => None, - } -} - -fn extend_errors(errors: &mut Vec, file: fm::FileId, new_errors: Errs) -where - Errs: IntoIterator, - Err: Into, -{ - errors.extend(new_errors.into_iter().map(|err| err.into().in_file(file))); -} - -/// Separate the globals Vec into two. The first element in the tuple will be the -/// literal globals, except for arrays, and the second will be all other globals. -/// We exclude array literals as they can contain complex types -fn filter_literal_globals( - globals: Vec, -) -> (Vec, Vec) { - globals.into_iter().partition(|global| match &global.stmt_def.expression.kind { - ExpressionKind::Literal(literal) => !matches!(literal, Literal::Array(_)), - _ => false, - }) -} - -fn resolve_globals( - context: &mut Context, - globals: Vec, - crate_id: CrateId, - errors: &mut Vec, -) -> Vec<(FileId, StmtId)> { - vecmap(globals, |global| { - let module_id = ModuleId { local_id: global.module_id, krate: crate_id }; - let path_resolver = StandardPathResolver::new(module_id); - let storage_slot = context.next_storage_slot(module_id); - - let mut resolver = Resolver::new( - &mut context.def_interner, - &path_resolver, - &context.def_maps, - global.file_id, - ); - - let name = global.stmt_def.pattern.name_ident().clone(); - - let hir_stmt = resolver.resolve_global_let(global.stmt_def); - extend_errors(errors, global.file_id, resolver.take_errors()); - - context.def_interner.update_global(global.stmt_id, hir_stmt); - - context.def_interner.push_global(global.stmt_id, name, global.module_id, storage_slot); - - (global.file_id, global.stmt_id) - }) -} - -fn type_check_globals( - interner: &mut NodeInterner, - global_ids: Vec<(FileId, StmtId)>, - all_errors: &mut Vec, -) { - for (file_id, stmt_id) in global_ids { - let errors = TypeChecker::check_global(&stmt_id, interner); - extend_errors(all_errors, file_id, errors); - } -} - -/// Create the mappings from TypeId -> StructType -/// so that expressions can access the fields of structs -fn resolve_structs( - context: &mut Context, - structs: HashMap, - crate_id: CrateId, - errors: &mut Vec, -) { - // We must first go through the struct list once to ensure all IDs are pushed to - // the def_interner map. This lets structs refer to each other regardless of declaration order - // without resolve_struct_fields non-deterministically unwrapping a value - // that isn't in the HashMap. - for (type_id, typ) in &structs { - context.def_interner.push_empty_struct(*type_id, typ); - } - - for (type_id, typ) in structs { - let (generics, fields) = resolve_struct_fields(context, crate_id, typ, errors); - context.def_interner.update_struct(type_id, |struct_def| { - struct_def.set_fields(fields); - struct_def.generics = generics; - }); - } -} - -fn resolve_struct_fields( - context: &mut Context, - krate: CrateId, - unresolved: UnresolvedStruct, - all_errors: &mut Vec, -) -> (Generics, Vec<(Ident, Type)>) { - let path_resolver = - StandardPathResolver::new(ModuleId { local_id: unresolved.module_id, krate }); - - let file = unresolved.file_id; - - let (generics, fields, errors) = - Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) - .resolve_struct_fields(unresolved.struct_def); - - extend_errors(all_errors, unresolved.file_id, errors); - (generics, fields) -} - -fn resolve_type_aliases( - context: &mut Context, - type_aliases: HashMap, - crate_id: CrateId, - all_errors: &mut Vec, -) { - for (type_id, unresolved_typ) in type_aliases { - let path_resolver = StandardPathResolver::new(ModuleId { - local_id: unresolved_typ.module_id, - krate: crate_id, - }); - let file = unresolved_typ.file_id; - let (typ, generics, errors) = - Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) - .resolve_type_aliases(unresolved_typ.type_alias_def); - extend_errors(all_errors, file, errors); - - context.def_interner.set_type_alias(type_id, typ, generics); - } -} - -fn resolve_impls( - interner: &mut NodeInterner, - crate_id: CrateId, - def_maps: &HashMap, - collected_impls: ImplMap, - errors: &mut Vec, -) -> Vec<(FileId, FuncId)> { - let mut file_method_ids = Vec::new(); - - for ((unresolved_type, module_id), methods) in collected_impls { - let path_resolver = - StandardPathResolver::new(ModuleId { local_id: module_id, krate: crate_id }); - - let file = def_maps[&crate_id].file_id(module_id); - - for (generics, _, functions) in methods { - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); - resolver.add_generics(&generics); - let generics = resolver.get_generics().to_vec(); - let self_type = resolver.resolve_type(unresolved_type.clone()); - - let mut file_func_ids = resolve_function_set( - interner, - crate_id, - def_maps, - functions, - Some(self_type.clone()), - generics, - errors, - ); - - if self_type != Type::Error { - for (file_id, method_id) in &file_func_ids { - let method_name = interner.function_name(method_id).to_owned(); - - if let Some(first_fn) = - interner.add_method(&self_type, method_name.clone(), *method_id) - { - let error = ResolverError::DuplicateDefinition { - name: method_name, - first_span: interner.function_ident(&first_fn).span(), - second_span: interner.function_ident(method_id).span(), - }; - - errors.push(error.into_file_diagnostic(*file_id)); - } - } - } - file_method_ids.append(&mut file_func_ids); - } - } - - file_method_ids -} - -fn resolve_free_functions( - interner: &mut NodeInterner, - crate_id: CrateId, - def_maps: &HashMap, - collected_functions: Vec, - self_type: Option, - errors: &mut Vec, -) -> Vec<(FileId, FuncId)> { - // Lower each function in the crate. This is now possible since imports have been resolved - collected_functions - .into_iter() - .flat_map(|unresolved_functions| { - resolve_function_set( - interner, - crate_id, - def_maps, - unresolved_functions, - self_type.clone(), - vec![], // no impl generics - errors, - ) - }) - .collect() -} - -fn resolve_function_set( - interner: &mut NodeInterner, - crate_id: CrateId, - def_maps: &HashMap, - unresolved_functions: UnresolvedFunctions, - self_type: Option, - impl_generics: Vec<(Rc, Shared, Span)>, - errors: &mut Vec, -) -> Vec<(FileId, FuncId)> { - let file_id = unresolved_functions.file_id; - - vecmap(unresolved_functions.functions, |(mod_id, func_id, func)| { - let module_id = ModuleId { krate: crate_id, local_id: mod_id }; - let path_resolver = - StandardPathResolver::new(ModuleId { local_id: mod_id, krate: crate_id }); - - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file_id); - // Must use set_generics here to ensure we re-use the same generics from when - // the impl was originally collected. Otherwise the function will be using different - // TypeVariables for the same generic, causing it to instantiate incorrectly. - resolver.set_generics(impl_generics.clone()); - resolver.set_self_type(self_type.clone()); - - let (hir_func, func_meta, errs) = resolver.resolve_function(func, func_id, module_id); - interner.push_fn_meta(func_meta, func_id); - interner.update_fn(func_id, hir_func); - extend_errors(errors, file_id, errs); - (file_id, func_id) - }) -} - -fn type_check_functions( - interner: &mut NodeInterner, - file_func_ids: Vec<(FileId, FuncId)>, - errors: &mut Vec, -) { - for (file, func) in file_func_ids { - extend_errors(errors, file, type_check_func(interner, func)); - } -} diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs deleted file mode 100644 index 53ed397e647..00000000000 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ /dev/null @@ -1,355 +0,0 @@ -use fm::FileId; -use noirc_errors::{FileDiagnostic, Location}; - -use crate::{ - graph::CrateId, hir::def_collector::dc_crate::UnresolvedStruct, node_interner::StructId, - parser::SubModule, Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias, ParsedModule, - TypeImpl, -}; - -use super::{ - dc_crate::{DefCollector, UnresolvedFunctions, UnresolvedGlobal, UnresolvedTypeAlias}, - errors::{DefCollectorErrorKind, DuplicateType}, -}; -use crate::hir::def_map::{parse_file, LocalModuleId, ModuleData, ModuleId}; -use crate::hir::resolution::import::ImportDirective; -use crate::hir::Context; - -/// Given a module collect all definitions into ModuleData -struct ModCollector<'a> { - pub(crate) def_collector: &'a mut DefCollector, - pub(crate) file_id: FileId, - pub(crate) module_id: LocalModuleId, -} - -/// Walk a module and collect its definitions. -/// -/// This performs the entirety of the definition collection phase of the name resolution pass. -pub fn collect_defs( - def_collector: &mut DefCollector, - ast: ParsedModule, - file_id: FileId, - module_id: LocalModuleId, - crate_id: CrateId, - context: &mut Context, - errors: &mut Vec, -) { - let mut collector = ModCollector { def_collector, file_id, module_id }; - - // First resolve the module declarations - for decl in ast.module_decls { - collector.parse_module_declaration(context, &decl, crate_id, errors); - } - - collector.collect_submodules(context, crate_id, ast.submodules, file_id, errors); - - // Then add the imports to defCollector to resolve once all modules in the hierarchy have been resolved - for import in ast.imports { - collector.def_collector.collected_imports.push(ImportDirective { - module_id: collector.module_id, - path: import.path, - alias: import.alias, - }); - } - - collector.collect_globals(context, ast.globals, errors); - - collector.collect_structs(ast.types, crate_id, errors); - - collector.collect_type_aliases(context, ast.type_aliases, errors); - - collector.collect_functions(context, ast.functions, errors); - - collector.collect_impls(context, ast.impls); -} - -impl<'a> ModCollector<'a> { - fn collect_globals( - &mut self, - context: &mut Context, - globals: Vec, - errors: &mut Vec, - ) { - for global in globals { - let name = global.pattern.name_ident().clone(); - - // First create dummy function in the DefInterner - // So that we can get a StmtId - let stmt_id = context.def_interner.push_empty_global(); - - // Add the statement to the scope so its path can be looked up later - let result = - self.def_collector.def_map.modules[self.module_id.0].declare_global(name, stmt_id); - - if let Err((first_def, second_def)) = result { - let err = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Global, - first_def, - second_def, - }; - errors.push(err.into_file_diagnostic(self.file_id)); - } - - self.def_collector.collected_globals.push(UnresolvedGlobal { - file_id: self.file_id, - module_id: self.module_id, - stmt_id, - stmt_def: global, - }); - } - } - - fn collect_impls(&mut self, context: &mut Context, impls: Vec) { - for r#impl in impls { - let mut unresolved_functions = - UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; - - for method in r#impl.methods { - let func_id = context.def_interner.push_empty_fn(); - context.def_interner.push_function_definition(method.name().to_owned(), func_id); - unresolved_functions.push_fn(self.module_id, func_id, method); - } - - let key = (r#impl.object_type, self.module_id); - let methods = self.def_collector.collected_impls.entry(key).or_default(); - methods.push((r#impl.generics, r#impl.type_span, unresolved_functions)); - } - } - - fn collect_functions( - &mut self, - context: &mut Context, - functions: Vec, - errors: &mut Vec, - ) { - let mut unresolved_functions = - UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; - - for function in functions { - let name = function.name_ident().clone(); - - // First create dummy function in the DefInterner - // So that we can get a FuncId - let func_id = context.def_interner.push_empty_fn(); - context.def_interner.push_function_definition(name.0.contents.clone(), func_id); - - // Now link this func_id to a crate level map with the noir function and the module id - // Encountering a NoirFunction, we retrieve it's module_data to get the namespace - // Once we have lowered it to a HirFunction, we retrieve it's Id from the DefInterner - // and replace it - // With this method we iterate each function in the Crate and not each module - // This may not be great because we have to pull the module_data for each function - unresolved_functions.push_fn(self.module_id, func_id, function); - - // Add function to scope/ns of the module - let result = self.def_collector.def_map.modules[self.module_id.0] - .declare_function(name, func_id); - - if let Err((first_def, second_def)) = result { - let error = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Function, - first_def, - second_def, - }; - errors.push(error.into_file_diagnostic(self.file_id)); - } - } - - self.def_collector.collected_functions.push(unresolved_functions); - } - - /// Collect any struct definitions declared within the ast. - /// Returns a vector of errors if any structs were already defined. - fn collect_structs( - &mut self, - types: Vec, - krate: CrateId, - errors: &mut Vec, - ) { - for struct_definition in types { - let name = struct_definition.name.clone(); - - // Create the corresponding module for the struct namespace - let id = match self.push_child_module(&name, self.file_id, false, false, errors) { - Some(local_id) => StructId(ModuleId { krate, local_id }), - None => continue, - }; - - // Add the struct to scope so its path can be looked up later - let result = - self.def_collector.def_map.modules[self.module_id.0].declare_struct(name, id); - - if let Err((first_def, second_def)) = result { - let err = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::TypeDefinition, - first_def, - second_def, - }; - errors.push(err.into_file_diagnostic(self.file_id)); - } - - // And store the TypeId -> StructType mapping somewhere it is reachable - let unresolved = UnresolvedStruct { - file_id: self.file_id, - module_id: self.module_id, - struct_def: struct_definition, - }; - self.def_collector.collected_types.insert(id, unresolved); - } - } - - /// Collect any type aliases definitions declared within the ast. - /// Returns a vector of errors if any type aliases were already defined. - fn collect_type_aliases( - &mut self, - context: &mut Context, - type_aliases: Vec, - errors: &mut Vec, - ) { - for type_alias in type_aliases { - let name = type_alias.name.clone(); - - // And store the TypeId -> TypeAlias mapping somewhere it is reachable - let unresolved = UnresolvedTypeAlias { - file_id: self.file_id, - module_id: self.module_id, - type_alias_def: type_alias, - }; - - let type_alias_id = context.def_interner.push_type_alias(&unresolved); - - // Add the type alias to scope so its path can be looked up later - let result = self.def_collector.def_map.modules[self.module_id.0] - .declare_type_alias(name, type_alias_id); - - if let Err((first_def, second_def)) = result { - let err = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Function, - first_def, - second_def, - }; - errors.push(err.into_file_diagnostic(self.file_id)); - } - - self.def_collector.collected_type_aliases.insert(type_alias_id, unresolved); - } - } - - fn collect_submodules( - &mut self, - context: &mut Context, - crate_id: CrateId, - submodules: Vec, - file_id: FileId, - errors: &mut Vec, - ) { - for submodule in submodules { - if let Some(child) = self.push_child_module( - &submodule.name, - file_id, - true, - submodule.is_contract, - errors, - ) { - collect_defs( - self.def_collector, - submodule.contents, - file_id, - child, - crate_id, - context, - errors, - ); - } - } - } - - /// Search for a module named `mod_name` - /// Parse it, add it as a child to the parent module in which it was declared - /// and then collect all definitions of the child module - fn parse_module_declaration( - &mut self, - context: &mut Context, - mod_name: &Ident, - crate_id: CrateId, - errors: &mut Vec, - ) { - let child_file_id = - match context.file_manager.find_module(self.file_id, &mod_name.0.contents) { - Ok(child_file_id) => child_file_id, - Err(_) => { - let err = - DefCollectorErrorKind::UnresolvedModuleDecl { mod_name: mod_name.clone() }; - errors.push(err.into_file_diagnostic(self.file_id)); - return; - } - }; - - // Parse the AST for the module we just found and then recursively look for it's defs - let ast = parse_file(&mut context.file_manager, child_file_id, errors); - - // Add module into def collector and get a ModuleId - if let Some(child_mod_id) = - self.push_child_module(mod_name, child_file_id, true, false, errors) - { - collect_defs( - self.def_collector, - ast, - child_file_id, - child_mod_id, - crate_id, - context, - errors, - ); - } - } - - /// Add a child module to the current def_map. - /// On error this returns None and pushes to `errors` - fn push_child_module( - &mut self, - mod_name: &Ident, - file_id: FileId, - add_to_parent_scope: bool, - is_contract: bool, - errors: &mut Vec, - ) -> Option { - let parent = Some(self.module_id); - let location = Location::new(mod_name.span(), file_id); - let new_module = ModuleData::new(parent, location, is_contract); - let module_id = self.def_collector.def_map.modules.insert(new_module); - - let modules = &mut self.def_collector.def_map.modules; - - // Update the parent module to reference the child - modules[self.module_id.0].children.insert(mod_name.clone(), LocalModuleId(module_id)); - - // Add this child module into the scope of the parent module as a module definition - // module definitions are definitions which can only exist at the module level. - // ModuleDefinitionIds can be used across crates since they contain the CrateId - // - // We do not want to do this in the case of struct modules (each struct type corresponds - // to a child module containing its methods) since the module name should not shadow - // the struct name. - if add_to_parent_scope { - let mod_id = ModuleId { - krate: self.def_collector.def_map.krate, - local_id: LocalModuleId(module_id), - }; - - if let Err((first_def, second_def)) = - modules[self.module_id.0].declare_child_module(mod_name.to_owned(), mod_id) - { - let err = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Module, - first_def, - second_def, - }; - errors.push(err.into_file_diagnostic(self.file_id)); - return None; - } - } - - Some(LocalModuleId(module_id)) - } -} diff --git a/crates/noirc_frontend/src/hir/def_collector/errors.rs b/crates/noirc_frontend/src/hir/def_collector/errors.rs deleted file mode 100644 index d47d985e12e..00000000000 --- a/crates/noirc_frontend/src/hir/def_collector/errors.rs +++ /dev/null @@ -1,95 +0,0 @@ -use crate::hir::resolution::import::PathResolutionError; -use crate::Ident; - -use noirc_errors::CustomDiagnostic as Diagnostic; -use noirc_errors::FileDiagnostic; -use noirc_errors::Span; -use thiserror::Error; - -use std::fmt; - -#[derive(Debug)] -pub enum DuplicateType { - Function, - Module, - Global, - TypeDefinition, - Import, -} - -#[derive(Error, Debug)] -pub enum DefCollectorErrorKind { - #[error("duplicate {typ} found in namespace")] - Duplicate { typ: DuplicateType, first_def: Ident, second_def: Ident }, - #[error("unresolved import")] - UnresolvedModuleDecl { mod_name: Ident }, - #[error("path resolution error")] - PathResolutionError(PathResolutionError), - #[error("Non-struct type used in impl")] - NonStructTypeInImpl { span: Span }, - #[error("Cannot `impl` a type defined outside the current crate")] - ForeignImpl { span: Span, type_name: String }, -} - -impl DefCollectorErrorKind { - pub fn into_file_diagnostic(self, file: fm::FileId) -> FileDiagnostic { - Diagnostic::from(self).in_file(file) - } -} - -impl fmt::Display for DuplicateType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - DuplicateType::Function => write!(f, "function"), - DuplicateType::Module => write!(f, "module"), - DuplicateType::Global => write!(f, "global"), - DuplicateType::TypeDefinition => write!(f, "type definition"), - DuplicateType::Import => write!(f, "import"), - } - } -} - -impl From for Diagnostic { - fn from(error: DefCollectorErrorKind) -> Diagnostic { - match error { - DefCollectorErrorKind::Duplicate { typ, first_def, second_def } => { - let primary_message = format!( - "duplicate definitions of {} with name {} found", - &typ, &first_def.0.contents - ); - { - let first_span = first_def.0.span(); - let second_span = second_def.0.span(); - let mut diag = Diagnostic::simple_error( - primary_message, - format!("first {:?} found here", &typ), - first_span, - ); - diag.add_secondary(format!("second {:?} found here", &typ), second_span); - diag - } - } - DefCollectorErrorKind::UnresolvedModuleDecl { mod_name } => { - let span = mod_name.0.span(); - let mod_name = &mod_name.0.contents; - - Diagnostic::simple_error( - format!("could not resolve module `{mod_name}` "), - String::new(), - span, - ) - } - DefCollectorErrorKind::PathResolutionError(error) => error.into(), - DefCollectorErrorKind::NonStructTypeInImpl { span } => Diagnostic::simple_error( - "Non-struct type used in impl".into(), - "Only struct types may have implementation methods".into(), - span, - ), - DefCollectorErrorKind::ForeignImpl { span, type_name } => Diagnostic::simple_error( - "Cannot `impl` a type that was defined outside the current crate".into(), - format!("{type_name} was defined outside the current crate"), - span, - ), - } - } -} diff --git a/crates/noirc_frontend/src/hir/def_map/mod.rs b/crates/noirc_frontend/src/hir/def_map/mod.rs deleted file mode 100644 index 2dc8c5ec96f..00000000000 --- a/crates/noirc_frontend/src/hir/def_map/mod.rs +++ /dev/null @@ -1,223 +0,0 @@ -use crate::graph::CrateId; -use crate::hir::def_collector::dc_crate::DefCollector; -use crate::hir::Context; -use crate::node_interner::{FuncId, NodeInterner}; -use crate::parser::{parse_program, ParsedModule}; -use crate::token::Attribute; -use arena::{Arena, Index}; -use fm::{FileId, FileManager}; -use noirc_errors::{FileDiagnostic, Location}; -use std::collections::HashMap; - -mod module_def; -pub use module_def::*; -mod item_scope; -pub use item_scope::*; -mod module_data; -pub use module_data::*; -mod namespace; -pub use namespace::*; - -/// The name that is used for a non-contract program's entry-point function. -pub const MAIN_FUNCTION: &str = "main"; - -// XXX: Ultimately, we want to constrain an index to be of a certain type just like in RA -/// Lets first check if this is offered by any external crate -/// XXX: RA has made this a crate on crates.io -#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] -pub struct LocalModuleId(pub Index); - -impl LocalModuleId { - pub fn dummy_id() -> LocalModuleId { - LocalModuleId(Index::from_raw_parts(std::usize::MAX, std::u64::MAX)) - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct ModuleId { - pub krate: CrateId, - pub local_id: LocalModuleId, -} - -impl ModuleId { - pub fn dummy_id() -> ModuleId { - ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() } - } -} - -impl ModuleId { - pub fn module(self, def_maps: &HashMap) -> &ModuleData { - &def_maps[&self.krate].modules()[self.local_id.0] - } -} - -/// Map of all modules and scopes defined within a crate. -/// -/// The definitions of the crate are accessible indirectly via the scopes of each module. -#[derive(Debug)] -pub struct CrateDefMap { - pub(crate) root: LocalModuleId, - - pub(crate) modules: Arena, - - pub(crate) krate: CrateId, - - pub(crate) extern_prelude: HashMap, -} - -impl CrateDefMap { - /// Collect all definitions in the crate - pub fn collect_defs( - crate_id: CrateId, - context: &mut Context, - errors: &mut Vec, - ) { - // Check if this Crate has already been compiled - // XXX: There is probably a better alternative for this. - // Without this check, the compiler will panic as it does not - // expect the same crate to be processed twice. It would not - // make the implementation wrong, if the same crate was processed twice, it just makes it slow. - if context.def_map(&crate_id).is_some() { - return; - } - - // First parse the root file. - let root_file_id = context.crate_graph[crate_id].root_file_id; - let ast = parse_file(&mut context.file_manager, root_file_id, errors); - - // Allocate a default Module for the root, giving it a ModuleId - let mut modules: Arena = Arena::default(); - let location = Location::new(Default::default(), root_file_id); - let root = modules.insert(ModuleData::new(None, location, false)); - - let def_map = CrateDefMap { - root: LocalModuleId(root), - modules, - krate: crate_id, - extern_prelude: HashMap::new(), - }; - - // Now we want to populate the CrateDefMap using the DefCollector - DefCollector::collect(def_map, context, ast, root_file_id, errors); - } - - pub fn root(&self) -> LocalModuleId { - self.root - } - pub fn modules(&self) -> &Arena { - &self.modules - } - pub fn krate(&self) -> CrateId { - self.krate - } - - /// Find the main function for this crate - pub fn main_function(&self) -> Option { - let root_module = &self.modules()[self.root.0]; - - // This function accepts an Ident, so we attach a dummy span to - // "main". Equality is implemented only on the contents. - root_module.find_func_with_name(&MAIN_FUNCTION.into()) - } - - pub fn file_id(&self, module_id: LocalModuleId) -> FileId { - self.modules[module_id.0].location.file - } - - /// Go through all modules in this crate, and find all functions in - /// each module with the #[test] attribute - pub fn get_all_test_functions<'a>( - &'a self, - interner: &'a NodeInterner, - ) -> impl Iterator + 'a { - self.modules.iter().flat_map(|(_, module)| { - module - .value_definitions() - .filter_map(|id| id.as_function()) - .filter(|id| interner.function_meta(id).attributes == Some(Attribute::Test)) - }) - } - - /// Go through all modules in this crate, find all `contract ... { ... }` declarations, - /// and collect them all into a Vec. - pub fn get_all_contracts(&self) -> Vec { - self.modules - .iter() - .filter_map(|(id, module)| { - if module.is_contract { - let functions = - module.value_definitions().filter_map(|id| id.as_function()).collect(); - let name = self.get_module_path(id, module.parent); - Some(Contract { name, location: module.location, functions }) - } else { - None - } - }) - .collect() - } - - /// Find a child module's name by inspecting its parent. - /// Currently required as modules do not store their own names. - pub fn get_module_path(&self, child_id: Index, parent: Option) -> String { - self.get_module_path_with_separator(child_id, parent, ".") - } - - pub fn get_module_path_with_separator( - &self, - child_id: Index, - parent: Option, - separator: &str, - ) -> String { - if let Some(id) = parent { - let parent = &self.modules[id.0]; - let name = parent - .children - .iter() - .find(|(_, id)| id.0 == child_id) - .map(|(name, _)| &name.0.contents) - .expect("Child module was not a child of the given parent module"); - - let parent_name = self.get_module_path_with_separator(id.0, parent.parent, separator); - if parent_name.is_empty() { - name.to_string() - } else { - format!("{parent_name}{separator}{name}") - } - } else { - String::new() - } - } -} - -/// A 'contract' in Noir source code with the given name and functions. -/// This is not an AST node, it is just a convenient form to return for CrateDefMap::get_all_contracts. -pub struct Contract { - /// To keep `name` semi-unique, it is prefixed with the names of parent modules via CrateDefMap::get_module_path - pub name: String, - pub location: Location, - pub functions: Vec, -} - -/// Given a FileId, fetch the File, from the FileManager and parse it's content -pub fn parse_file( - fm: &mut FileManager, - file_id: FileId, - all_errors: &mut Vec, -) -> ParsedModule { - let file = fm.fetch_file(file_id); - let (program, errors) = parse_program(file.source()); - all_errors.extend(errors.into_iter().map(|error| error.in_file(file_id))); - program -} - -impl std::ops::Index for CrateDefMap { - type Output = ModuleData; - fn index(&self, local_module_id: LocalModuleId) -> &ModuleData { - &self.modules[local_module_id.0] - } -} -impl std::ops::IndexMut for CrateDefMap { - fn index_mut(&mut self, local_module_id: LocalModuleId) -> &mut ModuleData { - &mut self.modules[local_module_id.0] - } -} diff --git a/crates/noirc_frontend/src/hir/mod.rs b/crates/noirc_frontend/src/hir/mod.rs deleted file mode 100644 index d0b24e90a76..00000000000 --- a/crates/noirc_frontend/src/hir/mod.rs +++ /dev/null @@ -1,153 +0,0 @@ -pub mod def_collector; -pub mod def_map; -pub mod resolution; -pub mod scope; -pub mod type_check; - -use crate::graph::{CrateGraph, CrateId}; -use crate::hir_def::function::FuncMeta; -use crate::node_interner::{FuncId, NodeInterner}; -use def_map::{Contract, CrateDefMap}; -use fm::FileManager; -use std::collections::HashMap; - -/// Helper object which groups together several useful context objects used -/// during name resolution. Once name resolution is finished, only the -/// def_interner is required for type inference and monomorphization. -pub struct Context { - pub def_interner: NodeInterner, - pub crate_graph: CrateGraph, - pub(crate) def_maps: HashMap, - pub file_manager: FileManager, - - /// Maps a given (contract) module id to the next available storage slot - /// for that contract. - pub storage_slots: HashMap, -} - -#[derive(Debug, Copy, Clone)] -pub enum FunctionNameMatch<'a> { - Anything, - Exact(&'a str), - Contains(&'a str), -} - -pub type StorageSlot = u32; - -impl Context { - pub fn new(file_manager: FileManager, crate_graph: CrateGraph) -> Context { - Context { - def_interner: NodeInterner::default(), - def_maps: HashMap::new(), - crate_graph, - file_manager, - storage_slots: HashMap::new(), - } - } - - /// Returns the CrateDefMap for a given CrateId. - /// It is perfectly valid for the compiler to look - /// up a CrateDefMap and it is not available. - /// This is how the compiler knows to compile a Crate. - pub fn def_map(&self, crate_id: &CrateId) -> Option<&CrateDefMap> { - self.def_maps.get(crate_id) - } - - /// Return the CrateId for each crate that has been compiled - /// successfully - pub fn crates(&self) -> impl Iterator + '_ { - self.crate_graph.iter_keys() - } - - pub fn root_crate_id(&self) -> &CrateId { - self.crate_graph.root_crate_id() - } - - // TODO: Decide if we actually need `function_name` and `fully_qualified_function_name` - pub fn function_name(&self, id: &FuncId) -> &str { - self.def_interner.function_name(id) - } - - pub fn fully_qualified_function_name(&self, crate_id: &CrateId, id: &FuncId) -> String { - let def_map = self.def_map(crate_id).expect("The local crate should be analyzed already"); - - let name = self.def_interner.function_name(id); - - let meta = self.def_interner.function_meta(id); - let module = self.module(meta.module_id); - - let parent = - def_map.get_module_path_with_separator(meta.module_id.local_id.0, module.parent, "::"); - - if parent.is_empty() { - name.into() - } else { - format!("{parent}::{name}") - } - } - - pub fn function_meta(&self, func_id: &FuncId) -> FuncMeta { - self.def_interner.function_meta(func_id) - } - - /// Returns the FuncId of the 'main' function in a crate. - /// - Expects check_crate to be called beforehand - /// - Panics if no main function is found - pub fn get_main_function(&self, crate_id: &CrateId) -> Option { - // Find the local crate, one should always be present - let local_crate = self.def_map(crate_id).unwrap(); - - local_crate.main_function() - } - - /// Returns a list of all functions in the current crate marked with #[test] - /// whose names contain the given pattern string. An empty pattern string - /// will return all functions marked with #[test]. - pub fn get_all_test_functions_in_crate_matching( - &self, - crate_id: &CrateId, - pattern: FunctionNameMatch, - ) -> Vec<(String, FuncId)> { - let interner = &self.def_interner; - let def_map = self.def_map(crate_id).expect("The local crate should be analyzed already"); - - def_map - .get_all_test_functions(interner) - .filter_map(|id| { - let fully_qualified_name = self.fully_qualified_function_name(crate_id, &id); - match &pattern { - FunctionNameMatch::Anything => Some((fully_qualified_name, id)), - FunctionNameMatch::Exact(pattern) => { - (&fully_qualified_name == pattern).then_some((fully_qualified_name, id)) - } - FunctionNameMatch::Contains(pattern) => { - fully_qualified_name.contains(pattern).then_some((fully_qualified_name, id)) - } - } - }) - .collect() - } - - /// Return a Vec of all `contract` declarations in the source code and the functions they contain - pub fn get_all_contracts(&self, crate_id: &CrateId) -> Vec { - self.def_map(crate_id) - .expect("The local crate should be analyzed already") - .get_all_contracts() - } - - fn module(&self, module_id: def_map::ModuleId) -> &def_map::ModuleData { - module_id.module(&self.def_maps) - } - - /// Returns the next available storage slot in the given module. - /// Returns None if the given module is not a contract module. - fn next_storage_slot(&mut self, module_id: def_map::ModuleId) -> Option { - let module = self.module(module_id); - - module.is_contract.then(|| { - let next_slot = self.storage_slots.entry(module_id).or_insert(0); - *next_slot += 1; - *next_slot - }) - } -} diff --git a/crates/noirc_frontend/src/hir/resolution/errors.rs b/crates/noirc_frontend/src/hir/resolution/errors.rs deleted file mode 100644 index 1215d897eda..00000000000 --- a/crates/noirc_frontend/src/hir/resolution/errors.rs +++ /dev/null @@ -1,288 +0,0 @@ -pub use noirc_errors::Span; -use noirc_errors::{CustomDiagnostic as Diagnostic, FileDiagnostic}; -use thiserror::Error; - -use crate::{parser::ParserError, Ident, Type}; - -use super::import::PathResolutionError; - -#[derive(Error, Debug, Clone, PartialEq, Eq)] -pub enum PubPosition { - #[error("parameter")] - Parameter, - #[error("return type")] - ReturnType, -} - -#[derive(Error, Debug, Clone, PartialEq, Eq)] -pub enum ResolverError { - #[error("Duplicate definition")] - DuplicateDefinition { name: String, first_span: Span, second_span: Span }, - #[error("Unused variable")] - UnusedVariable { ident: Ident }, - #[error("Could not find variable in this scope")] - VariableNotDeclared { name: String, span: Span }, - #[error("path is not an identifier")] - PathIsNotIdent { span: Span }, - #[error("could not resolve path")] - PathResolutionError(PathResolutionError), - #[error("Expected")] - Expected { span: Span, expected: String, got: String }, - #[error("Duplicate field in constructor")] - DuplicateField { field: Ident }, - #[error("No such field in struct")] - NoSuchField { field: Ident, struct_definition: Ident }, - #[error("Missing fields from struct")] - MissingFields { span: Span, missing_fields: Vec, struct_definition: Ident }, - #[error("Unneeded 'mut', pattern is already marked as mutable")] - UnnecessaryMut { first_mut: Span, second_mut: Span }, - #[error("Unneeded 'pub', function is not the main method")] - UnnecessaryPub { ident: Ident, position: PubPosition }, - #[error("Required 'pub', main function must return public value")] - NecessaryPub { ident: Ident }, - #[error("'distinct' keyword can only be used with main method")] - DistinctNotAllowed { ident: Ident }, - #[error("Missing expression for declared constant")] - MissingRhsExpr { name: String, span: Span }, - #[error("Expression invalid in an array length context")] - InvalidArrayLengthExpr { span: Span }, - #[error("Integer too large to be evaluated in an array length context")] - IntegerTooLarge { span: Span }, - #[error("No global or generic type parameter found with the given name")] - NoSuchNumericTypeVariable { path: crate::Path }, - #[error("Closures cannot capture mutable variables")] - CapturedMutableVariable { span: Span }, - #[error("Test functions are not allowed to have any parameters")] - TestFunctionHasParameters { span: Span }, - #[error("Only struct types can be used in constructor expressions")] - NonStructUsedInConstructor { typ: Type, span: Span }, - #[error("Only struct types can have generics")] - NonStructWithGenerics { span: Span }, - #[error("Cannot apply generics on Self type")] - GenericsOnSelfType { span: Span }, - #[error("Incorrect amount of arguments to generic type constructor")] - IncorrectGenericCount { span: Span, struct_type: String, actual: usize, expected: usize }, - #[error("{0}")] - ParserError(Box), - #[error("Function is not defined in a contract yet sets its contract visibility")] - ContractFunctionTypeInNormalFunction { span: Span }, - #[error("Cannot create a mutable reference to {variable}, it was declared to be immutable")] - MutableReferenceToImmutableVariable { variable: String, span: Span }, - #[error("Mutable references to array indices are unsupported")] - MutableReferenceToArrayElement { span: Span }, - #[error("Function is not defined in a contract yet sets is_internal")] - ContractFunctionInternalInNormalFunction { span: Span }, - #[error("Numeric constants should be printed without formatting braces")] - NumericConstantInFormatString { name: String, span: Span }, -} - -impl ResolverError { - pub fn into_file_diagnostic(self, file: fm::FileId) -> FileDiagnostic { - Diagnostic::from(self).in_file(file) - } -} - -impl From for Diagnostic { - /// Only user errors can be transformed into a Diagnostic - /// ICEs will make the compiler panic, as they could affect the - /// soundness of the generated program - fn from(error: ResolverError) -> Diagnostic { - match error { - ResolverError::DuplicateDefinition { name, first_span, second_span } => { - let mut diag = Diagnostic::simple_error( - format!("duplicate definitions of {name} found"), - "first definition found here".to_string(), - first_span, - ); - diag.add_secondary("second definition found here".to_string(), second_span); - diag - } - ResolverError::UnusedVariable { ident } => { - let name = &ident.0.contents; - - Diagnostic::simple_warning( - format!("unused variable {name}"), - "unused variable ".to_string(), - ident.span(), - ) - } - ResolverError::VariableNotDeclared { name, span } => Diagnostic::simple_error( - format!("cannot find `{name}` in this scope "), - "not found in this scope".to_string(), - span, - ), - ResolverError::PathIsNotIdent { span } => Diagnostic::simple_error( - "cannot use path as an identifier".to_string(), - String::new(), - span, - ), - ResolverError::PathResolutionError(error) => error.into(), - ResolverError::Expected { span, expected, got } => Diagnostic::simple_error( - format!("expected {expected} got {got}"), - String::new(), - span, - ), - ResolverError::DuplicateField { field } => Diagnostic::simple_error( - format!("duplicate field {field}"), - String::new(), - field.span(), - ), - ResolverError::NoSuchField { field, struct_definition } => { - let mut error = Diagnostic::simple_error( - format!("no such field {field} defined in struct {struct_definition}"), - String::new(), - field.span(), - ); - - error.add_secondary( - format!("{struct_definition} defined here with no {field} field"), - struct_definition.span(), - ); - error - } - ResolverError::MissingFields { span, missing_fields, struct_definition } => { - let plural = if missing_fields.len() != 1 { "s" } else { "" }; - let missing_fields = missing_fields.join(", "); - - let mut error = Diagnostic::simple_error( - format!("missing field{plural}: {missing_fields}"), - String::new(), - span, - ); - - error.add_secondary( - format!("{struct_definition} defined here"), - struct_definition.span(), - ); - error - } - ResolverError::UnnecessaryMut { first_mut, second_mut } => { - let mut error = Diagnostic::simple_error( - "'mut' here is not necessary".to_owned(), - "".to_owned(), - second_mut, - ); - error.add_secondary( - "Pattern was already made mutable from this 'mut'".to_owned(), - first_mut, - ); - error - } - ResolverError::UnnecessaryPub { ident, position } => { - let name = &ident.0.contents; - - let mut diag = Diagnostic::simple_warning( - format!("unnecessary pub keyword on {position} for function {name}"), - format!("unnecessary pub {position}"), - ident.0.span(), - ); - - diag.add_note("The `pub` keyword only has effects on arguments to the entry-point function of a program. Thus, adding it to other function parameters can be deceiving and should be removed".to_owned()); - diag - } - ResolverError::NecessaryPub { ident } => { - let name = &ident.0.contents; - - let mut diag = Diagnostic::simple_error( - format!("missing pub keyword on return type of function {name}"), - "missing pub on return type".to_string(), - ident.0.span(), - ); - - diag.add_note("The `pub` keyword is mandatory for the entry-point function return type because the verifier cannot retrieve private witness and thus the function will not be able to return a 'priv' value".to_owned()); - diag - } - ResolverError::DistinctNotAllowed { ident } => { - let name = &ident.0.contents; - - let mut diag = Diagnostic::simple_error( - format!("Invalid `distinct` keyword on return type of function {name}"), - "Invalid distinct on return type".to_string(), - ident.0.span(), - ); - - diag.add_note("The `distinct` keyword is only valid when used on the main function of a program, as its only purpose is to ensure that all witness indices that occur in the abi are unique".to_owned()); - diag - } - ResolverError::MissingRhsExpr { name, span } => Diagnostic::simple_error( - format!( - "no expression specifying the value stored by the constant variable {name}" - ), - "expected expression to be stored for let statement".to_string(), - span, - ), - ResolverError::InvalidArrayLengthExpr { span } => Diagnostic::simple_error( - "Expression invalid in an array-length context".into(), - "Array-length expressions can only have simple integer operations and any variables used must be global constants".into(), - span, - ), - ResolverError::IntegerTooLarge { span } => Diagnostic::simple_error( - "Integer too large to be evaluated to an array-length".into(), - "Array-lengths may be a maximum size of usize::MAX, including intermediate calculations".into(), - span, - ), - ResolverError::NoSuchNumericTypeVariable { path } => Diagnostic::simple_error( - format!("Cannot find a global or generic type parameter named `{path}`"), - "Only globals or generic type parameters are allowed to be used as an array type's length".to_string(), - path.span(), - ), - ResolverError::CapturedMutableVariable { span } => Diagnostic::simple_error( - "Closures cannot capture mutable variables".into(), - "Mutable variable".into(), - span, - ), - ResolverError::TestFunctionHasParameters { span } => Diagnostic::simple_error( - "Test functions cannot have any parameters".into(), - "Try removing the parameters or moving the test into a wrapper function".into(), - span, - ), - ResolverError::NonStructUsedInConstructor { typ, span } => Diagnostic::simple_error( - "Only struct types can be used in constructor expressions".into(), - format!("{typ} has no fields to construct it with"), - span, - ), - ResolverError::NonStructWithGenerics { span } => Diagnostic::simple_error( - "Only struct types can have generic arguments".into(), - "Try removing the generic arguments".into(), - span, - ), - ResolverError::GenericsOnSelfType { span } => Diagnostic::simple_error( - "Cannot apply generics to Self type".into(), - "Use an explicit type name or apply the generics at the start of the impl instead".into(), - span, - ), - ResolverError::IncorrectGenericCount { span, struct_type, actual, expected } => { - let expected_plural = if expected == 1 { "" } else { "s" }; - let actual_plural = if actual == 1 { "is" } else { "are" }; - - Diagnostic::simple_error( - format!("The struct type {struct_type} has {expected} generic{expected_plural} but {actual} {actual_plural} given here"), - "Incorrect number of generic arguments".into(), - span, - ) - } - ResolverError::ParserError(error) => (*error).into(), - ResolverError::ContractFunctionTypeInNormalFunction { span } => Diagnostic::simple_error( - "Only functions defined within contracts can set their contract function type".into(), - "Non-contract functions cannot be 'open'".into(), - span, - ), - ResolverError::MutableReferenceToImmutableVariable { variable, span } => { - Diagnostic::simple_error(format!("Cannot mutably reference the immutable variable {variable}"), format!("{variable} is immutable"), span) - }, - ResolverError::MutableReferenceToArrayElement { span } => { - Diagnostic::simple_error("Mutable references to array elements are currently unsupported".into(), "Try storing the element in a fresh variable first".into(), span) - }, - ResolverError::ContractFunctionInternalInNormalFunction { span } => Diagnostic::simple_error( - "Only functions defined within contracts can set their functions to be internal".into(), - "Non-contract functions cannot be 'internal'".into(), - span, - ), - ResolverError::NumericConstantInFormatString { name, span } => Diagnostic::simple_error( - format!("cannot find `{name}` in this scope "), - "Numeric constants should be printed without formatting braces".to_string(), - span, - ), - } - } -} diff --git a/crates/noirc_frontend/src/hir/type_check/errors.rs b/crates/noirc_frontend/src/hir/type_check/errors.rs deleted file mode 100644 index cd8d87435c9..00000000000 --- a/crates/noirc_frontend/src/hir/type_check/errors.rs +++ /dev/null @@ -1,241 +0,0 @@ -use acvm::FieldElement; -use noirc_errors::CustomDiagnostic as Diagnostic; -use noirc_errors::Span; -use thiserror::Error; - -use crate::hir::resolution::errors::ResolverError; -use crate::hir_def::expr::HirBinaryOp; -use crate::hir_def::types::Type; -use crate::FunctionReturnType; -use crate::Signedness; - -#[derive(Error, Debug, Clone, PartialEq, Eq)] -pub enum Source { - #[error("Binary")] - Binary, - #[error("Assignment")] - Assignment, - #[error("ArrayElements")] - ArrayElements, - #[error("ArrayLen")] - ArrayLen, - #[error("StringLen")] - StringLen, - #[error("Comparison")] - Comparison, - #[error("BinOp")] - BinOp, - #[error("Return")] - Return(FunctionReturnType, Span), -} - -#[derive(Error, Debug, Clone, PartialEq, Eq)] -pub enum TypeCheckError { - #[error("Operator {op:?} cannot be used in a {place:?}")] - OpCannotBeUsed { op: HirBinaryOp, place: &'static str, span: Span }, - #[error("The literal `{expr:?}` cannot fit into `{ty}` which has range `{range}`")] - OverflowingAssignment { expr: FieldElement, ty: Type, range: String, span: Span }, - #[error("Type {typ:?} cannot be used in a {place:?}")] - TypeCannotBeUsed { typ: Type, place: &'static str, span: Span }, - #[error("Expected type {expected_typ:?} is not the same as {expr_typ:?}")] - TypeMismatch { expected_typ: String, expr_typ: String, expr_span: Span }, - #[error("Expected type {expected} is not the same as {actual}")] - TypeMismatchWithSource { expected: Type, actual: Type, span: Span, source: Source }, - #[error("Expected {expected:?} found {found:?}")] - ArityMisMatch { expected: u16, found: u16, span: Span }, - #[error("Return type in a function cannot be public")] - PublicReturnType { typ: Type, span: Span }, - #[error("Cannot cast type {from}, 'as' is only for primitive field or integer types")] - InvalidCast { from: Type, span: Span }, - #[error("Expected a function, but found a(n) {found}")] - ExpectedFunction { found: Type, span: Span }, - #[error("Type {lhs_type} has no member named {field_name}")] - AccessUnknownMember { lhs_type: Type, field_name: String, span: Span }, - #[error("Function expects {expected} parameters but {found} given")] - ParameterCountMismatch { expected: usize, found: usize, span: Span }, - #[error("Only integer and Field types may be casted to")] - UnsupportedCast { span: Span }, - #[error("Index {index} is out of bounds for this tuple {lhs_type} of length {length}")] - TupleIndexOutOfBounds { index: usize, lhs_type: Type, length: usize, span: Span }, - #[error("Variable {name} must be mutable to be assigned to")] - VariableMustBeMutable { name: String, span: Span }, - #[error("No method named '{method_name}' found for type '{object_type}'")] - UnresolvedMethodCall { method_name: String, object_type: Type, span: Span }, - #[error("Comparisons are invalid on Field types. Try casting the operands to a sized integer type first")] - InvalidComparisonOnField { span: Span }, - #[error("Integers must have the same signedness LHS is {sign_x:?}, RHS is {sign_y:?}")] - IntegerSignedness { sign_x: Signedness, sign_y: Signedness, span: Span }, - #[error("Integers must have the same bit width LHS is {bit_width_x}, RHS is {bit_width_y}")] - IntegerBitWidth { bit_width_x: u32, bit_width_y: u32, span: Span }, - #[error("{kind} cannot be used in an infix operation")] - InvalidInfixOp { kind: &'static str, span: Span }, - #[error("{kind} cannot be used in a unary operation")] - InvalidUnaryOp { kind: String, span: Span }, - #[error("Bitwise operations are invalid on Field types. Try casting the operands to a sized integer type first.")] - InvalidBitwiseOperationOnField { span: Span }, - #[error("Integer cannot be used with type {typ}")] - IntegerTypeMismatch { typ: Type, span: Span }, - #[error("Cannot use an integer and a Field in a binary operation, try converting the Field into an integer first")] - IntegerAndFieldBinaryOperation { span: Span }, - #[error("Fields cannot be compared, try casting to an integer first")] - FieldComparison { span: Span }, - #[error("The number of bits to use for this bitwise operation is ambiguous. Either the operand's type or return type should be specified")] - AmbiguousBitWidth { span: Span }, - #[error("Error with additional context")] - Context { err: Box, ctx: &'static str }, - #[error("Array is not homogeneous")] - NonHomogeneousArray { - first_span: Span, - first_type: String, - first_index: usize, - second_span: Span, - second_type: String, - second_index: usize, - }, - #[error("Cannot infer type of expression, type annotations needed before this point")] - TypeAnnotationsNeeded { span: Span }, - #[error("use of deprecated function {name}")] - CallDeprecated { name: String, note: Option, span: Span }, - #[error("{0}")] - ResolverError(ResolverError), - #[error("Unused expression result of type {expr_type}")] - UnusedResultError { expr_type: Type, expr_span: Span }, -} - -impl TypeCheckError { - pub fn add_context(self, ctx: &'static str) -> Self { - TypeCheckError::Context { err: Box::new(self), ctx } - } -} - -impl From for Diagnostic { - fn from(error: TypeCheckError) -> Diagnostic { - match error { - TypeCheckError::TypeCannotBeUsed { typ, place, span } => Diagnostic::simple_error( - format!("The type {} cannot be used in a {}", &typ, place), - String::new(), - span, - ), - TypeCheckError::Context { err, ctx } => { - let mut diag = Diagnostic::from(*err); - diag.add_note(ctx.to_owned()); - diag - } - TypeCheckError::OpCannotBeUsed { op, place, span } => Diagnostic::simple_error( - format!("The operator {op:?} cannot be used in a {place}"), - String::new(), - span, - ), - TypeCheckError::TypeMismatch { expected_typ, expr_typ, expr_span } => { - Diagnostic::simple_error( - format!("Expected type {expected_typ}, found type {expr_typ}"), - String::new(), - expr_span, - ) - } - TypeCheckError::NonHomogeneousArray { - first_span, - first_type, - first_index, - second_span, - second_type, - second_index, - } => { - let mut diag = Diagnostic::simple_error( - format!( - "Non homogeneous array, different element types found at indices ({first_index},{second_index})" - ), - format!("Found type {first_type}"), - first_span, - ); - diag.add_secondary(format!("but then found type {second_type}"), second_span); - diag - } - TypeCheckError::ArityMisMatch { expected, found, span } => { - let plural = if expected == 1 { "" } else { "s" }; - let msg = format!("Expected {expected} argument{plural}, but found {found}"); - Diagnostic::simple_error(msg, String::new(), span) - } - TypeCheckError::ParameterCountMismatch { expected, found, span } => { - let empty_or_s = if expected == 1 { "" } else { "s" }; - let was_or_were = if found == 1 { "was" } else { "were" }; - let msg = format!("Function expects {expected} parameter{empty_or_s} but {found} {was_or_were} given"); - Diagnostic::simple_error(msg, String::new(), span) - } - TypeCheckError::InvalidCast { span, .. } - | TypeCheckError::ExpectedFunction { span, .. } - | TypeCheckError::AccessUnknownMember { span, .. } - | TypeCheckError::UnsupportedCast { span } - | TypeCheckError::TupleIndexOutOfBounds { span, .. } - | TypeCheckError::VariableMustBeMutable { span, .. } - | TypeCheckError::UnresolvedMethodCall { span, .. } - | TypeCheckError::InvalidComparisonOnField { span } - | TypeCheckError::IntegerSignedness { span, .. } - | TypeCheckError::IntegerBitWidth { span, .. } - | TypeCheckError::InvalidInfixOp { span, .. } - | TypeCheckError::InvalidUnaryOp { span, .. } - | TypeCheckError::InvalidBitwiseOperationOnField { span, .. } - | TypeCheckError::IntegerTypeMismatch { span, .. } - | TypeCheckError::FieldComparison { span, .. } - | TypeCheckError::AmbiguousBitWidth { span, .. } - | TypeCheckError::IntegerAndFieldBinaryOperation { span } - | TypeCheckError::OverflowingAssignment { span, .. } => { - Diagnostic::simple_error(error.to_string(), String::new(), span) - } - TypeCheckError::PublicReturnType { typ, span } => Diagnostic::simple_error( - "Functions cannot declare a public return type".to_string(), - format!("return type is {typ}"), - span, - ), - TypeCheckError::TypeAnnotationsNeeded { span } => Diagnostic::simple_error( - "Expression type is ambiguous".to_string(), - "Type must be known at this point".to_string(), - span, - ), - TypeCheckError::ResolverError(error) => error.into(), - TypeCheckError::TypeMismatchWithSource { expected, actual, span, source } => { - let message = match source { - Source::Binary => format!("Types in a binary operation should match, but found {expected} and {actual}"), - Source::Assignment => { - format!("Cannot assign an expression of type {actual} to a value of type {expected}") - } - Source::ArrayElements => format!("Cannot compare {expected} and {actual}, the array element types differ"), - Source::ArrayLen => format!("Can only compare arrays of the same length. Here LHS is of length {expected}, and RHS is {actual}"), - Source::StringLen => format!("Can only compare strings of the same length. Here LHS is of length {expected}, and RHS is {actual}"), - Source::Comparison => format!("Unsupported types for comparison: {expected} and {actual}"), - Source::BinOp => format!("Unsupported types for binary operation: {expected} and {actual}"), - Source::Return(ret_ty, expr_span) => { - let ret_ty_span = match ret_ty { - FunctionReturnType::Default(span) | FunctionReturnType::Ty(_, span) => span - }; - - let mut diagnostic = Diagnostic::simple_error(format!("expected type {expected}, found type {actual}"), format!("expected {expected} because of return type"), ret_ty_span); - - if let FunctionReturnType::Default(_) = ret_ty { - diagnostic.add_note(format!("help: try adding a return type: `-> {actual}`")); - } - - diagnostic.add_secondary(format!("{actual} returned here"), expr_span); - - return diagnostic - }, - }; - - Diagnostic::simple_error(message, String::new(), span) - } - TypeCheckError::CallDeprecated { span, ref note, .. } => { - let primary_message = error.to_string(); - let secondary_message = note.clone().unwrap_or_default(); - - Diagnostic::simple_warning(primary_message, secondary_message, span) - } - TypeCheckError::UnusedResultError { expr_type, expr_span } => { - Diagnostic::simple_warning( - format!("Unused expression result of type {expr_type}"), - String::new(), - expr_span, - ) - } - } - } -} diff --git a/crates/noirc_frontend/src/hir/type_check/mod.rs b/crates/noirc_frontend/src/hir/type_check/mod.rs deleted file mode 100644 index 8596a9cc28c..00000000000 --- a/crates/noirc_frontend/src/hir/type_check/mod.rs +++ /dev/null @@ -1,452 +0,0 @@ -//! This file contains type_check_func, the entry point to the type checking pass (for each function). -//! -//! The pass structure of type checking is relatively straightforward. It is a single pass through -//! the HIR of each function and outputs the inferred type of each HIR node into the NodeInterner, -//! keyed by the ID of the node. -//! -//! Although this algorithm features inference via TypeVariables, there is no generalization step -//! as all functions are required to give their full signatures. Closures are inferred but are -//! never generalized and thus cannot be used polymorphically. -mod errors; -mod expr; -mod stmt; - -pub use errors::TypeCheckError; - -use crate::{ - hir_def::{expr::HirExpression, stmt::HirStatement}, - node_interner::{ExprId, FuncId, NodeInterner, StmtId}, - Type, -}; - -use self::errors::Source; - -type TypeCheckFn = Box Result<(), TypeCheckError>>; - -pub struct TypeChecker<'interner> { - delayed_type_checks: Vec, - interner: &'interner mut NodeInterner, - errors: Vec, -} - -/// Type checks a function and assigns the -/// appropriate types to expressions in a side table -pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec { - let meta = interner.function_meta(&func_id); - let declared_return_type = meta.return_type().clone(); - let can_ignore_ret = meta.can_ignore_return_type(); - - let function_body = interner.function(&func_id); - let function_body_id = function_body.as_expr(); - - let mut type_checker = TypeChecker::new(interner); - - // Bind each parameter to its annotated type. - // This is locally obvious, but it must be bound here so that the - // Definition object of the parameter in the NodeInterner is given the correct type. - for param in meta.parameters.into_iter() { - type_checker.bind_pattern(¶m.0, param.1); - } - - let (function_last_type, delayed_type_check_functions, mut errors) = - type_checker.check_function_body(function_body_id); - - // Go through any delayed type checking errors to see if they are resolved, or error otherwise. - for type_check_fn in delayed_type_check_functions { - if let Err(error) = type_check_fn() { - errors.push(error); - } - } - - // Check declared return type and actual return type - if !can_ignore_ret { - let (expr_span, empty_function) = function_info(interner, function_body_id); - - let func_span = interner.expr_span(function_body_id); // XXX: We could be more specific and return the span of the last stmt, however stmts do not have spans yet - function_last_type.unify_with_coercions( - &declared_return_type, - *function_body_id, - interner, - &mut errors, - || { - let mut error = TypeCheckError::TypeMismatchWithSource { - expected: declared_return_type.clone(), - actual: function_last_type.clone(), - span: func_span, - source: Source::Return(meta.return_type, expr_span), - }; - - if empty_function { - error = error.add_context( - "implicitly returns `()` as its body has no tail or `return` expression", - ); - } - - error - }, - ); - } - - errors -} - -fn function_info( - interner: &mut NodeInterner, - function_body_id: &ExprId, -) -> (noirc_errors::Span, bool) { - let (expr_span, empty_function) = - if let HirExpression::Block(block) = interner.expression(function_body_id) { - let last_stmt = block.statements().last(); - let mut span = interner.expr_span(function_body_id); - - if let Some(last_stmt) = last_stmt { - if let HirStatement::Expression(expr) = interner.statement(last_stmt) { - span = interner.expr_span(&expr); - } - } - - (span, last_stmt.is_none()) - } else { - (interner.expr_span(function_body_id), false) - }; - (expr_span, empty_function) -} - -impl<'interner> TypeChecker<'interner> { - fn new(interner: &'interner mut NodeInterner) -> Self { - Self { delayed_type_checks: Vec::new(), interner, errors: vec![] } - } - - pub fn push_delayed_type_check(&mut self, f: TypeCheckFn) { - self.delayed_type_checks.push(f); - } - - fn check_function_body( - mut self, - body: &ExprId, - ) -> (Type, Vec, Vec) { - let body_type = self.check_expression(body); - (body_type, self.delayed_type_checks, self.errors) - } - - pub fn check_global(id: &StmtId, interner: &'interner mut NodeInterner) -> Vec { - let mut this = Self { delayed_type_checks: Vec::new(), interner, errors: vec![] }; - this.check_statement(id); - this.errors - } - - /// Wrapper of Type::unify using self.errors - fn unify( - &mut self, - actual: &Type, - expected: &Type, - make_error: impl FnOnce() -> TypeCheckError, - ) { - actual.unify(expected, &mut self.errors, make_error); - } - - /// Wrapper of Type::unify_with_coercions using self.errors - fn unify_with_coercions( - &mut self, - actual: &Type, - expected: &Type, - expression: ExprId, - make_error: impl FnOnce() -> TypeCheckError, - ) { - actual.unify_with_coercions( - expected, - expression, - self.interner, - &mut self.errors, - make_error, - ); - } -} - -// XXX: These tests are all manual currently. -/// We can either build a test apparatus or pass raw code through the resolver -#[cfg(test)] -mod test { - use std::collections::HashMap; - use std::vec; - - use fm::FileId; - use iter_extended::vecmap; - use noirc_errors::{Location, Span}; - - use crate::graph::CrateId; - use crate::hir::def_map::{ModuleData, ModuleId}; - use crate::hir::resolution::import::PathResolutionError; - use crate::hir_def::expr::HirIdent; - use crate::hir_def::stmt::HirLetStatement; - use crate::hir_def::stmt::HirPattern::Identifier; - use crate::hir_def::types::Type; - use crate::hir_def::{ - expr::{HirBinaryOp, HirBlockExpression, HirExpression, HirInfixExpression}, - function::{FuncMeta, HirFunction}, - stmt::HirStatement, - }; - use crate::node_interner::{DefinitionKind, FuncId, NodeInterner}; - use crate::{ - hir::{ - def_map::{CrateDefMap, LocalModuleId, ModuleDefId}, - resolution::{path_resolver::PathResolver, resolver::Resolver}, - }, - parse_program, FunctionKind, Path, - }; - use crate::{BinaryOpKind, Distinctness, FunctionReturnType, Visibility}; - - #[test] - fn basic_let() { - let mut interner = NodeInterner::default(); - - // Add a simple let Statement into the interner - // let z = x + y; - // - // Push x variable - let x_id = interner.push_definition("x".into(), false, DefinitionKind::Local(None)); - - // Safety: The FileId in a location isn't used for tests - let file = FileId::default(); - let location = Location::new(Span::default(), file); - - let x = HirIdent { id: x_id, location }; - - // Push y variable - let y_id = interner.push_definition("y".into(), false, DefinitionKind::Local(None)); - let y = HirIdent { id: y_id, location }; - - // Push z variable - let z_id = interner.push_definition("z".into(), false, DefinitionKind::Local(None)); - let z = HirIdent { id: z_id, location }; - - // Push x and y as expressions - let x_expr_id = interner.push_expr(HirExpression::Ident(x)); - let y_expr_id = interner.push_expr(HirExpression::Ident(y)); - - // Create Infix - let operator = HirBinaryOp { location, kind: BinaryOpKind::Add }; - let expr = HirInfixExpression { lhs: x_expr_id, operator, rhs: y_expr_id }; - let expr_id = interner.push_expr(HirExpression::Infix(expr)); - interner.push_expr_location(expr_id, Span::single_char(0), file); - - interner.push_expr_location(x_expr_id, Span::single_char(0), file); - interner.push_expr_location(y_expr_id, Span::single_char(0), file); - - // Create let statement - let let_stmt = HirLetStatement { - pattern: Identifier(z), - r#type: Type::FieldElement, - expression: expr_id, - }; - let stmt_id = interner.push_stmt(HirStatement::Let(let_stmt)); - let expr_id = interner.push_expr(HirExpression::Block(HirBlockExpression(vec![stmt_id]))); - interner.push_expr_location(expr_id, Span::single_char(0), file); - - // Create function to enclose the let statement - let func = HirFunction::unchecked_from_expr(expr_id); - let func_id = interner.push_fn(func); - - let name = HirIdent { - location, - id: interner.push_definition("test_func".into(), false, DefinitionKind::Local(None)), - }; - - // Add function meta - let func_meta = FuncMeta { - name, - kind: FunctionKind::Normal, - module_id: ModuleId::dummy_id(), - attributes: None, - location, - contract_function_type: None, - is_internal: None, - is_unconstrained: false, - typ: Type::Function( - vec![Type::FieldElement, Type::FieldElement], - Box::new(Type::Unit), - Box::new(Type::Unit), - ), - parameters: vec![ - (Identifier(x), Type::FieldElement, Visibility::Private), - (Identifier(y), Type::FieldElement, Visibility::Private), - ] - .into(), - return_visibility: Visibility::Private, - return_distinctness: Distinctness::DuplicationAllowed, - has_body: true, - return_type: FunctionReturnType::Default(Span::default()), - }; - interner.push_fn_meta(func_meta, func_id); - - let errors = super::type_check_func(&mut interner, func_id); - assert!(errors.is_empty()); - } - - #[test] - #[should_panic] - fn basic_let_stmt() { - let src = r#" - fn main(x : Field) { - let k = [x,x]; - let _z = x + k; - } - "#; - - type_check_src_code(src, vec![String::from("main")]); - } - - #[test] - fn basic_index_expr() { - let src = r#" - fn main(x : Field) { - let k = [x,x]; - let _z = x + k[0]; - } - "#; - - type_check_src_code(src, vec![String::from("main")]); - } - #[test] - fn basic_call_expr() { - let src = r#" - fn main(x : Field) { - let _z = x + foo(x); - } - - fn foo(x : Field) -> Field { - x - } - "#; - - type_check_src_code(src, vec![String::from("main"), String::from("foo")]); - } - #[test] - fn basic_for_expr() { - let src = r#" - fn main(_x : Field) { - let _j = for _i in 0..10 { - for _k in 0..100 { - - } - }; - } - - "#; - - type_check_src_code(src, vec![String::from("main"), String::from("foo")]); - } - #[test] - fn basic_closure() { - let src = r#" - fn main(x : Field) -> pub Field { - let closure = |y| y + x; - closure(x) - } - "#; - - type_check_src_code(src, vec![String::from("main"), String::from("foo")]); - } - - #[test] - fn closure_with_no_args() { - let src = r#" - fn main(x : Field) -> pub Field { - let closure = || x; - closure() - } - "#; - - type_check_src_code(src, vec![String::from("main")]); - } - // This is the same Stub that is in the resolver, maybe we can pull this out into a test module and re-use? - struct TestPathResolver(HashMap); - - impl PathResolver for TestPathResolver { - fn resolve( - &self, - _def_maps: &HashMap, - path: Path, - ) -> Result { - // Not here that foo::bar and hello::foo::bar would fetch the same thing - let name = path.segments.last().unwrap(); - self.0 - .get(&name.0.contents) - .cloned() - .ok_or_else(move || PathResolutionError::Unresolved(name.clone())) - } - - fn local_module_id(&self) -> LocalModuleId { - LocalModuleId(arena::Index::from_raw_parts(0, 0)) - } - - fn module_id(&self) -> ModuleId { - ModuleId { krate: CrateId::dummy_id(), local_id: self.local_module_id() } - } - } - - impl TestPathResolver { - fn insert_func(&mut self, name: String, func_id: FuncId) { - self.0.insert(name, func_id.into()); - } - } - - // This function assumes that there is only one function and this is the - // func id that is returned - fn type_check_src_code(src: &str, func_namespace: Vec) { - let (program, errors) = parse_program(src); - let mut interner = NodeInterner::default(); - - // Using assert_eq here instead of assert(errors.is_empty()) displays - // the whole vec if the assert fails rather than just two booleans - assert_eq!(errors, vec![]); - - let main_id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition("main".into(), main_id); - - let func_ids = vecmap(&func_namespace, |name| { - let id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition(name.into(), id); - id - }); - - let mut path_resolver = TestPathResolver(HashMap::new()); - for (name, id) in func_namespace.into_iter().zip(func_ids.clone()) { - path_resolver.insert_func(name.to_owned(), id); - } - - let mut def_maps: HashMap = HashMap::new(); - let file = FileId::default(); - - let mut modules = arena::Arena::new(); - let location = Location::new(Default::default(), file); - modules.insert(ModuleData::new(None, location, false)); - - def_maps.insert( - CrateId::dummy_id(), - CrateDefMap { - root: path_resolver.local_module_id(), - modules, - krate: CrateId::dummy_id(), - extern_prelude: HashMap::new(), - }, - ); - - let func_meta = vecmap(program.functions, |nf| { - let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); - let (hir_func, func_meta, resolver_errors) = - resolver.resolve_function(nf, main_id, ModuleId::dummy_id()); - assert_eq!(resolver_errors, vec![]); - (hir_func, func_meta) - }); - - for ((hir_func, meta), func_id) in func_meta.into_iter().zip(func_ids.clone()) { - interner.update_fn(func_id, hir_func); - interner.push_fn_meta(meta, func_id); - } - - // Type check section - let errors = super::type_check_func(&mut interner, func_ids.first().cloned().unwrap()); - assert_eq!(errors, vec![]); - } -} diff --git a/crates/noirc_frontend/src/hir_def/function.rs b/crates/noirc_frontend/src/hir_def/function.rs deleted file mode 100644 index 5ef2e89d81f..00000000000 --- a/crates/noirc_frontend/src/hir_def/function.rs +++ /dev/null @@ -1,176 +0,0 @@ -use iter_extended::vecmap; -use noirc_errors::{Location, Span}; - -use super::expr::{HirBlockExpression, HirExpression, HirIdent}; -use super::stmt::HirPattern; -use crate::hir::def_map::ModuleId; -use crate::node_interner::{ExprId, NodeInterner}; -use crate::{token::Attribute, FunctionKind}; -use crate::{ContractFunctionType, Distinctness, FunctionReturnType, Type, Visibility}; - -/// A Hir function is a block expression -/// with a list of statements -#[derive(Debug, Clone)] -pub struct HirFunction(ExprId); - -impl HirFunction { - pub fn empty() -> HirFunction { - HirFunction(ExprId::empty_block_id()) - } - - pub const fn unchecked_from_expr(expr_id: ExprId) -> HirFunction { - HirFunction(expr_id) - } - - pub const fn as_expr(&self) -> &ExprId { - &self.0 - } - - pub fn block(&self, interner: &NodeInterner) -> HirBlockExpression { - match interner.expression(&self.0) { - HirExpression::Block(block_expr) => block_expr, - _ => unreachable!("ice: functions can only be block expressions"), - } - } -} - -/// An interned function parameter from a function definition -pub type Param = (HirPattern, Type, Visibility); - -#[derive(Debug, Clone)] -pub struct Parameters(pub Vec); - -impl Parameters { - pub fn span(&self) -> Span { - assert!(!self.is_empty()); - let mut spans = vecmap(&self.0, |param| match ¶m.0 { - HirPattern::Identifier(ident) => ident.location.span, - HirPattern::Mutable(_, span) => *span, - HirPattern::Tuple(_, span) => *span, - HirPattern::Struct(_, _, span) => *span, - }); - - let merged_span = spans.pop().unwrap(); - for span in spans { - let _ = merged_span.merge(span); - } - - merged_span - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn iter(&self) -> impl Iterator { - self.0.iter() - } -} - -impl IntoIterator for Parameters { - type Item = Param; - type IntoIter = as IntoIterator>::IntoIter; - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -impl From> for Parameters { - fn from(vec: Vec) -> Parameters { - Parameters(vec) - } -} - -pub type FunctionSignature = (Vec, Option); - -/// A FuncMeta contains the signature of the function and any associated meta data like -/// the function's Location, FunctionKind, and attributes. If the function's body is -/// needed, it can be retrieved separately via `NodeInterner::function(&self, &FuncId)`. -#[derive(Debug, Clone)] -pub struct FuncMeta { - pub name: HirIdent, - - pub kind: FunctionKind, - - pub module_id: ModuleId, - - /// A function's attributes are the `#[...]` items above the function - /// definition, if any. Currently, this is limited to a maximum of only one - /// Attribute per function. - pub attributes: Option, - - /// This function's type in its contract. - /// If this function is not in a contract, this is always 'Secret'. - pub contract_function_type: Option, - - /// This function's visibility. - /// If this function is internal can only be called by itself. - /// Will be None if not in contract. - pub is_internal: Option, - - pub is_unconstrained: bool, - - pub parameters: Parameters, - - pub return_type: FunctionReturnType, - - pub return_visibility: Visibility, - - pub return_distinctness: Distinctness, - - /// The type of this function. Either a Type::Function - /// or a Type::Forall for generic functions. - pub typ: Type, - - pub location: Location, - - // This flag is needed for the attribute check pass - pub has_body: bool, -} - -impl FuncMeta { - /// Builtin, LowLevel and Oracle functions usually have the return type - /// declared, however their function bodies will be empty - /// So this method tells the type checker to ignore the return - /// of the empty function, which is unit - pub fn can_ignore_return_type(&self) -> bool { - match self.kind { - FunctionKind::LowLevel | FunctionKind::Builtin | FunctionKind::Oracle => true, - FunctionKind::Normal => false, - } - } - - pub fn into_function_signature(self) -> FunctionSignature { - // Doesn't use `self.return_type()` so we aren't working with references and don't need a `clone()` - let return_type = match self.typ { - Type::Function(_, ret, _env) => *ret, - Type::Forall(_, typ) => match *typ { - Type::Function(_, ret, _env) => *ret, - _ => unreachable!(), - }, - _ => unreachable!(), - }; - let return_type = match return_type { - Type::Unit => None, - typ => Some(typ), - }; - - (self.parameters.0, return_type) - } - - /// Gives the (uninstantiated) return type of this function. - pub fn return_type(&self) -> &Type { - match &self.typ { - Type::Function(_, ret, _env) => ret, - Type::Forall(_, typ) => match typ.as_ref() { - Type::Function(_, ret, _env) => ret, - _ => unreachable!(), - }, - _ => unreachable!(), - } - } -} diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs deleted file mode 100644 index 7988c20d244..00000000000 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ /dev/null @@ -1,1337 +0,0 @@ -use std::{ - cell::RefCell, - collections::{BTreeSet, HashMap}, - rc::Rc, -}; - -use crate::{ - hir::type_check::TypeCheckError, - node_interner::{ExprId, NodeInterner, TypeAliasId}, -}; -use iter_extended::vecmap; -use noirc_errors::Span; -use noirc_printable_type::PrintableType; - -use crate::{node_interner::StructId, node_interner::TraitId, Ident, Signedness}; - -use super::expr::{HirCallExpression, HirExpression, HirIdent}; - -#[derive(Debug, PartialEq, Eq, Clone, Hash)] -pub enum Type { - /// A primitive Field type - FieldElement, - - /// Array(N, E) is an array of N elements of type E. It is expected that N - /// is either a type variable of some kind or a Type::Constant. - Array(Box, Box), - - /// A primitive integer type with the given sign and bit count. - /// E.g. `u32` would be `Integer(Unsigned, 32)` - Integer(Signedness, u32), - - /// The primitive `bool` type. - Bool, - - /// String(N) is an array of characters of length N. It is expected that N - /// is either a type variable of some kind or a Type::Constant. - String(Box), - - /// FmtString(N, Vec) is an array of characters of length N that contains - /// a list of fields specified inside the string by the following regular expression r"\{([\S]+)\}" - FmtString(Box, Box), - - /// The unit type `()`. - Unit, - - /// A user-defined struct type. The `Shared` field here refers to - /// the shared definition for each instance of this struct type. The `Vec` - /// represents the generic arguments (if any) to this struct type. - Struct(Shared, Vec), - - /// A tuple type with the given list of fields in the order they appear in source code. - Tuple(Vec), - - /// TypeVariables are stand-in variables for some type which is not yet known. - /// They are not to be confused with NamedGenerics. While the later mostly works - /// as with normal types (ie. for two NamedGenerics T and U, T != U), TypeVariables - /// will be automatically rebound as necessary to satisfy any calls to unify. - /// - /// TypeVariables are often created when a generic function is instantiated. This - /// is a process that replaces each NamedGeneric in a generic function with a TypeVariable. - /// Doing this at each call site of a generic function is how they can be called with - /// different argument types each time. - TypeVariable(TypeVariable, TypeVariableKind), - - /// NamedGenerics are the 'T' or 'U' in a user-defined generic function - /// like `fn foo(...) {}`. Unlike TypeVariables, they cannot be bound over. - NamedGeneric(TypeVariable, Rc), - - /// A functions with arguments, a return type and environment. - /// the environment should be `Unit` by default, - /// for closures it should contain a `Tuple` type with the captured - /// variable types. - Function(Vec, Box, Box), - - /// &mut T - MutableReference(Box), - - /// A type generic over the given type variables. - /// Storing both the TypeVariableId and TypeVariable isn't necessary - /// but it makes handling them both easier. The TypeVariableId should - /// never be bound over during type checking, but during monomorphization it - /// will be and thus needs the full TypeVariable link. - Forall(Generics, Box), - - /// A type-level integer. Included to let an Array's size type variable - /// bind to an integer without special checks to bind it to a non-type. - Constant(u64), - - /// The type of a slice is an array of size NotConstant. - /// The size of an array literal is resolved to this if it ever uses operations - /// involving slices. - NotConstant, - - /// The result of some type error. Remembering type errors as their own type variant lets - /// us avoid issuing repeat type errors for the same item. For example, a lambda with - /// an invalid type would otherwise issue a new error each time it is called - /// if not for this variant. - Error, -} - -/// A list of TypeVariableIds to bind to a type. Storing the -/// TypeVariable in addition to the matching TypeVariableId allows -/// the binding to later be undone if needed. -pub type TypeBindings = HashMap; - -/// Represents a struct type in the type system. Each instance of this -/// rust struct will be shared across all Type::Struct variants that represent -/// the same struct type. -#[derive(Debug, Eq)] -pub struct StructType { - /// A unique id representing this struct type. Used to check if two - /// struct types are equal. - pub id: StructId, - - pub name: Ident, - - /// Fields are ordered and private, they should only - /// be accessed through get_field(), get_fields(), or instantiate() - /// since these will handle applying generic arguments to fields as well. - fields: Vec<(Ident, Type)>, - - pub generics: Generics, - pub span: Span, -} - -#[derive(Debug, PartialEq, Eq)] -pub enum TraitItemType { - /// A function declaration in a trait. - Function { - name: Ident, - generics: Generics, - arguments: Vec, - return_type: Type, - span: Span, - }, - - /// A constant declaration in a trait. - Constant { name: Ident, ty: Type, span: Span }, - - /// A type declaration in a trait. - Type { name: Ident, ty: Type, span: Span }, -} -/// Represents a trait type in the type system. Each instance of this -/// rust struct will be shared across all Type::Trait variants that represent -/// the same trait type. -#[derive(Debug, Eq)] -pub struct Trait { - /// A unique id representing this trait type. Used to check if two - /// struct traits are equal. - pub id: TraitId, - - pub items: Vec, - - pub name: Ident, - pub generics: Generics, - pub span: Span, -} - -/// Corresponds to generic lists such as `` in the source -/// program. The `TypeVariableId` portion is used to match two -/// type variables to check for equality, while the `TypeVariable` is -/// the actual part that can be mutated to bind it to another type. -pub type Generics = Vec<(TypeVariableId, TypeVariable)>; - -impl std::hash::Hash for StructType { - fn hash(&self, state: &mut H) { - self.id.hash(state); - } -} - -impl PartialEq for StructType { - fn eq(&self, other: &Self) -> bool { - self.id == other.id - } -} - -impl std::hash::Hash for Trait { - fn hash(&self, state: &mut H) { - self.id.hash(state); - } -} - -impl PartialEq for Trait { - fn eq(&self, other: &Self) -> bool { - self.id == other.id - } -} - -impl Trait { - pub fn new( - id: TraitId, - name: Ident, - span: Span, - items: Vec, - generics: Generics, - ) -> Trait { - Trait { id, name, span, items, generics } - } -} - -impl std::fmt::Display for Trait { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.name) - } -} - -impl StructType { - pub fn new( - id: StructId, - name: Ident, - span: Span, - fields: Vec<(Ident, Type)>, - generics: Generics, - ) -> StructType { - StructType { id, fields, name, span, generics } - } - - /// To account for cyclic references between structs, a struct's - /// fields are resolved strictly after the struct itself is initially - /// created. Therefore, this method is used to set the fields once they - /// become known. - pub fn set_fields(&mut self, fields: Vec<(Ident, Type)>) { - assert!(self.fields.is_empty()); - self.fields = fields; - } - - pub fn num_fields(&self) -> usize { - self.fields.len() - } - - /// Returns the field matching the given field name, as well as its field index. - pub fn get_field(&self, field_name: &str, generic_args: &[Type]) -> Option<(Type, usize)> { - assert_eq!(self.generics.len(), generic_args.len()); - - self.fields.iter().enumerate().find(|(_, (name, _))| name.0.contents == field_name).map( - |(i, (_, typ))| { - let substitutions = self - .generics - .iter() - .zip(generic_args) - .map(|((old_id, old_var), new)| (*old_id, (old_var.clone(), new.clone()))) - .collect(); - - (typ.substitute(&substitutions), i) - }, - ) - } - - /// Returns all the fields of this type, after being applied to the given generic arguments. - pub fn get_fields(&self, generic_args: &[Type]) -> Vec<(String, Type)> { - assert_eq!(self.generics.len(), generic_args.len()); - - let substitutions = self - .generics - .iter() - .zip(generic_args) - .map(|((old_id, old_var), new)| (*old_id, (old_var.clone(), new.clone()))) - .collect(); - - vecmap(&self.fields, |(name, typ)| { - let name = name.0.contents.clone(); - (name, typ.substitute(&substitutions)) - }) - } - - pub fn field_names(&self) -> BTreeSet { - self.fields.iter().map(|(name, _)| name.clone()).collect() - } - - /// True if the given index is the same index as a generic type of this struct - /// which is expected to be a numeric generic. - /// This is needed because we infer type kinds in Noir and don't have extensive kind checking. - pub fn generic_is_numeric(&self, index_of_generic: usize) -> bool { - let target_id = self.generics[index_of_generic].0; - self.fields.iter().any(|(_, field)| field.contains_numeric_typevar(target_id)) - } - - /// Instantiate this struct type, returning a Vec of the new generic args (in - /// the same order as self.generics) - pub fn instantiate(&self, interner: &mut NodeInterner) -> Vec { - vecmap(&self.generics, |_| interner.next_type_variable()) - } -} - -impl std::fmt::Display for StructType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.name) - } -} - -/// Wrap around an unsolved type -#[derive(Debug, Clone, Eq)] -pub struct TypeAliasType { - pub name: Ident, - pub id: TypeAliasId, - pub typ: Type, - pub generics: Generics, - pub span: Span, -} - -impl std::hash::Hash for TypeAliasType { - fn hash(&self, state: &mut H) { - self.id.hash(state); - } -} - -impl PartialEq for TypeAliasType { - fn eq(&self, other: &Self) -> bool { - self.id == other.id - } -} - -impl std::fmt::Display for TypeAliasType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.name)?; - - if !self.generics.is_empty() { - let generics = vecmap(&self.generics, |(_, binding)| binding.borrow().to_string()); - write!(f, "{}", generics.join(", "))?; - } - - Ok(()) - } -} - -impl TypeAliasType { - pub fn new( - id: TypeAliasId, - name: Ident, - span: Span, - typ: Type, - generics: Generics, - ) -> TypeAliasType { - TypeAliasType { id, typ, name, span, generics } - } - - pub fn set_type_and_generics(&mut self, new_typ: Type, new_generics: Generics) { - assert_eq!(self.typ, Type::Error); - self.typ = new_typ; - self.generics = new_generics; - } - - pub fn get_type(&self, generic_args: &[Type]) -> Type { - assert_eq!(self.generics.len(), generic_args.len()); - - let substitutions = self - .generics - .iter() - .zip(generic_args) - .map(|((old_id, old_var), new)| (*old_id, (old_var.clone(), new.clone()))) - .collect(); - - self.typ.substitute(&substitutions) - } -} - -/// A shared, mutable reference to some T. -/// Wrapper is required for Hash impl of RefCell. -#[derive(Debug, Eq, PartialOrd, Ord)] -pub struct Shared(Rc>); - -impl std::hash::Hash for Shared { - fn hash(&self, state: &mut H) { - self.0.borrow().hash(state); - } -} - -impl PartialEq for Shared { - fn eq(&self, other: &Self) -> bool { - let ref1 = self.0.borrow(); - let ref2 = other.0.borrow(); - *ref1 == *ref2 - } -} - -impl Clone for Shared { - fn clone(&self) -> Self { - Shared(self.0.clone()) - } -} - -impl From for Shared { - fn from(thing: T) -> Shared { - Shared::new(thing) - } -} - -impl Shared { - pub fn new(thing: T) -> Shared { - Shared(Rc::new(RefCell::new(thing))) - } - - pub fn borrow(&self) -> std::cell::Ref { - self.0.borrow() - } - - pub fn borrow_mut(&self) -> std::cell::RefMut { - self.0.borrow_mut() - } -} - -/// A restricted subset of binary operators useable on -/// type level integers for use in the array length positions of types. -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum BinaryTypeOperator { - Addition, - Subtraction, - Multiplication, - Division, - Modulo, -} - -#[derive(Debug, PartialEq, Eq, Clone, Hash)] -pub enum TypeVariableKind { - /// Can bind to any type - Normal, - - /// A generic integer or field type. This is a more specific kind of TypeVariable - /// that can only be bound to Type::Field, Type::Integer, or other polymorphic integers. - /// This is the type of undecorated integer literals like `46`. Typing them in this way - /// allows them to be polymorphic over the actual integer/field type used without requiring - /// type annotations on each integer literal. - IntegerOrField, - - /// A potentially constant array size. This will only bind to itself, Type::NotConstant, or - /// Type::Constant(n) with a matching size. This defaults to Type::Constant(n) if still unbound - /// during monomorphization. - Constant(u64), -} - -/// A TypeVariable is a mutable reference that is either -/// bound to some type, or unbound with a given TypeVariableId. -pub type TypeVariable = Shared; - -/// TypeBindings are the mutable insides of a TypeVariable. -/// They are either bound to some type, or are unbound. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TypeBinding { - Bound(Type), - Unbound(TypeVariableId), -} - -impl TypeBinding { - pub fn is_unbound(&self) -> bool { - matches!(self, TypeBinding::Unbound(_)) - } - - pub fn bind_to(&mut self, binding: Type, span: Span) -> Result<(), TypeCheckError> { - match self { - TypeBinding::Bound(_) => panic!("Tried to bind an already bound type variable!"), - TypeBinding::Unbound(id) => { - if binding.occurs(*id) { - Err(TypeCheckError::TypeAnnotationsNeeded { span }) - } else { - *self = TypeBinding::Bound(binding); - Ok(()) - } - } - } - } -} - -/// A unique ID used to differentiate different type variables -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct TypeVariableId(pub usize); - -impl Type { - pub fn default_int_type() -> Type { - Type::FieldElement - } - - pub fn type_variable(id: TypeVariableId) -> Type { - Type::TypeVariable(Shared::new(TypeBinding::Unbound(id)), TypeVariableKind::Normal) - } - - /// Returns a TypeVariable(_, TypeVariableKind::Constant(length)) to bind to - /// a constant integer for e.g. an array length. - pub fn constant_variable(length: u64, interner: &mut NodeInterner) -> Type { - let id = interner.next_type_variable_id(); - let kind = TypeVariableKind::Constant(length); - Type::TypeVariable(Shared::new(TypeBinding::Unbound(id)), kind) - } - - pub fn polymorphic_integer(interner: &mut NodeInterner) -> Type { - let id = interner.next_type_variable_id(); - let kind = TypeVariableKind::IntegerOrField; - Type::TypeVariable(Shared::new(TypeBinding::Unbound(id)), kind) - } - - /// A bit of an awkward name for this function - this function returns - /// true for type variables or polymorphic integers which are unbound. - /// NamedGenerics will always be false as although they are bindable, - /// they shouldn't be bound over until monomorphization. - pub fn is_bindable(&self) -> bool { - match self { - Type::TypeVariable(binding, _) => match &*binding.borrow() { - TypeBinding::Bound(binding) => binding.is_bindable(), - TypeBinding::Unbound(_) => true, - }, - _ => false, - } - } - - pub fn is_field(&self) -> bool { - matches!(self.follow_bindings(), Type::FieldElement) - } - - pub fn is_signed(&self) -> bool { - matches!(self.follow_bindings(), Type::Integer(Signedness::Signed, _)) - } - - pub fn is_unsigned(&self) -> bool { - matches!(self.follow_bindings(), Type::Integer(Signedness::Unsigned, _)) - } - - fn contains_numeric_typevar(&self, target_id: TypeVariableId) -> bool { - // True if the given type is a NamedGeneric with the target_id - let named_generic_id_matches_target = |typ: &Type| { - if let Type::NamedGeneric(type_variable, _) = typ { - match &*type_variable.borrow() { - TypeBinding::Bound(_) => { - unreachable!("Named generics should not be bound until monomorphization") - } - TypeBinding::Unbound(id) => target_id == *id, - } - } else { - false - } - }; - - match self { - Type::FieldElement - | Type::Integer(_, _) - | Type::Bool - | Type::Unit - | Type::Error - | Type::TypeVariable(_, _) - | Type::Constant(_) - | Type::NamedGeneric(_, _) - | Type::NotConstant - | Type::Forall(_, _) => false, - - Type::Array(length, elem) => { - elem.contains_numeric_typevar(target_id) || named_generic_id_matches_target(length) - } - - Type::Tuple(fields) => { - fields.iter().any(|field| field.contains_numeric_typevar(target_id)) - } - Type::Function(parameters, return_type, env) => { - parameters.iter().any(|parameter| parameter.contains_numeric_typevar(target_id)) - || return_type.contains_numeric_typevar(target_id) - || env.contains_numeric_typevar(target_id) - } - Type::Struct(struct_type, generics) => { - generics.iter().enumerate().any(|(i, generic)| { - if named_generic_id_matches_target(generic) { - struct_type.borrow().generic_is_numeric(i) - } else { - generic.contains_numeric_typevar(target_id) - } - }) - } - Type::MutableReference(element) => element.contains_numeric_typevar(target_id), - Type::String(length) => named_generic_id_matches_target(length), - Type::FmtString(length, elements) => { - elements.contains_numeric_typevar(target_id) - || named_generic_id_matches_target(length) - } - } - } -} - -impl std::fmt::Display for Type { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Type::FieldElement => { - write!(f, "Field") - } - Type::Array(len, typ) => { - if matches!(len.follow_bindings(), Type::NotConstant) { - write!(f, "[{typ}]") - } else { - write!(f, "[{typ}; {len}]") - } - } - Type::Integer(sign, num_bits) => match sign { - Signedness::Signed => write!(f, "i{num_bits}"), - Signedness::Unsigned => write!(f, "u{num_bits}"), - }, - Type::TypeVariable(id, TypeVariableKind::Normal) => write!(f, "{}", id.borrow()), - Type::TypeVariable(binding, TypeVariableKind::IntegerOrField) => { - if let TypeBinding::Unbound(_) = &*binding.borrow() { - // Show a Field by default if this TypeVariableKind::IntegerOrField is unbound, since that is - // what they bind to by default anyway. It is less confusing than displaying it - // as a generic. - write!(f, "Field") - } else { - write!(f, "{}", binding.borrow()) - } - } - Type::TypeVariable(binding, TypeVariableKind::Constant(n)) => { - if let TypeBinding::Unbound(_) = &*binding.borrow() { - // TypeVariableKind::Constant(n) binds to Type::Constant(n) by default, so just show that. - write!(f, "{n}") - } else { - write!(f, "{}", binding.borrow()) - } - } - Type::Struct(s, args) => { - let args = vecmap(args, |arg| arg.to_string()); - if args.is_empty() { - write!(f, "{}", s.borrow()) - } else { - write!(f, "{}<{}>", s.borrow(), args.join(", ")) - } - } - Type::Tuple(elements) => { - let elements = vecmap(elements, ToString::to_string); - write!(f, "({})", elements.join(", ")) - } - Type::Bool => write!(f, "bool"), - Type::String(len) => write!(f, "str<{len}>"), - Type::FmtString(len, elements) => { - write!(f, "fmtstr<{len}, {elements}>") - } - Type::Unit => write!(f, "()"), - Type::Error => write!(f, "error"), - Type::NamedGeneric(binding, name) => match &*binding.borrow() { - TypeBinding::Bound(binding) => binding.fmt(f), - TypeBinding::Unbound(_) if name.is_empty() => write!(f, "_"), - TypeBinding::Unbound(_) => write!(f, "{name}"), - }, - Type::Constant(x) => x.fmt(f), - Type::Forall(typevars, typ) => { - let typevars = vecmap(typevars, |(var, _)| var.to_string()); - write!(f, "forall {}. {}", typevars.join(" "), typ) - } - Type::Function(args, ret, env) => { - let closure_env_text = match **env { - Type::Unit => "".to_string(), - _ => format!(" with closure environment {env}"), - }; - - let args = vecmap(args.iter(), ToString::to_string); - - write!(f, "fn({}) -> {ret}{closure_env_text}", args.join(", ")) - } - Type::MutableReference(element) => { - write!(f, "&mut {element}") - } - Type::NotConstant => write!(f, "_"), - } - } -} - -impl std::fmt::Display for BinaryTypeOperator { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - BinaryTypeOperator::Addition => write!(f, "+"), - BinaryTypeOperator::Subtraction => write!(f, "-"), - BinaryTypeOperator::Multiplication => write!(f, "*"), - BinaryTypeOperator::Division => write!(f, "/"), - BinaryTypeOperator::Modulo => write!(f, "%"), - } - } -} - -impl std::fmt::Display for TypeVariableId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "_") - } -} - -impl std::fmt::Display for TypeBinding { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TypeBinding::Bound(typ) => typ.fmt(f), - TypeBinding::Unbound(id) => id.fmt(f), - } - } -} - -pub struct UnificationError; - -impl Type { - /// Try to bind a MaybeConstant variable to self, succeeding if self is a Constant, - /// MaybeConstant, or type variable. - pub fn try_bind_to_maybe_constant( - &self, - var: &TypeVariable, - target_length: u64, - ) -> Result<(), UnificationError> { - let target_id = match &*var.borrow() { - TypeBinding::Bound(_) => unreachable!(), - TypeBinding::Unbound(id) => *id, - }; - - match self { - Type::Constant(length) if *length == target_length => { - *var.borrow_mut() = TypeBinding::Bound(self.clone()); - Ok(()) - } - Type::NotConstant => { - *var.borrow_mut() = TypeBinding::Bound(Type::NotConstant); - Ok(()) - } - Type::TypeVariable(binding, kind) => { - let borrow = binding.borrow(); - match &*borrow { - TypeBinding::Bound(typ) => typ.try_bind_to_maybe_constant(var, target_length), - // Avoid infinitely recursive bindings - TypeBinding::Unbound(id) if *id == target_id => Ok(()), - TypeBinding::Unbound(_) => match kind { - TypeVariableKind::Normal => { - drop(borrow); - let clone = Type::TypeVariable( - var.clone(), - TypeVariableKind::Constant(target_length), - ); - *binding.borrow_mut() = TypeBinding::Bound(clone); - Ok(()) - } - TypeVariableKind::Constant(length) if *length == target_length => { - drop(borrow); - let clone = Type::TypeVariable( - var.clone(), - TypeVariableKind::Constant(target_length), - ); - *binding.borrow_mut() = TypeBinding::Bound(clone); - Ok(()) - } - TypeVariableKind::Constant(_) | TypeVariableKind::IntegerOrField => { - Err(UnificationError) - } - }, - } - } - _ => Err(UnificationError), - } - } - - /// Try to bind a PolymorphicInt variable to self, succeeding if self is an integer, field, - /// other PolymorphicInt type, or type variable. - pub fn try_bind_to_polymorphic_int(&self, var: &TypeVariable) -> Result<(), UnificationError> { - let target_id = match &*var.borrow() { - TypeBinding::Bound(_) => unreachable!(), - TypeBinding::Unbound(id) => *id, - }; - - match self { - Type::FieldElement | Type::Integer(..) => { - *var.borrow_mut() = TypeBinding::Bound(self.clone()); - Ok(()) - } - Type::TypeVariable(self_var, TypeVariableKind::IntegerOrField) => { - let borrow = self_var.borrow(); - match &*borrow { - TypeBinding::Bound(typ) => typ.try_bind_to_polymorphic_int(var), - // Avoid infinitely recursive bindings - TypeBinding::Unbound(id) if *id == target_id => Ok(()), - TypeBinding::Unbound(_) => { - drop(borrow); - *var.borrow_mut() = TypeBinding::Bound(self.clone()); - Ok(()) - } - } - } - Type::TypeVariable(binding, TypeVariableKind::Normal) => { - let borrow = binding.borrow(); - match &*borrow { - TypeBinding::Bound(typ) => typ.try_bind_to_polymorphic_int(var), - // Avoid infinitely recursive bindings - TypeBinding::Unbound(id) if *id == target_id => Ok(()), - TypeBinding::Unbound(_) => { - drop(borrow); - // PolymorphicInt is more specific than TypeVariable so we bind the type - // variable to PolymorphicInt instead. - let clone = - Type::TypeVariable(var.clone(), TypeVariableKind::IntegerOrField); - *binding.borrow_mut() = TypeBinding::Bound(clone); - Ok(()) - } - } - } - _ => Err(UnificationError), - } - } - - pub fn try_bind_to(&self, var: &TypeVariable) -> Result<(), UnificationError> { - let target_id = match &*var.borrow() { - TypeBinding::Bound(_) => unreachable!(), - TypeBinding::Unbound(id) => *id, - }; - - if let Some(binding) = self.get_inner_type_variable() { - match &*binding.borrow() { - TypeBinding::Bound(typ) => return typ.try_bind_to(var), - // Don't recursively bind the same id to itself - TypeBinding::Unbound(id) if *id == target_id => return Ok(()), - _ => (), - } - } - - // Check if the target id occurs within self before binding. Otherwise this could - // cause infinitely recursive types - if self.occurs(target_id) { - Err(UnificationError) - } else { - *var.borrow_mut() = TypeBinding::Bound(self.clone()); - Ok(()) - } - } - - fn get_inner_type_variable(&self) -> Option> { - match self { - Type::TypeVariable(var, _) | Type::NamedGeneric(var, _) => Some(var.clone()), - _ => None, - } - } - - /// Try to unify this type with another, setting any type variables found - /// equal to the other type in the process. Unification is more strict - /// than sub-typing but less strict than Eq. Returns true if the unification - /// succeeded. Note that any bindings performed in a failed unification are - /// not undone. This may cause further type errors later on. - pub fn unify( - &self, - expected: &Type, - errors: &mut Vec, - make_error: impl FnOnce() -> TypeCheckError, - ) { - if let Err(UnificationError) = self.try_unify(expected) { - errors.push(make_error()); - } - } - - /// `try_unify` is a bit of a misnomer since although errors are not committed, - /// any unified bindings are on success. - fn try_unify(&self, other: &Type) -> Result<(), UnificationError> { - use Type::*; - use TypeVariableKind as Kind; - - match (self, other) { - (Error, _) | (_, Error) => Ok(()), - - (TypeVariable(binding, Kind::IntegerOrField), other) - | (other, TypeVariable(binding, Kind::IntegerOrField)) => { - // If it is already bound, unify against what it is bound to - if let TypeBinding::Bound(link) = &*binding.borrow() { - return link.try_unify(other); - } - - // Otherwise, check it is unified against an integer and bind it - other.try_bind_to_polymorphic_int(binding) - } - - (TypeVariable(binding, Kind::Normal), other) - | (other, TypeVariable(binding, Kind::Normal)) => { - if let TypeBinding::Bound(link) = &*binding.borrow() { - return link.try_unify(other); - } - - other.try_bind_to(binding) - } - - (TypeVariable(binding, Kind::Constant(length)), other) - | (other, TypeVariable(binding, Kind::Constant(length))) => { - if let TypeBinding::Bound(link) = &*binding.borrow() { - return link.try_unify(other); - } - - other.try_bind_to_maybe_constant(binding, *length) - } - - (Array(len_a, elem_a), Array(len_b, elem_b)) => { - len_a.try_unify(len_b)?; - elem_a.try_unify(elem_b) - } - - (String(len_a), String(len_b)) => len_a.try_unify(len_b), - - (FmtString(len_a, elements_a), FmtString(len_b, elements_b)) => { - len_a.try_unify(len_b)?; - elements_a.try_unify(elements_b) - } - - (Tuple(elements_a), Tuple(elements_b)) => { - if elements_a.len() != elements_b.len() { - Err(UnificationError) - } else { - for (a, b) in elements_a.iter().zip(elements_b) { - a.try_unify(b)?; - } - Ok(()) - } - } - - // No recursive try_unify call for struct fields. Don't want - // to mutate shared type variables within struct definitions. - // This isn't possible currently but will be once noir gets generic types - (Struct(fields_a, args_a), Struct(fields_b, args_b)) => { - if fields_a == fields_b { - for (a, b) in args_a.iter().zip(args_b) { - a.try_unify(b)?; - } - Ok(()) - } else { - Err(UnificationError) - } - } - - (NamedGeneric(binding_a, name_a), NamedGeneric(binding_b, name_b)) => { - // Ensure NamedGenerics are never bound during type checking - assert!(binding_a.borrow().is_unbound()); - assert!(binding_b.borrow().is_unbound()); - - if name_a == name_b { - Ok(()) - } else { - Err(UnificationError) - } - } - - (Function(params_a, ret_a, env_a), Function(params_b, ret_b, env_b)) => { - if params_a.len() == params_b.len() { - for (a, b) in params_a.iter().zip(params_b.iter()) { - a.try_unify(b)?; - } - - env_a.try_unify(env_b)?; - ret_b.try_unify(ret_a) - } else { - Err(UnificationError) - } - } - - (MutableReference(elem_a), MutableReference(elem_b)) => elem_a.try_unify(elem_b), - - (other_a, other_b) => { - if other_a == other_b { - Ok(()) - } else { - Err(UnificationError) - } - } - } - } - - /// Similar to `unify` but if the check fails this will attempt to coerce the - /// argument to the target type. When this happens, the given expression is wrapped in - /// a new expression to convert its type. E.g. `array` -> `array.as_slice()` - /// - /// Currently the only type coercion in Noir is `[T; N]` into `[T]` via `.as_slice()`. - pub fn unify_with_coercions( - &self, - expected: &Type, - expression: ExprId, - interner: &mut NodeInterner, - errors: &mut Vec, - make_error: impl FnOnce() -> TypeCheckError, - ) { - if let Err(UnificationError) = self.try_unify(expected) { - if !self.try_array_to_slice_coercion(expected, expression, interner) { - errors.push(make_error()); - } - } - } - - /// Try to apply the array to slice coercion to this given type pair and expression. - /// If self can be converted to target this way, do so and return true to indicate success. - fn try_array_to_slice_coercion( - &self, - target: &Type, - expression: ExprId, - interner: &mut NodeInterner, - ) -> bool { - let this = self.follow_bindings(); - let target = target.follow_bindings(); - - if let (Type::Array(size1, element1), Type::Array(size2, element2)) = (&this, &target) { - let size1 = size1.follow_bindings(); - let size2 = size2.follow_bindings(); - - // If we have an array and our target is a slice - if matches!(size1, Type::Constant(_)) && matches!(size2, Type::NotConstant) { - // Still have to ensure the element types match. - // Don't need to issue an error here if not, it will be done in unify_with_coercions - if element1.try_unify(element2).is_ok() { - convert_array_expression_to_slice(expression, this, target, interner); - return true; - } - } - } - false - } - - /// If this type is a Type::Constant (used in array lengths), or is bound - /// to a Type::Constant, return the constant as a u64. - pub fn evaluate_to_u64(&self) -> Option { - if let Some(binding) = self.get_inner_type_variable() { - if let TypeBinding::Bound(binding) = &*binding.borrow() { - return binding.evaluate_to_u64(); - } - } - - match self { - Type::TypeVariable(_, TypeVariableKind::Constant(size)) => Some(*size), - Type::Array(len, _elem) => len.evaluate_to_u64(), - Type::Constant(x) => Some(*x), - _ => None, - } - } - - /// Iterate over the fields of this type. - /// Panics if the type is not a struct or tuple. - pub fn iter_fields(&self) -> impl Iterator { - let fields: Vec<_> = match self { - // Unfortunately the .borrow() here forces us to collect into a Vec - // only to have to call .into_iter again afterward. Trying to elide - // collecting to a Vec leads to us dropping the temporary Ref before - // the iterator is returned - Type::Struct(def, args) => vecmap(&def.borrow().fields, |(name, _)| { - let name = &name.0.contents; - let typ = def.borrow().get_field(name, args).unwrap().0; - (name.clone(), typ) - }), - Type::Tuple(fields) => { - let fields = fields.iter().enumerate(); - vecmap(fields, |(i, field)| (i.to_string(), field.clone())) - } - other => panic!("Tried to iterate over the fields of '{other}', which has none"), - }; - fields.into_iter() - } - - /// Retrieves the type of the given field name - /// Panics if the type is not a struct or tuple. - pub fn get_field_type(&self, field_name: &str) -> Type { - match self { - Type::Struct(def, args) => def.borrow().get_field(field_name, args).unwrap().0, - Type::Tuple(fields) => { - let mut fields = fields.iter().enumerate(); - fields.find(|(i, _)| i.to_string() == *field_name).unwrap().1.clone() - } - other => panic!("Tried to iterate over the fields of '{other}', which has none"), - } - } - - /// Instantiate this type, replacing any type variables it is quantified - /// over with fresh type variables. If this type is not a Type::Forall, - /// it is unchanged. - pub fn instantiate(&self, interner: &mut NodeInterner) -> (Type, TypeBindings) { - match self { - Type::Forall(typevars, typ) => { - let replacements = typevars - .iter() - .map(|(id, var)| { - let new = interner.next_type_variable(); - (*id, (var.clone(), new)) - }) - .collect(); - - let instantiated = typ.substitute(&replacements); - (instantiated, replacements) - } - other => (other.clone(), HashMap::new()), - } - } - - /// Substitute any type variables found within this type with the - /// given bindings if found. If a type variable is not found within - /// the given TypeBindings, it is unchanged. - pub fn substitute(&self, type_bindings: &TypeBindings) -> Type { - if type_bindings.is_empty() { - return self.clone(); - } - - let substitute_binding = |binding: &TypeVariable| match &*binding.borrow() { - TypeBinding::Bound(binding) => binding.substitute(type_bindings), - TypeBinding::Unbound(id) => match type_bindings.get(id) { - Some((_, binding)) => binding.clone(), - None => self.clone(), - }, - }; - - match self { - Type::Array(size, element) => { - let size = Box::new(size.substitute(type_bindings)); - let element = Box::new(element.substitute(type_bindings)); - Type::Array(size, element) - } - Type::String(size) => { - let size = Box::new(size.substitute(type_bindings)); - Type::String(size) - } - Type::FmtString(size, fields) => { - let size = Box::new(size.substitute(type_bindings)); - let fields = Box::new(fields.substitute(type_bindings)); - Type::FmtString(size, fields) - } - Type::NamedGeneric(binding, _) | Type::TypeVariable(binding, _) => { - substitute_binding(binding) - } - // Do not substitute fields, it can lead to infinite recursion - // and we should not match fields when type checking anyway. - Type::Struct(fields, args) => { - let args = vecmap(args, |arg| arg.substitute(type_bindings)); - Type::Struct(fields.clone(), args) - } - Type::Tuple(fields) => { - let fields = vecmap(fields, |field| field.substitute(type_bindings)); - Type::Tuple(fields) - } - Type::Forall(typevars, typ) => { - // Trying to substitute a variable defined within a nested Forall - // is usually impossible and indicative of an error in the type checker somewhere. - for (var, _) in typevars { - assert!(!type_bindings.contains_key(var)); - } - let typ = Box::new(typ.substitute(type_bindings)); - Type::Forall(typevars.clone(), typ) - } - Type::Function(args, ret, env) => { - let args = vecmap(args, |arg| arg.substitute(type_bindings)); - let ret = Box::new(ret.substitute(type_bindings)); - let env = Box::new(env.substitute(type_bindings)); - Type::Function(args, ret, env) - } - Type::MutableReference(element) => { - Type::MutableReference(Box::new(element.substitute(type_bindings))) - } - - Type::FieldElement - | Type::Integer(_, _) - | Type::Bool - | Type::Constant(_) - | Type::Error - | Type::NotConstant - | Type::Unit => self.clone(), - } - } - - /// True if the given TypeVariableId is free anywhere within self - fn occurs(&self, target_id: TypeVariableId) -> bool { - match self { - Type::Array(len, elem) => len.occurs(target_id) || elem.occurs(target_id), - Type::String(len) => len.occurs(target_id), - Type::FmtString(len, fields) => { - let len_occurs = len.occurs(target_id); - let field_occurs = fields.occurs(target_id); - len_occurs || field_occurs - } - Type::Struct(_, generic_args) => generic_args.iter().any(|arg| arg.occurs(target_id)), - Type::Tuple(fields) => fields.iter().any(|field| field.occurs(target_id)), - Type::NamedGeneric(binding, _) | Type::TypeVariable(binding, _) => { - match &*binding.borrow() { - TypeBinding::Bound(binding) => binding.occurs(target_id), - TypeBinding::Unbound(id) => *id == target_id, - } - } - Type::Forall(typevars, typ) => { - !typevars.iter().any(|(id, _)| *id == target_id) && typ.occurs(target_id) - } - Type::Function(args, ret, env) => { - args.iter().any(|arg| arg.occurs(target_id)) - || ret.occurs(target_id) - || env.occurs(target_id) - } - Type::MutableReference(element) => element.occurs(target_id), - - Type::FieldElement - | Type::Integer(_, _) - | Type::Bool - | Type::Constant(_) - | Type::Error - | Type::NotConstant - | Type::Unit => false, - } - } - - /// Follow any TypeVariable bindings within this type. Doing so ensures - /// that if the bindings are rebound or unbound from under the type then the - /// returned type will not change (because it will no longer contain the - /// links that may be unbound). - /// - /// Expected to be called on an instantiated type (with no Type::Foralls) - pub fn follow_bindings(&self) -> Type { - use Type::*; - match self { - Array(size, elem) => { - Array(Box::new(size.follow_bindings()), Box::new(elem.follow_bindings())) - } - String(size) => String(Box::new(size.follow_bindings())), - FmtString(size, args) => { - let size = Box::new(size.follow_bindings()); - let args = Box::new(args.follow_bindings()); - FmtString(size, args) - } - Struct(def, args) => { - let args = vecmap(args, |arg| arg.follow_bindings()); - Struct(def.clone(), args) - } - Tuple(args) => Tuple(vecmap(args, |arg| arg.follow_bindings())), - - TypeVariable(var, _) | NamedGeneric(var, _) => { - if let TypeBinding::Bound(typ) = &*var.borrow() { - return typ.follow_bindings(); - } - self.clone() - } - - Function(args, ret, env) => { - let args = vecmap(args, |arg| arg.follow_bindings()); - let ret = Box::new(ret.follow_bindings()); - let env = Box::new(env.follow_bindings()); - Function(args, ret, env) - } - - MutableReference(element) => MutableReference(Box::new(element.follow_bindings())), - - // Expect that this function should only be called on instantiated types - Forall(..) => unreachable!(), - - FieldElement | Integer(_, _) | Bool | Constant(_) | Unit | Error | NotConstant => { - self.clone() - } - } - } -} - -/// Wraps a given `expression` in `expression.as_slice()` -fn convert_array_expression_to_slice( - expression: ExprId, - array_type: Type, - target_type: Type, - interner: &mut NodeInterner, -) { - let as_slice_method = interner - .lookup_primitive_method(&array_type, "as_slice") - .expect("Expected 'as_slice' method to be present in Noir's stdlib"); - - let as_slice_id = interner.function_definition_id(as_slice_method); - let location = interner.expr_location(&expression); - let as_slice = HirExpression::Ident(HirIdent { location, id: as_slice_id }); - let func = interner.push_expr(as_slice); - - let arguments = vec![expression]; - let call = HirExpression::Call(HirCallExpression { func, arguments, location }); - let call = interner.push_expr(call); - - interner.push_expr_location(call, location.span, location.file); - interner.push_expr_location(func, location.span, location.file); - - interner.push_expr_type(&call, target_type.clone()); - interner.push_expr_type( - &func, - Type::Function(vec![array_type], Box::new(target_type), Box::new(Type::Unit)), - ); -} - -impl BinaryTypeOperator { - /// Return the actual rust numeric function associated with this operator - pub fn function(self) -> fn(u64, u64) -> u64 { - match self { - BinaryTypeOperator::Addition => |a, b| a.wrapping_add(b), - BinaryTypeOperator::Subtraction => |a, b| a.wrapping_sub(b), - BinaryTypeOperator::Multiplication => |a, b| a.wrapping_mul(b), - BinaryTypeOperator::Division => |a, b| a.wrapping_div(b), - BinaryTypeOperator::Modulo => |a, b| a.wrapping_rem(b), // % b, - } - } -} - -impl TypeVariableKind { - /// Returns the default type this type variable should be bound to if it is still unbound - /// during monomorphization. - pub(crate) fn default_type(&self) -> Type { - match self { - TypeVariableKind::IntegerOrField | TypeVariableKind::Normal => Type::default_int_type(), - TypeVariableKind::Constant(length) => Type::Constant(*length), - } - } -} - -impl From for PrintableType { - fn from(value: Type) -> Self { - Self::from(&value) - } -} - -impl From<&Type> for PrintableType { - fn from(value: &Type) -> Self { - // Note; use strict_eq instead of partial_eq when comparing field types - // in this method, you most likely want to distinguish between public and private - match value { - Type::FieldElement => PrintableType::Field, - Type::Array(size, typ) => { - let length = size.evaluate_to_u64().expect("Cannot print variable sized arrays"); - let typ = typ.as_ref(); - PrintableType::Array { length, typ: Box::new(typ.into()) } - } - Type::Integer(sign, bit_width) => match sign { - Signedness::Unsigned => PrintableType::UnsignedInteger { width: *bit_width }, - Signedness::Signed => PrintableType::SignedInteger { width: *bit_width }, - }, - Type::TypeVariable(binding, TypeVariableKind::IntegerOrField) => { - match &*binding.borrow() { - TypeBinding::Bound(typ) => typ.into(), - TypeBinding::Unbound(_) => Type::default_int_type().into(), - } - } - Type::Bool => PrintableType::Boolean, - Type::String(size) => { - let size = size.evaluate_to_u64().expect("Cannot print variable sized strings"); - PrintableType::String { length: size } - } - Type::FmtString(_, _) => unreachable!("format strings cannot be printed"), - Type::Error => unreachable!(), - Type::Unit => unreachable!(), - Type::Constant(_) => unreachable!(), - Type::Struct(def, ref args) => { - let struct_type = def.borrow(); - let fields = struct_type.get_fields(args); - let fields = vecmap(fields, |(name, typ)| (name, typ.into())); - PrintableType::Struct { fields, name: struct_type.name.to_string() } - } - Type::Tuple(_) => todo!("printing tuple types is not yet implemented"), - Type::TypeVariable(_, _) => unreachable!(), - Type::NamedGeneric(..) => unreachable!(), - Type::Forall(..) => unreachable!(), - Type::Function(_, _, _) => unreachable!(), - Type::MutableReference(_) => unreachable!("cannot print &mut"), - Type::NotConstant => unreachable!(), - } - } -} diff --git a/crates/noirc_frontend/src/lexer/errors.rs b/crates/noirc_frontend/src/lexer/errors.rs deleted file mode 100644 index 0b6440dec44..00000000000 --- a/crates/noirc_frontend/src/lexer/errors.rs +++ /dev/null @@ -1,100 +0,0 @@ -use crate::token::SpannedToken; - -use super::token::Token; -use noirc_errors::CustomDiagnostic as Diagnostic; -use noirc_errors::Span; -use thiserror::Error; - -#[derive(Error, Clone, Debug, PartialEq, Eq)] -pub enum LexerErrorKind { - #[error("An unexpected character {:?} was found.", found)] - UnexpectedCharacter { span: Span, expected: String, found: Option }, - #[error("NotADoubleChar : {:?} is not a double char token", found)] - NotADoubleChar { span: Span, found: Token }, - #[error("InvalidIntegerLiteral : {:?} is not a integer", found)] - InvalidIntegerLiteral { span: Span, found: String }, - #[error("MalformedFuncAttribute : {:?} is not a valid attribute", found)] - MalformedFuncAttribute { span: Span, found: String }, - #[error("TooManyBits")] - TooManyBits { span: Span, max: u32, got: u32 }, - #[error("LogicalAnd used instead of bitwise and")] - LogicalAnd { span: Span }, - #[error("Unterminated block comment")] - UnterminatedBlockComment { span: Span }, -} - -impl LexerErrorKind { - pub fn span(&self) -> Span { - match self { - LexerErrorKind::UnexpectedCharacter { span, .. } => *span, - LexerErrorKind::NotADoubleChar { span, .. } => *span, - LexerErrorKind::InvalidIntegerLiteral { span, .. } => *span, - LexerErrorKind::MalformedFuncAttribute { span, .. } => *span, - LexerErrorKind::TooManyBits { span, .. } => *span, - LexerErrorKind::LogicalAnd { span } => *span, - LexerErrorKind::UnterminatedBlockComment { span } => *span, - } - } - - fn parts(&self) -> (String, String, Span) { - match self { - LexerErrorKind::UnexpectedCharacter { - span, - expected, - found, - } => { - let found: String = found.map(Into::into).unwrap_or_else(|| "".into()); - - ( - "an unexpected character was found".to_string(), - format!(" expected {expected} , but got {}", found), - *span, - ) - }, - LexerErrorKind::NotADoubleChar { span, found } => ( - format!("tried to parse {found} as double char"), - format!( - " {found:?} is not a double char, this is an internal error" - ), - *span, - ), - LexerErrorKind::InvalidIntegerLiteral { span, found } => ( - "invalid integer literal".to_string(), - format!(" {found} is not an integer"), - *span, - ), - LexerErrorKind::MalformedFuncAttribute { span, found } => ( - "malformed function attribute".to_string(), - format!(" {found} is not a valid attribute"), - *span, - ), - LexerErrorKind::TooManyBits { span, max, got } => ( - "integer literal too large".to_string(), - format!( - "The maximum number of bits needed to represent a field is {max}, This integer type needs {got} bits" - ), - *span, - ), - LexerErrorKind::LogicalAnd { span } => ( - "Noir has no logical-and (&&) operator since short-circuiting is much less efficient when compiling to circuits".to_string(), - "Try `&` instead, or use `if` only if you require short-circuiting".to_string(), - *span, - ), - LexerErrorKind::UnterminatedBlockComment { span } => ("unterminated block comment".to_string(), "Unterminated block comment".to_string(), *span), - } - } -} - -impl From for Diagnostic { - fn from(error: LexerErrorKind) -> Diagnostic { - let (primary, secondary, span) = error.parts(); - Diagnostic::simple_error(primary, secondary, span) - } -} - -impl From for chumsky::error::Simple { - fn from(error: LexerErrorKind) -> Self { - let (_, message, span) = error.parts(); - chumsky::error::Simple::custom(span, message) - } -} diff --git a/crates/noirc_frontend/src/lexer/lexer.rs b/crates/noirc_frontend/src/lexer/lexer.rs deleted file mode 100644 index fc72f43674d..00000000000 --- a/crates/noirc_frontend/src/lexer/lexer.rs +++ /dev/null @@ -1,738 +0,0 @@ -use super::{ - errors::LexerErrorKind, - token::{Attribute, IntType, Keyword, SpannedToken, Token, Tokens}, -}; -use acvm::FieldElement; -use noirc_errors::{Position, Span}; -use std::str::Chars; -use std::{ - iter::{Peekable, Zip}, - ops::RangeFrom, -}; - -/// The job of the lexer is to transform an iterator of characters (`char_iter`) -/// into an iterator of `SpannedToken`. Each `Token` corresponds roughly to 1 word or operator. -/// Tokens are tagged with their location in the source file (a `Span`) for use in error reporting. -pub struct Lexer<'a> { - char_iter: Peekable, RangeFrom>>, - position: Position, - done: bool, -} - -pub type SpannedTokenResult = Result; - -impl<'a> Lexer<'a> { - /// Given a source file of noir code, return all the tokens in the file - /// in order, along with any lexing errors that occurred. - pub fn lex(source: &'a str) -> (Tokens, Vec) { - let lexer = Lexer::new(source); - let mut tokens = vec![]; - let mut errors = vec![]; - for result in lexer { - match result { - Ok(token) => tokens.push(token), - Err(error) => errors.push(error), - } - } - (Tokens(tokens), errors) - } - - fn new(source: &'a str) -> Self { - Lexer { - // We zip with the character index here to ensure the first char has index 0 - char_iter: source.chars().zip(0..).peekable(), - position: 0, - done: false, - } - } - - /// Iterates the cursor and returns the char at the new cursor position - fn next_char(&mut self) -> Option { - let (c, index) = self.char_iter.next()?; - self.position = index; - Some(c) - } - - /// Peeks at the next char. Does not iterate the cursor - fn peek_char(&mut self) -> Option { - self.char_iter.peek().map(|(c, _)| *c) - } - - /// Peeks at the next char and returns true if it is equal to the char argument - fn peek_char_is(&mut self, ch: char) -> bool { - self.peek_char() == Some(ch) - } - - fn ampersand(&mut self) -> SpannedTokenResult { - if self.peek_char_is('&') { - // When we issue this error the first '&' will already be consumed - // and the next token issued will be the next '&'. - let span = Span::new(self.position..self.position + 1); - Err(LexerErrorKind::LogicalAnd { span }) - } else { - self.single_char_token(Token::Ampersand) - } - } - - fn next_token(&mut self) -> SpannedTokenResult { - match self.next_char() { - Some(x) if { x.is_whitespace() } => { - self.eat_whitespace(); - self.next_token() - } - Some('<') => self.glue(Token::Less), - Some('>') => self.glue(Token::Greater), - Some('=') => self.glue(Token::Assign), - Some('/') => self.glue(Token::Slash), - Some('.') => self.glue(Token::Dot), - Some(':') => self.glue(Token::Colon), - Some('!') => self.glue(Token::Bang), - Some('-') => self.glue(Token::Minus), - Some('&') => self.ampersand(), - Some('|') => self.single_char_token(Token::Pipe), - Some('%') => self.single_char_token(Token::Percent), - Some('^') => self.single_char_token(Token::Caret), - Some(';') => self.single_char_token(Token::Semicolon), - Some('*') => self.single_char_token(Token::Star), - Some('(') => self.single_char_token(Token::LeftParen), - Some(')') => self.single_char_token(Token::RightParen), - Some(',') => self.single_char_token(Token::Comma), - Some('+') => self.single_char_token(Token::Plus), - Some('{') => self.single_char_token(Token::LeftBrace), - Some('}') => self.single_char_token(Token::RightBrace), - Some('[') => self.single_char_token(Token::LeftBracket), - Some(']') => self.single_char_token(Token::RightBracket), - Some('"') => Ok(self.eat_string_literal(false)), - Some('f') => self.eat_format_string_or_alpha_numeric(), - Some('#') => self.eat_attribute(), - Some(ch) if ch.is_ascii_alphanumeric() || ch == '_' => self.eat_alpha_numeric(ch), - Some(ch) => { - // We don't report invalid tokens in the source as errors until parsing to - // avoid reporting the error twice. See the note on Token::Invalid's documentation for details. - Ok(Token::Invalid(ch).into_single_span(self.position)) - } - None => { - self.done = true; - Ok(Token::EOF.into_single_span(self.position)) - } - } - } - - fn single_char_token(&self, token: Token) -> SpannedTokenResult { - Ok(token.into_single_span(self.position)) - } - - fn single_double_peek_token( - &mut self, - character: char, - single: Token, - double: Token, - ) -> SpannedTokenResult { - let start = self.position; - - match self.peek_char_is(character) { - false => Ok(single.into_single_span(start)), - true => { - self.next_char(); - Ok(double.into_span(start, start + 1)) - } - } - } - - /// Given that some tokens can contain two characters, such as <= , !=, >= - /// Glue will take the first character of the token and check if it can be glued onto the next character - /// forming a double token - fn glue(&mut self, prev_token: Token) -> SpannedTokenResult { - let spanned_prev_token = prev_token.clone().into_single_span(self.position); - match prev_token { - Token::Dot => self.single_double_peek_token('.', prev_token, Token::DoubleDot), - Token::Less => { - let start = self.position; - if self.peek_char_is('=') { - self.next_char(); - Ok(Token::LessEqual.into_span(start, start + 1)) - } else if self.peek_char_is('<') { - self.next_char(); - Ok(Token::ShiftLeft.into_span(start, start + 1)) - } else { - Ok(prev_token.into_single_span(start)) - } - } - Token::Greater => { - let start = self.position; - if self.peek_char_is('=') { - self.next_char(); - Ok(Token::GreaterEqual.into_span(start, start + 1)) - // Note: There is deliberately no case for RightShift. We always lex >> as - // two separate Greater tokens to help the parser parse nested generic types. - } else { - Ok(prev_token.into_single_span(start)) - } - } - Token::Bang => self.single_double_peek_token('=', prev_token, Token::NotEqual), - Token::Assign => self.single_double_peek_token('=', prev_token, Token::Equal), - Token::Minus => self.single_double_peek_token('>', prev_token, Token::Arrow), - Token::Colon => self.single_double_peek_token(':', prev_token, Token::DoubleColon), - Token::Slash => { - if self.peek_char_is('/') { - self.next_char(); - return self.parse_comment(); - } else if self.peek_char_is('*') { - self.next_char(); - return self.parse_block_comment(); - } - Ok(spanned_prev_token) - } - _ => Err(LexerErrorKind::NotADoubleChar { - span: Span::single_char(self.position), - found: prev_token, - }), - } - } - - /// Keeps consuming tokens as long as the predicate is satisfied - fn eat_while bool>( - &mut self, - initial_char: Option, - predicate: F, - ) -> (String, Position, Position) { - let start = self.position; - - // This function is only called when we want to continue consuming a character of the same type. - // For example, we see a digit and we want to consume the whole integer - // Therefore, the current character which triggered this function will need to be appended - let mut word = String::new(); - if let Some(init_char) = initial_char { - word.push(init_char); - } - - // Keep checking that we are not at the EOF - while let Some(peek_char) = self.peek_char() { - // Then check for the predicate, if predicate matches append char and increment the cursor - // If not, return word. The next character will be analyzed on the next iteration of next_token, - // Which will increment the cursor - if !predicate(peek_char) { - return (word, start, self.position); - } - word.push(peek_char); - - // If we arrive at this point, then the char has been added to the word and we should increment the cursor - self.next_char(); - } - - (word, start, self.position) - } - - fn eat_alpha_numeric(&mut self, initial_char: char) -> SpannedTokenResult { - match initial_char { - 'A'..='Z' | 'a'..='z' | '_' => Ok(self.eat_word(initial_char)?), - '0'..='9' => self.eat_digit(initial_char), - _ => Err(LexerErrorKind::UnexpectedCharacter { - span: Span::single_char(self.position), - found: initial_char.into(), - expected: "an alpha numeric character".to_owned(), - }), - } - } - - fn eat_attribute(&mut self) -> SpannedTokenResult { - if !self.peek_char_is('[') { - return Err(LexerErrorKind::UnexpectedCharacter { - span: Span::single_char(self.position), - found: self.next_char(), - expected: "[".to_owned(), - }); - } - self.next_char(); - - let (word, start, end) = self.eat_while(None, |ch| ch != ']'); - - if !self.peek_char_is(']') { - return Err(LexerErrorKind::UnexpectedCharacter { - span: Span::single_char(self.position), - expected: "]".to_owned(), - found: self.next_char(), - }); - } - self.next_char(); - - let attribute = Attribute::lookup_attribute(&word, Span::exclusive(start, end))?; - - // Move start position backwards to cover the left bracket - // Move end position forwards to cover the right bracket - Ok(attribute.into_span(start - 1, end + 1)) - } - - //XXX(low): Can increase performance if we use iterator semantic and utilize some of the methods on String. See below - // https://doc.rust-lang.org/stable/std/primitive.str.html#method.rsplit - fn eat_word(&mut self, initial_char: char) -> SpannedTokenResult { - let (word, start, end) = self.eat_while(Some(initial_char), |ch| { - ch.is_ascii_alphabetic() || ch.is_numeric() || ch == '_' - }); - - // Check if word either an identifier or a keyword - if let Some(keyword_token) = Keyword::lookup_keyword(&word) { - return Ok(keyword_token.into_span(start, end)); - } - - // Check if word an int type - // if no error occurred, then it is either a valid integer type or it is not an int type - let parsed_token = IntType::lookup_int_type(&word, Span::exclusive(start, end))?; - - // Check if it is an int type - if let Some(int_type_token) = parsed_token { - return Ok(int_type_token.into_span(start, end)); - } - - // Else it is just an identifier - let ident_token = Token::Ident(word); - Ok(ident_token.into_span(start, end)) - } - - fn eat_digit(&mut self, initial_char: char) -> SpannedTokenResult { - let (integer_str, start, end) = self.eat_while(Some(initial_char), |ch| { - ch.is_ascii_digit() | ch.is_ascii_hexdigit() | (ch == 'x') - }); - - let integer = match FieldElement::try_from_str(&integer_str) { - None => { - return Err(LexerErrorKind::InvalidIntegerLiteral { - span: Span::exclusive(start, end), - found: integer_str, - }) - } - Some(integer) => integer, - }; - - let integer_token = Token::Int(integer); - Ok(integer_token.into_span(start, end)) - } - - fn eat_string_literal(&mut self, is_format_string: bool) -> SpannedToken { - let (str_literal, start_span, end_span) = self.eat_while(None, |ch| ch != '"'); - let str_literal_token = - if is_format_string { Token::FmtStr(str_literal) } else { Token::Str(str_literal) }; - self.next_char(); // Advance past the closing quote - str_literal_token.into_span(start_span, end_span) - } - - fn eat_format_string_or_alpha_numeric(&mut self) -> SpannedTokenResult { - if self.peek_char_is('"') { - self.next_char(); - Ok(self.eat_string_literal(true)) - } else { - self.eat_alpha_numeric('f') - } - } - - fn parse_comment(&mut self) -> SpannedTokenResult { - let _ = self.eat_while(None, |ch| ch != '\n'); - self.next_token() - } - - fn parse_block_comment(&mut self) -> SpannedTokenResult { - let span = Span::new(self.position..self.position + 1); - let mut depth = 1usize; - - while let Some(ch) = self.next_char() { - match ch { - '/' if self.peek_char_is('*') => { - self.next_char(); - depth += 1; - } - '*' if self.peek_char_is('/') => { - self.next_char(); - depth -= 1; - - // This block comment is closed, so for a construction like "/* */ */" - // there will be a successfully parsed block comment "/* */" - // and " */" will be processed separately. - if depth == 0 { - break; - } - } - _ => {} - } - } - - if depth == 0 { - self.next_token() - } else { - Err(LexerErrorKind::UnterminatedBlockComment { span }) - } - } - - /// Skips white space. They are not significant in the source language - fn eat_whitespace(&mut self) { - self.eat_while(None, |ch| ch.is_whitespace()); - } -} - -impl<'a> Iterator for Lexer<'a> { - type Item = SpannedTokenResult; - fn next(&mut self) -> Option { - if self.done { - None - } else { - Some(self.next_token()) - } - } -} - -#[test] -fn test_single_double_char() { - let input = "! != + ( ) { } [ ] | , ; : :: < <= > >= & - -> . .. % / * = == << >>"; - - let expected = vec![ - Token::Bang, - Token::NotEqual, - Token::Plus, - Token::LeftParen, - Token::RightParen, - Token::LeftBrace, - Token::RightBrace, - Token::LeftBracket, - Token::RightBracket, - Token::Pipe, - Token::Comma, - Token::Semicolon, - Token::Colon, - Token::DoubleColon, - Token::Less, - Token::LessEqual, - Token::Greater, - Token::GreaterEqual, - Token::Ampersand, - Token::Minus, - Token::Arrow, - Token::Dot, - Token::DoubleDot, - Token::Percent, - Token::Slash, - Token::Star, - Token::Assign, - Token::Equal, - Token::ShiftLeft, - Token::Greater, - Token::Greater, - Token::EOF, - ]; - - let mut lexer = Lexer::new(input); - - for token in expected.into_iter() { - let got = lexer.next_token().unwrap(); - assert_eq!(got, token); - } -} - -#[test] -fn invalid_attribute() { - let input = "#"; - let mut lexer = Lexer::new(input); - - let token = lexer.next().unwrap(); - assert!(token.is_err()); -} - -#[test] -fn deprecated_attribute() { - let input = r#"#[deprecated]"#; - let mut lexer = Lexer::new(input); - - let token = lexer.next().unwrap().unwrap(); - assert_eq!(token.token(), &Token::Attribute(Attribute::Deprecated(None))); -} - -#[test] -fn deprecated_attribute_with_note() { - let input = r#"#[deprecated("hello")]"#; - let mut lexer = Lexer::new(input); - - let token = lexer.next().unwrap().unwrap(); - assert_eq!(token.token(), &Token::Attribute(Attribute::Deprecated("hello".to_string().into()))); -} - -#[test] -fn custom_attribute() { - let input = r#"#[custom(hello)]"#; - let mut lexer = Lexer::new(input); - - let token = lexer.next().unwrap().unwrap(); - assert_eq!(token.token(), &Token::Attribute(Attribute::Custom("custom(hello)".to_string()))); -} - -#[test] -fn test_custom_gate_syntax() { - let input = "#[foreign(sha256)]#[foreign(blake2s)]#[builtin(sum)]"; - - let expected = vec![ - Token::Attribute(Attribute::Foreign("sha256".to_string())), - Token::Attribute(Attribute::Foreign("blake2s".to_string())), - Token::Attribute(Attribute::Builtin("sum".to_string())), - ]; - - let mut lexer = Lexer::new(input); - for token in expected.into_iter() { - let got = lexer.next_token().unwrap(); - assert_eq!(got, token); - } -} - -#[test] -fn test_int_type() { - let input = "u16 i16 i108 u104.5"; - - let expected = vec![ - Token::IntType(IntType::Unsigned(16)), - Token::IntType(IntType::Signed(16)), - Token::IntType(IntType::Signed(108)), - Token::IntType(IntType::Unsigned(104)), - Token::Dot, - Token::Int(5_i128.into()), - ]; - - let mut lexer = Lexer::new(input); - for token in expected.into_iter() { - let got = lexer.next_token().unwrap(); - assert_eq!(got, token); - } -} - -#[test] -fn test_arithmetic_sugar() { - let input = "+= -= *= /= %="; - - let expected = vec![ - Token::Plus, - Token::Assign, - Token::Minus, - Token::Assign, - Token::Star, - Token::Assign, - Token::Slash, - Token::Assign, - Token::Percent, - Token::Assign, - ]; - - let mut lexer = Lexer::new(input); - for token in expected.into_iter() { - let got = lexer.next_token().unwrap(); - assert_eq!(got, token); - } -} - -#[test] -fn unterminated_block_comment() { - let input = "/*/"; - - let mut lexer = Lexer::new(input); - let token = lexer.next().unwrap(); - - assert!(token.is_err()); -} - -#[test] -fn test_comment() { - let input = "// hello - let x = 5 - "; - - let expected = vec![ - Token::Keyword(Keyword::Let), - Token::Ident("x".to_string()), - Token::Assign, - Token::Int(FieldElement::from(5_i128)), - ]; - - let mut lexer = Lexer::new(input); - for token in expected.into_iter() { - let first_lexer_output = lexer.next_token().unwrap(); - assert_eq!(first_lexer_output, token); - } -} - -#[test] -fn test_block_comment() { - let input = " - /* comment */ - let x = 5 - /* comment */ - "; - - let expected = vec![ - Token::Keyword(Keyword::Let), - Token::Ident("x".to_string()), - Token::Assign, - Token::Int(FieldElement::from(5_i128)), - ]; - - let mut lexer = Lexer::new(input); - for token in expected.into_iter() { - let first_lexer_output = lexer.next_token().unwrap(); - assert_eq!(first_lexer_output, token); - } -} - -#[test] -fn test_nested_block_comments() { - let input = " - /* /* */ /** */ /*! */ */ - let x = 5 - /* /* */ /** */ /*! */ */ - "; - - let expected = vec![ - Token::Keyword(Keyword::Let), - Token::Ident("x".to_string()), - Token::Assign, - Token::Int(FieldElement::from(5_i128)), - ]; - - let mut lexer = Lexer::new(input); - for token in expected.into_iter() { - let first_lexer_output = lexer.next_token().unwrap(); - assert_eq!(first_lexer_output, token); - } -} -#[test] -fn test_eat_string_literal() { - let input = "let _word = \"hello\""; - - let expected = vec![ - Token::Keyword(Keyword::Let), - Token::Ident("_word".to_string()), - Token::Assign, - Token::Str("hello".to_string()), - ]; - let mut lexer = Lexer::new(input); - - for token in expected.into_iter() { - let got = lexer.next_token().unwrap(); - assert_eq!(got, token); - } -} - -#[test] -fn test_eat_hex_int() { - let input = "0x05"; - - let expected = vec![Token::Int(5_i128.into())]; - let mut lexer = Lexer::new(input); - - for token in expected.into_iter() { - let got = lexer.next_token().unwrap(); - assert_eq!(got, token); - } -} - -#[test] -fn test_span() { - let input = "let x = 5"; - - // Let - let start_position = Position::default(); - let let_position = start_position + 2; - let let_token = Token::Keyword(Keyword::Let).into_span(start_position, let_position); - - // Skip whitespace - let whitespace_position = let_position + 1; - - // Identifier position - let ident_position = whitespace_position + 1; - let ident_token = Token::Ident("x".to_string()).into_single_span(ident_position); - - // Skip whitespace - let whitespace_position = ident_position + 1; - - // Assign position - let assign_position = whitespace_position + 1; - let assign_token = Token::Assign.into_single_span(assign_position); - - // Skip whitespace - let whitespace_position = assign_position + 1; - - // Int position - let int_position = whitespace_position + 1; - let int_token = Token::Int(5_i128.into()).into_single_span(int_position); - - let expected = vec![let_token, ident_token, assign_token, int_token]; - let mut lexer = Lexer::new(input); - - for spanned_token in expected.into_iter() { - let got = lexer.next_token().unwrap(); - assert_eq!(got.to_span(), spanned_token.to_span()); - assert_eq!(got, spanned_token); - } -} - -#[test] -fn test_basic_language_syntax() { - let input = " - let five = 5; - let ten : Field = 10; - let mul = fn(x, y) { - x * y; - }; - constrain mul(five, ten) == 50; - assert(ten + five == 15); - "; - - let expected = vec![ - Token::Keyword(Keyword::Let), - Token::Ident("five".to_string()), - Token::Assign, - Token::Int(5_i128.into()), - Token::Semicolon, - Token::Keyword(Keyword::Let), - Token::Ident("ten".to_string()), - Token::Colon, - Token::Keyword(Keyword::Field), - Token::Assign, - Token::Int(10_i128.into()), - Token::Semicolon, - Token::Keyword(Keyword::Let), - Token::Ident("mul".to_string()), - Token::Assign, - Token::Keyword(Keyword::Fn), - Token::LeftParen, - Token::Ident("x".to_string()), - Token::Comma, - Token::Ident("y".to_string()), - Token::RightParen, - Token::LeftBrace, - Token::Ident("x".to_string()), - Token::Star, - Token::Ident("y".to_string()), - Token::Semicolon, - Token::RightBrace, - Token::Semicolon, - Token::Keyword(Keyword::Constrain), - Token::Ident("mul".to_string()), - Token::LeftParen, - Token::Ident("five".to_string()), - Token::Comma, - Token::Ident("ten".to_string()), - Token::RightParen, - Token::Equal, - Token::Int(50_i128.into()), - Token::Semicolon, - Token::Keyword(Keyword::Assert), - Token::LeftParen, - Token::Ident("ten".to_string()), - Token::Plus, - Token::Ident("five".to_string()), - Token::Equal, - Token::Int(15_i128.into()), - Token::RightParen, - Token::Semicolon, - Token::EOF, - ]; - let mut lexer = Lexer::new(input); - - for token in expected.into_iter() { - let got = lexer.next_token().unwrap(); - assert_eq!(got, token); - } -} diff --git a/crates/noirc_frontend/src/lexer/token.rs b/crates/noirc_frontend/src/lexer/token.rs deleted file mode 100644 index 6291ac4de12..00000000000 --- a/crates/noirc_frontend/src/lexer/token.rs +++ /dev/null @@ -1,613 +0,0 @@ -use acvm::FieldElement; -use noirc_errors::{Position, Span, Spanned}; -use std::{fmt, iter::Map, vec::IntoIter}; - -use crate::lexer::errors::LexerErrorKind; - -/// Represents a token in noir's grammar - a word, number, -/// or symbol that can be used in noir's syntax. This is the -/// smallest unit of grammar. A parser may (will) decide to parse -/// items differently depending on the Tokens present but will -/// never parse the same ordering of identical tokens differently. -#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] -pub enum Token { - Ident(String), - Int(FieldElement), - Bool(bool), - Str(String), - FmtStr(String), - Keyword(Keyword), - IntType(IntType), - Attribute(Attribute), - /// < - Less, - /// <= - LessEqual, - /// > - Greater, - /// >= - GreaterEqual, - /// == - Equal, - /// != - NotEqual, - /// + - Plus, - /// - - Minus, - /// * - Star, - /// / - Slash, - /// % - Percent, - /// & - Ampersand, - /// ^ - Caret, - /// << - ShiftLeft, - /// >> - ShiftRight, - /// . - Dot, - /// .. - DoubleDot, - /// ( - LeftParen, - /// ) - RightParen, - /// { - LeftBrace, - /// } - RightBrace, - /// [ - LeftBracket, - /// ] - RightBracket, - /// -> - Arrow, - /// | - Pipe, - /// # - Pound, - /// , - Comma, - /// : - Colon, - /// :: - DoubleColon, - /// ; - Semicolon, - /// ! - Bang, - /// = - Assign, - #[allow(clippy::upper_case_acronyms)] - EOF, - - /// An invalid character is one that is not in noir's language or grammar. - /// - /// We don't report invalid tokens in the source as errors until parsing to - /// avoid reporting the error twice (once while lexing, again when it is encountered - /// during parsing). Reporting during lexing then removing these from the token stream - /// would not be equivalent as it would change the resulting parse. - Invalid(char), -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct SpannedToken(Spanned); - -impl PartialEq for Token { - fn eq(&self, other: &SpannedToken) -> bool { - self == &other.0.contents - } -} -impl PartialEq for SpannedToken { - fn eq(&self, other: &Token) -> bool { - &self.0.contents == other - } -} - -impl From for Token { - fn from(spt: SpannedToken) -> Self { - spt.0.contents - } -} - -impl SpannedToken { - pub fn new(token: Token, span: Span) -> SpannedToken { - SpannedToken(Spanned::from(span, token)) - } - pub fn to_span(&self) -> Span { - self.0.span() - } - pub fn token(&self) -> &Token { - &self.0.contents - } - pub fn into_token(self) -> Token { - self.0.contents - } - pub fn kind(&self) -> TokenKind { - self.token().kind() - } -} - -impl std::fmt::Display for SpannedToken { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.token().fmt(f) - } -} - -impl fmt::Display for Token { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Token::Ident(ref s) => write!(f, "{s}"), - Token::Int(n) => write!(f, "{}", n.to_u128()), - Token::Bool(b) => write!(f, "{b}"), - Token::Str(ref b) => write!(f, "{b}"), - Token::FmtStr(ref b) => write!(f, "f{b}"), - Token::Keyword(k) => write!(f, "{k}"), - Token::Attribute(ref a) => write!(f, "{a}"), - Token::IntType(ref i) => write!(f, "{i}"), - Token::Less => write!(f, "<"), - Token::LessEqual => write!(f, "<="), - Token::Greater => write!(f, ">"), - Token::GreaterEqual => write!(f, ">="), - Token::Equal => write!(f, "=="), - Token::NotEqual => write!(f, "!="), - Token::Plus => write!(f, "+"), - Token::Minus => write!(f, "-"), - Token::Star => write!(f, "*"), - Token::Slash => write!(f, "/"), - Token::Percent => write!(f, "%"), - Token::Ampersand => write!(f, "&"), - Token::Caret => write!(f, "^"), - Token::ShiftLeft => write!(f, "<<"), - Token::ShiftRight => write!(f, ">>"), - Token::Dot => write!(f, "."), - Token::DoubleDot => write!(f, ".."), - Token::LeftParen => write!(f, "("), - Token::RightParen => write!(f, ")"), - Token::LeftBrace => write!(f, "{{"), - Token::RightBrace => write!(f, "}}"), - Token::LeftBracket => write!(f, "["), - Token::RightBracket => write!(f, "]"), - Token::Arrow => write!(f, "->"), - Token::Pipe => write!(f, "|"), - Token::Pound => write!(f, "#"), - Token::Comma => write!(f, ","), - Token::Colon => write!(f, ":"), - Token::DoubleColon => write!(f, "::"), - Token::Semicolon => write!(f, ";"), - Token::Assign => write!(f, "="), - Token::Bang => write!(f, "!"), - Token::EOF => write!(f, "end of input"), - Token::Invalid(c) => write!(f, "{c}"), - } - } -} - -#[derive(PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] -/// The different kinds of tokens that are possible in the target language -pub enum TokenKind { - Token(Token), - Ident, - Literal, - Keyword, - Attribute, -} - -impl fmt::Display for TokenKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TokenKind::Token(ref tok) => write!(f, "{tok}"), - TokenKind::Ident => write!(f, "identifier"), - TokenKind::Literal => write!(f, "literal"), - TokenKind::Keyword => write!(f, "keyword"), - TokenKind::Attribute => write!(f, "attribute"), - } - } -} - -impl Token { - pub fn kind(&self) -> TokenKind { - match *self { - Token::Ident(_) => TokenKind::Ident, - Token::Int(_) | Token::Bool(_) | Token::Str(_) | Token::FmtStr(_) => TokenKind::Literal, - Token::Keyword(_) => TokenKind::Keyword, - Token::Attribute(_) => TokenKind::Attribute, - ref tok => TokenKind::Token(tok.clone()), - } - } - - pub fn is_ident(&self) -> bool { - matches!(self, Token::Ident(_)) - } - - pub(super) fn into_single_span(self, position: Position) -> SpannedToken { - self.into_span(position, position) - } - - pub(super) fn into_span(self, start: Position, end: Position) -> SpannedToken { - SpannedToken(Spanned::from_position(start, end, self)) - } - - /// These are all the operators allowed as part of - /// a short-hand assignment: a = b - pub fn assign_shorthand_operators() -> [Token; 10] { - use Token::*; - [Plus, Minus, Star, Slash, Percent, Ampersand, Caret, ShiftLeft, ShiftRight, Pipe] - } - - pub fn try_into_binary_op(self, span: Span) -> Option> { - use crate::BinaryOpKind::*; - let binary_op = match self { - Token::Plus => Add, - Token::Ampersand => And, - Token::Caret => Xor, - Token::ShiftLeft => ShiftLeft, - Token::ShiftRight => ShiftRight, - Token::Pipe => Or, - Token::Minus => Subtract, - Token::Star => Multiply, - Token::Slash => Divide, - Token::Equal => Equal, - Token::NotEqual => NotEqual, - Token::Less => Less, - Token::LessEqual => LessEqual, - Token::Greater => Greater, - Token::GreaterEqual => GreaterEqual, - Token::Percent => Modulo, - _ => return None, - }; - Some(Spanned::from(span, binary_op)) - } -} - -#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] -pub enum IntType { - Unsigned(u32), // u32 = Unsigned(32) - Signed(u32), // i64 = Signed(64) -} - -impl fmt::Display for IntType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - IntType::Unsigned(num) => write!(f, "u{num}"), - IntType::Signed(num) => write!(f, "i{num}"), - } - } -} - -impl IntType { - // XXX: Result - // Is not the best API. We could split this into two functions. One that checks if the the - // word is a integer, which only returns an Option - pub(crate) fn lookup_int_type(word: &str, span: Span) -> Result, LexerErrorKind> { - // Check if the first string is a 'u' or 'i' - - let is_signed = if word.starts_with('i') { - true - } else if word.starts_with('u') { - false - } else { - return Ok(None); - }; - - // Word start with 'u' or 'i'. Check if the latter is an integer - - let str_as_u32 = match word[1..].parse::() { - Ok(str_as_u32) => str_as_u32, - Err(_) => return Ok(None), - }; - - let max_bits = FieldElement::max_num_bits(); - - if str_as_u32 > max_bits { - return Err(LexerErrorKind::TooManyBits { span, max: max_bits, got: str_as_u32 }); - } - - if is_signed { - Ok(Some(Token::IntType(IntType::Signed(str_as_u32)))) - } else { - Ok(Some(Token::IntType(IntType::Unsigned(str_as_u32)))) - } - } -} - -#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] -// Attributes are special language markers in the target language -// An example of one is `#[SHA256]` . Currently only Foreign attributes are supported -// Calls to functions which have the foreign attribute are executed in the host language -pub enum Attribute { - Foreign(String), - Builtin(String), - Oracle(String), - Deprecated(Option), - Test, - Custom(String), -} - -impl fmt::Display for Attribute { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Attribute::Foreign(ref k) => write!(f, "#[foreign({k})]"), - Attribute::Builtin(ref k) => write!(f, "#[builtin({k})]"), - Attribute::Oracle(ref k) => write!(f, "#[oracle({k})]"), - Attribute::Test => write!(f, "#[test]"), - Attribute::Deprecated(None) => write!(f, "#[deprecated]"), - Attribute::Deprecated(Some(ref note)) => write!(f, r#"#[deprecated("{note}")]"#), - Attribute::Custom(ref k) => write!(f, "#[{k}]"), - } - } -} - -impl Attribute { - /// If the string is a fixed attribute return that, else - /// return the custom attribute - pub(crate) fn lookup_attribute(word: &str, span: Span) -> Result { - let word_segments: Vec<&str> = word - .split(|c| c == '(' || c == ')') - .filter(|string_segment| !string_segment.is_empty()) - .collect(); - - let validate = |slice: &str| { - let is_valid = slice - .chars() - .all(|ch| { - ch.is_ascii_alphabetic() - || ch.is_numeric() - || ch == '_' - || ch == '(' - || ch == ')' - }) - .then_some(()); - - is_valid.ok_or(LexerErrorKind::MalformedFuncAttribute { span, found: word.to_owned() }) - }; - - let attribute = match &word_segments[..] { - ["foreign", name] => { - validate(name)?; - Attribute::Foreign(name.to_string()) - } - ["builtin", name] => { - validate(name)?; - Attribute::Builtin(name.to_string()) - } - ["oracle", name] => { - validate(name)?; - Attribute::Oracle(name.to_string()) - } - ["deprecated"] => Attribute::Deprecated(None), - ["deprecated", name] => { - if !name.starts_with('"') && !name.ends_with('"') { - return Err(LexerErrorKind::MalformedFuncAttribute { - span, - found: word.to_owned(), - }); - } - - Attribute::Deprecated(name.trim_matches('"').to_string().into()) - } - ["test"] => Attribute::Test, - tokens => { - tokens.iter().try_for_each(|token| validate(token))?; - Attribute::Custom(word.to_owned()) - } - }; - - Ok(Token::Attribute(attribute)) - } - - pub fn builtin(self) -> Option { - match self { - Attribute::Builtin(name) => Some(name), - _ => None, - } - } - - pub fn foreign(self) -> Option { - match self { - Attribute::Foreign(name) => Some(name), - _ => None, - } - } - - pub fn is_foreign(&self) -> bool { - matches!(self, Attribute::Foreign(_)) - } - - pub fn is_low_level(&self) -> bool { - matches!(self, Attribute::Foreign(_) | Attribute::Builtin(_)) - } -} - -impl AsRef for Attribute { - fn as_ref(&self) -> &str { - match self { - Attribute::Foreign(string) => string, - Attribute::Builtin(string) => string, - Attribute::Oracle(string) => string, - Attribute::Deprecated(Some(string)) => string, - Attribute::Test | Attribute::Deprecated(None) => "", - Attribute::Custom(string) => string, - } - } -} - -/// All keywords in Noir. -/// Note that `self` is not present - it is a contextual keyword rather than a true one as it is -/// only special within `impl`s. Otherwise `self` functions as a normal identifier. -#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone, PartialOrd, Ord)] -#[cfg_attr(test, derive(strum_macros::EnumIter))] -pub enum Keyword { - As, - Assert, - Bool, - Char, - CompTime, - Constrain, - Contract, - Crate, - Dep, - Distinct, - Else, - Field, - Fn, - For, - FormatString, - Global, - If, - Impl, - In, - Internal, - Let, - Mod, - Mut, - Open, - Pub, - Return, - String, - Struct, - Trait, - Type, - Unconstrained, - Use, - Where, - While, -} - -impl fmt::Display for Keyword { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Keyword::As => write!(f, "as"), - Keyword::Assert => write!(f, "assert"), - Keyword::Bool => write!(f, "bool"), - Keyword::Char => write!(f, "char"), - Keyword::CompTime => write!(f, "comptime"), - Keyword::Constrain => write!(f, "constrain"), - Keyword::Contract => write!(f, "contract"), - Keyword::Crate => write!(f, "crate"), - Keyword::Dep => write!(f, "dep"), - Keyword::Distinct => write!(f, "distinct"), - Keyword::Else => write!(f, "else"), - Keyword::Field => write!(f, "Field"), - Keyword::Fn => write!(f, "fn"), - Keyword::For => write!(f, "for"), - Keyword::FormatString => write!(f, "fmtstr"), - Keyword::Global => write!(f, "global"), - Keyword::If => write!(f, "if"), - Keyword::Impl => write!(f, "impl"), - Keyword::In => write!(f, "in"), - Keyword::Internal => write!(f, "internal"), - Keyword::Let => write!(f, "let"), - Keyword::Mod => write!(f, "mod"), - Keyword::Mut => write!(f, "mut"), - Keyword::Open => write!(f, "open"), - Keyword::Pub => write!(f, "pub"), - Keyword::Return => write!(f, "return"), - Keyword::String => write!(f, "str"), - Keyword::Struct => write!(f, "struct"), - Keyword::Trait => write!(f, "trait"), - Keyword::Type => write!(f, "type"), - Keyword::Unconstrained => write!(f, "unconstrained"), - Keyword::Use => write!(f, "use"), - Keyword::Where => write!(f, "where"), - Keyword::While => write!(f, "while"), - } - } -} - -impl Keyword { - /// Looks up a word in the source program and returns the associated keyword, if found. - pub(crate) fn lookup_keyword(word: &str) -> Option { - let keyword = match word { - "as" => Keyword::As, - "assert" => Keyword::Assert, - "bool" => Keyword::Bool, - "char" => Keyword::Char, - "comptime" => Keyword::CompTime, - "constrain" => Keyword::Constrain, - "contract" => Keyword::Contract, - "crate" => Keyword::Crate, - "dep" => Keyword::Dep, - "distinct" => Keyword::Distinct, - "else" => Keyword::Else, - "Field" => Keyword::Field, - "fn" => Keyword::Fn, - "for" => Keyword::For, - "fmtstr" => Keyword::FormatString, - "global" => Keyword::Global, - "if" => Keyword::If, - "impl" => Keyword::Impl, - "in" => Keyword::In, - "internal" => Keyword::Internal, - "let" => Keyword::Let, - "mod" => Keyword::Mod, - "mut" => Keyword::Mut, - "open" => Keyword::Open, - "pub" => Keyword::Pub, - "return" => Keyword::Return, - "str" => Keyword::String, - "struct" => Keyword::Struct, - "trait" => Keyword::Trait, - "type" => Keyword::Type, - "unconstrained" => Keyword::Unconstrained, - "use" => Keyword::Use, - "where" => Keyword::Where, - "while" => Keyword::While, - - "true" => return Some(Token::Bool(true)), - "false" => return Some(Token::Bool(false)), - _ => return None, - }; - - Some(Token::Keyword(keyword)) - } -} - -#[cfg(test)] -mod keywords { - use strum::IntoEnumIterator; - - use super::{Keyword, Token}; - - #[test] - fn lookup_consistency() { - for keyword in Keyword::iter() { - let resolved_token = - Keyword::lookup_keyword(&format!("{keyword}")).unwrap_or_else(|| { - panic!("Keyword::lookup_keyword couldn't find Keyword {}", keyword) - }); - - assert_eq!( - resolved_token, - Token::Keyword(keyword), - "Keyword::lookup_keyword returns unexpected Keyword" - ); - } - } -} - -pub struct Tokens(pub Vec); - -type TokenMapIter = Map, fn(SpannedToken) -> (Token, Span)>; - -impl<'a> From for chumsky::Stream<'a, Token, Span, TokenMapIter> { - fn from(tokens: Tokens) -> Self { - let end_of_input = match tokens.0.last() { - Some(spanned_token) => spanned_token.to_span(), - None => Span::single_char(0), - }; - - fn get_span(token: SpannedToken) -> (Token, Span) { - let span = token.to_span(); - (token.into_token(), span) - } - - let iter = tokens.0.into_iter().map(get_span as fn(_) -> _); - chumsky::Stream::from_iter(end_of_input, iter) - } -} diff --git a/crates/noirc_frontend/src/monomorphization/mod.rs b/crates/noirc_frontend/src/monomorphization/mod.rs deleted file mode 100644 index 2ef980176d3..00000000000 --- a/crates/noirc_frontend/src/monomorphization/mod.rs +++ /dev/null @@ -1,1475 +0,0 @@ -//! Coming after type checking, monomorphization is the last pass in Noir's frontend. -//! It accepts the type checked HIR as input and produces a monomorphized AST as output. -//! This file implements the pass itself, while the AST is defined in the ast module. -//! -//! Unlike the HIR, which is stored within the NodeInterner, the monomorphized AST is -//! self-contained and does not need an external context struct. As a result, the NodeInterner -//! can be safely discarded after monomorphization. -//! -//! The entry point to this pass is the `monomorphize` function which, starting from a given -//! function, will monomorphize the entire reachable program. -use acvm::FieldElement; -use iter_extended::{btree_map, vecmap}; -use noirc_printable_type::PrintableType; -use std::collections::{BTreeMap, HashMap, VecDeque}; - -use crate::{ - hir_def::{ - expr::*, - function::{FuncMeta, FunctionSignature, Parameters}, - stmt::{HirAssignStatement, HirLValue, HirLetStatement, HirPattern, HirStatement}, - types, - }, - node_interner::{self, DefinitionKind, NodeInterner, StmtId}, - token::Attribute, - ContractFunctionType, FunctionKind, Type, TypeBinding, TypeBindings, TypeVariableKind, - Visibility, -}; - -use self::ast::{Definition, FuncId, Function, LocalId, Program}; - -pub mod ast; -pub mod printer; - -struct LambdaContext { - env_ident: ast::Ident, - captures: Vec, -} - -/// The context struct for the monomorphization pass. -/// -/// This struct holds the FIFO queue of functions to monomorphize, which is added to -/// whenever a new (function, type) combination is encountered. -struct Monomorphizer<'interner> { - /// Globals are keyed by their unique ID and expected type so that we can monomorphize - /// a new version of the global for each type. Note that 'global' here means 'globally - /// visible' and thus includes both functions and global variables. - /// - /// Using nested HashMaps here lets us avoid cloning HirTypes when calling .get() - globals: HashMap>, - - /// Unlike globals, locals are only keyed by their unique ID because they are never - /// duplicated during monomorphization. Doing so would allow them to be used polymorphically - /// but would also cause them to be re-evaluated which is a performance trap that would - /// confuse users. - locals: HashMap, - - /// Queue of functions to monomorphize next - queue: VecDeque<(node_interner::FuncId, FuncId, TypeBindings)>, - - /// When a function finishes being monomorphized, the monomorphized ast::Function is - /// stored here along with its FuncId. - finished_functions: BTreeMap, - - /// Used to reference existing definitions in the HIR - interner: &'interner NodeInterner, - - lambda_envs_stack: Vec, - - next_local_id: u32, - next_function_id: u32, -} - -type HirType = crate::Type; - -/// Starting from the given `main` function, monomorphize the entire program, -/// replacing all references to type variables and NamedGenerics with concrete -/// types, duplicating definitions as necessary to do so. -/// -/// Instead of iterating over every function, this pass starts with the main function -/// and monomorphizes every function reachable from it via function calls and references. -/// Thus, if a function is not used in the program, it will not be monomorphized. -/// -/// Note that there is no requirement on the `main` function that can be passed into -/// this function. Typically, this is the function named "main" in the source project, -/// but it can also be, for example, an arbitrary test function for running `nargo test`. -pub fn monomorphize(main: node_interner::FuncId, interner: &NodeInterner) -> Program { - let mut monomorphizer = Monomorphizer::new(interner); - let function_sig = monomorphizer.compile_main(main); - - while !monomorphizer.queue.is_empty() { - let (next_fn_id, new_id, bindings) = monomorphizer.queue.pop_front().unwrap(); - monomorphizer.locals.clear(); - - perform_instantiation_bindings(&bindings); - monomorphizer.function(next_fn_id, new_id); - undo_instantiation_bindings(bindings); - } - - let functions = vecmap(monomorphizer.finished_functions, |(_, f)| f); - let FuncMeta { return_distinctness, .. } = interner.function_meta(&main); - Program::new(functions, function_sig, return_distinctness) -} - -impl<'interner> Monomorphizer<'interner> { - fn new(interner: &'interner NodeInterner) -> Self { - Monomorphizer { - globals: HashMap::new(), - locals: HashMap::new(), - queue: VecDeque::new(), - finished_functions: BTreeMap::new(), - next_local_id: 0, - next_function_id: 0, - interner, - lambda_envs_stack: Vec::new(), - } - } - - fn next_local_id(&mut self) -> LocalId { - let id = self.next_local_id; - self.next_local_id += 1; - LocalId(id) - } - - fn next_function_id(&mut self) -> ast::FuncId { - let id = self.next_function_id; - self.next_function_id += 1; - ast::FuncId(id) - } - - fn lookup_local(&mut self, id: node_interner::DefinitionId) -> Option { - self.locals.get(&id).copied().map(Definition::Local) - } - - fn lookup_function( - &mut self, - id: node_interner::FuncId, - expr_id: node_interner::ExprId, - typ: &HirType, - ) -> Definition { - let typ = typ.follow_bindings(); - match self.globals.get(&id).and_then(|inner_map| inner_map.get(&typ)) { - Some(id) => Definition::Function(*id), - None => { - // Function has not been monomorphized yet - let meta = self.interner.function_meta(&id); - match meta.kind { - FunctionKind::LowLevel => { - let attribute = meta.attributes.expect("all low level functions must contain an attribute which contains the opcode which it links to"); - let opcode = attribute.foreign().expect( - "ice: function marked as foreign, but attribute kind does not match this", - ); - Definition::LowLevel(opcode) - } - FunctionKind::Builtin => { - let attribute = meta.attributes.expect("all low level functions must contain an attribute which contains the opcode which it links to"); - let opcode = attribute.builtin().expect( - "ice: function marked as builtin, but attribute kind does not match this", - ); - Definition::Builtin(opcode) - } - FunctionKind::Normal => { - let id = self.queue_function(id, expr_id, typ); - Definition::Function(id) - } - FunctionKind::Oracle => { - let attr = - meta.attributes.expect("Oracle function must have an oracle attribute"); - match attr { - Attribute::Oracle(name) => Definition::Oracle(name), - _ => unreachable!("Oracle function must have an oracle attribute"), - } - } - } - } - } - } - - fn define_local(&mut self, id: node_interner::DefinitionId, new_id: LocalId) { - self.locals.insert(id, new_id); - } - - /// Prerequisite: typ = typ.follow_bindings() - fn define_global(&mut self, id: node_interner::FuncId, typ: HirType, new_id: FuncId) { - self.globals.entry(id).or_default().insert(typ, new_id); - } - - fn compile_main(&mut self, main_id: node_interner::FuncId) -> FunctionSignature { - let new_main_id = self.next_function_id(); - assert_eq!(new_main_id, Program::main_id()); - self.function(main_id, new_main_id); - - let main_meta = self.interner.function_meta(&main_id); - main_meta.into_function_signature() - } - - fn function(&mut self, f: node_interner::FuncId, id: FuncId) { - let meta = self.interner.function_meta(&f); - let name = self.interner.function_name(&f).to_owned(); - - let return_type = Self::convert_type(meta.return_type()); - let parameters = self.parameters(meta.parameters); - let body = self.expr(*self.interner.function(&f).as_expr()); - let unconstrained = meta.is_unconstrained - || matches!(meta.contract_function_type, Some(ContractFunctionType::Open)); - - let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; - self.push_function(id, function); - } - - fn push_function(&mut self, id: FuncId, function: ast::Function) { - let existing = self.finished_functions.insert(id, function); - assert!(existing.is_none()); - } - - /// Monomorphize each parameter, expanding tuple/struct patterns into multiple parameters - /// and binding any generic types found. - fn parameters(&mut self, params: Parameters) -> Vec<(ast::LocalId, bool, String, ast::Type)> { - let mut new_params = Vec::with_capacity(params.len()); - for parameter in params { - self.parameter(parameter.0, ¶meter.1, &mut new_params); - } - new_params - } - - fn parameter( - &mut self, - param: HirPattern, - typ: &HirType, - new_params: &mut Vec<(ast::LocalId, bool, String, ast::Type)>, - ) { - match param { - HirPattern::Identifier(ident) => { - let new_id = self.next_local_id(); - let definition = self.interner.definition(ident.id); - let name = definition.name.clone(); - new_params.push((new_id, definition.mutable, name, Self::convert_type(typ))); - self.define_local(ident.id, new_id); - } - HirPattern::Mutable(pattern, _) => self.parameter(*pattern, typ, new_params), - HirPattern::Tuple(fields, _) => { - let tuple_field_types = unwrap_tuple_type(typ); - - for (field, typ) in fields.into_iter().zip(tuple_field_types) { - self.parameter(field, &typ, new_params); - } - } - HirPattern::Struct(_, fields, _) => { - let struct_field_types = unwrap_struct_type(typ); - assert_eq!(struct_field_types.len(), fields.len()); - - let mut fields = btree_map(fields, |(name, field)| (name.0.contents, field)); - - // Iterate over `struct_field_types` since `unwrap_struct_type` will always - // return the fields in the order defined by the struct type. - for (field_name, field_type) in struct_field_types { - let field = fields.remove(&field_name).unwrap_or_else(|| { - unreachable!("Expected a field named '{field_name}' in the struct pattern") - }); - - self.parameter(field, &field_type, new_params); - } - } - } - } - - fn expr(&mut self, expr: node_interner::ExprId) -> ast::Expression { - use ast::Expression::Literal; - use ast::Literal::*; - - match self.interner.expression(&expr) { - HirExpression::Ident(ident) => self.ident(ident, expr), - HirExpression::Literal(HirLiteral::Str(contents)) => Literal(Str(contents)), - HirExpression::Literal(HirLiteral::FmtStr(contents, idents)) => { - let fields = vecmap(idents, |ident| self.expr(ident)); - Literal(FmtStr( - contents, - fields.len() as u64, - Box::new(ast::Expression::Tuple(fields)), - )) - } - HirExpression::Literal(HirLiteral::Bool(value)) => Literal(Bool(value)), - HirExpression::Literal(HirLiteral::Integer(value)) => { - let typ = Self::convert_type(&self.interner.id_type(expr)); - Literal(Integer(value, typ)) - } - HirExpression::Literal(HirLiteral::Array(array)) => match array { - HirArrayLiteral::Standard(array) => self.standard_array(expr, array), - HirArrayLiteral::Repeated { repeated_element, length } => { - self.repeated_array(expr, repeated_element, length) - } - }, - HirExpression::Literal(HirLiteral::Unit) => ast::Expression::Block(vec![]), - HirExpression::Block(block) => self.block(block.0), - - HirExpression::Prefix(prefix) => ast::Expression::Unary(ast::Unary { - operator: prefix.operator, - rhs: Box::new(self.expr(prefix.rhs)), - result_type: Self::convert_type(&self.interner.id_type(expr)), - }), - - HirExpression::Infix(infix) => { - let lhs = Box::new(self.expr(infix.lhs)); - let rhs = Box::new(self.expr(infix.rhs)); - let operator = infix.operator.kind; - let location = self.interner.expr_location(&expr); - ast::Expression::Binary(ast::Binary { lhs, rhs, operator, location }) - } - - HirExpression::Index(index) => self.index(expr, index), - - HirExpression::MemberAccess(access) => { - let field_index = self.interner.get_field_index(expr); - let expr = Box::new(self.expr(access.lhs)); - ast::Expression::ExtractTupleField(expr, field_index) - } - - HirExpression::Call(call) => self.function_call(call, expr), - - HirExpression::Cast(cast) => ast::Expression::Cast(ast::Cast { - lhs: Box::new(self.expr(cast.lhs)), - r#type: Self::convert_type(&cast.r#type), - location: self.interner.expr_location(&expr), - }), - - HirExpression::For(for_expr) => { - let start = self.expr(for_expr.start_range); - let end = self.expr(for_expr.end_range); - let index_variable = self.next_local_id(); - self.define_local(for_expr.identifier.id, index_variable); - - let block = Box::new(self.expr(for_expr.block)); - - ast::Expression::For(ast::For { - index_variable, - index_name: self.interner.definition_name(for_expr.identifier.id).to_owned(), - index_type: Self::convert_type(&self.interner.id_type(for_expr.start_range)), - start_range: Box::new(start), - end_range: Box::new(end), - start_range_location: self.interner.expr_location(&for_expr.start_range), - end_range_location: self.interner.expr_location(&for_expr.end_range), - block, - }) - } - - HirExpression::If(if_expr) => { - let cond = self.expr(if_expr.condition); - let then = self.expr(if_expr.consequence); - let else_ = if_expr.alternative.map(|alt| Box::new(self.expr(alt))); - ast::Expression::If(ast::If { - condition: Box::new(cond), - consequence: Box::new(then), - alternative: else_, - typ: Self::convert_type(&self.interner.id_type(expr)), - }) - } - - HirExpression::Tuple(fields) => { - let fields = vecmap(fields, |id| self.expr(id)); - ast::Expression::Tuple(fields) - } - HirExpression::Constructor(constructor) => self.constructor(constructor, expr), - - HirExpression::Lambda(lambda) => self.lambda(lambda, expr), - - HirExpression::MethodCall(_) => { - unreachable!("Encountered HirExpression::MethodCall during monomorphization") - } - HirExpression::Error => unreachable!("Encountered Error node during monomorphization"), - } - } - - fn standard_array( - &mut self, - array: node_interner::ExprId, - array_elements: Vec, - ) -> ast::Expression { - let typ = Self::convert_type(&self.interner.id_type(array)); - let contents = vecmap(array_elements, |id| self.expr(id)); - ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { contents, typ })) - } - - fn repeated_array( - &mut self, - array: node_interner::ExprId, - repeated_element: node_interner::ExprId, - length: HirType, - ) -> ast::Expression { - let typ = Self::convert_type(&self.interner.id_type(array)); - - let contents = self.expr(repeated_element); - let length = length - .evaluate_to_u64() - .expect("Length of array is unknown when evaluating numeric generic"); - - let contents = vec![contents; length as usize]; - ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { contents, typ })) - } - - fn index(&mut self, id: node_interner::ExprId, index: HirIndexExpression) -> ast::Expression { - let element_type = Self::convert_type(&self.interner.id_type(id)); - - let collection = Box::new(self.expr(index.collection)); - let index = Box::new(self.expr(index.index)); - let location = self.interner.expr_location(&id); - ast::Expression::Index(ast::Index { collection, index, element_type, location }) - } - - fn statement(&mut self, id: StmtId) -> ast::Expression { - match self.interner.statement(&id) { - HirStatement::Let(let_statement) => self.let_statement(let_statement), - HirStatement::Constrain(constrain) => { - let expr = self.expr(constrain.0); - let location = self.interner.expr_location(&constrain.0); - ast::Expression::Constrain(Box::new(expr), location) - } - HirStatement::Assign(assign) => self.assign(assign), - HirStatement::Expression(expr) => self.expr(expr), - HirStatement::Semi(expr) => ast::Expression::Semi(Box::new(self.expr(expr))), - HirStatement::Error => unreachable!(), - } - } - - fn let_statement(&mut self, let_statement: HirLetStatement) -> ast::Expression { - let expr = self.expr(let_statement.expression); - let expected_type = self.interner.id_type(let_statement.expression); - self.unpack_pattern(let_statement.pattern, expr, &expected_type) - } - - fn constructor( - &mut self, - constructor: HirConstructorExpression, - id: node_interner::ExprId, - ) -> ast::Expression { - let typ = self.interner.id_type(id); - let field_types = unwrap_struct_type(&typ); - - let field_type_map = btree_map(&field_types, |x| x.clone()); - - // Create let bindings for each field value first to preserve evaluation order before - // they are reordered and packed into the resulting tuple - let mut field_vars = BTreeMap::new(); - let mut new_exprs = Vec::with_capacity(constructor.fields.len()); - - for (field_name, expr_id) in constructor.fields { - let new_id = self.next_local_id(); - let field_type = field_type_map.get(&field_name.0.contents).unwrap(); - let typ = Self::convert_type(field_type); - - field_vars.insert(field_name.0.contents.clone(), (new_id, typ)); - let expression = Box::new(self.expr(expr_id)); - - new_exprs.push(ast::Expression::Let(ast::Let { - id: new_id, - mutable: false, - name: field_name.0.contents, - expression, - })); - } - - // We must ensure the tuple created from the variables here matches the order - // of the fields as defined in the type. To do this, we iterate over field_types, - // rather than field_type_map which is a sorted BTreeMap. - let field_idents = vecmap(field_types, |(name, _)| { - let (id, typ) = field_vars.remove(&name).unwrap_or_else(|| { - unreachable!("Expected field {name} to be present in constructor for {typ}") - }); - - let definition = Definition::Local(id); - let mutable = false; - ast::Expression::Ident(ast::Ident { definition, mutable, location: None, name, typ }) - }); - - // Finally we can return the created Tuple from the new block - new_exprs.push(ast::Expression::Tuple(field_idents)); - ast::Expression::Block(new_exprs) - } - - fn block(&mut self, statement_ids: Vec) -> ast::Expression { - ast::Expression::Block(vecmap(statement_ids, |id| self.statement(id))) - } - - fn unpack_pattern( - &mut self, - pattern: HirPattern, - value: ast::Expression, - typ: &HirType, - ) -> ast::Expression { - match pattern { - HirPattern::Identifier(ident) => { - let new_id = self.next_local_id(); - self.define_local(ident.id, new_id); - let definition = self.interner.definition(ident.id); - - ast::Expression::Let(ast::Let { - id: new_id, - mutable: definition.mutable, - name: definition.name.clone(), - expression: Box::new(value), - }) - } - HirPattern::Mutable(pattern, _) => self.unpack_pattern(*pattern, value, typ), - HirPattern::Tuple(patterns, _) => { - let fields = unwrap_tuple_type(typ); - self.unpack_tuple_pattern(value, patterns.into_iter().zip(fields)) - } - HirPattern::Struct(_, patterns, _) => { - let fields = unwrap_struct_type(typ); - assert_eq!(patterns.len(), fields.len()); - - let mut patterns = - btree_map(patterns, |(name, pattern)| (name.0.contents, pattern)); - - // We iterate through the type's fields to match the order defined in the struct type - let patterns_iter = fields.into_iter().map(|(field_name, field_type)| { - let pattern = patterns.remove(&field_name).unwrap(); - (pattern, field_type) - }); - - self.unpack_tuple_pattern(value, patterns_iter) - } - } - } - - fn unpack_tuple_pattern( - &mut self, - value: ast::Expression, - fields: impl Iterator, - ) -> ast::Expression { - let fresh_id = self.next_local_id(); - - let mut definitions = vec![ast::Expression::Let(ast::Let { - id: fresh_id, - mutable: false, - name: "_".into(), - expression: Box::new(value), - })]; - - for (i, (field_pattern, field_type)) in fields.into_iter().enumerate() { - let location = None; - let mutable = false; - let definition = Definition::Local(fresh_id); - let name = i.to_string(); - let typ = Self::convert_type(&field_type); - - let new_rhs = - ast::Expression::Ident(ast::Ident { location, mutable, definition, name, typ }); - - let new_rhs = ast::Expression::ExtractTupleField(Box::new(new_rhs), i); - let new_expr = self.unpack_pattern(field_pattern, new_rhs, &field_type); - definitions.push(new_expr); - } - - ast::Expression::Block(definitions) - } - - /// Find a captured variable in the innermost closure, and construct an expression - fn lookup_captured_expr(&mut self, id: node_interner::DefinitionId) -> Option { - let ctx = self.lambda_envs_stack.last()?; - ctx.captures.iter().position(|capture| capture.ident.id == id).map(|index| { - ast::Expression::ExtractTupleField( - Box::new(ast::Expression::Ident(ctx.env_ident.clone())), - index, - ) - }) - } - - /// Find a captured variable in the innermost closure construct a LValue - fn lookup_captured_lvalue(&mut self, id: node_interner::DefinitionId) -> Option { - let ctx = self.lambda_envs_stack.last()?; - ctx.captures.iter().position(|capture| capture.ident.id == id).map(|index| { - ast::LValue::MemberAccess { - object: Box::new(ast::LValue::Ident(ctx.env_ident.clone())), - field_index: index, - } - }) - } - - /// A local (ie non-global) ident only - fn local_ident(&mut self, ident: &HirIdent) -> Option { - let definition = self.interner.definition(ident.id); - let name = definition.name.clone(); - let mutable = definition.mutable; - - let definition = self.lookup_local(ident.id)?; - let typ = Self::convert_type(&self.interner.id_type(ident.id)); - - Some(ast::Ident { location: Some(ident.location), mutable, definition, name, typ }) - } - - fn ident(&mut self, ident: HirIdent, expr_id: node_interner::ExprId) -> ast::Expression { - let definition = self.interner.definition(ident.id); - match &definition.kind { - DefinitionKind::Function(func_id) => { - let mutable = definition.mutable; - let location = Some(ident.location); - let name = definition.name.clone(); - let typ = self.interner.id_type(expr_id); - - let definition = self.lookup_function(*func_id, expr_id, &typ); - let typ = Self::convert_type(&typ); - let ident = ast::Ident { location, mutable, definition, name, typ: typ.clone() }; - let ident_expression = ast::Expression::Ident(ident); - if self.is_function_closure_type(&typ) { - ast::Expression::Tuple(vec![ - ast::Expression::ExtractTupleField( - Box::new(ident_expression.clone()), - 0usize, - ), - ast::Expression::ExtractTupleField(Box::new(ident_expression), 1usize), - ]) - } else { - ident_expression - } - } - DefinitionKind::Global(expr_id) => self.expr(*expr_id), - DefinitionKind::Local(_) => self.lookup_captured_expr(ident.id).unwrap_or_else(|| { - let ident = self.local_ident(&ident).unwrap(); - ast::Expression::Ident(ident) - }), - DefinitionKind::GenericType(type_variable) => { - let value = match &*type_variable.borrow() { - TypeBinding::Unbound(_) => { - unreachable!("Unbound type variable used in expression") - } - TypeBinding::Bound(binding) => binding.evaluate_to_u64().unwrap_or_else(|| { - panic!("Non-numeric type variable used in expression expecting a value") - }), - }; - - let value = FieldElement::from(value as u128); - ast::Expression::Literal(ast::Literal::Integer(value, ast::Type::Field)) - } - } - } - - /// Convert a non-tuple/struct type to a monomorphized type - fn convert_type(typ: &HirType) -> ast::Type { - match typ { - HirType::FieldElement => ast::Type::Field, - HirType::Integer(sign, bits) => ast::Type::Integer(*sign, *bits), - HirType::Bool => ast::Type::Bool, - HirType::String(size) => ast::Type::String(size.evaluate_to_u64().unwrap_or(0)), - HirType::FmtString(size, fields) => { - let size = size.evaluate_to_u64().unwrap_or(0); - let fields = Box::new(Self::convert_type(fields.as_ref())); - ast::Type::FmtString(size, fields) - } - HirType::Unit => ast::Type::Unit, - - HirType::Array(length, element) => { - let element = Box::new(Self::convert_type(element.as_ref())); - - if let Some(length) = length.evaluate_to_u64() { - ast::Type::Array(length, element) - } else { - ast::Type::Slice(element) - } - } - - HirType::NamedGeneric(binding, _) => { - if let TypeBinding::Bound(binding) = &*binding.borrow() { - return Self::convert_type(binding); - } - - // Default any remaining unbound type variables. - // This should only happen if the variable in question is unused - // and within a larger generic type. - // NOTE: Make sure to review this if there is ever type-directed dispatch, - // like automatic solving of traits. It should be fine since it is strictly - // after type checking, but care should be taken that it doesn't change which - // impls are chosen. - *binding.borrow_mut() = TypeBinding::Bound(HirType::default_int_type()); - ast::Type::Field - } - - HirType::TypeVariable(binding, kind) => { - if let TypeBinding::Bound(binding) = &*binding.borrow() { - return Self::convert_type(binding); - } - - // Default any remaining unbound type variables. - // This should only happen if the variable in question is unused - // and within a larger generic type. - // NOTE: Make sure to review this if there is ever type-directed dispatch, - // like automatic solving of traits. It should be fine since it is strictly - // after type checking, but care should be taken that it doesn't change which - // impls are chosen. - let default = kind.default_type(); - let monomorphized_default = Self::convert_type(&default); - *binding.borrow_mut() = TypeBinding::Bound(default); - monomorphized_default - } - - HirType::Struct(def, args) => { - let fields = def.borrow().get_fields(args); - let fields = vecmap(fields, |(_, field)| Self::convert_type(&field)); - ast::Type::Tuple(fields) - } - - HirType::Tuple(fields) => { - let fields = vecmap(fields, Self::convert_type); - ast::Type::Tuple(fields) - } - - HirType::Function(args, ret, env) => { - let args = vecmap(args, Self::convert_type); - let ret = Box::new(Self::convert_type(ret)); - let env = Self::convert_type(env); - match &env { - ast::Type::Unit => ast::Type::Function(args, ret, Box::new(env)), - ast::Type::Tuple(_elements) => ast::Type::Tuple(vec![ - env.clone(), - ast::Type::Function(args, ret, Box::new(env)), - ]), - _ => { - unreachable!( - "internal Type::Function env should be either a Unit or a Tuple, not {env}" - ) - } - } - } - - HirType::MutableReference(element) => { - let element = Self::convert_type(element); - ast::Type::MutableReference(Box::new(element)) - } - - HirType::Forall(_, _) - | HirType::Constant(_) - | HirType::NotConstant - | HirType::Error => { - unreachable!("Unexpected type {} found", typ) - } - } - } - - fn is_function_closure(&self, raw_func_id: node_interner::ExprId) -> bool { - let t = Self::convert_type(&self.interner.id_type(raw_func_id)); - if self.is_function_closure_type(&t) { - true - } else if let ast::Type::Tuple(elements) = t { - if elements.len() == 2 { - matches!(elements[1], ast::Type::Function(_, _, _)) - } else { - false - } - } else { - false - } - } - - fn is_function_closure_type(&self, t: &ast::Type) -> bool { - if let ast::Type::Function(_, _, env) = t { - let e = (*env).clone(); - matches!(*e, ast::Type::Tuple(_captures)) - } else { - false - } - } - - fn function_call( - &mut self, - call: HirCallExpression, - id: node_interner::ExprId, - ) -> ast::Expression { - let original_func = Box::new(self.expr(call.func)); - let mut arguments = vecmap(&call.arguments, |id| self.expr(*id)); - let hir_arguments = vecmap(&call.arguments, |id| self.interner.expression(id)); - let func: Box; - let return_type = self.interner.id_type(id); - let return_type = Self::convert_type(&return_type); - let location = call.location; - - if let ast::Expression::Ident(ident) = original_func.as_ref() { - if let Definition::Oracle(name) = &ident.definition { - if name.as_str() == "println" { - // Oracle calls are required to be wrapped in an unconstrained function - // Thus, the only argument to the `println` oracle is expected to always be an ident - self.append_printable_type_info(&hir_arguments[0], &mut arguments); - } - } - } - - let mut block_expressions = vec![]; - - let is_closure = self.is_function_closure(call.func); - if is_closure { - let local_id = self.next_local_id(); - - // store the function in a temporary variable before calling it - // this is needed for example if call.func is of the form `foo()()` - // without this, we would translate it to `foo().1(foo().0)` - let let_stmt = ast::Expression::Let(ast::Let { - id: local_id, - mutable: false, - name: "tmp".to_string(), - expression: Box::new(*original_func), - }); - block_expressions.push(let_stmt); - - let extracted_func = ast::Expression::Ident(ast::Ident { - location: None, - definition: Definition::Local(local_id), - mutable: false, - name: "tmp".to_string(), - typ: Self::convert_type(&self.interner.id_type(call.func)), - }); - - func = Box::new(ast::Expression::ExtractTupleField( - Box::new(extracted_func.clone()), - 1usize, - )); - let env_argument = ast::Expression::ExtractTupleField(Box::new(extracted_func), 0usize); - arguments.insert(0, env_argument); - } else { - func = original_func.clone(); - }; - - let call = self - .try_evaluate_call(&func, &return_type) - .unwrap_or(ast::Expression::Call(ast::Call { func, arguments, return_type, location })); - - if !block_expressions.is_empty() { - block_expressions.push(call); - ast::Expression::Block(block_expressions) - } else { - call - } - } - - /// Adds a function argument that contains type metadata that is required to tell - /// `println` how to convert values passed to an foreign call back to a human-readable string. - /// The values passed to an foreign call will be a simple list of field elements, - /// thus requiring extra metadata to correctly decode this list of elements. - /// - /// The Noir compiler has a `PrintableType` that handles encoding/decoding a list - /// of field elements to/from JSON. The type metadata attached in this method - /// is the serialized `PrintableType` for the argument passed to the function. - /// The caller that is running a Noir program should then deserialize the `PrintableType`, - /// and accurately decode the list of field elements passed to the foreign call. - fn append_printable_type_info( - &mut self, - hir_argument: &HirExpression, - arguments: &mut Vec, - ) { - match hir_argument { - HirExpression::Ident(ident) => { - let typ = self.interner.id_type(ident.id); - let typ: Type = typ.follow_bindings(); - let is_fmt_str = match typ { - // A format string has many different possible types that need to be handled. - // Loop over each element in the format string to fetch each type's relevant metadata - Type::FmtString(_, elements) => { - match *elements { - Type::Tuple(element_types) => { - for typ in element_types { - Self::append_printable_type_info_inner(&typ, arguments); - } - } - _ => unreachable!( - "ICE: format string type should be a tuple but got a {elements}" - ), - } - true - } - _ => { - Self::append_printable_type_info_inner(&typ, arguments); - false - } - }; - // The caller needs information as to whether it is handling a format string or a single type - arguments.push(ast::Expression::Literal(ast::Literal::Bool(is_fmt_str))); - } - _ => unreachable!("logging expr {:?} is not supported", arguments[0]), - } - } - - fn append_printable_type_info_inner(typ: &Type, arguments: &mut Vec) { - if let HirType::Array(size, _) = typ { - if let HirType::NotConstant = **size { - unreachable!("println does not support slices. Convert the slice to an array before passing it to println"); - } - } - let printable_type: PrintableType = typ.into(); - let abi_as_string = - serde_json::to_string(&printable_type).expect("ICE: expected PrintableType to serialize"); - - arguments.push(ast::Expression::Literal(ast::Literal::Str(abi_as_string))); - } - - /// Try to evaluate certain builtin functions (currently only 'array_len' and field modulus methods) - /// at their call site. - /// NOTE: Evaluating at the call site means we cannot track aliased functions. - /// E.g. `let f = std::array::len; f(arr)` will fail to evaluate. - /// To fix this we need to evaluate on the identifier instead, which - /// requires us to evaluate to a Lambda value which isn't in noir yet. - fn try_evaluate_call( - &mut self, - func: &ast::Expression, - result_type: &ast::Type, - ) -> Option { - if let ast::Expression::Ident(ident) = func { - if let Definition::Builtin(opcode) = &ident.definition { - // TODO(#1736): Move this builtin to the SSA pass - return match opcode.as_str() { - "modulus_num_bits" => Some(ast::Expression::Literal(ast::Literal::Integer( - (FieldElement::max_num_bits() as u128).into(), - ast::Type::Field, - ))), - "zeroed" => Some(self.zeroed_value_of_type(result_type)), - "modulus_le_bits" => { - let bits = FieldElement::modulus().to_radix_le(2); - Some(self.modulus_array_literal(bits, 1)) - } - "modulus_be_bits" => { - let bits = FieldElement::modulus().to_radix_be(2); - Some(self.modulus_array_literal(bits, 1)) - } - "modulus_be_bytes" => { - let bytes = FieldElement::modulus().to_bytes_be(); - Some(self.modulus_array_literal(bytes, 8)) - } - "modulus_le_bytes" => { - let bytes = FieldElement::modulus().to_bytes_le(); - Some(self.modulus_array_literal(bytes, 8)) - } - _ => None, - }; - } - } - None - } - - fn modulus_array_literal(&self, bytes: Vec, arr_elem_bits: u32) -> ast::Expression { - use ast::*; - let int_type = Type::Integer(crate::Signedness::Unsigned, arr_elem_bits); - - let bytes_as_expr = vecmap(bytes, |byte| { - Expression::Literal(Literal::Integer((byte as u128).into(), int_type.clone())) - }); - - let typ = Type::Array(bytes_as_expr.len() as u64, Box::new(int_type)); - - let arr_literal = ArrayLiteral { typ, contents: bytes_as_expr }; - Expression::Literal(Literal::Array(arr_literal)) - } - - fn queue_function( - &mut self, - id: node_interner::FuncId, - expr_id: node_interner::ExprId, - function_type: HirType, - ) -> FuncId { - let new_id = self.next_function_id(); - self.define_global(id, function_type, new_id); - - let bindings = self.interner.get_instantiation_bindings(expr_id); - let bindings = self.follow_bindings(bindings); - - self.queue.push_back((id, new_id, bindings)); - new_id - } - - /// Follow any type variable links within the given TypeBindings to produce - /// a new TypeBindings that won't be changed when bindings are pushed or popped - /// during {perform,undo}_monomorphization_bindings. - /// - /// Without this, a monomorphized type may fail to propagate passed more than 2 - /// function calls deep since it is possible for a previous link in the chain to - /// unbind a type variable that was previously bound. - fn follow_bindings(&self, bindings: &TypeBindings) -> TypeBindings { - bindings - .iter() - .map(|(id, (var, binding))| { - let binding2 = binding.follow_bindings(); - (*id, (var.clone(), binding2)) - }) - .collect() - } - - fn assign(&mut self, assign: HirAssignStatement) -> ast::Expression { - let expression = Box::new(self.expr(assign.expression)); - let lvalue = self.lvalue(assign.lvalue); - ast::Expression::Assign(ast::Assign { expression, lvalue }) - } - - fn lvalue(&mut self, lvalue: HirLValue) -> ast::LValue { - match lvalue { - HirLValue::Ident(ident, _) => self - .lookup_captured_lvalue(ident.id) - .unwrap_or_else(|| ast::LValue::Ident(self.local_ident(&ident).unwrap())), - HirLValue::MemberAccess { object, field_index, .. } => { - let field_index = field_index.unwrap(); - let object = Box::new(self.lvalue(*object)); - ast::LValue::MemberAccess { object, field_index } - } - HirLValue::Index { array, index, typ } => { - let location = self.interner.expr_location(&index); - let array = Box::new(self.lvalue(*array)); - let index = Box::new(self.expr(index)); - let element_type = Self::convert_type(&typ); - ast::LValue::Index { array, index, element_type, location } - } - HirLValue::Dereference { lvalue, element_type } => { - let reference = Box::new(self.lvalue(*lvalue)); - let element_type = Self::convert_type(&element_type); - ast::LValue::Dereference { reference, element_type } - } - } - } - - fn lambda(&mut self, lambda: HirLambda, expr: node_interner::ExprId) -> ast::Expression { - if lambda.captures.is_empty() { - self.lambda_no_capture(lambda) - } else { - let (setup, closure_variable) = self.lambda_with_setup(lambda, expr); - ast::Expression::Block(vec![setup, closure_variable]) - } - } - - fn lambda_no_capture(&mut self, lambda: HirLambda) -> ast::Expression { - let ret_type = Self::convert_type(&lambda.return_type); - let lambda_name = "lambda"; - let parameter_types = vecmap(&lambda.parameters, |(_, typ)| Self::convert_type(typ)); - - // Manually convert to Parameters type so we can reuse the self.parameters method - let parameters = - vecmap(lambda.parameters, |(pattern, typ)| (pattern, typ, Visibility::Private)).into(); - - let parameters = self.parameters(parameters); - let body = self.expr(lambda.body); - - let id = self.next_function_id(); - let return_type = ret_type.clone(); - let name = lambda_name.to_owned(); - let unconstrained = false; - - let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; - self.push_function(id, function); - - let typ = - ast::Type::Function(parameter_types, Box::new(ret_type), Box::new(ast::Type::Unit)); - - let name = lambda_name.to_owned(); - ast::Expression::Ident(ast::Ident { - definition: Definition::Function(id), - mutable: false, - location: None, - name, - typ, - }) - } - - fn lambda_with_setup( - &mut self, - lambda: HirLambda, - expr: node_interner::ExprId, - ) -> (ast::Expression, ast::Expression) { - // returns (, ) - // which can be used directly in callsites or transformed - // directly to a single `Expression` - // for other cases by `lambda` which is called by `expr` - // - // it solves the problem of detecting special cases where - // we call something like - // `{let env$.. = ..;}.1({let env$.. = ..;}.0, ..)` - // which was leading to redefinition errors - // - // instead of detecting and extracting - // patterns in the resulting tree, - // which seems more fragile, we directly reuse the return parameters - // of this function in those cases - let ret_type = Self::convert_type(&lambda.return_type); - let lambda_name = "lambda"; - let parameter_types = vecmap(&lambda.parameters, |(_, typ)| Self::convert_type(typ)); - - // Manually convert to Parameters type so we can reuse the self.parameters method - let parameters = - vecmap(lambda.parameters, |(pattern, typ)| (pattern, typ, Visibility::Private)).into(); - - let mut converted_parameters = self.parameters(parameters); - - let id = self.next_function_id(); - let name = lambda_name.to_owned(); - let return_type = ret_type.clone(); - - let env_local_id = self.next_local_id(); - let env_name = "env"; - let env_tuple = ast::Expression::Tuple(vecmap(&lambda.captures, |capture| { - match capture.transitive_capture_index { - Some(field_index) => match self.lambda_envs_stack.last() { - Some(lambda_ctx) => ast::Expression::ExtractTupleField( - Box::new(ast::Expression::Ident(lambda_ctx.env_ident.clone())), - field_index, - ), - None => unreachable!( - "Expected to find a parent closure environment, but found none" - ), - }, - None => { - let ident = self.local_ident(&capture.ident).unwrap(); - ast::Expression::Ident(ident) - } - } - })); - let expr_type = self.interner.id_type(expr); - let env_typ = if let types::Type::Function(_, _, function_env_type) = expr_type { - Self::convert_type(&function_env_type) - } else { - unreachable!("expected a Function type for a Lambda node") - }; - - let env_let_stmt = ast::Expression::Let(ast::Let { - id: env_local_id, - mutable: false, - name: env_name.to_string(), - expression: Box::new(env_tuple), - }); - - let location = None; // TODO: This should match the location of the lambda expression - let mutable = false; - let definition = Definition::Local(env_local_id); - - let env_ident = ast::Ident { - location, - mutable, - definition, - name: env_name.to_string(), - typ: env_typ.clone(), - }; - - self.lambda_envs_stack - .push(LambdaContext { env_ident: env_ident.clone(), captures: lambda.captures }); - let body = self.expr(lambda.body); - self.lambda_envs_stack.pop(); - - let lambda_fn_typ: ast::Type = - ast::Type::Function(parameter_types, Box::new(ret_type), Box::new(env_typ.clone())); - let lambda_fn = ast::Expression::Ident(ast::Ident { - definition: Definition::Function(id), - mutable: false, - location: None, // TODO: This should match the location of the lambda expression - name: name.clone(), - typ: lambda_fn_typ.clone(), - }); - - let mut parameters = vec![]; - parameters.push((env_local_id, true, env_name.to_string(), env_typ.clone())); - parameters.append(&mut converted_parameters); - - let unconstrained = false; - let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; - self.push_function(id, function); - - let lambda_value = - ast::Expression::Tuple(vec![ast::Expression::Ident(env_ident), lambda_fn]); - let block_local_id = self.next_local_id(); - let block_ident_name = "closure_variable"; - let block_let_stmt = ast::Expression::Let(ast::Let { - id: block_local_id, - mutable: false, - name: block_ident_name.to_string(), - expression: Box::new(ast::Expression::Block(vec![env_let_stmt, lambda_value])), - }); - - let closure_definition = Definition::Local(block_local_id); - - let closure_ident = ast::Expression::Ident(ast::Ident { - location, - mutable: false, - definition: closure_definition, - name: block_ident_name.to_string(), - typ: ast::Type::Tuple(vec![env_typ, lambda_fn_typ]), - }); - - (block_let_stmt, closure_ident) - } - - /// Implements std::unsafe::zeroed by returning an appropriate zeroed - /// ast literal or collection node for the given type. Note that for functions - /// there is no obvious zeroed value so this should be considered unsafe to use. - fn zeroed_value_of_type(&mut self, typ: &ast::Type) -> ast::Expression { - match typ { - ast::Type::Field | ast::Type::Integer(..) => { - ast::Expression::Literal(ast::Literal::Integer(0_u128.into(), typ.clone())) - } - ast::Type::Bool => ast::Expression::Literal(ast::Literal::Bool(false)), - // There is no unit literal currently. Replace it with 'false' since it should be ignored - // anyway. - ast::Type::Unit => ast::Expression::Literal(ast::Literal::Bool(false)), - ast::Type::Array(length, element_type) => { - let element = self.zeroed_value_of_type(element_type.as_ref()); - ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { - contents: vec![element; *length as usize], - typ: ast::Type::Array(*length, element_type.clone()), - })) - } - ast::Type::String(length) => { - ast::Expression::Literal(ast::Literal::Str("\0".repeat(*length as usize))) - } - ast::Type::FmtString(length, fields) => { - let zeroed_tuple = self.zeroed_value_of_type(fields); - let fields_len = match &zeroed_tuple { - ast::Expression::Tuple(fields) => fields.len() as u64, - _ => unreachable!("ICE: format string fields should be structured in a tuple, but got a {zeroed_tuple}"), - }; - ast::Expression::Literal(ast::Literal::FmtStr( - "\0".repeat(*length as usize), - fields_len, - Box::new(zeroed_tuple), - )) - } - ast::Type::Tuple(fields) => { - ast::Expression::Tuple(vecmap(fields, |field| self.zeroed_value_of_type(field))) - } - ast::Type::Function(parameter_types, ret_type, env) => { - self.create_zeroed_function(parameter_types, ret_type, env) - } - ast::Type::Slice(element_type) => { - ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { - contents: vec![], - typ: ast::Type::Slice(element_type.clone()), - })) - } - ast::Type::MutableReference(element) => { - use crate::UnaryOp::MutableReference; - let rhs = Box::new(self.zeroed_value_of_type(element)); - let result_type = typ.clone(); - ast::Expression::Unary(ast::Unary { rhs, result_type, operator: MutableReference }) - } - } - } - - // Creating a zeroed function value is almost always an error if it is used later, - // Hence why std::unsafe::zeroed is unsafe. - // - // To avoid confusing later passes, we arbitrarily choose to construct a function - // that satisfies the input type by discarding all its parameters and returning a - // zeroed value of the result type. - fn create_zeroed_function( - &mut self, - parameter_types: &[ast::Type], - ret_type: &ast::Type, - env_type: &ast::Type, - ) -> ast::Expression { - let lambda_name = "zeroed_lambda"; - - let parameters = vecmap(parameter_types, |parameter_type| { - (self.next_local_id(), false, "_".into(), parameter_type.clone()) - }); - - let body = self.zeroed_value_of_type(ret_type); - - let id = self.next_function_id(); - let return_type = ret_type.clone(); - let name = lambda_name.to_owned(); - - let unconstrained = false; - let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; - self.push_function(id, function); - - ast::Expression::Ident(ast::Ident { - definition: Definition::Function(id), - mutable: false, - location: None, - name: lambda_name.to_owned(), - typ: ast::Type::Function( - parameter_types.to_owned(), - Box::new(ret_type.clone()), - Box::new(env_type.clone()), - ), - }) - } -} - -fn unwrap_tuple_type(typ: &HirType) -> Vec { - match typ { - HirType::Tuple(fields) => fields.clone(), - HirType::TypeVariable(binding, TypeVariableKind::Normal) => match &*binding.borrow() { - TypeBinding::Bound(binding) => unwrap_tuple_type(binding), - TypeBinding::Unbound(_) => unreachable!(), - }, - other => unreachable!("unwrap_tuple_type: expected tuple, found {:?}", other), - } -} - -fn unwrap_struct_type(typ: &HirType) -> Vec<(String, HirType)> { - match typ { - HirType::Struct(def, args) => def.borrow().get_fields(args), - HirType::TypeVariable(binding, TypeVariableKind::Normal) => match &*binding.borrow() { - TypeBinding::Bound(binding) => unwrap_struct_type(binding), - TypeBinding::Unbound(_) => unreachable!(), - }, - other => unreachable!("unwrap_struct_type: expected struct, found {:?}", other), - } -} - -fn perform_instantiation_bindings(bindings: &TypeBindings) { - for (var, binding) in bindings.values() { - *var.borrow_mut() = TypeBinding::Bound(binding.clone()); - } -} - -fn undo_instantiation_bindings(bindings: TypeBindings) { - for (id, (var, _)) in bindings { - *var.borrow_mut() = TypeBinding::Unbound(id); - } -} - -#[cfg(test)] -mod tests { - use std::collections::HashMap; - - use fm::FileId; - use iter_extended::vecmap; - use noirc_errors::Location; - - use crate::{ - graph::CrateId, - hir::{ - def_map::{CrateDefMap, LocalModuleId, ModuleData, ModuleDefId, ModuleId}, - resolution::{ - import::PathResolutionError, path_resolver::PathResolver, resolver::Resolver, - }, - }, - hir_def::function::HirFunction, - node_interner::{FuncId, NodeInterner}, - parse_program, - }; - - use super::monomorphize; - - // TODO: refactor into a more general test utility? - // mostly copied from hir / type_check / mod.rs and adapted a bit - fn type_check_src_code(src: &str, func_namespace: Vec) -> (FuncId, NodeInterner) { - let (program, errors) = parse_program(src); - let mut interner = NodeInterner::default(); - - // Using assert_eq here instead of assert(errors.is_empty()) displays - // the whole vec if the assert fails rather than just two booleans - assert_eq!(errors, vec![]); - - let main_id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition("main".into(), main_id); - - let func_ids = vecmap(&func_namespace, |name| { - let id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition(name.into(), id); - id - }); - - let mut path_resolver = TestPathResolver(HashMap::new()); - for (name, id) in func_namespace.into_iter().zip(func_ids.clone()) { - path_resolver.insert_func(name.to_owned(), id); - } - - let mut def_maps: HashMap = HashMap::new(); - let file = FileId::default(); - - let mut modules = arena::Arena::new(); - let location = Location::new(Default::default(), file); - modules.insert(ModuleData::new(None, location, false)); - - def_maps.insert( - CrateId::dummy_id(), - CrateDefMap { - root: path_resolver.local_module_id(), - modules, - krate: CrateId::dummy_id(), - extern_prelude: HashMap::new(), - }, - ); - - let func_meta = vecmap(program.functions, |nf| { - let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); - let (hir_func, func_meta, _resolver_errors) = - resolver.resolve_function(nf, main_id, ModuleId::dummy_id()); - // TODO: not sure why, we do get an error here, - // but otherwise seem to get an ok monomorphization result - // assert_eq!(resolver_errors, vec![]); - (hir_func, func_meta) - }); - - println!("Before update_fn"); - - for ((hir_func, meta), func_id) in func_meta.into_iter().zip(func_ids.clone()) { - interner.update_fn(func_id, hir_func); - interner.push_fn_meta(meta, func_id); - } - - println!("Before type_check_func"); - - // Type check section - let errors = crate::hir::type_check::type_check_func( - &mut interner, - func_ids.first().cloned().unwrap(), - ); - assert_eq!(errors, vec![]); - (func_ids.first().cloned().unwrap(), interner) - } - - // TODO: refactor into a more general test utility? - // TestPathResolver struct and impls copied from hir / type_check / mod.rs - struct TestPathResolver(HashMap); - - impl PathResolver for TestPathResolver { - fn resolve( - &self, - _def_maps: &HashMap, - path: crate::Path, - ) -> Result { - // Not here that foo::bar and hello::foo::bar would fetch the same thing - let name = path.segments.last().unwrap(); - let mod_def = self.0.get(&name.0.contents).cloned(); - mod_def.ok_or_else(move || PathResolutionError::Unresolved(name.clone())) - } - - fn local_module_id(&self) -> LocalModuleId { - // This is not LocalModuleId::dummy since we need to use this to index into a Vec - // later and do not want to push u32::MAX number of elements before we do. - LocalModuleId(arena::Index::from_raw_parts(0, 0)) - } - - fn module_id(&self) -> ModuleId { - ModuleId { krate: CrateId::dummy_id(), local_id: self.local_module_id() } - } - } - - impl TestPathResolver { - fn insert_func(&mut self, name: String, func_id: FuncId) { - self.0.insert(name, func_id.into()); - } - } - - // a helper test method - // TODO: maybe just compare trimmed src/expected - // for easier formatting? - fn check_rewrite(src: &str, expected: &str) { - let (func, interner) = type_check_src_code(src, vec!["main".to_string()]); - let program = monomorphize(func, &interner); - // println!("[{}]", program); - assert!(format!("{}", program) == expected); - } - - #[test] - fn simple_closure_with_no_captured_variables() { - let src = r#" - fn main() -> pub Field { - let x = 1; - let closure = || x; - closure() - } - "#; - - let expected_rewrite = r#"fn main$f0() -> Field { - let x$0 = 1; - let closure$3 = { - let closure_variable$2 = { - let env$1 = (x$l0); - (env$l1, lambda$f1) - }; - closure_variable$l2 - }; - { - let tmp$4 = closure$l3; - tmp$l4.1(tmp$l4.0) - } -} -fn lambda$f1(mut env$l1: (Field)) -> Field { - env$l1.0 -} -"#; - check_rewrite(src, expected_rewrite); - } -} diff --git a/crates/noirc_frontend/src/parser/errors.rs b/crates/noirc_frontend/src/parser/errors.rs deleted file mode 100644 index ec3095a989d..00000000000 --- a/crates/noirc_frontend/src/parser/errors.rs +++ /dev/null @@ -1,191 +0,0 @@ -use crate::lexer::token::Token; -use crate::Expression; -use small_ord_set::SmallOrdSet; -use thiserror::Error; - -use iter_extended::vecmap; -use noirc_errors::CustomDiagnostic as Diagnostic; -use noirc_errors::Span; - -use super::labels::ParsingRuleLabel; - -#[derive(Debug, Clone, PartialEq, Eq, Error)] -pub enum ParserErrorReason { - #[error("Unexpected '{0}', expected a field name")] - ExpectedFieldName(Token), - #[error("expected a pattern but found a type - {0}")] - ExpectedPatternButFoundType(Token), - #[error("Expected a ; separating these two statements")] - MissingSeparatingSemi, - #[error("constrain keyword is deprecated")] - ConstrainDeprecated, - #[error("Expression is invalid in an array-length type: '{0}'. Only unsigned integer constants, globals, generics, +, -, *, /, and % may be used in this context.")] - InvalidArrayLengthExpression(Expression), - #[error("Early 'return' is unsupported")] - EarlyReturn, - #[error("Patterns aren't allowed in a trait's function declarations")] - PatternInTraitFunctionParameter, - #[error("comptime keyword is deprecated")] - ComptimeDeprecated, - #[error("{0} are experimental and aren't fully supported yet")] - ExperimentalFeature(&'static str), - #[error("Where clauses are allowed only on functions with generic parameters")] - WhereClauseOnNonGenericFunction, -} - -/// Represents a parsing error, or a parsing error in the making. -/// -/// `ParserError` is used extensively by the parser, as it not only used to report badly formed -/// token streams, but also as a general intermediate that accumulates information as various -/// parsing rules are tried. This struct is constructed and destructed with a very high frequency -/// and as such, the time taken to do so significantly impacts parsing performance. For this -/// reason we use `SmallOrdSet` to avoid heap allocations for as long as possible - this greatly -/// inflates the size of the error, but this is justified by a resulting increase in parsing -/// speeds of approximately 40% in release mode. -/// -/// Both `expected_tokens` and `expected_labels` use `SmallOrdSet` sized 1. In the of labels this -/// is optimal. In the of tokens we stop here due to fast diminishing returns. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ParserError { - expected_tokens: SmallOrdSet<[Token; 1]>, - expected_labels: SmallOrdSet<[ParsingRuleLabel; 1]>, - found: Token, - reason: Option, - span: Span, -} - -impl ParserError { - pub fn empty(found: Token, span: Span) -> ParserError { - ParserError { - expected_tokens: SmallOrdSet::new(), - expected_labels: SmallOrdSet::new(), - found, - reason: None, - span, - } - } - - pub fn expected_label(label: ParsingRuleLabel, found: Token, span: Span) -> ParserError { - let mut error = ParserError::empty(found, span); - error.expected_labels.insert(label); - error - } - - pub fn with_reason(reason: ParserErrorReason, span: Span) -> ParserError { - let mut error = ParserError::empty(Token::EOF, span); - error.reason = Some(reason); - error - } - - pub fn found(&self) -> &Token { - &self.found - } - - pub fn span(&self) -> Span { - self.span - } -} - -impl std::fmt::Display for ParserError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut expected = vecmap(&self.expected_tokens, ToString::to_string); - expected.append(&mut vecmap(&self.expected_labels, |label| format!("{label}"))); - - if expected.is_empty() { - write!(f, "Unexpected {} in input", self.found) - } else if expected.len() == 1 { - let first = expected.first().unwrap(); - let vowel = "aeiou".contains(first.chars().next().unwrap()); - write!( - f, - "Expected a{} {} but found {}", - if vowel { "n" } else { "" }, - first, - self.found - ) - } else { - let expected = expected.iter().map(ToString::to_string).collect::>().join(", "); - - write!(f, "Unexpected {}, expected one of {}", self.found, expected) - } - } -} - -impl From for Diagnostic { - fn from(error: ParserError) -> Diagnostic { - match &error.reason { - Some(reason) => { - match reason { - ParserErrorReason::ConstrainDeprecated => Diagnostic::simple_warning( - "Use of deprecated keyword 'constrain'".into(), - "The 'constrain' keyword has been deprecated. Please use the 'assert' function instead.".into(), - error.span, - ), - ParserErrorReason::ComptimeDeprecated => Diagnostic::simple_warning( - "Use of deprecated keyword 'comptime'".into(), - "The 'comptime' keyword has been deprecated. It can be removed without affecting your program".into(), - error.span, - ), - ParserErrorReason::ExperimentalFeature(_) => Diagnostic::simple_warning( - reason.to_string(), - "".into(), - error.span, - ), - reason @ ParserErrorReason::ExpectedPatternButFoundType(ty) => { - Diagnostic::simple_error(reason.to_string(), format!("{ty} is a type and cannot be used as a variable name"), error.span) - } - other => { - - Diagnostic::simple_error(format!("{other}"), String::new(), error.span) - } - } - } - None => { - let primary = error.to_string(); - Diagnostic::simple_error(primary, String::new(), error.span) - } - } - } -} - -impl chumsky::Error for ParserError { - type Span = Span; - type Label = ParsingRuleLabel; - - fn expected_input_found(span: Self::Span, expected: Iter, found: Option) -> Self - where - Iter: IntoIterator>, - { - ParserError { - expected_tokens: expected.into_iter().map(|opt| opt.unwrap_or(Token::EOF)).collect(), - expected_labels: SmallOrdSet::new(), - found: found.unwrap_or(Token::EOF), - reason: None, - span, - } - } - - fn with_label(mut self, label: Self::Label) -> Self { - self.expected_tokens.clear(); - self.expected_labels.clear(); - self.expected_labels.insert(label); - self - } - - // Merge two errors into a new one that should encompass both. - // If one error has a more specific reason with it then keep - // that reason and discard the other if present. - // The spans of both errors must match, otherwise the error - // messages and error spans may not line up. - fn merge(mut self, mut other: Self) -> Self { - self.expected_tokens.append(&mut other.expected_tokens); - self.expected_labels.append(&mut other.expected_labels); - - if self.reason.is_none() { - self.reason = other.reason; - } - - self.span = self.span.merge(other.span); - self - } -} diff --git a/crates/noirc_frontend/src/parser/mod.rs b/crates/noirc_frontend/src/parser/mod.rs deleted file mode 100644 index ad519836b39..00000000000 --- a/crates/noirc_frontend/src/parser/mod.rs +++ /dev/null @@ -1,528 +0,0 @@ -//! The parser is the second pass of the noir compiler. -//! The parser's job is to take the output of the lexer (a stream of tokens) -//! and parse it into a valid Abstract Syntax Tree (Ast). During this, the parser -//! validates the grammar of the program and returns parsing errors for any syntactically -//! invalid constructs (such as `fn fn fn`). -//! -//! This file is mostly helper functions and types for the parser. For the parser itself, -//! see parser.rs. The definition of the abstract syntax tree can be found in the `ast` folder. -mod errors; -mod labels; -#[allow(clippy::module_inception)] -mod parser; - -use std::sync::atomic::{AtomicU32, Ordering}; - -use crate::token::{Keyword, Token}; -use crate::{ast::ImportStatement, Expression, NoirStruct}; -use crate::{ - BlockExpression, ExpressionKind, ForExpression, Ident, IndexExpression, LetStatement, - MethodCallExpression, NoirFunction, NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, - Recoverable, Statement, TraitImpl, TypeImpl, UnresolvedType, UseTree, -}; - -use acvm::FieldElement; -use chumsky::prelude::*; -use chumsky::primitive::Container; -pub use errors::ParserError; -pub use errors::ParserErrorReason; -use noirc_errors::Span; -pub use parser::parse_program; - -/// Counter used to generate unique names when desugaring -/// code in the parser requires the creation of fresh variables. -/// The parser is stateless so this is a static global instead. -static UNIQUE_NAME_COUNTER: AtomicU32 = AtomicU32::new(0); - -#[derive(Debug, Clone)] -pub(crate) enum TopLevelStatement { - Function(NoirFunction), - Module(Ident), - Import(UseTree), - Struct(NoirStruct), - Trait(NoirTrait), - TraitImpl(TraitImpl), - Impl(TypeImpl), - TypeAlias(NoirTypeAlias), - SubModule(SubModule), - Global(LetStatement), - Error, -} - -// Helper trait that gives us simpler type signatures for return types: -// e.g. impl Parser versus impl Parser> -pub trait NoirParser: Parser + Sized + Clone {} -impl NoirParser for P where P: Parser + Clone {} - -// ExprParser just serves as a type alias for NoirParser + Clone -trait ExprParser: NoirParser {} -impl

ExprParser for P where P: NoirParser {} - -fn parenthesized(parser: P) -> impl NoirParser -where - P: NoirParser, - T: Recoverable, -{ - use Token::*; - parser.delimited_by(just(LeftParen), just(RightParen)).recover_with(nested_delimiters( - LeftParen, - RightParen, - [(LeftBracket, RightBracket)], - Recoverable::error, - )) -} - -fn spanned(parser: P) -> impl NoirParser<(T, Span)> -where - P: NoirParser, -{ - parser.map_with_span(|value, span| (value, span)) -} - -// Parse with the first parser, then continue by -// repeating the second parser 0 or more times. -// The passed in function is then used to combine the -// results of both parsers along with their spans at -// each step. -fn foldl_with_span( - first_parser: P1, - to_be_repeated: P2, - f: F, -) -> impl NoirParser -where - P1: NoirParser, - P2: NoirParser, - F: Fn(T1, T2, Span) -> T1 + Clone, -{ - spanned(first_parser) - .then(spanned(to_be_repeated).repeated()) - .foldl(move |(a, a_span), (b, b_span)| { - let span = a_span.merge(b_span); - (f(a, b, span), span) - }) - .map(|(value, _span)| value) -} - -/// Sequence the two parsers. -/// Fails if the first parser fails, otherwise forces -/// the second parser to succeed while logging any errors. -fn then_commit<'a, P1, P2, T1, T2: 'a>( - first_parser: P1, - second_parser: P2, -) -> impl NoirParser<(T1, T2)> + 'a -where - P1: NoirParser + 'a, - P2: NoirParser + 'a, - T2: Clone + Recoverable, -{ - let second_parser = skip_then_retry_until(second_parser) - .map_with_span(|option, span| option.unwrap_or_else(|| Recoverable::error(span))); - - first_parser.then(second_parser) -} - -fn then_commit_ignore<'a, P1, P2, T1: 'a, T2: 'a>( - first_parser: P1, - second_parser: P2, -) -> impl NoirParser + 'a -where - P1: NoirParser + 'a, - P2: NoirParser + 'a, - T2: Clone, -{ - let second_parser = skip_then_retry_until(second_parser); - first_parser.then_ignore(second_parser) -} - -fn ignore_then_commit<'a, P1, P2, T1: 'a, T2: Clone + 'a>( - first_parser: P1, - second_parser: P2, -) -> impl NoirParser + 'a -where - P1: NoirParser + 'a, - P2: NoirParser + 'a, - T2: Recoverable, -{ - let second_parser = skip_then_retry_until(second_parser) - .map_with_span(|option, span| option.unwrap_or_else(|| Recoverable::error(span))); - - first_parser.ignore_then(second_parser) -} - -fn skip_then_retry_until<'a, P, T: 'a>(parser: P) -> impl NoirParser> + 'a -where - P: NoirParser + 'a, - T: Clone, -{ - let terminators = [ - Token::EOF, - Token::Colon, - Token::Semicolon, - Token::RightBrace, - Token::Keyword(Keyword::Let), - Token::Keyword(Keyword::Constrain), - ]; - force(parser.recover_with(chumsky::prelude::skip_then_retry_until(terminators))) -} - -/// General recovery strategy: try to skip to the target token, failing if we encounter the -/// 'too_far' token beforehand. -/// -/// Expects all of `too_far` to be contained within `targets` -fn try_skip_until(targets: C1, too_far: C2) -> impl NoirParser -where - T: Recoverable + Clone, - C1: Container + Clone, - C2: Container + Clone, -{ - chumsky::prelude::none_of(targets) - .repeated() - .ignore_then(one_of(too_far.clone()).rewind()) - .try_map(move |peek, span| { - if too_far.get_iter().any(|t| t == peek) { - // This error will never be shown to the user - Err(ParserError::empty(Token::EOF, span)) - } else { - Ok(Recoverable::error(span)) - } - }) -} - -/// Recovery strategy for statements: If a statement fails to parse skip until the next ';' or fail -/// if we find a '}' first. -fn statement_recovery() -> impl NoirParser { - use Token::*; - try_skip_until([Semicolon, RightBrace], RightBrace) -} - -fn parameter_recovery() -> impl NoirParser { - use Token::*; - try_skip_until([Comma, RightParen], RightParen) -} - -fn parameter_name_recovery() -> impl NoirParser { - use Token::*; - try_skip_until([Colon, RightParen, Comma], [RightParen, Comma]) -} - -fn top_level_statement_recovery() -> impl NoirParser { - none_of([Token::Semicolon, Token::RightBrace, Token::EOF]) - .repeated() - .ignore_then(one_of([Token::Semicolon])) - .map(|_| TopLevelStatement::Error) -} - -/// Force the given parser to succeed, logging any errors it had -fn force<'a, T: 'a>(parser: impl NoirParser + 'a) -> impl NoirParser> + 'a { - parser.map(Some).recover_via(empty().map(|_| None)) -} - -/// A ParsedModule contains an entire Ast for one file. -#[derive(Clone, Debug, Default)] -pub struct ParsedModule { - pub imports: Vec, - pub functions: Vec, - pub types: Vec, - pub traits: Vec, - pub trait_impls: Vec, - pub impls: Vec, - pub type_aliases: Vec, - pub globals: Vec, - - /// Module declarations like `mod foo;` - pub module_decls: Vec, - - /// Full submodules as in `mod foo { ... definitions ... }` - pub submodules: Vec, -} - -/// A submodule defined via `mod name { contents }` in some larger file. -/// These submodules always share the same file as some larger ParsedModule -#[derive(Clone, Debug)] -pub struct SubModule { - pub name: Ident, - pub contents: ParsedModule, - pub is_contract: bool, -} - -impl ParsedModule { - fn push_function(&mut self, func: NoirFunction) { - self.functions.push(func); - } - - fn push_type(&mut self, typ: NoirStruct) { - self.types.push(typ); - } - - fn push_trait(&mut self, noir_trait: NoirTrait) { - self.traits.push(noir_trait); - } - - fn push_trait_impl(&mut self, trait_impl: TraitImpl) { - self.trait_impls.push(trait_impl); - } - - fn push_impl(&mut self, r#impl: TypeImpl) { - self.impls.push(r#impl); - } - - fn push_type_alias(&mut self, type_alias: NoirTypeAlias) { - self.type_aliases.push(type_alias); - } - - fn push_import(&mut self, import_stmt: UseTree) { - self.imports.extend(import_stmt.desugar(None)); - } - - fn push_module_decl(&mut self, mod_name: Ident) { - self.module_decls.push(mod_name); - } - - fn push_submodule(&mut self, submodule: SubModule) { - self.submodules.push(submodule); - } - - fn push_global(&mut self, global: LetStatement) { - self.globals.push(global); - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd)] -pub enum Precedence { - Lowest, - Or, - And, - Xor, - LessGreater, - Shift, - Sum, - Product, - Highest, -} - -impl Precedence { - // Higher the number, the higher(more priority) the precedence - // XXX: Check the precedence is correct for operators - fn token_precedence(tok: &Token) -> Option { - let precedence = match tok { - Token::Equal => Precedence::Lowest, - Token::NotEqual => Precedence::Lowest, - Token::Pipe => Precedence::Or, - Token::Ampersand => Precedence::And, - Token::Caret => Precedence::Xor, - Token::Less => Precedence::LessGreater, - Token::LessEqual => Precedence::LessGreater, - Token::Greater => Precedence::LessGreater, - Token::GreaterEqual => Precedence::LessGreater, - Token::ShiftLeft => Precedence::Shift, - Token::ShiftRight => Precedence::Shift, - Token::Plus => Precedence::Sum, - Token::Minus => Precedence::Sum, - Token::Slash => Precedence::Product, - Token::Star => Precedence::Product, - Token::Percent => Precedence::Product, - _ => return None, - }; - - assert_ne!(precedence, Precedence::Highest, "expression_with_precedence in the parser currently relies on the highest precedence level being uninhabited"); - Some(precedence) - } - - /// Return the next higher precedence. E.g. `Sum.next() == Product` - fn next(self) -> Self { - use Precedence::*; - match self { - Lowest => Or, - Or => Xor, - Xor => And, - And => LessGreater, - LessGreater => Shift, - Shift => Sum, - Sum => Product, - Product => Highest, - Highest => Highest, - } - } - - /// TypeExpressions only contain basic arithmetic operators and - /// notably exclude `>` due to parsing conflicts with generic type brackets. - fn next_type_precedence(self) -> Self { - use Precedence::*; - match self { - Lowest => Sum, - Sum => Product, - Product => Highest, - Highest => Highest, - other => unreachable!("Unexpected precedence level in type expression: {:?}", other), - } - } - - /// The operators with the lowest precedence still useable in type expressions - /// are '+' and '-' with precedence Sum. - fn lowest_type_precedence() -> Self { - Precedence::Sum - } -} - -enum ForRange { - Range(/*start:*/ Expression, /*end:*/ Expression), - Array(Expression), -} - -impl ForRange { - /// Create a 'for' expression taking care of desugaring a 'for e in array' loop - /// into the following if needed: - /// - /// { - /// let fresh1 = array; - /// for fresh2 in 0 .. std::array::len(fresh1) { - /// let elem = fresh1[fresh2]; - /// ... - /// } - /// } - fn into_for(self, identifier: Ident, block: Expression, for_loop_span: Span) -> ExpressionKind { - match self { - ForRange::Range(start_range, end_range) => { - ExpressionKind::For(Box::new(ForExpression { - identifier, - start_range, - end_range, - block, - })) - } - ForRange::Array(array) => { - let array_span = array.span; - let start_range = ExpressionKind::integer(FieldElement::zero()); - let start_range = Expression::new(start_range, array_span); - - let next_unique_id = UNIQUE_NAME_COUNTER.fetch_add(1, Ordering::Relaxed); - let array_name = format!("$i{next_unique_id}"); - let array_span = array.span; - let array_ident = Ident::new(array_name, array_span); - - // let fresh1 = array; - let let_array = Statement::Let(LetStatement { - pattern: Pattern::Identifier(array_ident.clone()), - r#type: UnresolvedType::Unspecified, - expression: array, - }); - - // array.len() - let segments = vec![array_ident]; - let array_ident = - ExpressionKind::Variable(Path { segments, kind: PathKind::Plain }); - - let end_range = ExpressionKind::MethodCall(Box::new(MethodCallExpression { - object: Expression::new(array_ident.clone(), array_span), - method_name: Ident::new("len".to_string(), array_span), - arguments: vec![], - })); - let end_range = Expression::new(end_range, array_span); - - let next_unique_id = UNIQUE_NAME_COUNTER.fetch_add(1, Ordering::Relaxed); - let index_name = format!("$i{next_unique_id}"); - let fresh_identifier = Ident::new(index_name.clone(), array_span); - - // array[i] - let segments = vec![Ident::new(index_name, array_span)]; - let index_ident = - ExpressionKind::Variable(Path { segments, kind: PathKind::Plain }); - - let loop_element = ExpressionKind::Index(Box::new(IndexExpression { - collection: Expression::new(array_ident, array_span), - index: Expression::new(index_ident, array_span), - })); - - // let elem = array[i]; - let let_elem = Statement::Let(LetStatement { - pattern: Pattern::Identifier(identifier), - r#type: UnresolvedType::Unspecified, - expression: Expression::new(loop_element, array_span), - }); - - let block_span = block.span; - let new_block = BlockExpression(vec![let_elem, Statement::Expression(block)]); - let new_block = Expression::new(ExpressionKind::Block(new_block), block_span); - let for_loop = ExpressionKind::For(Box::new(ForExpression { - identifier: fresh_identifier, - start_range, - end_range, - block: new_block, - })); - - ExpressionKind::Block(BlockExpression(vec![ - let_array, - Statement::Expression(Expression::new(for_loop, for_loop_span)), - ])) - } - } - } -} - -impl std::fmt::Display for TopLevelStatement { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TopLevelStatement::Function(fun) => fun.fmt(f), - TopLevelStatement::Module(m) => write!(f, "mod {m}"), - TopLevelStatement::Import(tree) => write!(f, "use {tree}"), - TopLevelStatement::Trait(t) => t.fmt(f), - TopLevelStatement::TraitImpl(i) => i.fmt(f), - TopLevelStatement::Struct(s) => s.fmt(f), - TopLevelStatement::Impl(i) => i.fmt(f), - TopLevelStatement::TypeAlias(t) => t.fmt(f), - TopLevelStatement::SubModule(s) => s.fmt(f), - TopLevelStatement::Global(c) => c.fmt(f), - TopLevelStatement::Error => write!(f, "error"), - } - } -} - -impl std::fmt::Display for ParsedModule { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - for decl in &self.module_decls { - writeln!(f, "mod {decl};")?; - } - - for import in &self.imports { - write!(f, "{import}")?; - } - - for global_const in &self.globals { - write!(f, "{global_const}")?; - } - - for type_ in &self.types { - write!(f, "{type_}")?; - } - - for function in &self.functions { - write!(f, "{function}")?; - } - - for impl_ in &self.impls { - write!(f, "{impl_}")?; - } - - for type_alias in &self.type_aliases { - write!(f, "{type_alias}")?; - } - - for submodule in &self.submodules { - write!(f, "{submodule}")?; - } - - Ok(()) - } -} - -impl std::fmt::Display for SubModule { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "mod {} {{", self.name)?; - - for line in self.contents.to_string().lines() { - write!(f, "\n {line}")?; - } - - write!(f, "\n}}") - } -} diff --git a/crates/noirc_printable_type/Cargo.toml b/crates/noirc_printable_type/Cargo.toml deleted file mode 100644 index b3de1a63dec..00000000000 --- a/crates/noirc_printable_type/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "noirc_printable_type" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -acvm.workspace = true -iter-extended.workspace = true -regex = "1.9.1" -serde.workspace = true -serde_json.workspace = true -thiserror.workspace = true - -[dev-dependencies] diff --git a/crates/wasm/Cargo.toml b/crates/wasm/Cargo.toml deleted file mode 100644 index 2b834318168..00000000000 --- a/crates/wasm/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "noir_wasm" -version.workspace = true -authors.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - - -[lib] -crate-type = ["cdylib"] - -[dependencies] - -acvm.workspace = true -fm.workspace = true -noirc_driver.workspace = true -noirc_frontend.workspace = true -wasm-bindgen.workspace = true -serde.workspace = true -log = "0.4.17" -wasm-logger = "0.2.0" -console_error_panic_hook = "0.1.7" -gloo-utils = { version = "0.1", features = ["serde"] } - -# This is an unused dependency, we are adding it -# so that we can enable the js feature in getrandom. -getrandom = { version = "*", features = ["js"] } - -[build-dependencies] -build-data = "0.1.3" diff --git a/crates/wasm/package.json b/crates/wasm/package.json deleted file mode 100644 index b01e36d27b1..00000000000 --- a/crates/wasm/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@noir-lang/noir_wasm", - "collaborators": [ - "The Noir Team " - ], - "version": "0.10.3", - "license": "(MIT OR Apache-2.0)", - "main": "./nodejs/noir_wasm.js", - "types": "./web/noir_wasm.d.ts", - "module": "./web/noir_wasm.js", - "files": [ - "nodejs", - "web", - "package.json" - ], - "sideEffects": false, - "packageManager": "yarn@3.5.1", - "repository": { - "type": "git", - "url": "https://github.com/noir-lang/noir_wasm.git" - }, - "scripts": { - "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", - "test:browser": "web-test-runner" - }, - "peerDependencies": { - "@noir-lang/noir-source-resolver": "^1.1.3" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.3.4-fix.0", - "@noir-lang/noir-source-resolver": "^1.1.3", - "@web/dev-server-esbuild": "^0.3.6", - "@web/test-runner": "^0.15.3", - "@web/test-runner-playwright": "^0.10.0", - "chai": "^4.3.7", - "mocha": "^10.2.0", - "ts-node": "^10.9.1", - "typescript": "^5.0.4" - } -} diff --git a/crates/wasm/src/compile.rs b/crates/wasm/src/compile.rs deleted file mode 100644 index 01f286f924f..00000000000 --- a/crates/wasm/src/compile.rs +++ /dev/null @@ -1,138 +0,0 @@ -use acvm::acir::circuit::Circuit; -use fm::FileManager; -use gloo_utils::format::JsValueSerdeExt; -use log::debug; -use noirc_driver::{ - check_crate, compile_contracts, compile_no_check, prepare_crate, prepare_dependency, - propagate_dep, CompileOptions, CompiledContract, -}; -use noirc_frontend::{graph::CrateGraph, hir::Context}; -use serde::{Deserialize, Serialize}; -use std::path::Path; -use wasm_bindgen::prelude::*; - -#[derive(Debug, Serialize, Deserialize)] -pub struct WASMCompileOptions { - #[serde(default = "default_entry_point")] - entry_point: String, - - #[serde(default = "default_circuit_name")] - circuit_name: String, - - // Compile each contract function used within the program - #[serde(default = "bool::default")] - contracts: bool, - - #[serde(default)] - compile_options: CompileOptions, - - #[serde(default)] - optional_dependencies_set: Vec, - - #[serde(default = "default_log_level")] - log_level: String, -} - -fn default_log_level() -> String { - String::from("info") -} - -fn default_circuit_name() -> String { - String::from("contract") -} - -fn default_entry_point() -> String { - String::from("main.nr") -} - -impl Default for WASMCompileOptions { - fn default() -> Self { - Self { - entry_point: default_entry_point(), - circuit_name: default_circuit_name(), - log_level: default_log_level(), - contracts: false, - compile_options: CompileOptions::default(), - optional_dependencies_set: vec![], - } - } -} - -fn add_noir_lib(context: &mut Context, crate_name: &str) { - let path_to_lib = Path::new(&crate_name).join("lib.nr"); - let library_crate = prepare_dependency(context, &path_to_lib); - - propagate_dep(context, library_crate, &crate_name.parse().unwrap()); -} - -#[wasm_bindgen] -pub fn compile(args: JsValue) -> JsValue { - console_error_panic_hook::set_once(); - - let options: WASMCompileOptions = if args.is_undefined() || args.is_null() { - debug!("Initializing compiler with default values."); - WASMCompileOptions::default() - } else { - JsValueSerdeExt::into_serde(&args).expect("Could not deserialize compile arguments") - }; - - debug!("Compiler configuration {:?}", &options); - - let root = Path::new("/"); - let fm = FileManager::new(root); - let graph = CrateGraph::default(); - let mut context = Context::new(fm, graph); - - let path = Path::new(&options.entry_point); - let crate_id = prepare_crate(&mut context, path); - - for dependency in options.optional_dependencies_set { - add_noir_lib(&mut context, dependency.as_str()); - } - - check_crate(&mut context, crate_id, false).expect("Crate check failed"); - - if options.contracts { - let compiled_contracts = - compile_contracts(&mut context, crate_id, &options.compile_options) - .expect("Contract compilation failed") - .0; - - let optimized_contracts: Vec = - compiled_contracts.into_iter().map(optimize_contract).collect(); - - ::from_serde(&optimized_contracts).unwrap() - } else { - let main = context.get_main_function(&crate_id).expect("Could not find main function!"); - let mut compiled_program = - compile_no_check(&context, &options.compile_options, main).expect("Compilation failed"); - - compiled_program.circuit = optimize_circuit(compiled_program.circuit); - - ::from_serde(&compiled_program).unwrap() - } -} - -fn optimize_contract(contract: CompiledContract) -> CompiledContract { - CompiledContract { - name: contract.name, - functions: contract - .functions - .into_iter() - .map(|mut func| { - func.bytecode = optimize_circuit(func.bytecode); - func - }) - .collect(), - } -} - -fn optimize_circuit(circuit: Circuit) -> Circuit { - // For now we default to plonk width = 3, though we can add it as a parameter - let language = acvm::Language::PLONKCSat { width: 3 }; - #[allow(deprecated)] - let opcode_supported = acvm::pwg::default_is_opcode_supported(language); - acvm::compiler::compile(circuit, language, opcode_supported) - .expect("Circuit optimization failed") - .0 -} diff --git a/crates/wasm/test/browser/index.test.ts b/crates/wasm/test/browser/index.test.ts deleted file mode 100644 index 9cc49069bfd..00000000000 --- a/crates/wasm/test/browser/index.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { expect } from "@esm-bundle/chai"; -import initNoirWasm from "../../result"; -import { compileNoirSource, nargoArtifactPath, noirSourcePath } from "../shared"; - -beforeEach(async () => { - await initNoirWasm(); -}); - -async function getFileContent(path: string): Promise { - const mainnrSourceURL = new URL(path, import.meta.url); - const response = await fetch(mainnrSourceURL); - return await response.text(); -} - -async function getSource(): Promise { - return getFileContent(noirSourcePath) -} - -async function getPrecompiledSource(): Promise { - const compiledData = await getFileContent(nargoArtifactPath); - return JSON.parse(compiledData).bytecode; -} - -describe("noir wasm compilation", () => { - it("matches nargos compilation", async () => { - const source = await getSource(); - - const wasmCircuitBase64 = await compileNoirSource(source); - - const cliCircuitBase64 = await getPrecompiledSource(); - - - expect(wasmCircuitBase64).to.equal(cliCircuitBase64); - }).timeout(10e3); -}); diff --git a/crates/wasm/test/node/index.test.ts b/crates/wasm/test/node/index.test.ts deleted file mode 100644 index 9710023b29e..00000000000 --- a/crates/wasm/test/node/index.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { expect } from "@esm-bundle/chai"; -import { compileNoirSource, nargoArtifactPath, noirSourcePath } from "../shared"; -import { readFileSync } from "node:fs"; - -async function getFileContent(path: string): Promise { - return readFileSync(path).toString() -} - -async function getSource(): Promise { - return getFileContent(noirSourcePath) -} - -async function getPrecompiledSource(): Promise { - const compiledData = await getFileContent(nargoArtifactPath); - return JSON.parse(compiledData).bytecode; -} - -describe("noir wasm compilation", () => { - it("matches nargos compilation", async () => { - const source = await getSource(); - - const wasmCircuitBase64 = await compileNoirSource(source); - - const cliCircuitBase64 = await getPrecompiledSource(); - - console.log("wasm", wasmCircuitBase64); - - console.log("cli", cliCircuitBase64); - - console.log("Compilation is a match? ", wasmCircuitBase64 === cliCircuitBase64); - - expect(wasmCircuitBase64).to.equal(cliCircuitBase64); - }).timeout(10e3); -}); diff --git a/crates/wasm/web-test-runner.config.mjs b/crates/wasm/web-test-runner.config.mjs deleted file mode 100644 index 8d245789238..00000000000 --- a/crates/wasm/web-test-runner.config.mjs +++ /dev/null @@ -1,23 +0,0 @@ -import { esbuildPlugin } from "@web/dev-server-esbuild"; -import { playwrightLauncher } from "@web/test-runner-playwright"; - -export default { - browsers: [ - playwrightLauncher({ product: "chromium" }), - playwrightLauncher({ product: "webkit" }), - playwrightLauncher({ product: "firefox" }), - ], - plugins: [ - esbuildPlugin({ - ts: true, - }), - ], - files: ["test/browser/**/*.test.ts"], - nodeResolve: true, - testFramework: { - config: { - ui: "bdd", - timeout: 40000, - }, - }, -}; diff --git a/cspell.json b/cspell.json index 9953b6f0cd0..d7a25b5378c 100644 --- a/cspell.json +++ b/cspell.json @@ -3,6 +3,7 @@ "words": [ // In code // + "aarch", "aeiou", "arraysort", "arithmetization", diff --git a/deny.toml b/deny.toml new file mode 100644 index 00000000000..8d6d609bff8 --- /dev/null +++ b/deny.toml @@ -0,0 +1,100 @@ +# This section is considered when running `cargo deny check advisories` +# More documentation for the advisories section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html +[advisories] +vulnerability = "deny" +unmaintained = "warn" +unsound = "warn" +yanked = "warn" +notice = "warn" + +# This section is considered when running `cargo deny check bans`. +# More documentation about the 'bans' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html +[bans] +# Lint level for when multiple versions of the same crate are detected +multiple-versions = "warn" +# Lint level for when a crate version requirement is `*` +wildcards = "allow" +highlight = "all" +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, +] +# Certain crates/versions that will be skipped when doing duplicate detection. +skip = [] +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive +# dependencies starting at the specified crate, up to a certain depth, which is +# by default infinite +skip-tree = [] + +[licenses] +unlicensed = "deny" +confidence-threshold = 0.9 +# copyleft = "deny" + +# List of explicitly allowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.7 short identifier (+ optional exception)]. +allow = [ + "MIT", + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "ISC", + "0BSD", + "Unicode-DFS-2016", + "Unlicense", + "Zlib", + # https://github.com/briansmith/ring/issues/902 + "LicenseRef-ring", + # https://github.com/briansmith/webpki/issues/148 + "LicenseRef-webpki", + # https://github.com/rustls/webpki/blob/main/LICENSE ISC Style + "LicenseRef-rustls-webpki", +] + +# Allow 1 or more licenses on a per-crate basis, so that particular licenses +# aren't accepted for every possible crate as with the normal allow list +exceptions = [ + # CC0 is a permissive license but somewhat unclear status for source code + # so we prefer to not have dependencies using it + # https://tldrlegal.com/license/creative-commons-cc0-1.0-universal + { allow = ["CC0-1.0"], name = "more-asserts" }, + { allow = ["MPL-2.0"], name = "sized-chunks" }, + { allow = ["MPL-2.0"], name = "webpki-roots" }, + +] + +[[licenses.clarify]] +name = "ring" +expression = "LicenseRef-ring" +license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }] + +[[licenses.clarify]] +name = "webpki" +expression = "LicenseRef-webpki" +license-files = [{ path = "LICENSE", hash = 0x001c7e6c }] + +[[licenses.clarify]] +name = "rustls-webpki" +expression = "LicenseRef-rustls-webpki" +license-files = [{ path = "LICENSE", hash = 0x001c7e6c }] + +# This section is considered when running `cargo deny check sources`. +# More documentation about the 'sources' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html +[sources] +# Lint level for what to happen when a crate from a crate registry that is not +# in the allow list is encountered +unknown-registry = "warn" +# Lint level for what to happen when a crate from a git repository that is not +# in the allow list is encountered +unknown-git = "deny" +allow-git = [ + "https://github.com/jfecher/chumsky" +] \ No newline at end of file diff --git a/flake.nix b/flake.nix index 5514dc767df..b6d5a3e750f 100644 --- a/flake.nix +++ b/flake.nix @@ -76,6 +76,11 @@ sharedEnvironment = { # We enable backtraces on any failure for help with debugging RUST_BACKTRACE = "1"; + + BARRETENBERG_ARCHIVE = builtins.fetchurl { + url = "https://github.com/AztecProtocol/barretenberg/releases/download/barretenberg-v0.4.5/acvm_backend.wasm.tar.gz"; + sha256 = "sha256:0z24yhvxc0dr13xj7y4xs9p42lzxwpazrmsrdpcgynfajkk6vqy4"; + }; }; nativeEnvironment = sharedEnvironment // { @@ -94,12 +99,18 @@ GIT_COMMIT = if (self ? rev) then self.rev else "unknown"; GIT_DIRTY = if (self ? rev) then "false" else "true"; + # We use `include_str!` macro to embed the solidity verifier template so we need to create a special + # source filter to include .sol files in addition to usual rust/cargo source files. + solidityFilter = path: _type: builtins.match ".*sol$" path != null; + # We use `.bytecode` and `.tr` files to test interactions with `bb` so we add a source filter to include these. + bytecodeFilter = path: _type: builtins.match ".*bytecode$" path != null; + witnessFilter = path: _type: builtins.match ".*tr$" path != null; # We use `.nr` and `.toml` files in tests so we need to create a special source # filter to include those files in addition to usual rust/cargo source files noirFilter = path: _type: builtins.match ".*nr$" path != null; tomlFilter = path: _type: builtins.match ".*toml$" path != null; sourceFilter = path: type: - (noirFilter path type) || (tomlFilter path type) || (craneLib.filterCargoSources path type); + (solidityFilter path type) || (bytecodeFilter path type)|| (witnessFilter path type) || (noirFilter path type) || (tomlFilter path type) || (craneLib.filterCargoSources path type); # As per https://discourse.nixos.org/t/gcc11stdenv-and-clang/17734/7 since it seems that aarch64-linux uses # gcc9 instead of gcc11 for the C++ stdlib, while all other targets we support provide the correct libstdc++ @@ -113,11 +124,17 @@ # Need libiconv and apple Security on Darwin. See https://github.com/ipetkov/crane/issues/156 pkgs.libiconv pkgs.darwin.apple_sdk.frameworks.Security + ] ++ [ + # Need to install various packages used by the `bb` binary. + pkgs.curl + stdenv.cc.cc.lib + pkgs.gcc.cc.lib + pkgs.gzip ]; sharedArgs = { # x-release-please-start-version - version = "0.10.3"; + version = "0.11.1"; # x-release-please-end src = pkgs.lib.cleanSourceWith { @@ -144,42 +161,70 @@ pkgs.pkg-config # This provides the `lld` linker to cargo pkgs.llvmPackages.bintools + ] ++ pkgs.lib.optionals stdenv.isLinux [ + # This is linux specific and used to patch the rpath and interpreter of the bb binary + pkgs.patchelf ]; buildInputs = [ - pkgs.llvmPackages.openmp - pkgs.barretenberg ] ++ extraBuildInputs; }; - # Combine the environment and other configuration needed for crane to build with the wasm feature - wasmArgs = wasmEnvironment // sharedArgs // { - pname = "noir-wasm"; + # Combine the environmnet with cargo args needed to build wasm package + noirWasmArgs = sharedEnvironment // sharedArgs // { + pname = "noir_wasm"; - # We disable the default "plonk_bn254" feature and enable the "plonk_bn254_wasm" feature - cargoExtraArgs = "--no-default-features --features='plonk_bn254_wasm'"; + src = ./.; + + cargoExtraArgs = "--package noir_wasm --target wasm32-unknown-unknown"; buildInputs = [ ] ++ extraBuildInputs; + + doCheck = false; }; - # Combine the environmnet with cargo args needed to build wasm package - noirWasmArgs = sharedEnvironment // sharedArgs // { - pname = "noir_wasm"; + # Combine the environment with cargo args needed to build wasm package + noirc_abi_WasmArgs = sharedEnvironment // sharedArgs // { + pname = "noirc_abi_wasm"; src = ./.; - cargoExtraArgs = "--package noir_wasm --target wasm32-unknown-unknown"; + cargoExtraArgs = "--package noirc_abi_wasm --target wasm32-unknown-unknown"; buildInputs = [ ] ++ extraBuildInputs; doCheck = false; }; + + # Conditionally download the binary based on whether it is linux or mac + bb_binary = let + platformSpecificUrl = if stdenv.hostPlatform.isLinux then + "https://github.com/AztecProtocol/barretenberg/releases/download/barretenberg-v0.4.3/bb-ubuntu.tar.gz" + else if stdenv.hostPlatform.isDarwin then + "https://github.com/AztecProtocol/barretenberg/releases/download/barretenberg-v0.4.3/barretenberg-x86_64-apple-darwin.tar.gz" + else + throw "Unsupported platform"; + + platformSpecificHash = if stdenv.hostPlatform.isLinux then + "sha256:0rcsjws87f4v28cw9734c10pg7c49apigf4lg3m0ji5vbhhmfnhr" + else if stdenv.hostPlatform.isDarwin then + "sha256:0pnsd56z0vkai7m0advawfgcvq9jbnpqm7lk98n5flqj583x3w35" + else + throw "Unsupported platform"; + in builtins.fetchurl { + url = platformSpecificUrl; + sha256 = platformSpecificHash; + }; # The `port` is parameterized to support parallel test runs without colliding static servers testArgs = port: testEnvironment // { + BB_BINARY_PATH = "/tmp/backend_binary"; + + BB_BINARY_URL = "http://0.0.0.0:${toString port}/${builtins.baseNameOf bb_binary}"; + # We provide `barretenberg-transcript00` from the overlay to the tests as a URL hosted via a static server # This is necessary because the Nix sandbox has no network access and downloading during tests would fail - TRANSCRIPT_URL = "http://0.0.0.0:${toString port}/${builtins.baseNameOf pkgs.barretenberg-transcript00}"; + BARRETENBERG_TRANSCRIPT_URL = "http://0.0.0.0:${toString port}/${builtins.baseNameOf pkgs.barretenberg-transcript00}"; # This copies the `barretenberg-transcript00` from the Nix store into this sandbox # which avoids exposing the entire Nix store to the static server it starts @@ -188,6 +233,24 @@ # We also set the NARGO_BACKEND_CACHE_DIR environment variable to the $TMP directory so we can successfully cache # the transcript; which isn't possible with the default path because the Nix sandbox disabled $HOME preCheck = '' + echo "Extracting bb binary" + mkdir extracted + tar -xf ${bb_binary} -C extracted + + # Conditionally patch the binary for Linux + ${if stdenv.hostPlatform.isLinux then '' + + cp extracted/cpp/build/bin/bb /tmp/backend_binary + + echo "Patching bb binary for Linux" + patchelf --set-rpath "${stdenv.cc.cc.lib}/lib:${pkgs.gcc.cc.lib}/lib" /tmp/backend_binary + patchelf --set-interpreter ${stdenv.cc.libc}/lib/ld-linux-x86-64.so.2 /tmp/backend_binary + '' else if stdenv.hostPlatform.isDarwin then '' + cp extracted/bb /tmp/backend_binary + '' else + throw "Unsupported platform" + } + export NARGO_BACKEND_CACHE_DIR=$TMP cp ${pkgs.barretenberg-transcript00} . echo "Starting simple static server" @@ -202,8 +265,8 @@ # Build *just* the cargo dependencies, so we can reuse all of that work between runs native-cargo-artifacts = craneLib.buildDepsOnly nativeArgs; - wasm-cargo-artifacts = craneLib.buildDepsOnly wasmArgs; noir-wasm-cargo-artifacts = craneLib.buildDepsOnly noirWasmArgs; + noirc-abi-wasm-cargo-artifacts = craneLib.buildDepsOnly noirc_abi_WasmArgs; noir-native = craneLib.buildPackage (nativeArgs // { inherit GIT_COMMIT GIT_DIRTY; @@ -214,15 +277,6 @@ doCheck = false; }); - noir-wasm = craneLib.buildPackage (wasmArgs // { - inherit GIT_COMMIT GIT_DIRTY; - - cargoArtifacts = wasm-cargo-artifacts; - - # We don't want to run checks or tests when just building the project - doCheck = false; - }); - wasm-bindgen-cli = pkgs.callPackage ./wasm-bindgen-cli.nix { rustPlatform = pkgs.makeRustPlatform { rustc = rustToolchain; @@ -238,6 +292,13 @@ cargoArtifacts = native-cargo-artifacts; }); + cargo-fmt = craneLib.cargoFmt (nativeArgs // { + inherit GIT_COMMIT GIT_DIRTY; + + cargoArtifacts = native-cargo-artifacts; + doCheck = true; + }); + cargo-test = craneLib.cargoTest (nativeArgs // (testArgs 8000) // { inherit GIT_COMMIT GIT_DIRTY; @@ -249,12 +310,11 @@ default = noir-native; inherit noir-native; - inherit noir-wasm; # We expose the `*-cargo-artifacts` derivations so we can cache our cargo dependencies in CI inherit native-cargo-artifacts; - inherit wasm-cargo-artifacts; inherit noir-wasm-cargo-artifacts; + inherit noirc-abi-wasm-cargo-artifacts; }; # TODO(#1197): Look into installable apps with Nix flakes @@ -267,6 +327,8 @@ inputsFrom = builtins.attrValues checks; nativeBuildInputs = with pkgs; [ + curl + gzip which starship git @@ -276,6 +338,12 @@ llvmPackages.lldb # This ensures the right lldb is in the environment for running rust-lldb wasm-bindgen-cli jq + binaryen + yarn + rust-bin.stable."1.66.1".default + rust-analyzer + rustup + nodejs-18_x ]; shellHook = '' @@ -309,14 +377,50 @@ ]; buildPhaseCargoCommand = '' - bash crates/wasm/buildPhaseCargoCommand.sh release + bash compiler/wasm/buildPhaseCargoCommand.sh release ''; installPhase = '' - bash crates/wasm/installPhase.sh + bash compiler/wasm/installPhase.sh ''; }); + + # TODO: This fails with a "section too large" error on MacOS so we should limit to linux targets + # or fix the failure + packages.noirc_abi_wasm = craneLib.buildPackage (noirc_abi_WasmArgs // { + + inherit GIT_COMMIT; + inherit GIT_DIRTY; + doCheck = false; + + cargoArtifacts = noirc-abi-wasm-cargo-artifacts; + + COMMIT_SHORT = builtins.substring 0 7 GIT_COMMIT; + VERSION_APPENDIX = if GIT_DIRTY == "true" then "-dirty" else ""; + PKG_PATH = "./pkg"; + CARGO_TARGET_DIR = "./target"; + + nativeBuildInputs = with pkgs; [ + which + git + jq + rustToolchain + wasm-bindgen-cli + binaryen + toml2json + ]; + + buildPhaseCargoCommand = '' + bash tooling/noirc_abi_wasm/buildPhaseCargoCommand.sh release + ''; + + installPhase = '' + bash tooling/noirc_abi_wasm/installPhase.sh + ''; + + }); + }); } diff --git a/noir_stdlib/src/array.nr b/noir_stdlib/src/array.nr index 9082e161e91..c1e7cfdcfe6 100644 --- a/noir_stdlib/src/array.nr +++ b/noir_stdlib/src/array.nr @@ -9,7 +9,7 @@ impl [T; N] { fn sort(_self: Self) -> Self {} // Sort with a custom sorting function. - fn sort_via(mut a: Self, ordering: fn(T, T) -> bool) -> Self { + fn sort_via(mut a: Self, ordering: fn[Env](T, T) -> bool) -> Self { for i in 1 .. a.len() { for j in 0..i { if ordering(a[i], a[j]) { @@ -33,7 +33,7 @@ impl [T; N] { // Apply a function to each element of an array, returning a new array // containing the mapped elements. - fn map(self, f: fn(T) -> U) -> [U; N] { + fn map(self, f: fn[Env](T) -> U) -> [U; N] { let first_elem = f(self[0]); let mut ret = [first_elem; N]; @@ -47,7 +47,7 @@ impl [T; N] { // Apply a function to each element of the array and an accumulator value, // returning the final accumulated value. This function is also sometimes // called `foldl`, `fold_left`, `reduce`, or `inject`. - fn fold(self, mut accumulator: U, f: fn(U, T) -> U) -> U { + fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U { for elem in self { accumulator = f(accumulator, elem); } @@ -57,7 +57,7 @@ impl [T; N] { // Apply a function to each element of the array and an accumulator value, // returning the final accumulated value. Unlike fold, reduce uses the first // element of the given array as its starting accumulator value. - fn reduce(self, f: fn(T, T) -> T) -> T { + fn reduce(self, f: fn[Env](T, T) -> T) -> T { let mut accumulator = self[0]; for i in 1 .. self.len() { accumulator = f(accumulator, self[i]); @@ -66,7 +66,7 @@ impl [T; N] { } // Returns true if all elements in the array satisfy the predicate - fn all(self, predicate: fn(T) -> bool) -> bool { + fn all(self, predicate: fn[Env](T) -> bool) -> bool { let mut ret = true; for elem in self { ret &= predicate(elem); @@ -75,7 +75,7 @@ impl [T; N] { } // Returns true if any element in the array satisfies the predicate - fn any(self, predicate: fn(T) -> bool) -> bool { + fn any(self, predicate: fn[Env](T) -> bool) -> bool { let mut ret = false; for elem in self { ret |= predicate(elem); diff --git a/noir_stdlib/src/grumpkin_scalar.nr b/noir_stdlib/src/grumpkin_scalar.nr new file mode 100644 index 00000000000..e3cc2a9a8ed --- /dev/null +++ b/noir_stdlib/src/grumpkin_scalar.nr @@ -0,0 +1,21 @@ +struct GrumpkinScalar { + low: Field, + high: Field, +} + +impl GrumpkinScalar { + fn new(low: Field, high: Field) -> Self { + // TODO: check that the low and high value fit within the grumpkin modulus + GrumpkinScalar { low, high } + } +} + +global GRUMPKIN_SCALAR_SERIALIZED_LEN: Field = 2; + +fn deserialize_grumpkin_scalar(fields: [Field; GRUMPKIN_SCALAR_SERIALIZED_LEN]) -> GrumpkinScalar { + GrumpkinScalar { low: fields[0], high: fields[1] } +} + +fn serialize_grumpkin_scalar(scalar: GrumpkinScalar) -> [Field; GRUMPKIN_SCALAR_SERIALIZED_LEN] { + [scalar.low, scalar.high] +} diff --git a/noir_stdlib/src/grumpkin_scalar_mul.nr b/noir_stdlib/src/grumpkin_scalar_mul.nr new file mode 100644 index 00000000000..0d73b9dd194 --- /dev/null +++ b/noir_stdlib/src/grumpkin_scalar_mul.nr @@ -0,0 +1,7 @@ +use crate::grumpkin_scalar::GrumpkinScalar; +use crate::scalar_mul::fixed_base_embedded_curve; + +fn grumpkin_fixed_base(scalar: GrumpkinScalar) -> [Field; 2] { + // TODO: this should use both the low and high limbs to do the scalar multiplication + fixed_base_embedded_curve(scalar.low, scalar.high) +} diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index f033334c140..224c3a03f21 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -6,6 +6,8 @@ mod schnorr; mod ecdsa_secp256k1; mod ecdsa_secp256r1; mod eddsa; +mod grumpkin_scalar; +mod grumpkin_scalar_mul; mod scalar_mul; mod sha256; mod sha512; diff --git a/noir_stdlib/src/option.nr b/noir_stdlib/src/option.nr index 919c40fd9e0..11a632011b0 100644 --- a/noir_stdlib/src/option.nr +++ b/noir_stdlib/src/option.nr @@ -48,7 +48,7 @@ impl Option { /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return /// a default value. - fn unwrap_or_else(self, default: fn() -> T) -> T { + fn unwrap_or_else(self, default: fn[Env]() -> T) -> T { if self._is_some { self._value } else { @@ -57,7 +57,7 @@ impl Option { } /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`. - fn map(self, f: fn(T) -> U) -> Option { + fn map(self, f: fn[Env](T) -> U) -> Option { if self._is_some { Option::some(f(self._value)) } else { @@ -66,7 +66,7 @@ impl Option { } /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value. - fn map_or(self, default: U, f: fn(T) -> U) -> U { + fn map_or(self, default: U, f: fn[Env](T) -> U) -> U { if self._is_some { f(self._value) } else { @@ -75,7 +75,7 @@ impl Option { } /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`. - fn map_or_else(self, default: fn() -> U, f: fn(T) -> U) -> U { + fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U { if self._is_some { f(self._value) } else { @@ -96,7 +96,7 @@ impl Option { /// with the Some value contained within self, and returns the result of that call. /// /// In some languages this function is called `flat_map` or `bind`. - fn and_then(self, f: fn(T) -> Option) -> Option { + fn and_then(self, f: fn[Env](T) -> Option) -> Option { if self._is_some { f(self._value) } else { @@ -114,7 +114,7 @@ impl Option { } /// If self is Some, return self. Otherwise, return `default()`. - fn or_else(self, default: fn() -> Self) -> Self { + fn or_else(self, default: fn[Env]() -> Self) -> Self { if self._is_some { self } else { @@ -140,7 +140,7 @@ impl Option { /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true. /// Otherwise, this returns `None` - fn filter(self, predicate: fn(T) -> bool) -> Self { + fn filter(self, predicate: fn[Env](T) -> bool) -> Self { if self._is_some { if predicate(self._value) { self diff --git a/noir_stdlib/src/scalar_mul.nr b/noir_stdlib/src/scalar_mul.nr index 8399284f149..fe017efbde4 100644 --- a/noir_stdlib/src/scalar_mul.nr +++ b/noir_stdlib/src/scalar_mul.nr @@ -1,2 +1,8 @@ +// Computes a fixed base scalar multiplication over the embedded curve. +// For bn254, We have Grumpkin and Baby JubJub. +// For bls12-381, we have JubJub and Bandersnatch. +// +// The embedded curve being used is decided by the +// underlying proof system. #[foreign(fixed_base_scalar_mul)] -fn fixed_base(_input : Field) -> [Field; 2] {} +fn fixed_base_embedded_curve(_low : Field, _high : Field) -> [Field; 2] {} diff --git a/noir_stdlib/src/slice.nr b/noir_stdlib/src/slice.nr index 4f73f3a2994..053a8acacb6 100644 --- a/noir_stdlib/src/slice.nr +++ b/noir_stdlib/src/slice.nr @@ -22,16 +22,28 @@ impl [T] { #[builtin(slice_pop_front)] fn pop_front(_self: Self) -> (T, Self) { } + fn insert(self, _index: Field, _elem: T) -> Self { + // TODO(#2462): Slice insert with a dynamic index + crate::assert_constant(_index); + self.__slice_insert(_index, _elem) + } + /// Insert an element at a specified index, shifting all elements /// after it to the right #[builtin(slice_insert)] - fn insert(_self: Self, _index: Field, _elem: T) -> Self { } + fn __slice_insert(_self: Self, _index: Field, _elem: T) -> Self { } + + fn remove(self, _index: Field) -> (Self, T) { + // TODO(#2462): Slice remove with a dynamic index + crate::assert_constant(_index); + self.__slice_remove(_index) + } /// Remove an element at a specified index, shifting all elements /// after it to the left, returning the altered slice and /// the removed element #[builtin(slice_remove)] - fn remove(_self: Self, _index: Field) -> (Self, T) { } + fn __slice_remove(_self: Self, _index: Field) -> (Self, T) { } // Append each element of the `other` slice to the end of `self`. // This returns a new slice and leaves both input slices unchanged. diff --git a/release-please-config.json b/release-please-config.json index a84fc0de82c..e06379f5ae7 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -15,13 +15,16 @@ "flake.nix", { "type": "json", - "path": "crates/wasm/package.json", + "path": "compiler/wasm/package.json", + "jsonpath": "$.version" + }, + { + "type": "json", + "path": "tooling/noirc_abi_wasm/package.json", "jsonpath": "$.version" } ] } }, - "plugins": [ - "sentence-case" - ] + "plugins": ["sentence-case"] } diff --git a/release-tests/test/6_array.test.js b/release-tests/test/6_array.test.js index 3638ecb7e3a..530b7f85bf4 100644 --- a/release-tests/test/6_array.test.js +++ b/release-tests/test/6_array.test.js @@ -19,27 +19,27 @@ test("promise resolved", async () => { promiseResolved = true; }); -test("nargo builds ../crates/nargo_cli/tests/execution_success/6_array sucessfully", async () => { +test("nargo builds ../tooling/nargo_cli/tests/execution_success/6_array sucessfully", async () => { await within(async () => { - cd("../crates/nargo_cli/tests/execution_success/6_array"); + cd("../tooling/nargo_cli/tests/execution_success/6_array"); const command = `${NARGO_BIN} check`; await $`${command}`.nothrow(); }); }); -test("nargo creates proof ../crates/nargo_cli/tests/execution_success/6_array sucessfully", async () => { +test("nargo creates proof ../tooling/nargo_cli/tests/execution_success/6_array sucessfully", async () => { await within(async () => { - cd("../crates/nargo_cli/tests/execution_success/6_array"); + cd("../tooling/nargo_cli/tests/execution_success/6_array"); const command = `${NARGO_BIN} prove 6_array`; await $`${command}`.nothrow(); }); }); -test("nargo verifies proof ../crates/nargo_cli/tests/execution_success/6_array sucessfully", async () => { +test("nargo verifies proof ../tooling/nargo_cli/tests/execution_success/6_array sucessfully", async () => { await within(async () => { - cd("../crates/nargo_cli/tests/execution_success/6_array"); + cd("../tooling/nargo_cli/tests/execution_success/6_array"); const command = `${NARGO_BIN} verify 6_array`; await $`${command}`.nothrow(); diff --git a/tooling/acvm_backend_barretenberg/.gitignore b/tooling/acvm_backend_barretenberg/.gitignore new file mode 100644 index 00000000000..106a4f552a0 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/.gitignore @@ -0,0 +1 @@ +!src/witness.tr diff --git a/tooling/acvm_backend_barretenberg/CHANGELOG.md b/tooling/acvm_backend_barretenberg/CHANGELOG.md new file mode 100644 index 00000000000..4387d8ccb5f --- /dev/null +++ b/tooling/acvm_backend_barretenberg/CHANGELOG.md @@ -0,0 +1,233 @@ +# Changelog + +## [0.11.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.10.1...v0.11.0) (2023-08-18) + + +### ⚠ BREAKING CHANGES + +* Update `acvm` to 0.22.0 ([#240](https://github.com/noir-lang/acvm-backend-barretenberg/issues/240)) + +### Features + +* Update `acvm` to 0.22.0 ([#240](https://github.com/noir-lang/acvm-backend-barretenberg/issues/240)) ([d8342fd](https://github.com/noir-lang/acvm-backend-barretenberg/commit/d8342fd6da605ac3bbd889edf89cd122bc4689ce)) + +## [0.10.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.10.0...v0.10.1) (2023-08-18) + + +### Features + +* Migrate to `wasmer` 3.3.0 ([#236](https://github.com/noir-lang/acvm-backend-barretenberg/issues/236)) ([e115e38](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e115e38856887c6b1eeead3534534ac7e6327ea9)) + +## [0.10.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.9.1...v0.10.0) (2023-07-26) + + +### ⚠ BREAKING CHANGES + +* Migrate to ACVM 0.21.0 ([#234](https://github.com/noir-lang/acvm-backend-barretenberg/issues/234)) + +### Features + +* Migrate to ACVM 0.21.0 ([#234](https://github.com/noir-lang/acvm-backend-barretenberg/issues/234)) ([15c8676](https://github.com/noir-lang/acvm-backend-barretenberg/commit/15c86768685d2946a767c350f6ef5972c86677eb)) + +## [0.9.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.9.0...v0.9.1) (2023-07-21) + + +### Features + +* add support for atomic memory opcodes ([#232](https://github.com/noir-lang/acvm-backend-barretenberg/issues/232)) ([a7aa6e9](https://github.com/noir-lang/acvm-backend-barretenberg/commit/a7aa6e9505bb402c1b3db0a990845ed26928e7aa)) + +## [0.9.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.8.0...v0.9.0) (2023-07-17) + + +### ⚠ BREAKING CHANGES + +* update to ACVM 0.19.0 ([#230](https://github.com/noir-lang/acvm-backend-barretenberg/issues/230)) + +### Miscellaneous Chores + +* update to ACVM 0.19.0 ([#230](https://github.com/noir-lang/acvm-backend-barretenberg/issues/230)) ([3f1d967](https://github.com/noir-lang/acvm-backend-barretenberg/commit/3f1d9674b904acb02c2a3e52481be8a6104c3a9d)) + +## [0.8.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.7.0...v0.8.0) (2023-07-12) + + +### ⚠ BREAKING CHANGES + +* Update to acvm 0.18.1 ([#228](https://github.com/noir-lang/acvm-backend-barretenberg/issues/228)) + +### Features + +* Update to acvm 0.18.1 ([#228](https://github.com/noir-lang/acvm-backend-barretenberg/issues/228)) ([397098b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/397098b239efbe16785b1c9af108ca9fc4e24497)) + +## [0.7.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.6.1...v0.7.0) (2023-07-08) + + +### ⚠ BREAKING CHANGES + +* **bberg:** add secp256r1 builtin to barretenberg ([#223](https://github.com/noir-lang/acvm-backend-barretenberg/issues/223)) + +### Features + +* **bberg:** add secp256r1 builtin to barretenberg ([#223](https://github.com/noir-lang/acvm-backend-barretenberg/issues/223)) ([ceb4770](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ceb47705a492fcdcea1f3c098aaab42ea8edbf2e)) + +## [0.6.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.6.0...v0.6.1) (2023-07-06) + + +### Features + +* switch RecursiveAggregation support to true ([#225](https://github.com/noir-lang/acvm-backend-barretenberg/issues/225)) ([e9462ae](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e9462ae015ec0dfb0a23ccbb89562071f87940f5)) + +## [0.6.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.5.1...v0.6.0) (2023-07-06) + + +### ⚠ BREAKING CHANGES + +* Update to ACVM 0.16.0 ([#221](https://github.com/noir-lang/acvm-backend-barretenberg/issues/221)) + +### Features + +* Update to ACVM 0.16.0 ([#221](https://github.com/noir-lang/acvm-backend-barretenberg/issues/221)) ([062d5ed](https://github.com/noir-lang/acvm-backend-barretenberg/commit/062d5ed9b476fab8ac8d3ca13371699fb2aac332)) + +## [0.5.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.5.0...v0.5.1) (2023-06-20) + + +### Bug Fixes + +* Remove wasm32 target ([#219](https://github.com/noir-lang/acvm-backend-barretenberg/issues/219)) ([e4cbb6d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e4cbb6d476e8746de33c38506e2fcb970f1c866a)) + +## [0.5.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.4.0...v0.5.0) (2023-06-15) + + +### ⚠ BREAKING CHANGES + +* Update to target ACVM 0.15.0 ([#217](https://github.com/noir-lang/acvm-backend-barretenberg/issues/217)) + +### Features + +* Update to target ACVM 0.15.0 ([#217](https://github.com/noir-lang/acvm-backend-barretenberg/issues/217)) ([9331898](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9331898f161321c8b6a82d5ea850f197952b2ed2)) + +## [0.4.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.3.0...v0.4.0) (2023-06-07) + + +### ⚠ BREAKING CHANGES + +* Recursion ([#207](https://github.com/noir-lang/acvm-backend-barretenberg/issues/207)) + +### Features + +* Recursion ([#207](https://github.com/noir-lang/acvm-backend-barretenberg/issues/207)) ([6fc479b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/6fc479b9ae99d59bbfeb1b895d63cdbea469dcaa)) + +## [0.3.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.2.0...v0.3.0) (2023-06-01) + + +### ⚠ BREAKING CHANGES + +* Update to ACVM 0.13.0 ([#205](https://github.com/noir-lang/acvm-backend-barretenberg/issues/205)) +* added keccakvar constraints ([#213](https://github.com/noir-lang/acvm-backend-barretenberg/issues/213)) +* update pedersen hashes for new implementation ([#212](https://github.com/noir-lang/acvm-backend-barretenberg/issues/212)) + +### Features + +* added keccakvar constraints ([91ea65f](https://github.com/noir-lang/acvm-backend-barretenberg/commit/91ea65f6af7039095c7a3af7bc1e4ce302a68a8d)) +* added keccakvar constraints ([#213](https://github.com/noir-lang/acvm-backend-barretenberg/issues/213)) ([91ea65f](https://github.com/noir-lang/acvm-backend-barretenberg/commit/91ea65f6af7039095c7a3af7bc1e4ce302a68a8d)) +* Update to ACVM 0.13.0 ([#205](https://github.com/noir-lang/acvm-backend-barretenberg/issues/205)) ([298446e](https://github.com/noir-lang/acvm-backend-barretenberg/commit/298446ef8b69f528b6e2fd2abb2298d7b0a8118e)) + + +### Bug Fixes + +* Add or cleanup implementations for JS target ([#199](https://github.com/noir-lang/acvm-backend-barretenberg/issues/199)) ([f6134b7](https://github.com/noir-lang/acvm-backend-barretenberg/commit/f6134b7b502cb74882300b0046ab91ab000daf3c)) +* update pedersen hashes for new impl ([9a233ce](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9a233ce8db9984b29b9cce0603f758d5281c89c9)) +* update pedersen hashes for new implementation ([#212](https://github.com/noir-lang/acvm-backend-barretenberg/issues/212)) ([9a233ce](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9a233ce8db9984b29b9cce0603f758d5281c89c9)) + +## [0.2.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.1.2...v0.2.0) (2023-05-22) + + +### ⚠ BREAKING CHANGES + +* Update to acvm 0.12.0 ([#165](https://github.com/noir-lang/acvm-backend-barretenberg/issues/165)) +* Add serialization logic for RAM and ROM opcodes ([#153](https://github.com/noir-lang/acvm-backend-barretenberg/issues/153)) + +### Features + +* Add serde to `ConstraintSystem` types ([#196](https://github.com/noir-lang/acvm-backend-barretenberg/issues/196)) ([4c04a79](https://github.com/noir-lang/acvm-backend-barretenberg/commit/4c04a79e6d2b0115f3b4526c60f9f7dae8b464ae)) +* Add serialization logic for RAM and ROM opcodes ([#153](https://github.com/noir-lang/acvm-backend-barretenberg/issues/153)) ([3d3847d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/3d3847de70e74a8f65c64e165ad15ae3d31f5350)) +* Update to acvm 0.12.0 ([#165](https://github.com/noir-lang/acvm-backend-barretenberg/issues/165)) ([d613c79](https://github.com/noir-lang/acvm-backend-barretenberg/commit/d613c79584a599f4adbd11d2ce3b61403c185b73)) + +## [0.1.2](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.1.1...v0.1.2) (2023-05-11) + + +### Bug Fixes + +* Remove star dependencies to allow publishing ([#182](https://github.com/noir-lang/acvm-backend-barretenberg/issues/182)) ([1727a79](https://github.com/noir-lang/acvm-backend-barretenberg/commit/1727a79ce7e66d95528f70c445cb4ec1b1ece636)) + +## [0.1.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.1.0...v0.1.1) (2023-05-11) + + +### Bug Fixes + +* Add description so crate can be published ([#180](https://github.com/noir-lang/acvm-backend-barretenberg/issues/180)) ([caabf94](https://github.com/noir-lang/acvm-backend-barretenberg/commit/caabf9434031c6023a5e3a436c87fba0a1072539)) + +## 0.1.0 (2023-05-10) + + +### ⚠ BREAKING CHANGES + +* Update to ACVM v0.11.0 ([#151](https://github.com/noir-lang/acvm-backend-barretenberg/issues/151)) +* Add Keccak constraints ([#150](https://github.com/noir-lang/acvm-backend-barretenberg/issues/150)) +* migrate to ACVM 0.10.3 ([#148](https://github.com/noir-lang/acvm-backend-barretenberg/issues/148)) +* remove all crates other than `acvm-backend-barretenberg` and remove workspace ([#147](https://github.com/noir-lang/acvm-backend-barretenberg/issues/147)) +* merge `barretenberg_static_lib` and `barretenberg_wasm` ([#117](https://github.com/noir-lang/acvm-backend-barretenberg/issues/117)) +* remove dead blake2 code ([#137](https://github.com/noir-lang/acvm-backend-barretenberg/issues/137)) +* Implement pseudo-builder pattern for ConstraintSystem & hide struct fields ([#120](https://github.com/noir-lang/acvm-backend-barretenberg/issues/120)) +* return boolean rather than `FieldElement` from `verify_signature` ([#123](https://github.com/noir-lang/acvm-backend-barretenberg/issues/123)) +* avoid exposing internals of Assignments type ([#119](https://github.com/noir-lang/acvm-backend-barretenberg/issues/119)) +* update to acvm 0.9.0 ([#106](https://github.com/noir-lang/acvm-backend-barretenberg/issues/106)) +* Depend upon upstream barretenberg & switch to UltraPlonk ([#84](https://github.com/noir-lang/acvm-backend-barretenberg/issues/84)) +* update to ACVM 0.7.0 ([#90](https://github.com/noir-lang/acvm-backend-barretenberg/issues/90)) +* Remove create_proof and verify functions ([#82](https://github.com/noir-lang/acvm-backend-barretenberg/issues/82)) +* update to acvm v0.5.0 ([#60](https://github.com/noir-lang/acvm-backend-barretenberg/issues/60)) + +### Features + +* **acvm_interop:** Updates to reflect new acvm methods using pk/vk ([#50](https://github.com/noir-lang/acvm-backend-barretenberg/issues/50)) ([cff757d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/cff757dca7971161e4bd25e7a744d910c37c22be)) +* Add Keccak constraints ([#150](https://github.com/noir-lang/acvm-backend-barretenberg/issues/150)) ([ce2b9ed](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ce2b9ed456bd8d2ad8357c15736d62c2a5812add)) +* allow overriding transcript location with BARRETENBERG_TRANSCRIPT env var ([#86](https://github.com/noir-lang/acvm-backend-barretenberg/issues/86)) ([af92b99](https://github.com/noir-lang/acvm-backend-barretenberg/commit/af92b99c7b5f37e9659931af378a851b3658a80b)) +* **ci:** add concurrency group for rust workflow ([#63](https://github.com/noir-lang/acvm-backend-barretenberg/issues/63)) ([5c936bc](https://github.com/noir-lang/acvm-backend-barretenberg/commit/5c936bc63cc3adcf9d43c9c4ce69053566089ad9)) +* Depend upon upstream barretenberg & switch to UltraPlonk ([#84](https://github.com/noir-lang/acvm-backend-barretenberg/issues/84)) ([8437bf7](https://github.com/noir-lang/acvm-backend-barretenberg/commit/8437bf7e08acadf43b55b307545336596a9fe766)) +* Implement pseudo-builder pattern for ConstraintSystem & hide struct fields ([#120](https://github.com/noir-lang/acvm-backend-barretenberg/issues/120)) ([8ed67d6](https://github.com/noir-lang/acvm-backend-barretenberg/commit/8ed67d68c71d655e1a6a5c38fa9ea1c3566f771d)) +* Leverage rustls when using downloader crate ([#46](https://github.com/noir-lang/acvm-backend-barretenberg/issues/46)) ([9de36b6](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9de36b642d125d1fb4facd1bf60db67946be70ae)) +* merge `barretenberg_static_lib` and `barretenberg_wasm` ([#117](https://github.com/noir-lang/acvm-backend-barretenberg/issues/117)) ([ba1d0d6](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ba1d0d61b94de91b15044d97608907c21bfb5299)) +* migrate to ACVM 0.10.3 ([#148](https://github.com/noir-lang/acvm-backend-barretenberg/issues/148)) ([c9fb9e8](https://github.com/noir-lang/acvm-backend-barretenberg/commit/c9fb9e806f1400a2ff7594a0669bec56025220bb)) +* remove all crates other than `acvm-backend-barretenberg` and remove workspace ([#147](https://github.com/noir-lang/acvm-backend-barretenberg/issues/147)) ([8fe7111](https://github.com/noir-lang/acvm-backend-barretenberg/commit/8fe7111ebdcb043764a83436744662e8c3ca5abc)) +* remove dead blake2 code ([#137](https://github.com/noir-lang/acvm-backend-barretenberg/issues/137)) ([14d8a5b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/14d8a5b893eb1cb91d5bde908643b487b41809d6)) +* replace `downloader` dependency with `reqwest` ([#114](https://github.com/noir-lang/acvm-backend-barretenberg/issues/114)) ([dd62231](https://github.com/noir-lang/acvm-backend-barretenberg/commit/dd62231b8bfcee32e1029d31a07895b16159339c)) +* return boolean from `verify_signature` ([e560602](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e560602ebbd547386ca4cab35735ffa92e98ac4b)) +* return boolean rather than `FieldElement` from `check_membership` ([#124](https://github.com/noir-lang/acvm-backend-barretenberg/issues/124)) ([a0a338e](https://github.com/noir-lang/acvm-backend-barretenberg/commit/a0a338e2295635a07f6b9e497c029160a5f323bc)) +* return boolean rather than `FieldElement` from `verify_signature` ([#123](https://github.com/noir-lang/acvm-backend-barretenberg/issues/123)) ([e560602](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e560602ebbd547386ca4cab35735ffa92e98ac4b)) +* store transcript in `.nargo/backends` directory ([#91](https://github.com/noir-lang/acvm-backend-barretenberg/issues/91)) ([c6b5023](https://github.com/noir-lang/acvm-backend-barretenberg/commit/c6b50231da065e7550bfe8bddf8e46f4cd8002d7)) +* update `aztec_backend_wasm` to use new serialization ([#94](https://github.com/noir-lang/acvm-backend-barretenberg/issues/94)) ([28014d8](https://github.com/noir-lang/acvm-backend-barretenberg/commit/28014d803d052a7f459e03dbd7b5b9210449b1d0)) +* update to acvm 0.9.0 ([#106](https://github.com/noir-lang/acvm-backend-barretenberg/issues/106)) ([ff350fb](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ff350fb111043964b8a14fc0df62508c87506423)) +* Update to ACVM v0.11.0 ([#151](https://github.com/noir-lang/acvm-backend-barretenberg/issues/151)) ([9202415](https://github.com/noir-lang/acvm-backend-barretenberg/commit/92024155532e15f25acb2f3ed8d5ca78da0fddd9)) +* update to acvm v0.5.0 ([#60](https://github.com/noir-lang/acvm-backend-barretenberg/issues/60)) ([74b4d8d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/74b4d8d8b118e4477880c04149e5e9d93d388384)) + + +### Bug Fixes + +* Avoid exposing internals of Assignments type ([614c81b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/614c81b0ea5e110bbf5a61a526bb0173f4fe377a)) +* avoid exposing internals of Assignments type ([#119](https://github.com/noir-lang/acvm-backend-barretenberg/issues/119)) ([614c81b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/614c81b0ea5e110bbf5a61a526bb0173f4fe377a)) +* fix serialisation of arithmetic expressions ([#145](https://github.com/noir-lang/acvm-backend-barretenberg/issues/145)) ([7f42535](https://github.com/noir-lang/acvm-backend-barretenberg/commit/7f4253570257d9dedcfa8c8fb96b9d097ef06419)) +* Implement random_get for wasm backend ([#102](https://github.com/noir-lang/acvm-backend-barretenberg/issues/102)) ([9c0f06e](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9c0f06ef56f23e2b5794e810f433e36ff2c5d6b5)) +* rename gates to opcodes ([#59](https://github.com/noir-lang/acvm-backend-barretenberg/issues/59)) ([6e05307](https://github.com/noir-lang/acvm-backend-barretenberg/commit/6e053072d8b9c5d93c296f10782251ccb597f902)) +* reorganize and ensure contracts can be compiled in Remix ([#112](https://github.com/noir-lang/acvm-backend-barretenberg/issues/112)) ([7ec5693](https://github.com/noir-lang/acvm-backend-barretenberg/commit/7ec5693f194a79c379ae2952bc17a31ee63a42b9)) +* replace `serialize_circuit` function with `from<&Circuit>` ([#118](https://github.com/noir-lang/acvm-backend-barretenberg/issues/118)) ([94f83a7](https://github.com/noir-lang/acvm-backend-barretenberg/commit/94f83a78e32d91dfb7ae9824923695d9b4c425b0)) +* Replace serialize_circuit function with `from<&Circuit>` ([94f83a7](https://github.com/noir-lang/acvm-backend-barretenberg/commit/94f83a78e32d91dfb7ae9824923695d9b4c425b0)) +* Update bb-sys to resolve bugs in some environments ([#129](https://github.com/noir-lang/acvm-backend-barretenberg/issues/129)) ([e3d4504](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e3d4504f15e1295e637c4da80b1d08c87c267c45)) +* Update dependency containing pk write fix for large general circuits ([#78](https://github.com/noir-lang/acvm-backend-barretenberg/issues/78)) ([2cb523d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/2cb523d2ab95249157b22e198d9dcd6841c3eed8)) +* Update to bb-sys 0.1.1 and update bb in lockfile ([00bb157](https://github.com/noir-lang/acvm-backend-barretenberg/commit/00bb15779dfb64539eeb3f3bb4c4deeba106f2fe)) +* update to bb-sys 0.1.1 and update bb in lockfile ([#111](https://github.com/noir-lang/acvm-backend-barretenberg/issues/111)) ([00bb157](https://github.com/noir-lang/acvm-backend-barretenberg/commit/00bb15779dfb64539eeb3f3bb4c4deeba106f2fe)) +* use `Barretenberg.call` to query circuit size from wasm ([#121](https://github.com/noir-lang/acvm-backend-barretenberg/issues/121)) ([a775af1](https://github.com/noir-lang/acvm-backend-barretenberg/commit/a775af14137cc7bc2e9d8a063fa718a5a9abe6cb)) + + +### Miscellaneous Chores + +* Remove create_proof and verify functions ([#82](https://github.com/noir-lang/acvm-backend-barretenberg/issues/82)) ([ad0c422](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ad0c4228488457bd155ff381186ecf583f18bfac)) +* update to ACVM 0.7.0 ([#90](https://github.com/noir-lang/acvm-backend-barretenberg/issues/90)) ([6c03687](https://github.com/noir-lang/acvm-backend-barretenberg/commit/6c036870a6a8e26612ab8b4f90a162f7540b42e2)) diff --git a/tooling/acvm_backend_barretenberg/Cargo.toml b/tooling/acvm_backend_barretenberg/Cargo.toml new file mode 100644 index 00000000000..a86fa90b0be --- /dev/null +++ b/tooling/acvm_backend_barretenberg/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "acvm-backend-barretenberg" +description = "An ACVM backend which allows proving/verifying ACIR circuits against Aztec Lab's Barretenberg library." +version = "0.11.0" +authors.workspace = true +edition.workspace = true +rust-version = "1.66" +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +acvm.workspace = true +dirs.workspace = true +thiserror.workspace = true +serde.workspace = true +serde_json.workspace = true + +tempfile = "3.6.0" + +## bb binary downloading +tar = "~0.4.15" +flate2 = "~1.0.1" +reqwest = { version = "0.11.16", default-features = false, features = [ + "rustls-tls", + "blocking", +] } + +[dev-dependencies] +test-binary = "3.0.1" + +[build-dependencies] +build-target = "0.4.0" +const_format = "0.2.30" diff --git a/tooling/acvm_backend_barretenberg/build.rs b/tooling/acvm_backend_barretenberg/build.rs new file mode 100644 index 00000000000..e4d213cfa38 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/build.rs @@ -0,0 +1,54 @@ +use build_target::{Arch, Os}; +use const_format::formatcp; + +// Useful for printing debugging messages during the build +// macro_rules! p { +// ($($tokens: tt)*) => { +// println!("cargo:warning={}", format!($($tokens)*)) +// } +// } + +const USERNAME: &str = "AztecProtocol"; +const REPO: &str = "barretenberg"; +const VERSION: &str = "0.5.1"; +const TAG: &str = formatcp!("barretenberg-v{}", VERSION); + +const API_URL: &str = + formatcp!("https://github.com/{}/{}/releases/download/{}", USERNAME, REPO, TAG); + +fn main() -> Result<(), String> { + // We need to inject which OS we're building for so that we can download the correct barretenberg binary. + let os = match build_target::target_os().unwrap() { + os @ (Os::Linux | Os::MacOs) => os, + Os::Windows => todo!("Windows is not currently supported"), + os_name => panic!("Unsupported OS {os_name}"), + }; + + let arch = match build_target::target_arch().unwrap() { + arch @ (Arch::X86_64 | Arch::AARCH64) => arch, + arch_name => panic!("Unsupported Architecture {arch_name}"), + }; + + // Arm builds of linux are not supported + if let (Os::Linux, Arch::AARCH64) = (&os, &arch) { + panic!("ARM64 builds of linux are not supported") + }; + + println!("cargo:rustc-env=BB_BINARY_URL={}", get_bb_download_url(arch, os)); + + Ok(()) +} + +fn get_bb_download_url(target_arch: Arch, target_os: Os) -> String { + let archive_name = match target_os { + Os::Linux => "barretenberg-x86_64-linux-gnu.tar.gz", + Os::MacOs => match target_arch { + Arch::AARCH64 => "barretenberg-aarch64-apple-darwin.tar.gz", + Arch::X86_64 => "barretenberg-x86_64-apple-darwin.tar.gz", + arch => panic!("unsupported arch {arch}"), + }, + os => panic!("Unsupported OS {os}"), + }; + + format!("{API_URL}/{archive_name}") +} diff --git a/tooling/acvm_backend_barretenberg/src/cli/contract.rs b/tooling/acvm_backend_barretenberg/src/cli/contract.rs new file mode 100644 index 00000000000..6301431d0f3 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/cli/contract.rs @@ -0,0 +1,70 @@ +use std::path::{Path, PathBuf}; + +use crate::BackendError; + +/// VerifyCommand will call the barretenberg binary +/// to return a solidity library with the verification key +/// that can be used to verify proofs on-chain. +/// +/// This does not return a Solidity file that is able +/// to verify a proof. See acvm_interop/contract.sol for the +/// remaining logic that is missing. +pub(crate) struct ContractCommand { + pub(crate) crs_path: PathBuf, + pub(crate) vk_path: PathBuf, +} + +impl ContractCommand { + pub(crate) fn run(self, binary_path: &Path) -> Result { + let mut command = std::process::Command::new(binary_path); + + command + .arg("contract") + .arg("-c") + .arg(self.crs_path) + .arg("-k") + .arg(self.vk_path) + .arg("-o") + .arg("-"); + + let output = command.output()?; + + if output.status.success() { + String::from_utf8(output.stdout) + .map_err(|error| BackendError::MalformedResponse(error.into_bytes())) + } else { + Err(BackendError::CommandFailed(output.stderr)) + } + } +} + +#[test] +fn contract_command() -> Result<(), BackendError> { + use tempfile::tempdir; + + let backend = crate::get_mock_backend()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory_path = temp_directory.path(); + let bytecode_path = temp_directory_path.join("acir.gz"); + let vk_path = temp_directory_path.join("vk"); + + let crs_path = backend.backend_directory(); + + std::fs::File::create(&bytecode_path).expect("file should be created"); + + let write_vk_command = super::WriteVkCommand { + bytecode_path, + vk_path_output: vk_path.clone(), + is_recursive: false, + crs_path: crs_path.clone(), + }; + write_vk_command.run(backend.binary_path())?; + + let contract_command = ContractCommand { vk_path, crs_path }; + contract_command.run(backend.binary_path())?; + + drop(temp_directory); + + Ok(()) +} diff --git a/tooling/acvm_backend_barretenberg/src/cli/gates.rs b/tooling/acvm_backend_barretenberg/src/cli/gates.rs new file mode 100644 index 00000000000..446c6eee817 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/cli/gates.rs @@ -0,0 +1,59 @@ +use std::path::{Path, PathBuf}; + +use crate::BackendError; + +/// GatesCommand will call the barretenberg binary +/// to return the number of gates needed to create a proof +/// for the given bytecode. +pub(crate) struct GatesCommand { + pub(crate) crs_path: PathBuf, + pub(crate) bytecode_path: PathBuf, +} + +impl GatesCommand { + pub(crate) fn run(self, binary_path: &Path) -> Result { + let output = std::process::Command::new(binary_path) + .arg("gates") + .arg("-c") + .arg(self.crs_path) + .arg("-b") + .arg(self.bytecode_path) + .output()?; + + if !output.status.success() { + return Err(BackendError::CommandFailed(output.stderr)); + } + // Note: barretenberg includes the newline, so that subsequent prints to stdout + // are not on the same line as the gates output. + + let gates_bytes: [u8; 8] = + output.stdout.try_into().map_err(BackendError::MalformedResponse)?; + + // Convert bytes to u64 in little-endian format + let value = u64::from_le_bytes(gates_bytes); + + Ok(value as u32) + } +} + +#[test] +fn gate_command() -> Result<(), BackendError> { + use tempfile::tempdir; + + let backend = crate::get_mock_backend()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory_path = temp_directory.path(); + let bytecode_path = temp_directory_path.join("acir.gz"); + let crs_path = backend.backend_directory(); + + std::fs::File::create(&bytecode_path).expect("file should be created"); + + let gate_command = GatesCommand { crs_path, bytecode_path }; + + let output = gate_command.run(backend.binary_path())?; + // Mock backend always returns zero gates. + assert_eq!(output, 0); + + Ok(()) +} diff --git a/tooling/acvm_backend_barretenberg/src/cli/info.rs b/tooling/acvm_backend_barretenberg/src/cli/info.rs new file mode 100644 index 00000000000..5d9e662b6b7 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/cli/info.rs @@ -0,0 +1,88 @@ +use acvm::acir::circuit::opcodes::Opcode; +use acvm::Language; +use serde::Deserialize; +use std::collections::HashSet; +use std::path::{Path, PathBuf}; + +use crate::BackendError; + +pub(crate) struct InfoCommand { + pub(crate) crs_path: PathBuf, +} + +#[derive(Deserialize)] +struct InfoResponse { + language: LanguageResponse, + opcodes_supported: Vec, + black_box_functions_supported: Vec, +} + +#[derive(Deserialize)] +struct LanguageResponse { + name: String, + width: Option, +} + +impl InfoCommand { + pub(crate) fn run( + self, + binary_path: &Path, + ) -> Result<(Language, Box bool>), BackendError> { + let mut command = std::process::Command::new(binary_path); + + command.arg("info").arg("-c").arg(self.crs_path).arg("-o").arg("-"); + + let output = command.output()?; + + if !output.status.success() { + return Err(BackendError::CommandFailed(output.stderr)); + } + + let backend_info: InfoResponse = + serde_json::from_slice(&output.stdout).expect("Backend should return valid json"); + let language: Language = match backend_info.language.name.as_str() { + "PLONK-CSAT" => { + let width = backend_info.language.width.unwrap(); + Language::PLONKCSat { width } + } + "R1CS" => Language::R1CS, + _ => panic!("Unknown langauge"), + }; + + let opcodes_set: HashSet = backend_info.opcodes_supported.into_iter().collect(); + let black_box_functions_set: HashSet = + backend_info.black_box_functions_supported.into_iter().collect(); + + let is_opcode_supported = move |opcode: &Opcode| -> bool { + match opcode { + Opcode::Arithmetic(_) => opcodes_set.contains("arithmetic"), + Opcode::Directive(_) => opcodes_set.contains("directive"), + Opcode::Brillig(_) => opcodes_set.contains("brillig"), + Opcode::MemoryInit { .. } => opcodes_set.contains("memory_init"), + Opcode::MemoryOp { .. } => opcodes_set.contains("memory_op"), + Opcode::BlackBoxFuncCall(func) => { + black_box_functions_set.contains(func.get_black_box_func().name()) + } + } + }; + + Ok((language, Box::new(is_opcode_supported))) + } +} + +#[test] +fn info_command() -> Result<(), BackendError> { + use acvm::acir::circuit::opcodes::Opcode; + + use acvm::acir::native_types::Expression; + + let backend = crate::get_mock_backend()?; + let crs_path = backend.backend_directory(); + + let (language, is_opcode_supported) = InfoCommand { crs_path }.run(backend.binary_path())?; + + assert!(matches!(language, Language::PLONKCSat { width: 3 })); + assert!(is_opcode_supported(&Opcode::Arithmetic(Expression::default()))); + + Ok(()) +} diff --git a/tooling/acvm_backend_barretenberg/src/cli/mod.rs b/tooling/acvm_backend_barretenberg/src/cli/mod.rs new file mode 100644 index 00000000000..5018def4160 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/cli/mod.rs @@ -0,0 +1,30 @@ +// Reference: https://github.com/AztecProtocol/aztec-packages/blob/master/circuits/cpp/barretenberg/cpp/src/barretenberg/bb/main.cpp + +mod contract; +mod gates; +mod info; +mod prove; +mod verify; +mod write_vk; + +pub(crate) use contract::ContractCommand; +pub(crate) use gates::GatesCommand; +pub(crate) use info::InfoCommand; +pub(crate) use prove::ProveCommand; +pub(crate) use verify::VerifyCommand; +pub(crate) use write_vk::WriteVkCommand; + +#[test] +fn no_command_provided_works() -> Result<(), crate::BackendError> { + // This is a simple test to check that the binaries work + + let backend = crate::get_mock_backend()?; + + let output = std::process::Command::new(backend.binary_path()).output()?; + + let stderr = String::from_utf8_lossy(&output.stderr); + // Assert help message is printed due to no command being provided. + assert!(stderr.contains("Usage: mock_backend ")); + + Ok(()) +} diff --git a/tooling/acvm_backend_barretenberg/src/cli/prove.rs b/tooling/acvm_backend_barretenberg/src/cli/prove.rs new file mode 100644 index 00000000000..a229506a3dc --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/cli/prove.rs @@ -0,0 +1,69 @@ +use std::path::{Path, PathBuf}; + +use crate::BackendError; + +/// ProveCommand will call the barretenberg binary +/// to create a proof, given the witness and the bytecode. +/// +/// Note:Internally barretenberg will create and discard the +/// proving key, so this is not returned. +/// +/// The proof will be written to the specified output file. +pub(crate) struct ProveCommand { + pub(crate) crs_path: PathBuf, + pub(crate) is_recursive: bool, + pub(crate) bytecode_path: PathBuf, + pub(crate) witness_path: PathBuf, +} + +impl ProveCommand { + pub(crate) fn run(self, binary_path: &Path) -> Result, BackendError> { + let mut command = std::process::Command::new(binary_path); + + command + .arg("prove") + .arg("-c") + .arg(self.crs_path) + .arg("-b") + .arg(self.bytecode_path) + .arg("-w") + .arg(self.witness_path) + .arg("-o") + .arg("-"); + + if self.is_recursive { + command.arg("-r"); + } + + let output = command.output()?; + if output.status.success() { + Ok(output.stdout) + } else { + Err(BackendError::CommandFailed(output.stderr)) + } + } +} + +#[test] +fn prove_command() -> Result<(), BackendError> { + use tempfile::tempdir; + + let backend = crate::get_mock_backend()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory_path = temp_directory.path(); + let bytecode_path = temp_directory_path.join("acir.gz"); + let witness_path = temp_directory_path.join("witness.tr"); + + std::fs::File::create(&bytecode_path).expect("file should be created"); + std::fs::File::create(&witness_path).expect("file should be created"); + + let crs_path = backend.backend_directory(); + let prove_command = ProveCommand { crs_path, bytecode_path, witness_path, is_recursive: false }; + + let proof = prove_command.run(backend.binary_path())?; + assert_eq!(proof, "proof".as_bytes()); + drop(temp_directory); + + Ok(()) +} diff --git a/tooling/acvm_backend_barretenberg/src/cli/verify.rs b/tooling/acvm_backend_barretenberg/src/cli/verify.rs new file mode 100644 index 00000000000..741dd8cbd14 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/cli/verify.rs @@ -0,0 +1,86 @@ +use std::path::{Path, PathBuf}; + +use crate::BackendError; + +/// VerifyCommand will call the barretenberg binary +/// to verify a proof +pub(crate) struct VerifyCommand { + pub(crate) crs_path: PathBuf, + pub(crate) is_recursive: bool, + pub(crate) proof_path: PathBuf, + pub(crate) vk_path: PathBuf, +} + +impl VerifyCommand { + pub(crate) fn run(self, binary_path: &Path) -> Result { + let mut command = std::process::Command::new(binary_path); + + command + .arg("verify") + .arg("-c") + .arg(self.crs_path) + .arg("-p") + .arg(self.proof_path) + .arg("-k") + .arg(self.vk_path); + + if self.is_recursive { + command.arg("-r"); + } + + let output = command.output()?; + + // We currently do not distinguish between an invalid proof and an error inside the backend. + Ok(output.status.success()) + } +} + +#[test] +fn verify_command() -> Result<(), BackendError> { + use tempfile::tempdir; + + use super::{ProveCommand, WriteVkCommand}; + use crate::proof_system::write_to_file; + + let backend = crate::get_mock_backend()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory_path = temp_directory.path(); + let bytecode_path = temp_directory_path.join("acir.gz"); + let witness_path = temp_directory_path.join("witness.tr"); + let proof_path = temp_directory_path.join("1_mul.proof"); + let vk_path_output = temp_directory_path.join("vk"); + + let crs_path = backend.backend_directory(); + + std::fs::File::create(&bytecode_path).expect("file should be created"); + std::fs::File::create(&witness_path).expect("file should be created"); + + let write_vk_command = WriteVkCommand { + bytecode_path: bytecode_path.clone(), + crs_path: crs_path.clone(), + is_recursive: false, + vk_path_output: vk_path_output.clone(), + }; + + write_vk_command.run(backend.binary_path())?; + + let prove_command = ProveCommand { + crs_path: crs_path.clone(), + is_recursive: false, + bytecode_path, + witness_path, + }; + let proof = prove_command.run(backend.binary_path())?; + + write_to_file(&proof, &proof_path); + + let verify_command = + VerifyCommand { crs_path, is_recursive: false, proof_path, vk_path: vk_path_output }; + + let verified = verify_command.run(backend.binary_path())?; + assert!(verified); + + drop(temp_directory); + Ok(()) +} diff --git a/tooling/acvm_backend_barretenberg/src/cli/write_vk.rs b/tooling/acvm_backend_barretenberg/src/cli/write_vk.rs new file mode 100644 index 00000000000..05db7e47388 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/cli/write_vk.rs @@ -0,0 +1,62 @@ +use std::path::{Path, PathBuf}; + +use crate::BackendError; + +/// WriteCommand will call the barretenberg binary +/// to write a verification key to a file +pub(crate) struct WriteVkCommand { + pub(crate) crs_path: PathBuf, + pub(crate) is_recursive: bool, + pub(crate) bytecode_path: PathBuf, + pub(crate) vk_path_output: PathBuf, +} + +impl WriteVkCommand { + pub(crate) fn run(self, binary_path: &Path) -> Result<(), BackendError> { + let mut command = std::process::Command::new(binary_path); + + command + .arg("write_vk") + .arg("-c") + .arg(self.crs_path) + .arg("-b") + .arg(self.bytecode_path) + .arg("-o") + .arg(self.vk_path_output); + + if self.is_recursive { + command.arg("-r"); + } + + let output = command.output()?; + if output.status.success() { + Ok(()) + } else { + Err(BackendError::CommandFailed(output.stderr)) + } + } +} + +#[test] +fn write_vk_command() -> Result<(), BackendError> { + use tempfile::tempdir; + + let backend = crate::get_mock_backend()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory_path = temp_directory.path(); + let bytecode_path = temp_directory_path.join("acir.gz"); + let vk_path_output = temp_directory.path().join("vk"); + + let crs_path = backend.backend_directory(); + + std::fs::File::create(&bytecode_path).expect("file should be created"); + + let write_vk_command = + WriteVkCommand { bytecode_path, crs_path, is_recursive: false, vk_path_output }; + + write_vk_command.run(backend.binary_path())?; + drop(temp_directory); + + Ok(()) +} diff --git a/tooling/acvm_backend_barretenberg/src/contract.sol b/tooling/acvm_backend_barretenberg/src/contract.sol new file mode 100644 index 00000000000..abd45567969 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/contract.sol @@ -0,0 +1,2539 @@ + +/** + * @title Ultra Plonk proof verification contract + * @dev Top level Plonk proof verification contract, which allows Plonk proof to be verified + */ +abstract contract BaseUltraVerifier { + // VERIFICATION KEY MEMORY LOCATIONS + uint256 internal constant N_LOC = 0x380; + uint256 internal constant NUM_INPUTS_LOC = 0x3a0; + uint256 internal constant OMEGA_LOC = 0x3c0; + uint256 internal constant DOMAIN_INVERSE_LOC = 0x3e0; + uint256 internal constant Q1_X_LOC = 0x400; + uint256 internal constant Q1_Y_LOC = 0x420; + uint256 internal constant Q2_X_LOC = 0x440; + uint256 internal constant Q2_Y_LOC = 0x460; + uint256 internal constant Q3_X_LOC = 0x480; + uint256 internal constant Q3_Y_LOC = 0x4a0; + uint256 internal constant Q4_X_LOC = 0x4c0; + uint256 internal constant Q4_Y_LOC = 0x4e0; + uint256 internal constant QM_X_LOC = 0x500; + uint256 internal constant QM_Y_LOC = 0x520; + uint256 internal constant QC_X_LOC = 0x540; + uint256 internal constant QC_Y_LOC = 0x560; + uint256 internal constant QARITH_X_LOC = 0x580; + uint256 internal constant QARITH_Y_LOC = 0x5a0; + uint256 internal constant QSORT_X_LOC = 0x5c0; + uint256 internal constant QSORT_Y_LOC = 0x5e0; + uint256 internal constant QELLIPTIC_X_LOC = 0x600; + uint256 internal constant QELLIPTIC_Y_LOC = 0x620; + uint256 internal constant QAUX_X_LOC = 0x640; + uint256 internal constant QAUX_Y_LOC = 0x660; + uint256 internal constant SIGMA1_X_LOC = 0x680; + uint256 internal constant SIGMA1_Y_LOC = 0x6a0; + uint256 internal constant SIGMA2_X_LOC = 0x6c0; + uint256 internal constant SIGMA2_Y_LOC = 0x6e0; + uint256 internal constant SIGMA3_X_LOC = 0x700; + uint256 internal constant SIGMA3_Y_LOC = 0x720; + uint256 internal constant SIGMA4_X_LOC = 0x740; + uint256 internal constant SIGMA4_Y_LOC = 0x760; + uint256 internal constant TABLE1_X_LOC = 0x780; + uint256 internal constant TABLE1_Y_LOC = 0x7a0; + uint256 internal constant TABLE2_X_LOC = 0x7c0; + uint256 internal constant TABLE2_Y_LOC = 0x7e0; + uint256 internal constant TABLE3_X_LOC = 0x800; + uint256 internal constant TABLE3_Y_LOC = 0x820; + uint256 internal constant TABLE4_X_LOC = 0x840; + uint256 internal constant TABLE4_Y_LOC = 0x860; + uint256 internal constant TABLE_TYPE_X_LOC = 0x880; + uint256 internal constant TABLE_TYPE_Y_LOC = 0x8a0; + uint256 internal constant ID1_X_LOC = 0x8c0; + uint256 internal constant ID1_Y_LOC = 0x8e0; + uint256 internal constant ID2_X_LOC = 0x900; + uint256 internal constant ID2_Y_LOC = 0x920; + uint256 internal constant ID3_X_LOC = 0x940; + uint256 internal constant ID3_Y_LOC = 0x960; + uint256 internal constant ID4_X_LOC = 0x980; + uint256 internal constant ID4_Y_LOC = 0x9a0; + uint256 internal constant CONTAINS_RECURSIVE_PROOF_LOC = 0x9c0; + uint256 internal constant RECURSIVE_PROOF_PUBLIC_INPUT_INDICES_LOC = 0x9e0; + uint256 internal constant G2X_X0_LOC = 0xa00; + uint256 internal constant G2X_X1_LOC = 0xa20; + uint256 internal constant G2X_Y0_LOC = 0xa40; + uint256 internal constant G2X_Y1_LOC = 0xa60; + + // ### PROOF DATA MEMORY LOCATIONS + uint256 internal constant W1_X_LOC = 0x1200; + uint256 internal constant W1_Y_LOC = 0x1220; + uint256 internal constant W2_X_LOC = 0x1240; + uint256 internal constant W2_Y_LOC = 0x1260; + uint256 internal constant W3_X_LOC = 0x1280; + uint256 internal constant W3_Y_LOC = 0x12a0; + uint256 internal constant W4_X_LOC = 0x12c0; + uint256 internal constant W4_Y_LOC = 0x12e0; + uint256 internal constant S_X_LOC = 0x1300; + uint256 internal constant S_Y_LOC = 0x1320; + uint256 internal constant Z_X_LOC = 0x1340; + uint256 internal constant Z_Y_LOC = 0x1360; + uint256 internal constant Z_LOOKUP_X_LOC = 0x1380; + uint256 internal constant Z_LOOKUP_Y_LOC = 0x13a0; + uint256 internal constant T1_X_LOC = 0x13c0; + uint256 internal constant T1_Y_LOC = 0x13e0; + uint256 internal constant T2_X_LOC = 0x1400; + uint256 internal constant T2_Y_LOC = 0x1420; + uint256 internal constant T3_X_LOC = 0x1440; + uint256 internal constant T3_Y_LOC = 0x1460; + uint256 internal constant T4_X_LOC = 0x1480; + uint256 internal constant T4_Y_LOC = 0x14a0; + + uint256 internal constant W1_EVAL_LOC = 0x1600; + uint256 internal constant W2_EVAL_LOC = 0x1620; + uint256 internal constant W3_EVAL_LOC = 0x1640; + uint256 internal constant W4_EVAL_LOC = 0x1660; + uint256 internal constant S_EVAL_LOC = 0x1680; + uint256 internal constant Z_EVAL_LOC = 0x16a0; + uint256 internal constant Z_LOOKUP_EVAL_LOC = 0x16c0; + uint256 internal constant Q1_EVAL_LOC = 0x16e0; + uint256 internal constant Q2_EVAL_LOC = 0x1700; + uint256 internal constant Q3_EVAL_LOC = 0x1720; + uint256 internal constant Q4_EVAL_LOC = 0x1740; + uint256 internal constant QM_EVAL_LOC = 0x1760; + uint256 internal constant QC_EVAL_LOC = 0x1780; + uint256 internal constant QARITH_EVAL_LOC = 0x17a0; + uint256 internal constant QSORT_EVAL_LOC = 0x17c0; + uint256 internal constant QELLIPTIC_EVAL_LOC = 0x17e0; + uint256 internal constant QAUX_EVAL_LOC = 0x1800; + uint256 internal constant TABLE1_EVAL_LOC = 0x1840; + uint256 internal constant TABLE2_EVAL_LOC = 0x1860; + uint256 internal constant TABLE3_EVAL_LOC = 0x1880; + uint256 internal constant TABLE4_EVAL_LOC = 0x18a0; + uint256 internal constant TABLE_TYPE_EVAL_LOC = 0x18c0; + uint256 internal constant ID1_EVAL_LOC = 0x18e0; + uint256 internal constant ID2_EVAL_LOC = 0x1900; + uint256 internal constant ID3_EVAL_LOC = 0x1920; + uint256 internal constant ID4_EVAL_LOC = 0x1940; + uint256 internal constant SIGMA1_EVAL_LOC = 0x1960; + uint256 internal constant SIGMA2_EVAL_LOC = 0x1980; + uint256 internal constant SIGMA3_EVAL_LOC = 0x19a0; + uint256 internal constant SIGMA4_EVAL_LOC = 0x19c0; + uint256 internal constant W1_OMEGA_EVAL_LOC = 0x19e0; + uint256 internal constant W2_OMEGA_EVAL_LOC = 0x2000; + uint256 internal constant W3_OMEGA_EVAL_LOC = 0x2020; + uint256 internal constant W4_OMEGA_EVAL_LOC = 0x2040; + uint256 internal constant S_OMEGA_EVAL_LOC = 0x2060; + uint256 internal constant Z_OMEGA_EVAL_LOC = 0x2080; + uint256 internal constant Z_LOOKUP_OMEGA_EVAL_LOC = 0x20a0; + uint256 internal constant TABLE1_OMEGA_EVAL_LOC = 0x20c0; + uint256 internal constant TABLE2_OMEGA_EVAL_LOC = 0x20e0; + uint256 internal constant TABLE3_OMEGA_EVAL_LOC = 0x2100; + uint256 internal constant TABLE4_OMEGA_EVAL_LOC = 0x2120; + + uint256 internal constant PI_Z_X_LOC = 0x2300; + uint256 internal constant PI_Z_Y_LOC = 0x2320; + uint256 internal constant PI_Z_OMEGA_X_LOC = 0x2340; + uint256 internal constant PI_Z_OMEGA_Y_LOC = 0x2360; + + // Used for elliptic widget. These are alias names for wire + shifted wire evaluations + uint256 internal constant X1_EVAL_LOC = W2_EVAL_LOC; + uint256 internal constant X2_EVAL_LOC = W1_OMEGA_EVAL_LOC; + uint256 internal constant X3_EVAL_LOC = W2_OMEGA_EVAL_LOC; + uint256 internal constant Y1_EVAL_LOC = W3_EVAL_LOC; + uint256 internal constant Y2_EVAL_LOC = W4_OMEGA_EVAL_LOC; + uint256 internal constant Y3_EVAL_LOC = W3_OMEGA_EVAL_LOC; + uint256 internal constant QBETA_LOC = Q3_EVAL_LOC; + uint256 internal constant QBETA_SQR_LOC = Q4_EVAL_LOC; + uint256 internal constant QSIGN_LOC = Q1_EVAL_LOC; + + // ### CHALLENGES MEMORY OFFSETS + + uint256 internal constant C_BETA_LOC = 0x2600; + uint256 internal constant C_GAMMA_LOC = 0x2620; + uint256 internal constant C_ALPHA_LOC = 0x2640; + uint256 internal constant C_ETA_LOC = 0x2660; + uint256 internal constant C_ETA_SQR_LOC = 0x2680; + uint256 internal constant C_ETA_CUBE_LOC = 0x26a0; + + uint256 internal constant C_ZETA_LOC = 0x26c0; + uint256 internal constant C_CURRENT_LOC = 0x26e0; + uint256 internal constant C_V0_LOC = 0x2700; + uint256 internal constant C_V1_LOC = 0x2720; + uint256 internal constant C_V2_LOC = 0x2740; + uint256 internal constant C_V3_LOC = 0x2760; + uint256 internal constant C_V4_LOC = 0x2780; + uint256 internal constant C_V5_LOC = 0x27a0; + uint256 internal constant C_V6_LOC = 0x27c0; + uint256 internal constant C_V7_LOC = 0x27e0; + uint256 internal constant C_V8_LOC = 0x2800; + uint256 internal constant C_V9_LOC = 0x2820; + uint256 internal constant C_V10_LOC = 0x2840; + uint256 internal constant C_V11_LOC = 0x2860; + uint256 internal constant C_V12_LOC = 0x2880; + uint256 internal constant C_V13_LOC = 0x28a0; + uint256 internal constant C_V14_LOC = 0x28c0; + uint256 internal constant C_V15_LOC = 0x28e0; + uint256 internal constant C_V16_LOC = 0x2900; + uint256 internal constant C_V17_LOC = 0x2920; + uint256 internal constant C_V18_LOC = 0x2940; + uint256 internal constant C_V19_LOC = 0x2960; + uint256 internal constant C_V20_LOC = 0x2980; + uint256 internal constant C_V21_LOC = 0x29a0; + uint256 internal constant C_V22_LOC = 0x29c0; + uint256 internal constant C_V23_LOC = 0x29e0; + uint256 internal constant C_V24_LOC = 0x2a00; + uint256 internal constant C_V25_LOC = 0x2a20; + uint256 internal constant C_V26_LOC = 0x2a40; + uint256 internal constant C_V27_LOC = 0x2a60; + uint256 internal constant C_V28_LOC = 0x2a80; + uint256 internal constant C_V29_LOC = 0x2aa0; + uint256 internal constant C_V30_LOC = 0x2ac0; + + uint256 internal constant C_U_LOC = 0x2b00; + + // ### LOCAL VARIABLES MEMORY OFFSETS + uint256 internal constant DELTA_NUMERATOR_LOC = 0x3000; + uint256 internal constant DELTA_DENOMINATOR_LOC = 0x3020; + uint256 internal constant ZETA_POW_N_LOC = 0x3040; + uint256 internal constant PUBLIC_INPUT_DELTA_LOC = 0x3060; + uint256 internal constant ZERO_POLY_LOC = 0x3080; + uint256 internal constant L_START_LOC = 0x30a0; + uint256 internal constant L_END_LOC = 0x30c0; + uint256 internal constant R_ZERO_EVAL_LOC = 0x30e0; + + uint256 internal constant PLOOKUP_DELTA_NUMERATOR_LOC = 0x3100; + uint256 internal constant PLOOKUP_DELTA_DENOMINATOR_LOC = 0x3120; + uint256 internal constant PLOOKUP_DELTA_LOC = 0x3140; + + uint256 internal constant ACCUMULATOR_X_LOC = 0x3160; + uint256 internal constant ACCUMULATOR_Y_LOC = 0x3180; + uint256 internal constant ACCUMULATOR2_X_LOC = 0x31a0; + uint256 internal constant ACCUMULATOR2_Y_LOC = 0x31c0; + uint256 internal constant PAIRING_LHS_X_LOC = 0x31e0; + uint256 internal constant PAIRING_LHS_Y_LOC = 0x3200; + uint256 internal constant PAIRING_RHS_X_LOC = 0x3220; + uint256 internal constant PAIRING_RHS_Y_LOC = 0x3240; + + // ### SUCCESS FLAG MEMORY LOCATIONS + uint256 internal constant GRAND_PRODUCT_SUCCESS_FLAG = 0x3300; + uint256 internal constant ARITHMETIC_TERM_SUCCESS_FLAG = 0x3020; + uint256 internal constant BATCH_OPENING_SUCCESS_FLAG = 0x3340; + uint256 internal constant OPENING_COMMITMENT_SUCCESS_FLAG = 0x3360; + uint256 internal constant PAIRING_PREAMBLE_SUCCESS_FLAG = 0x3380; + uint256 internal constant PAIRING_SUCCESS_FLAG = 0x33a0; + uint256 internal constant RESULT_FLAG = 0x33c0; + + // misc stuff + uint256 internal constant OMEGA_INVERSE_LOC = 0x3400; + uint256 internal constant C_ALPHA_SQR_LOC = 0x3420; + uint256 internal constant C_ALPHA_CUBE_LOC = 0x3440; + uint256 internal constant C_ALPHA_QUAD_LOC = 0x3460; + uint256 internal constant C_ALPHA_BASE_LOC = 0x3480; + + // ### RECURSION VARIABLE MEMORY LOCATIONS + uint256 internal constant RECURSIVE_P1_X_LOC = 0x3500; + uint256 internal constant RECURSIVE_P1_Y_LOC = 0x3520; + uint256 internal constant RECURSIVE_P2_X_LOC = 0x3540; + uint256 internal constant RECURSIVE_P2_Y_LOC = 0x3560; + + uint256 internal constant PUBLIC_INPUTS_HASH_LOCATION = 0x3580; + + // sub-identity storage + uint256 internal constant PERMUTATION_IDENTITY = 0x3600; + uint256 internal constant PLOOKUP_IDENTITY = 0x3620; + uint256 internal constant ARITHMETIC_IDENTITY = 0x3640; + uint256 internal constant SORT_IDENTITY = 0x3660; + uint256 internal constant ELLIPTIC_IDENTITY = 0x3680; + uint256 internal constant AUX_IDENTITY = 0x36a0; + uint256 internal constant AUX_NON_NATIVE_FIELD_EVALUATION = 0x36c0; + uint256 internal constant AUX_LIMB_ACCUMULATOR_EVALUATION = 0x36e0; + uint256 internal constant AUX_RAM_CONSISTENCY_EVALUATION = 0x3700; + uint256 internal constant AUX_ROM_CONSISTENCY_EVALUATION = 0x3720; + uint256 internal constant AUX_MEMORY_EVALUATION = 0x3740; + + uint256 internal constant QUOTIENT_EVAL_LOC = 0x3760; + uint256 internal constant ZERO_POLY_INVERSE_LOC = 0x3780; + + // when hashing public inputs we use memory at NU_CHALLENGE_INPUT_LOC_A, as the hash input size is unknown at compile time + uint256 internal constant NU_CHALLENGE_INPUT_LOC_A = 0x37a0; + uint256 internal constant NU_CHALLENGE_INPUT_LOC_B = 0x37c0; + uint256 internal constant NU_CHALLENGE_INPUT_LOC_C = 0x37e0; + + bytes4 internal constant PUBLIC_INPUT_INVALID_BN128_G1_POINT_SELECTOR = 0xeba9f4a6; + bytes4 internal constant PUBLIC_INPUT_GE_P_SELECTOR = 0x374a972f; + bytes4 internal constant MOD_EXP_FAILURE_SELECTOR = 0xf894a7bc; + bytes4 internal constant EC_SCALAR_MUL_FAILURE_SELECTOR = 0xf755f369; + bytes4 internal constant PROOF_FAILURE_SELECTOR = 0x0711fcec; + + uint256 internal constant ETA_INPUT_LENGTH = 0xc0; // W1, W2, W3 = 6 * 0x20 bytes + + // We need to hash 41 field elements when generating the NU challenge + // w1, w2, w3, w4, s, z, z_lookup, q1, q2, q3, q4, qm, qc, qarith (14) + // qsort, qelliptic, qaux, sigma1, sigma2, sigma, sigma4, (7) + // table1, table2, table3, table4, tabletype, id1, id2, id3, id4, (9) + // w1_omega, w2_omega, w3_omega, w4_omega, s_omega, z_omega, z_lookup_omega, (7) + // table1_omega, table2_omega, table3_omega, table4_omega (4) + uint256 internal constant NU_INPUT_LENGTH = 0x520; // 0x520 = 41 * 0x20 + + // There are ELEVEN G1 group elements added into the transcript in the `beta` round, that we need to skip over + // W1, W2, W3, W4, S, Z, Z_LOOKUP, T1, T2, T3, T4 + uint256 internal constant NU_CALLDATA_SKIP_LENGTH = 0x2c0; // 11 * 0x40 = 0x2c0 + + uint256 internal constant NEGATIVE_INVERSE_OF_2_MODULO_P = + 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000; + uint256 internal constant LIMB_SIZE = 0x100000000000000000; // 2<<68 + uint256 internal constant SUBLIMB_SHIFT = 0x4000; // 2<<14 + + error PUBLIC_INPUT_COUNT_INVALID(uint256 expected, uint256 actual); + error PUBLIC_INPUT_INVALID_BN128_G1_POINT(); + error PUBLIC_INPUT_GE_P(); + error MOD_EXP_FAILURE(); + error EC_SCALAR_MUL_FAILURE(); + error PROOF_FAILURE(); + + function getVerificationKeyHash() public pure virtual returns (bytes32); + + function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure virtual; + + /** + * @notice Verify a Ultra Plonk proof + * @param _proof - The serialized proof + * @param _publicInputs - An array of the public inputs + * @return True if proof is valid, reverts otherwise + */ + function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) { + loadVerificationKey(N_LOC, OMEGA_INVERSE_LOC); + + uint256 requiredPublicInputCount; + assembly { + requiredPublicInputCount := mload(NUM_INPUTS_LOC) + } + if (requiredPublicInputCount != _publicInputs.length) { + revert PUBLIC_INPUT_COUNT_INVALID(requiredPublicInputCount, _publicInputs.length); + } + + assembly { + let q := 21888242871839275222246405745257275088696311157297823662689037894645226208583 // EC group order + let p := 21888242871839275222246405745257275088548364400416034343698204186575808495617 // Prime field order + + /** + * LOAD PROOF FROM CALLDATA + */ + { + let data_ptr := add(calldataload(0x04), 0x24) + + mstore(W1_Y_LOC, mod(calldataload(data_ptr), q)) + mstore(W1_X_LOC, mod(calldataload(add(data_ptr, 0x20)), q)) + + mstore(W2_Y_LOC, mod(calldataload(add(data_ptr, 0x40)), q)) + mstore(W2_X_LOC, mod(calldataload(add(data_ptr, 0x60)), q)) + + mstore(W3_Y_LOC, mod(calldataload(add(data_ptr, 0x80)), q)) + mstore(W3_X_LOC, mod(calldataload(add(data_ptr, 0xa0)), q)) + + mstore(W4_Y_LOC, mod(calldataload(add(data_ptr, 0xc0)), q)) + mstore(W4_X_LOC, mod(calldataload(add(data_ptr, 0xe0)), q)) + + mstore(S_Y_LOC, mod(calldataload(add(data_ptr, 0x100)), q)) + mstore(S_X_LOC, mod(calldataload(add(data_ptr, 0x120)), q)) + mstore(Z_Y_LOC, mod(calldataload(add(data_ptr, 0x140)), q)) + mstore(Z_X_LOC, mod(calldataload(add(data_ptr, 0x160)), q)) + mstore(Z_LOOKUP_Y_LOC, mod(calldataload(add(data_ptr, 0x180)), q)) + mstore(Z_LOOKUP_X_LOC, mod(calldataload(add(data_ptr, 0x1a0)), q)) + mstore(T1_Y_LOC, mod(calldataload(add(data_ptr, 0x1c0)), q)) + mstore(T1_X_LOC, mod(calldataload(add(data_ptr, 0x1e0)), q)) + + mstore(T2_Y_LOC, mod(calldataload(add(data_ptr, 0x200)), q)) + mstore(T2_X_LOC, mod(calldataload(add(data_ptr, 0x220)), q)) + + mstore(T3_Y_LOC, mod(calldataload(add(data_ptr, 0x240)), q)) + mstore(T3_X_LOC, mod(calldataload(add(data_ptr, 0x260)), q)) + + mstore(T4_Y_LOC, mod(calldataload(add(data_ptr, 0x280)), q)) + mstore(T4_X_LOC, mod(calldataload(add(data_ptr, 0x2a0)), q)) + + mstore(W1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x2c0)), p)) + mstore(W2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x2e0)), p)) + mstore(W3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x300)), p)) + mstore(W4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x320)), p)) + mstore(S_EVAL_LOC, mod(calldataload(add(data_ptr, 0x340)), p)) + mstore(Z_EVAL_LOC, mod(calldataload(add(data_ptr, 0x360)), p)) + mstore(Z_LOOKUP_EVAL_LOC, mod(calldataload(add(data_ptr, 0x380)), p)) + mstore(Q1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x3a0)), p)) + mstore(Q2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x3c0)), p)) + mstore(Q3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x3e0)), p)) + mstore(Q4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x400)), p)) + mstore(QM_EVAL_LOC, mod(calldataload(add(data_ptr, 0x420)), p)) + mstore(QC_EVAL_LOC, mod(calldataload(add(data_ptr, 0x440)), p)) + mstore(QARITH_EVAL_LOC, mod(calldataload(add(data_ptr, 0x460)), p)) + mstore(QSORT_EVAL_LOC, mod(calldataload(add(data_ptr, 0x480)), p)) + mstore(QELLIPTIC_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4a0)), p)) + mstore(QAUX_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4c0)), p)) + + mstore(SIGMA1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4e0)), p)) + mstore(SIGMA2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x500)), p)) + + mstore(SIGMA3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x520)), p)) + mstore(SIGMA4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x540)), p)) + + mstore(TABLE1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x560)), p)) + mstore(TABLE2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x580)), p)) + mstore(TABLE3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5a0)), p)) + mstore(TABLE4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5c0)), p)) + mstore(TABLE_TYPE_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5e0)), p)) + + mstore(ID1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x600)), p)) + mstore(ID2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x620)), p)) + mstore(ID3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x640)), p)) + mstore(ID4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x660)), p)) + + mstore(W1_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x680)), p)) + mstore(W2_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6a0)), p)) + mstore(W3_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6c0)), p)) + mstore(W4_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6e0)), p)) + mstore(S_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x700)), p)) + + mstore(Z_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x720)), p)) + + mstore(Z_LOOKUP_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x740)), p)) + mstore(TABLE1_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x760)), p)) + mstore(TABLE2_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x780)), p)) + mstore(TABLE3_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7a0)), p)) + mstore(TABLE4_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7c0)), p)) + + mstore(PI_Z_Y_LOC, mod(calldataload(add(data_ptr, 0x7e0)), q)) + mstore(PI_Z_X_LOC, mod(calldataload(add(data_ptr, 0x800)), q)) + + mstore(PI_Z_OMEGA_Y_LOC, mod(calldataload(add(data_ptr, 0x820)), q)) + mstore(PI_Z_OMEGA_X_LOC, mod(calldataload(add(data_ptr, 0x840)), q)) + } + + /** + * LOAD RECURSIVE PROOF INTO MEMORY + */ + { + if mload(CONTAINS_RECURSIVE_PROOF_LOC) { + let public_inputs_ptr := add(calldataload(0x24), 0x24) + let index_counter := add(shl(5, mload(RECURSIVE_PROOF_PUBLIC_INPUT_INDICES_LOC)), public_inputs_ptr) + + let x0 := calldataload(index_counter) + x0 := add(x0, shl(68, calldataload(add(index_counter, 0x20)))) + x0 := add(x0, shl(136, calldataload(add(index_counter, 0x40)))) + x0 := add(x0, shl(204, calldataload(add(index_counter, 0x60)))) + let y0 := calldataload(add(index_counter, 0x80)) + y0 := add(y0, shl(68, calldataload(add(index_counter, 0xa0)))) + y0 := add(y0, shl(136, calldataload(add(index_counter, 0xc0)))) + y0 := add(y0, shl(204, calldataload(add(index_counter, 0xe0)))) + let x1 := calldataload(add(index_counter, 0x100)) + x1 := add(x1, shl(68, calldataload(add(index_counter, 0x120)))) + x1 := add(x1, shl(136, calldataload(add(index_counter, 0x140)))) + x1 := add(x1, shl(204, calldataload(add(index_counter, 0x160)))) + let y1 := calldataload(add(index_counter, 0x180)) + y1 := add(y1, shl(68, calldataload(add(index_counter, 0x1a0)))) + y1 := add(y1, shl(136, calldataload(add(index_counter, 0x1c0)))) + y1 := add(y1, shl(204, calldataload(add(index_counter, 0x1e0)))) + mstore(RECURSIVE_P1_X_LOC, x0) + mstore(RECURSIVE_P1_Y_LOC, y0) + mstore(RECURSIVE_P2_X_LOC, x1) + mstore(RECURSIVE_P2_Y_LOC, y1) + + // validate these are valid bn128 G1 points + if iszero(and(and(lt(x0, q), lt(x1, q)), and(lt(y0, q), lt(y1, q)))) { + mstore(0x00, PUBLIC_INPUT_INVALID_BN128_G1_POINT_SELECTOR) + revert(0x00, 0x04) + } + } + } + + { + /** + * Generate initial challenge + */ + mstore(0x00, shl(224, mload(N_LOC))) + mstore(0x04, shl(224, mload(NUM_INPUTS_LOC))) + let challenge := keccak256(0x00, 0x08) + + /** + * Generate eta challenge + */ + mstore(PUBLIC_INPUTS_HASH_LOCATION, challenge) + // The public input location is stored at 0x24, we then add 0x24 to skip selector and the length of public inputs + let public_inputs_start := add(calldataload(0x24), 0x24) + // copy the public inputs over + let public_input_size := mul(mload(NUM_INPUTS_LOC), 0x20) + calldatacopy(add(PUBLIC_INPUTS_HASH_LOCATION, 0x20), public_inputs_start, public_input_size) + + // copy W1, W2, W3 into challenge. Each point is 0x40 bytes, so load 0xc0 = 3 * 0x40 bytes (ETA input length) + let w_start := add(calldataload(0x04), 0x24) + calldatacopy(add(add(PUBLIC_INPUTS_HASH_LOCATION, 0x20), public_input_size), w_start, ETA_INPUT_LENGTH) + + // Challenge is the old challenge + public inputs + W1, W2, W3 (0x20 + public_input_size + 0xc0) + let challenge_bytes_size := add(0x20, add(public_input_size, ETA_INPUT_LENGTH)) + + challenge := keccak256(PUBLIC_INPUTS_HASH_LOCATION, challenge_bytes_size) + { + let eta := mod(challenge, p) + mstore(C_ETA_LOC, eta) + mstore(C_ETA_SQR_LOC, mulmod(eta, eta, p)) + mstore(C_ETA_CUBE_LOC, mulmod(mload(C_ETA_SQR_LOC), eta, p)) + } + + /** + * Generate beta challenge + */ + mstore(0x00, challenge) + mstore(0x20, mload(W4_Y_LOC)) + mstore(0x40, mload(W4_X_LOC)) + mstore(0x60, mload(S_Y_LOC)) + mstore(0x80, mload(S_X_LOC)) + challenge := keccak256(0x00, 0xa0) + mstore(C_BETA_LOC, mod(challenge, p)) + + /** + * Generate gamma challenge + */ + mstore(0x00, challenge) + mstore8(0x20, 0x01) + challenge := keccak256(0x00, 0x21) + mstore(C_GAMMA_LOC, mod(challenge, p)) + + /** + * Generate alpha challenge + */ + mstore(0x00, challenge) + mstore(0x20, mload(Z_Y_LOC)) + mstore(0x40, mload(Z_X_LOC)) + mstore(0x60, mload(Z_LOOKUP_Y_LOC)) + mstore(0x80, mload(Z_LOOKUP_X_LOC)) + challenge := keccak256(0x00, 0xa0) + mstore(C_ALPHA_LOC, mod(challenge, p)) + + /** + * Compute and store some powers of alpha for future computations + */ + let alpha := mload(C_ALPHA_LOC) + mstore(C_ALPHA_SQR_LOC, mulmod(alpha, alpha, p)) + mstore(C_ALPHA_CUBE_LOC, mulmod(mload(C_ALPHA_SQR_LOC), alpha, p)) + mstore(C_ALPHA_QUAD_LOC, mulmod(mload(C_ALPHA_CUBE_LOC), alpha, p)) + mstore(C_ALPHA_BASE_LOC, alpha) + + /** + * Generate zeta challenge + */ + mstore(0x00, challenge) + mstore(0x20, mload(T1_Y_LOC)) + mstore(0x40, mload(T1_X_LOC)) + mstore(0x60, mload(T2_Y_LOC)) + mstore(0x80, mload(T2_X_LOC)) + mstore(0xa0, mload(T3_Y_LOC)) + mstore(0xc0, mload(T3_X_LOC)) + mstore(0xe0, mload(T4_Y_LOC)) + mstore(0x100, mload(T4_X_LOC)) + + challenge := keccak256(0x00, 0x120) + + mstore(C_ZETA_LOC, mod(challenge, p)) + mstore(C_CURRENT_LOC, challenge) + } + + /** + * EVALUATE FIELD OPERATIONS + */ + + /** + * COMPUTE PUBLIC INPUT DELTA + * ΔPI = ∏ᵢ∈ℓ(wᵢ + β σ(i) + γ) / ∏ᵢ∈ℓ(wᵢ + β σ'(i) + γ) + */ + { + let beta := mload(C_BETA_LOC) // β + let gamma := mload(C_GAMMA_LOC) // γ + let work_root := mload(OMEGA_LOC) // ω + let numerator_value := 1 + let denominator_value := 1 + + let p_clone := p // move p to the front of the stack + let valid_inputs := true + + // Load the starting point of the public inputs (jump over the selector and the length of public inputs [0x24]) + let public_inputs_ptr := add(calldataload(0x24), 0x24) + + // endpoint_ptr = public_inputs_ptr + num_inputs * 0x20. // every public input is 0x20 bytes + let endpoint_ptr := add(public_inputs_ptr, mul(mload(NUM_INPUTS_LOC), 0x20)) + + // root_1 = β * 0x05 + let root_1 := mulmod(beta, 0x05, p_clone) // k1.β + // root_2 = β * 0x0c + let root_2 := mulmod(beta, 0x0c, p_clone) + // @note 0x05 + 0x07 == 0x0c == external coset generator + + for {} lt(public_inputs_ptr, endpoint_ptr) { public_inputs_ptr := add(public_inputs_ptr, 0x20) } { + /** + * input = public_input[i] + * valid_inputs &= input < p + * temp = input + gamma + * numerator_value *= (β.σ(i) + wᵢ + γ) // σ(i) = 0x05.ωⁱ + * denominator_value *= (β.σ'(i) + wᵢ + γ) // σ'(i) = 0x0c.ωⁱ + * root_1 *= ω + * root_2 *= ω + */ + + let input := calldataload(public_inputs_ptr) + valid_inputs := and(valid_inputs, lt(input, p_clone)) + let temp := addmod(input, gamma, p_clone) + + numerator_value := mulmod(numerator_value, add(root_1, temp), p_clone) + denominator_value := mulmod(denominator_value, add(root_2, temp), p_clone) + + root_1 := mulmod(root_1, work_root, p_clone) + root_2 := mulmod(root_2, work_root, p_clone) + } + + // Revert if not all public inputs are field elements (i.e. < p) + if iszero(valid_inputs) { + mstore(0x00, PUBLIC_INPUT_GE_P_SELECTOR) + revert(0x00, 0x04) + } + + mstore(DELTA_NUMERATOR_LOC, numerator_value) + mstore(DELTA_DENOMINATOR_LOC, denominator_value) + } + + /** + * Compute Plookup delta factor [γ(1 + β)]^{n-k} + * k = num roots cut out of Z_H = 4 + */ + { + let delta_base := mulmod(mload(C_GAMMA_LOC), addmod(mload(C_BETA_LOC), 1, p), p) + let delta_numerator := delta_base + { + let exponent := mload(N_LOC) + let count := 1 + for {} lt(count, exponent) { count := add(count, count) } { + delta_numerator := mulmod(delta_numerator, delta_numerator, p) + } + } + mstore(PLOOKUP_DELTA_NUMERATOR_LOC, delta_numerator) + + let delta_denominator := mulmod(delta_base, delta_base, p) + delta_denominator := mulmod(delta_denominator, delta_denominator, p) + mstore(PLOOKUP_DELTA_DENOMINATOR_LOC, delta_denominator) + } + /** + * Compute lagrange poly and vanishing poly fractions + */ + { + /** + * vanishing_numerator = zeta + * ZETA_POW_N = zeta^n + * vanishing_numerator -= 1 + * accumulating_root = omega_inverse + * work_root = p - accumulating_root + * domain_inverse = domain_inverse + * vanishing_denominator = zeta + work_root + * work_root *= accumulating_root + * vanishing_denominator *= (zeta + work_root) + * work_root *= accumulating_root + * vanishing_denominator *= (zeta + work_root) + * vanishing_denominator *= (zeta + (zeta + accumulating_root)) + * work_root = omega + * lagrange_numerator = vanishing_numerator * domain_inverse + * l_start_denominator = zeta - 1 + * accumulating_root = work_root^2 + * l_end_denominator = accumulating_root^2 * work_root * zeta - 1 + * Note: l_end_denominator term contains a term \omega^5 to cut out 5 roots of unity from vanishing poly + */ + + let zeta := mload(C_ZETA_LOC) + + // compute zeta^n, where n is a power of 2 + let vanishing_numerator := zeta + { + // pow_small + let exponent := mload(N_LOC) + let count := 1 + for {} lt(count, exponent) { count := add(count, count) } { + vanishing_numerator := mulmod(vanishing_numerator, vanishing_numerator, p) + } + } + mstore(ZETA_POW_N_LOC, vanishing_numerator) + vanishing_numerator := addmod(vanishing_numerator, sub(p, 1), p) + + let accumulating_root := mload(OMEGA_INVERSE_LOC) + let work_root := sub(p, accumulating_root) + let domain_inverse := mload(DOMAIN_INVERSE_LOC) + + let vanishing_denominator := addmod(zeta, work_root, p) + work_root := mulmod(work_root, accumulating_root, p) + vanishing_denominator := mulmod(vanishing_denominator, addmod(zeta, work_root, p), p) + work_root := mulmod(work_root, accumulating_root, p) + vanishing_denominator := mulmod(vanishing_denominator, addmod(zeta, work_root, p), p) + vanishing_denominator := + mulmod(vanishing_denominator, addmod(zeta, mulmod(work_root, accumulating_root, p), p), p) + + work_root := mload(OMEGA_LOC) + + let lagrange_numerator := mulmod(vanishing_numerator, domain_inverse, p) + let l_start_denominator := addmod(zeta, sub(p, 1), p) + + accumulating_root := mulmod(work_root, work_root, p) + + let l_end_denominator := + addmod( + mulmod(mulmod(mulmod(accumulating_root, accumulating_root, p), work_root, p), zeta, p), sub(p, 1), p + ) + + /** + * Compute inversions using Montgomery's batch inversion trick + */ + let accumulator := mload(DELTA_DENOMINATOR_LOC) + let t0 := accumulator + accumulator := mulmod(accumulator, vanishing_denominator, p) + let t1 := accumulator + accumulator := mulmod(accumulator, vanishing_numerator, p) + let t2 := accumulator + accumulator := mulmod(accumulator, l_start_denominator, p) + let t3 := accumulator + accumulator := mulmod(accumulator, mload(PLOOKUP_DELTA_DENOMINATOR_LOC), p) + let t4 := accumulator + { + mstore(0, 0x20) + mstore(0x20, 0x20) + mstore(0x40, 0x20) + mstore(0x60, mulmod(accumulator, l_end_denominator, p)) + mstore(0x80, sub(p, 2)) + mstore(0xa0, p) + if iszero(staticcall(gas(), 0x05, 0x00, 0xc0, 0x00, 0x20)) { + mstore(0x0, MOD_EXP_FAILURE_SELECTOR) + revert(0x00, 0x04) + } + accumulator := mload(0x00) + } + + t4 := mulmod(accumulator, t4, p) + accumulator := mulmod(accumulator, l_end_denominator, p) + + t3 := mulmod(accumulator, t3, p) + accumulator := mulmod(accumulator, mload(PLOOKUP_DELTA_DENOMINATOR_LOC), p) + + t2 := mulmod(accumulator, t2, p) + accumulator := mulmod(accumulator, l_start_denominator, p) + + t1 := mulmod(accumulator, t1, p) + accumulator := mulmod(accumulator, vanishing_numerator, p) + + t0 := mulmod(accumulator, t0, p) + accumulator := mulmod(accumulator, vanishing_denominator, p) + + accumulator := mulmod(mulmod(accumulator, accumulator, p), mload(DELTA_DENOMINATOR_LOC), p) + + mstore(PUBLIC_INPUT_DELTA_LOC, mulmod(mload(DELTA_NUMERATOR_LOC), accumulator, p)) + mstore(ZERO_POLY_LOC, mulmod(vanishing_numerator, t0, p)) + mstore(ZERO_POLY_INVERSE_LOC, mulmod(vanishing_denominator, t1, p)) + mstore(L_START_LOC, mulmod(lagrange_numerator, t2, p)) + mstore(PLOOKUP_DELTA_LOC, mulmod(mload(PLOOKUP_DELTA_NUMERATOR_LOC), t3, p)) + mstore(L_END_LOC, mulmod(lagrange_numerator, t4, p)) + } + + /** + * UltraPlonk Widget Ordering: + * + * 1. Permutation widget + * 2. Plookup widget + * 3. Arithmetic widget + * 4. Fixed base widget (?) + * 5. GenPermSort widget + * 6. Elliptic widget + * 7. Auxiliary widget + */ + + /** + * COMPUTE PERMUTATION WIDGET EVALUATION + */ + { + let alpha := mload(C_ALPHA_LOC) + let beta := mload(C_BETA_LOC) + let gamma := mload(C_GAMMA_LOC) + + /** + * t1 = (W1 + gamma + beta * ID1) * (W2 + gamma + beta * ID2) + * t2 = (W3 + gamma + beta * ID3) * (W4 + gamma + beta * ID4) + * result = alpha_base * z_eval * t1 * t2 + * t1 = (W1 + gamma + beta * sigma_1_eval) * (W2 + gamma + beta * sigma_2_eval) + * t2 = (W2 + gamma + beta * sigma_3_eval) * (W3 + gamma + beta * sigma_4_eval) + * result -= (alpha_base * z_omega_eval * t1 * t2) + */ + let t1 := + mulmod( + add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(ID1_EVAL_LOC), p)), + add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(ID2_EVAL_LOC), p)), + p + ) + let t2 := + mulmod( + add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(ID3_EVAL_LOC), p)), + add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(ID4_EVAL_LOC), p)), + p + ) + let result := mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_EVAL_LOC), mulmod(t1, t2, p), p), p) + t1 := + mulmod( + add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA1_EVAL_LOC), p)), + add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA2_EVAL_LOC), p)), + p + ) + t2 := + mulmod( + add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA3_EVAL_LOC), p)), + add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA4_EVAL_LOC), p)), + p + ) + result := + addmod( + result, + sub(p, mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_OMEGA_EVAL_LOC), mulmod(t1, t2, p), p), p)), + p + ) + + /** + * alpha_base *= alpha + * result += alpha_base . (L_{n-k}(ʓ) . (z(ʓ.ω) - ∆_{PI})) + * alpha_base *= alpha + * result += alpha_base . (L_1(ʓ)(Z(ʓ) - 1)) + * alpha_Base *= alpha + */ + mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p)) + result := + addmod( + result, + mulmod( + mload(C_ALPHA_BASE_LOC), + mulmod( + mload(L_END_LOC), + addmod(mload(Z_OMEGA_EVAL_LOC), sub(p, mload(PUBLIC_INPUT_DELTA_LOC)), p), + p + ), + p + ), + p + ) + mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p)) + mstore( + PERMUTATION_IDENTITY, + addmod( + result, + mulmod( + mload(C_ALPHA_BASE_LOC), + mulmod(mload(L_START_LOC), addmod(mload(Z_EVAL_LOC), sub(p, 1), p), p), + p + ), + p + ) + ) + mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p)) + } + + /** + * COMPUTE PLOOKUP WIDGET EVALUATION + */ + { + /** + * Goal: f = (w1(z) + q2.w1(zω)) + η(w2(z) + qm.w2(zω)) + η²(w3(z) + qc.w_3(zω)) + q3(z).η³ + * f = η.q3(z) + * f += (w3(z) + qc.w_3(zω)) + * f *= η + * f += (w2(z) + qm.w2(zω)) + * f *= η + * f += (w1(z) + q2.w1(zω)) + */ + let f := mulmod(mload(C_ETA_LOC), mload(Q3_EVAL_LOC), p) + f := + addmod(f, addmod(mload(W3_EVAL_LOC), mulmod(mload(QC_EVAL_LOC), mload(W3_OMEGA_EVAL_LOC), p), p), p) + f := mulmod(f, mload(C_ETA_LOC), p) + f := + addmod(f, addmod(mload(W2_EVAL_LOC), mulmod(mload(QM_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p), p) + f := mulmod(f, mload(C_ETA_LOC), p) + f := + addmod(f, addmod(mload(W1_EVAL_LOC), mulmod(mload(Q2_EVAL_LOC), mload(W1_OMEGA_EVAL_LOC), p), p), p) + + // t(z) = table4(z).η³ + table3(z).η² + table2(z).η + table1(z) + let t := + addmod( + addmod( + addmod( + mulmod(mload(TABLE4_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), + mulmod(mload(TABLE3_EVAL_LOC), mload(C_ETA_SQR_LOC), p), + p + ), + mulmod(mload(TABLE2_EVAL_LOC), mload(C_ETA_LOC), p), + p + ), + mload(TABLE1_EVAL_LOC), + p + ) + + // t(zw) = table4(zw).η³ + table3(zw).η² + table2(zw).η + table1(zw) + let t_omega := + addmod( + addmod( + addmod( + mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), + mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_ETA_SQR_LOC), p), + p + ), + mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_ETA_LOC), p), + p + ), + mload(TABLE1_OMEGA_EVAL_LOC), + p + ) + + /** + * Goal: numerator = (TABLE_TYPE_EVAL * f(z) + γ) * (t(z) + βt(zω) + γ(β + 1)) * (β + 1) + * gamma_beta_constant = γ(β + 1) + * numerator = f * TABLE_TYPE_EVAL + gamma + * temp0 = t(z) + t(zω) * β + gamma_beta_constant + * numerator *= temp0 + * numerator *= (β + 1) + * temp0 = alpha * l_1 + * numerator += temp0 + * numerator *= z_lookup(z) + * numerator -= temp0 + */ + let gamma_beta_constant := mulmod(mload(C_GAMMA_LOC), addmod(mload(C_BETA_LOC), 1, p), p) + let numerator := addmod(mulmod(f, mload(TABLE_TYPE_EVAL_LOC), p), mload(C_GAMMA_LOC), p) + let temp0 := addmod(addmod(t, mulmod(t_omega, mload(C_BETA_LOC), p), p), gamma_beta_constant, p) + numerator := mulmod(numerator, temp0, p) + numerator := mulmod(numerator, addmod(mload(C_BETA_LOC), 1, p), p) + temp0 := mulmod(mload(C_ALPHA_LOC), mload(L_START_LOC), p) + numerator := addmod(numerator, temp0, p) + numerator := mulmod(numerator, mload(Z_LOOKUP_EVAL_LOC), p) + numerator := addmod(numerator, sub(p, temp0), p) + + /** + * Goal: denominator = z_lookup(zω)*[s(z) + βs(zω) + γ(1 + β)] - [z_lookup(zω) - [γ(1 + β)]^{n-k}]*α²L_end(z) + * note: delta_factor = [γ(1 + β)]^{n-k} + * denominator = s(z) + βs(zω) + γ(β + 1) + * temp1 = α²L_end(z) + * denominator -= temp1 + * denominator *= z_lookup(zω) + * denominator += temp1 * delta_factor + * PLOOKUP_IDENTITY = (numerator - denominator).alpha_base + * alpha_base *= alpha^3 + */ + let denominator := + addmod( + addmod(mload(S_EVAL_LOC), mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_BETA_LOC), p), p), + gamma_beta_constant, + p + ) + let temp1 := mulmod(mload(C_ALPHA_SQR_LOC), mload(L_END_LOC), p) + denominator := addmod(denominator, sub(p, temp1), p) + denominator := mulmod(denominator, mload(Z_LOOKUP_OMEGA_EVAL_LOC), p) + denominator := addmod(denominator, mulmod(temp1, mload(PLOOKUP_DELTA_LOC), p), p) + + mstore(PLOOKUP_IDENTITY, mulmod(addmod(numerator, sub(p, denominator), p), mload(C_ALPHA_BASE_LOC), p)) + + // update alpha + mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p)) + } + + /** + * COMPUTE ARITHMETIC WIDGET EVALUATION + */ + { + /** + * The basic arithmetic gate identity in standard plonk is as follows. + * (w_1 . w_2 . q_m) + (w_1 . q_1) + (w_2 . q_2) + (w_3 . q_3) + (w_4 . q_4) + q_c = 0 + * However, for Ultraplonk, we extend this to support "passing" wires between rows (shown without alpha scaling below): + * q_arith * ( ( (-1/2) * (q_arith - 3) * q_m * w_1 * w_2 + q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c ) + + * (q_arith - 1)*( α * (q_arith - 2) * (w_1 + w_4 - w_1_omega + q_m) + w_4_omega) ) = 0 + * + * This formula results in several cases depending on q_arith: + * 1. q_arith == 0: Arithmetic gate is completely disabled + * + * 2. q_arith == 1: Everything in the minigate on the right is disabled. The equation is just a standard plonk equation + * with extra wires: q_m * w_1 * w_2 + q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c = 0 + * + * 3. q_arith == 2: The (w_1 + w_4 - ...) term is disabled. THe equation is: + * (1/2) * q_m * w_1 * w_2 + q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c + w_4_omega = 0 + * It allows defining w_4 at next index (w_4_omega) in terms of current wire values + * + * 4. q_arith == 3: The product of w_1 and w_2 is disabled, but a mini addition gate is enabled. α allows us to split + * the equation into two: + * + * q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c + 2 * w_4_omega = 0 + * and + * w_1 + w_4 - w_1_omega + q_m = 0 (we are reusing q_m here) + * + * 5. q_arith > 3: The product of w_1 and w_2 is scaled by (q_arith - 3), while the w_4_omega term is scaled by (q_arith - 1). + * The equation can be split into two: + * + * (q_arith - 3)* q_m * w_1 * w_ 2 + q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c + (q_arith - 1) * w_4_omega = 0 + * and + * w_1 + w_4 - w_1_omega + q_m = 0 + * + * The problem that q_m is used both in both equations can be dealt with by appropriately changing selector values at + * the next gate. Then we can treat (q_arith - 1) as a simulated q_6 selector and scale q_m to handle (q_arith - 3) at + * product. + */ + + let w1q1 := mulmod(mload(W1_EVAL_LOC), mload(Q1_EVAL_LOC), p) + let w2q2 := mulmod(mload(W2_EVAL_LOC), mload(Q2_EVAL_LOC), p) + let w3q3 := mulmod(mload(W3_EVAL_LOC), mload(Q3_EVAL_LOC), p) + let w4q3 := mulmod(mload(W4_EVAL_LOC), mload(Q4_EVAL_LOC), p) + + // @todo - Add a explicit test that hits QARITH == 3 + // w1w2qm := (w_1 . w_2 . q_m . (QARITH_EVAL_LOC - 3)) / 2 + let w1w2qm := + mulmod( + mulmod( + mulmod(mulmod(mload(W1_EVAL_LOC), mload(W2_EVAL_LOC), p), mload(QM_EVAL_LOC), p), + addmod(mload(QARITH_EVAL_LOC), sub(p, 3), p), + p + ), + NEGATIVE_INVERSE_OF_2_MODULO_P, + p + ) + + // (w_1 . w_2 . q_m . (q_arith - 3)) / -2) + (w_1 . q_1) + (w_2 . q_2) + (w_3 . q_3) + (w_4 . q_4) + q_c + let identity := + addmod( + mload(QC_EVAL_LOC), addmod(w4q3, addmod(w3q3, addmod(w2q2, addmod(w1q1, w1w2qm, p), p), p), p), p + ) + + // if q_arith == 3 we evaluate an additional mini addition gate (on top of the regular one), where: + // w_1 + w_4 - w_1_omega + q_m = 0 + // we use this gate to save an addition gate when adding or subtracting non-native field elements + // α * (q_arith - 2) * (w_1 + w_4 - w_1_omega + q_m) + let extra_small_addition_gate_identity := + mulmod( + mload(C_ALPHA_LOC), + mulmod( + addmod(mload(QARITH_EVAL_LOC), sub(p, 2), p), + addmod( + mload(QM_EVAL_LOC), + addmod( + sub(p, mload(W1_OMEGA_EVAL_LOC)), addmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), p + ), + p + ), + p + ), + p + ) + + // if q_arith == 2 OR q_arith == 3 we add the 4th wire of the NEXT gate into the arithmetic identity + // N.B. if q_arith > 2, this wire value will be scaled by (q_arith - 1) relative to the other gate wires! + // alpha_base * q_arith * (identity + (q_arith - 1) * (w_4_omega + extra_small_addition_gate_identity)) + mstore( + ARITHMETIC_IDENTITY, + mulmod( + mload(C_ALPHA_BASE_LOC), + mulmod( + mload(QARITH_EVAL_LOC), + addmod( + identity, + mulmod( + addmod(mload(QARITH_EVAL_LOC), sub(p, 1), p), + addmod(mload(W4_OMEGA_EVAL_LOC), extra_small_addition_gate_identity, p), + p + ), + p + ), + p + ), + p + ) + ) + + // update alpha + mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p)) + } + + /** + * COMPUTE GENPERMSORT WIDGET EVALUATION + */ + { + /** + * D1 = (w2 - w1) + * D2 = (w3 - w2) + * D3 = (w4 - w3) + * D4 = (w1_omega - w4) + * + * α_a = alpha_base + * α_b = alpha_base * α + * α_c = alpha_base * α^2 + * α_d = alpha_base * α^3 + * + * range_accumulator = ( + * D1(D1 - 1)(D1 - 2)(D1 - 3).α_a + + * D2(D2 - 1)(D2 - 2)(D2 - 3).α_b + + * D3(D3 - 1)(D3 - 2)(D3 - 3).α_c + + * D4(D4 - 1)(D4 - 2)(D4 - 3).α_d + + * ) . q_sort + */ + let minus_two := sub(p, 2) + let minus_three := sub(p, 3) + let d1 := addmod(mload(W2_EVAL_LOC), sub(p, mload(W1_EVAL_LOC)), p) + let d2 := addmod(mload(W3_EVAL_LOC), sub(p, mload(W2_EVAL_LOC)), p) + let d3 := addmod(mload(W4_EVAL_LOC), sub(p, mload(W3_EVAL_LOC)), p) + let d4 := addmod(mload(W1_OMEGA_EVAL_LOC), sub(p, mload(W4_EVAL_LOC)), p) + + let range_accumulator := + mulmod( + mulmod( + mulmod(addmod(mulmod(d1, d1, p), sub(p, d1), p), addmod(d1, minus_two, p), p), + addmod(d1, minus_three, p), + p + ), + mload(C_ALPHA_BASE_LOC), + p + ) + range_accumulator := + addmod( + range_accumulator, + mulmod( + mulmod( + mulmod(addmod(mulmod(d2, d2, p), sub(p, d2), p), addmod(d2, minus_two, p), p), + addmod(d2, minus_three, p), + p + ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + p + ), + p + ) + range_accumulator := + addmod( + range_accumulator, + mulmod( + mulmod( + mulmod(addmod(mulmod(d3, d3, p), sub(p, d3), p), addmod(d3, minus_two, p), p), + addmod(d3, minus_three, p), + p + ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p), + p + ), + p + ) + range_accumulator := + addmod( + range_accumulator, + mulmod( + mulmod( + mulmod(addmod(mulmod(d4, d4, p), sub(p, d4), p), addmod(d4, minus_two, p), p), + addmod(d4, minus_three, p), + p + ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p), + p + ), + p + ) + range_accumulator := mulmod(range_accumulator, mload(QSORT_EVAL_LOC), p) + + mstore(SORT_IDENTITY, range_accumulator) + + // update alpha + mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_QUAD_LOC), p)) + } + + /** + * COMPUTE ELLIPTIC WIDGET EVALUATION + */ + { + /** + * endo_term = (-x_2) * x_1 * (x_3 * 2 + x_1) * q_beta + * endo_sqr_term = x_2^2 + * endo_sqr_term *= (x_3 - x_1) + * endo_sqr_term *= q_beta^2 + * leftovers = x_2^2 + * leftovers *= x_2 + * leftovers += x_1^2 * (x_3 + x_1) @follow-up Invalid comment in BB widget + * leftovers -= (y_2^2 + y_1^2) + * sign_term = y_2 * y_1 + * sign_term += sign_term + * sign_term *= q_sign + */ + + let endo_term := + mulmod( + mulmod( + mulmod(sub(p, mload(X2_EVAL_LOC)), mload(X1_EVAL_LOC), p), + addmod(addmod(mload(X3_EVAL_LOC), mload(X3_EVAL_LOC), p), mload(X1_EVAL_LOC), p), + p + ), + mload(QBETA_LOC), + p + ) + + let endo_sqr_term := mulmod(mload(X2_EVAL_LOC), mload(X2_EVAL_LOC), p) + endo_sqr_term := mulmod(endo_sqr_term, addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), p) + endo_sqr_term := mulmod(endo_sqr_term, mload(QBETA_SQR_LOC), p) + + let leftovers := mulmod(mload(X2_EVAL_LOC), mload(X2_EVAL_LOC), p) + leftovers := mulmod(leftovers, mload(X2_EVAL_LOC), p) + leftovers := + addmod( + leftovers, + mulmod( + mulmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), + addmod(mload(X3_EVAL_LOC), mload(X1_EVAL_LOC), p), + p + ), + p + ) + leftovers := + addmod( + leftovers, + sub( + p, + addmod( + mulmod(mload(Y2_EVAL_LOC), mload(Y2_EVAL_LOC), p), + mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p), + p + ) + ), + p + ) + + let sign_term := mulmod(mload(Y2_EVAL_LOC), mload(Y1_EVAL_LOC), p) + sign_term := addmod(sign_term, sign_term, p) + sign_term := mulmod(sign_term, mload(QSIGN_LOC), p) + + /** + * x_identity = endo_term + endo_sqr_term + sign_term + leftovers + * x_identity *= alpha_base + * endo_term = (x_2 * q_beta) * (y_3 + y_1) + * sign_term = -((y2 * q_sign) * (x_1 + x_3)) + * leftovers = - x1 * (y_3 + y_1) + y_1 * (x_1 - x_3) + * y_identity = (endo_term + sign_term + leftovers) * (alpha_base * α) + */ + + let x_identity := addmod(addmod(endo_term, endo_sqr_term, p), addmod(sign_term, leftovers, p), p) + x_identity := mulmod(x_identity, mload(C_ALPHA_BASE_LOC), p) + endo_term := + mulmod( + mulmod(mload(X2_EVAL_LOC), mload(QBETA_LOC), p), + addmod(mload(Y3_EVAL_LOC), mload(Y1_EVAL_LOC), p), + p + ) + sign_term := + sub( + p, + mulmod( + mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p), + addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), + p + ) + ) + leftovers := + addmod( + sub(p, mulmod(mload(X1_EVAL_LOC), addmod(mload(Y3_EVAL_LOC), mload(Y1_EVAL_LOC), p), p)), + mulmod(mload(Y1_EVAL_LOC), addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p), + p + ) + let y_identity := + mulmod( + addmod(addmod(endo_term, sign_term, p), leftovers, p), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + p + ) + + // ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL + mstore(ELLIPTIC_IDENTITY, mulmod(addmod(x_identity, y_identity, p), mload(QELLIPTIC_EVAL_LOC), p)) + + // update alpha + // The paper says to use ALPHA^2, we use ALPHA^4 this is a small oversight in the prover protocol + mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_QUAD_LOC), p)) + } + + /** + * COMPUTE AUXILIARY WIDGET EVALUATION + */ + { + { + /** + * Non native field arithmetic gate 2 + * _ _ + * / _ _ _ 14 \ + * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 | + * \_ _/ + * + * limb_subproduct = w_1 . w_2_omega + w_1_omega . w_2 + * non_native_field_gate_2 = w_1 * w_4 + w_4 * w_3 - w_3_omega + * non_native_field_gate_2 = non_native_field_gate_2 * limb_size + * non_native_field_gate_2 -= w_4_omega + * non_native_field_gate_2 += limb_subproduct + * non_native_field_gate_2 *= q_4 + * limb_subproduct *= limb_size + * limb_subproduct += w_1_omega * w_2_omega + * non_native_field_gate_1 = (limb_subproduct + w_3 + w_4) * q_3 + * non_native_field_gate_3 = (limb_subproduct + w_4 - (w_3_omega + w_4_omega)) * q_m + * non_native_field_identity = (non_native_field_gate_1 + non_native_field_gate_2 + non_native_field_gate_3) * q_2 + */ + + let limb_subproduct := + addmod( + mulmod(mload(W1_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), + mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_EVAL_LOC), p), + p + ) + + let non_native_field_gate_2 := + addmod( + addmod( + mulmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), + mulmod(mload(W2_EVAL_LOC), mload(W3_EVAL_LOC), p), + p + ), + sub(p, mload(W3_OMEGA_EVAL_LOC)), + p + ) + non_native_field_gate_2 := mulmod(non_native_field_gate_2, LIMB_SIZE, p) + non_native_field_gate_2 := addmod(non_native_field_gate_2, sub(p, mload(W4_OMEGA_EVAL_LOC)), p) + non_native_field_gate_2 := addmod(non_native_field_gate_2, limb_subproduct, p) + non_native_field_gate_2 := mulmod(non_native_field_gate_2, mload(Q4_EVAL_LOC), p) + limb_subproduct := mulmod(limb_subproduct, LIMB_SIZE, p) + limb_subproduct := + addmod(limb_subproduct, mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p) + let non_native_field_gate_1 := + mulmod( + addmod(limb_subproduct, sub(p, addmod(mload(W3_EVAL_LOC), mload(W4_EVAL_LOC), p)), p), + mload(Q3_EVAL_LOC), + p + ) + let non_native_field_gate_3 := + mulmod( + addmod( + addmod(limb_subproduct, mload(W4_EVAL_LOC), p), + sub(p, addmod(mload(W3_OMEGA_EVAL_LOC), mload(W4_OMEGA_EVAL_LOC), p)), + p + ), + mload(QM_EVAL_LOC), + p + ) + let non_native_field_identity := + mulmod( + addmod(addmod(non_native_field_gate_1, non_native_field_gate_2, p), non_native_field_gate_3, p), + mload(Q2_EVAL_LOC), + p + ) + + mstore(AUX_NON_NATIVE_FIELD_EVALUATION, non_native_field_identity) + } + + { + /** + * limb_accumulator_1 = w_2_omega; + * limb_accumulator_1 *= SUBLIMB_SHIFT; + * limb_accumulator_1 += w_1_omega; + * limb_accumulator_1 *= SUBLIMB_SHIFT; + * limb_accumulator_1 += w_3; + * limb_accumulator_1 *= SUBLIMB_SHIFT; + * limb_accumulator_1 += w_2; + * limb_accumulator_1 *= SUBLIMB_SHIFT; + * limb_accumulator_1 += w_1; + * limb_accumulator_1 -= w_4; + * limb_accumulator_1 *= q_4; + */ + let limb_accumulator_1 := mulmod(mload(W2_OMEGA_EVAL_LOC), SUBLIMB_SHIFT, p) + limb_accumulator_1 := addmod(limb_accumulator_1, mload(W1_OMEGA_EVAL_LOC), p) + limb_accumulator_1 := mulmod(limb_accumulator_1, SUBLIMB_SHIFT, p) + limb_accumulator_1 := addmod(limb_accumulator_1, mload(W3_EVAL_LOC), p) + limb_accumulator_1 := mulmod(limb_accumulator_1, SUBLIMB_SHIFT, p) + limb_accumulator_1 := addmod(limb_accumulator_1, mload(W2_EVAL_LOC), p) + limb_accumulator_1 := mulmod(limb_accumulator_1, SUBLIMB_SHIFT, p) + limb_accumulator_1 := addmod(limb_accumulator_1, mload(W1_EVAL_LOC), p) + limb_accumulator_1 := addmod(limb_accumulator_1, sub(p, mload(W4_EVAL_LOC)), p) + limb_accumulator_1 := mulmod(limb_accumulator_1, mload(Q4_EVAL_LOC), p) + + /** + * limb_accumulator_2 = w_3_omega; + * limb_accumulator_2 *= SUBLIMB_SHIFT; + * limb_accumulator_2 += w_2_omega; + * limb_accumulator_2 *= SUBLIMB_SHIFT; + * limb_accumulator_2 += w_1_omega; + * limb_accumulator_2 *= SUBLIMB_SHIFT; + * limb_accumulator_2 += w_4; + * limb_accumulator_2 *= SUBLIMB_SHIFT; + * limb_accumulator_2 += w_3; + * limb_accumulator_2 -= w_4_omega; + * limb_accumulator_2 *= q_m; + */ + let limb_accumulator_2 := mulmod(mload(W3_OMEGA_EVAL_LOC), SUBLIMB_SHIFT, p) + limb_accumulator_2 := addmod(limb_accumulator_2, mload(W2_OMEGA_EVAL_LOC), p) + limb_accumulator_2 := mulmod(limb_accumulator_2, SUBLIMB_SHIFT, p) + limb_accumulator_2 := addmod(limb_accumulator_2, mload(W1_OMEGA_EVAL_LOC), p) + limb_accumulator_2 := mulmod(limb_accumulator_2, SUBLIMB_SHIFT, p) + limb_accumulator_2 := addmod(limb_accumulator_2, mload(W4_EVAL_LOC), p) + limb_accumulator_2 := mulmod(limb_accumulator_2, SUBLIMB_SHIFT, p) + limb_accumulator_2 := addmod(limb_accumulator_2, mload(W3_EVAL_LOC), p) + limb_accumulator_2 := addmod(limb_accumulator_2, sub(p, mload(W4_OMEGA_EVAL_LOC)), p) + limb_accumulator_2 := mulmod(limb_accumulator_2, mload(QM_EVAL_LOC), p) + + mstore( + AUX_LIMB_ACCUMULATOR_EVALUATION, + mulmod(addmod(limb_accumulator_1, limb_accumulator_2, p), mload(Q3_EVAL_LOC), p) + ) + } + + { + /** + * memory_record_check = w_3; + * memory_record_check *= eta; + * memory_record_check += w_2; + * memory_record_check *= eta; + * memory_record_check += w_1; + * memory_record_check *= eta; + * memory_record_check += q_c; + * + * partial_record_check = memory_record_check; + * + * memory_record_check -= w_4; + */ + + let memory_record_check := mulmod(mload(W3_EVAL_LOC), mload(C_ETA_LOC), p) + memory_record_check := addmod(memory_record_check, mload(W2_EVAL_LOC), p) + memory_record_check := mulmod(memory_record_check, mload(C_ETA_LOC), p) + memory_record_check := addmod(memory_record_check, mload(W1_EVAL_LOC), p) + memory_record_check := mulmod(memory_record_check, mload(C_ETA_LOC), p) + memory_record_check := addmod(memory_record_check, mload(QC_EVAL_LOC), p) + + let partial_record_check := memory_record_check + memory_record_check := addmod(memory_record_check, sub(p, mload(W4_EVAL_LOC)), p) + + mstore(AUX_MEMORY_EVALUATION, memory_record_check) + + // index_delta = w_1_omega - w_1 + let index_delta := addmod(mload(W1_OMEGA_EVAL_LOC), sub(p, mload(W1_EVAL_LOC)), p) + // record_delta = w_4_omega - w_4 + let record_delta := addmod(mload(W4_OMEGA_EVAL_LOC), sub(p, mload(W4_EVAL_LOC)), p) + // index_is_monotonically_increasing = index_delta * (index_delta - 1) + let index_is_monotonically_increasing := mulmod(index_delta, addmod(index_delta, sub(p, 1), p), p) + + // adjacent_values_match_if_adjacent_indices_match = record_delta * (1 - index_delta) + let adjacent_values_match_if_adjacent_indices_match := + mulmod(record_delta, addmod(1, sub(p, index_delta), p), p) + + // AUX_ROM_CONSISTENCY_EVALUATION = ((adjacent_values_match_if_adjacent_indices_match * alpha) + index_is_monotonically_increasing) * alpha + partial_record_check + mstore( + AUX_ROM_CONSISTENCY_EVALUATION, + addmod( + mulmod( + addmod( + mulmod(adjacent_values_match_if_adjacent_indices_match, mload(C_ALPHA_LOC), p), + index_is_monotonically_increasing, + p + ), + mload(C_ALPHA_LOC), + p + ), + memory_record_check, + p + ) + ) + + { + /** + * next_gate_access_type = w_3_omega; + * next_gate_access_type *= eta; + * next_gate_access_type += w_2_omega; + * next_gate_access_type *= eta; + * next_gate_access_type += w_1_omega; + * next_gate_access_type *= eta; + * next_gate_access_type = w_4_omega - next_gate_access_type; + */ + let next_gate_access_type := mulmod(mload(W3_OMEGA_EVAL_LOC), mload(C_ETA_LOC), p) + next_gate_access_type := addmod(next_gate_access_type, mload(W2_OMEGA_EVAL_LOC), p) + next_gate_access_type := mulmod(next_gate_access_type, mload(C_ETA_LOC), p) + next_gate_access_type := addmod(next_gate_access_type, mload(W1_OMEGA_EVAL_LOC), p) + next_gate_access_type := mulmod(next_gate_access_type, mload(C_ETA_LOC), p) + next_gate_access_type := addmod(mload(W4_OMEGA_EVAL_LOC), sub(p, next_gate_access_type), p) + + // value_delta = w_3_omega - w_3 + let value_delta := addmod(mload(W3_OMEGA_EVAL_LOC), sub(p, mload(W3_EVAL_LOC)), p) + // adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation = (1 - index_delta) * value_delta * (1 - next_gate_access_type); + + let adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation := + mulmod( + addmod(1, sub(p, index_delta), p), + mulmod(value_delta, addmod(1, sub(p, next_gate_access_type), p), p), + p + ) + + // AUX_RAM_CONSISTENCY_EVALUATION + + /** + * access_type = w_4 - partial_record_check + * access_check = access_type^2 - access_type + * next_gate_access_type_is_boolean = next_gate_access_type^2 - next_gate_access_type + * RAM_consistency_check_identity = adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation; + * RAM_consistency_check_identity *= alpha; + * RAM_consistency_check_identity += index_is_monotonically_increasing; + * RAM_consistency_check_identity *= alpha; + * RAM_consistency_check_identity += next_gate_access_type_is_boolean; + * RAM_consistency_check_identity *= alpha; + * RAM_consistency_check_identity += access_check; + */ + + let access_type := addmod(mload(W4_EVAL_LOC), sub(p, partial_record_check), p) + let access_check := mulmod(access_type, addmod(access_type, sub(p, 1), p), p) + let next_gate_access_type_is_boolean := + mulmod(next_gate_access_type, addmod(next_gate_access_type, sub(p, 1), p), p) + let RAM_cci := + mulmod( + adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation, + mload(C_ALPHA_LOC), + p + ) + RAM_cci := addmod(RAM_cci, index_is_monotonically_increasing, p) + RAM_cci := mulmod(RAM_cci, mload(C_ALPHA_LOC), p) + RAM_cci := addmod(RAM_cci, next_gate_access_type_is_boolean, p) + RAM_cci := mulmod(RAM_cci, mload(C_ALPHA_LOC), p) + RAM_cci := addmod(RAM_cci, access_check, p) + + mstore(AUX_RAM_CONSISTENCY_EVALUATION, RAM_cci) + } + + { + // timestamp_delta = w_2_omega - w_2 + let timestamp_delta := addmod(mload(W2_OMEGA_EVAL_LOC), sub(p, mload(W2_EVAL_LOC)), p) + + // RAM_timestamp_check_identity = (1 - index_delta) * timestamp_delta - w_3 + let RAM_timestamp_check_identity := + addmod( + mulmod(timestamp_delta, addmod(1, sub(p, index_delta), p), p), sub(p, mload(W3_EVAL_LOC)), p + ) + + /** + * memory_identity = ROM_consistency_check_identity * q_2; + * memory_identity += RAM_timestamp_check_identity * q_4; + * memory_identity += memory_record_check * q_m; + * memory_identity *= q_1; + * memory_identity += (RAM_consistency_check_identity * q_arith); + * + * auxiliary_identity = memory_identity + non_native_field_identity + limb_accumulator_identity; + * auxiliary_identity *= q_aux; + * auxiliary_identity *= alpha_base; + */ + let memory_identity := mulmod(mload(AUX_ROM_CONSISTENCY_EVALUATION), mload(Q2_EVAL_LOC), p) + memory_identity := + addmod(memory_identity, mulmod(RAM_timestamp_check_identity, mload(Q4_EVAL_LOC), p), p) + memory_identity := + addmod(memory_identity, mulmod(mload(AUX_MEMORY_EVALUATION), mload(QM_EVAL_LOC), p), p) + memory_identity := mulmod(memory_identity, mload(Q1_EVAL_LOC), p) + memory_identity := + addmod( + memory_identity, mulmod(mload(AUX_RAM_CONSISTENCY_EVALUATION), mload(QARITH_EVAL_LOC), p), p + ) + + let auxiliary_identity := addmod(memory_identity, mload(AUX_NON_NATIVE_FIELD_EVALUATION), p) + auxiliary_identity := addmod(auxiliary_identity, mload(AUX_LIMB_ACCUMULATOR_EVALUATION), p) + auxiliary_identity := mulmod(auxiliary_identity, mload(QAUX_EVAL_LOC), p) + auxiliary_identity := mulmod(auxiliary_identity, mload(C_ALPHA_BASE_LOC), p) + + mstore(AUX_IDENTITY, auxiliary_identity) + + // update alpha + mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p)) + } + } + } + + { + /** + * quotient = ARITHMETIC_IDENTITY + * quotient += PERMUTATION_IDENTITY + * quotient += PLOOKUP_IDENTITY + * quotient += SORT_IDENTITY + * quotient += ELLIPTIC_IDENTITY + * quotient += AUX_IDENTITY + * quotient *= ZERO_POLY_INVERSE + */ + mstore( + QUOTIENT_EVAL_LOC, + mulmod( + addmod( + addmod( + addmod( + addmod( + addmod(mload(PERMUTATION_IDENTITY), mload(PLOOKUP_IDENTITY), p), + mload(ARITHMETIC_IDENTITY), + p + ), + mload(SORT_IDENTITY), + p + ), + mload(ELLIPTIC_IDENTITY), + p + ), + mload(AUX_IDENTITY), + p + ), + mload(ZERO_POLY_INVERSE_LOC), + p + ) + ) + } + + /** + * GENERATE NU AND SEPARATOR CHALLENGES + */ + { + let current_challenge := mload(C_CURRENT_LOC) + // get a calldata pointer that points to the start of the data we want to copy + let calldata_ptr := add(calldataload(0x04), 0x24) + + calldata_ptr := add(calldata_ptr, NU_CALLDATA_SKIP_LENGTH) + + mstore(NU_CHALLENGE_INPUT_LOC_A, current_challenge) + mstore(NU_CHALLENGE_INPUT_LOC_B, mload(QUOTIENT_EVAL_LOC)) + calldatacopy(NU_CHALLENGE_INPUT_LOC_C, calldata_ptr, NU_INPUT_LENGTH) + + // hash length = (0x20 + num field elements), we include the previous challenge in the hash + let challenge := keccak256(NU_CHALLENGE_INPUT_LOC_A, add(NU_INPUT_LENGTH, 0x40)) + + mstore(C_V0_LOC, mod(challenge, p)) + // We need THIRTY-ONE independent nu challenges! + mstore(0x00, challenge) + mstore8(0x20, 0x01) + mstore(C_V1_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x02) + mstore(C_V2_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x03) + mstore(C_V3_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x04) + mstore(C_V4_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x05) + mstore(C_V5_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x06) + mstore(C_V6_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x07) + mstore(C_V7_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x08) + mstore(C_V8_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x09) + mstore(C_V9_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x0a) + mstore(C_V10_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x0b) + mstore(C_V11_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x0c) + mstore(C_V12_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x0d) + mstore(C_V13_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x0e) + mstore(C_V14_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x0f) + mstore(C_V15_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x10) + mstore(C_V16_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x11) + mstore(C_V17_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x12) + mstore(C_V18_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x13) + mstore(C_V19_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x14) + mstore(C_V20_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x15) + mstore(C_V21_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x16) + mstore(C_V22_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x17) + mstore(C_V23_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x18) + mstore(C_V24_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x19) + mstore(C_V25_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x1a) + mstore(C_V26_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x1b) + mstore(C_V27_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x1c) + mstore(C_V28_LOC, mod(keccak256(0x00, 0x21), p)) + mstore8(0x20, 0x1d) + mstore(C_V29_LOC, mod(keccak256(0x00, 0x21), p)) + + // @follow-up - Why are both v29 and v30 using appending 0x1d to the prior challenge and hashing, should it not change? + mstore8(0x20, 0x1d) + challenge := keccak256(0x00, 0x21) + mstore(C_V30_LOC, mod(challenge, p)) + + // separator + mstore(0x00, challenge) + mstore(0x20, mload(PI_Z_Y_LOC)) + mstore(0x40, mload(PI_Z_X_LOC)) + mstore(0x60, mload(PI_Z_OMEGA_Y_LOC)) + mstore(0x80, mload(PI_Z_OMEGA_X_LOC)) + + mstore(C_U_LOC, mod(keccak256(0x00, 0xa0), p)) + } + + let success := 0 + // VALIDATE T1 + { + let x := mload(T1_X_LOC) + let y := mload(T1_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)) + mstore(ACCUMULATOR_X_LOC, x) + mstore(add(ACCUMULATOR_X_LOC, 0x20), y) + } + // VALIDATE T2 + { + let x := mload(T2_X_LOC) // 0x1400 + let y := mload(T2_Y_LOC) // 0x1420 + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(ZETA_POW_N_LOC)) + // accumulator_2 = [T2].zeta^n + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = [T1] + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE T3 + { + let x := mload(T3_X_LOC) + let y := mload(T3_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(mload(ZETA_POW_N_LOC), mload(ZETA_POW_N_LOC), p)) + // accumulator_2 = [T3].zeta^{2n} + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE T4 + { + let x := mload(T4_X_LOC) + let y := mload(T4_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(mulmod(mload(ZETA_POW_N_LOC), mload(ZETA_POW_N_LOC), p), mload(ZETA_POW_N_LOC), p)) + // accumulator_2 = [T4].zeta^{3n} + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE W1 + { + let x := mload(W1_X_LOC) + let y := mload(W1_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V0_LOC), p)) + // accumulator_2 = v0.(u + 1).[W1] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE W2 + { + let x := mload(W2_X_LOC) + let y := mload(W2_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V1_LOC), p)) + // accumulator_2 = v1.(u + 1).[W2] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE W3 + { + let x := mload(W3_X_LOC) + let y := mload(W3_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V2_LOC), p)) + // accumulator_2 = v2.(u + 1).[W3] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE W4 + { + let x := mload(W4_X_LOC) + let y := mload(W4_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V3_LOC), p)) + // accumulator_2 = v3.(u + 1).[W4] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE S + { + let x := mload(S_X_LOC) + let y := mload(S_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V4_LOC), p)) + // accumulator_2 = v4.(u + 1).[S] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE Z + { + let x := mload(Z_X_LOC) + let y := mload(Z_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V5_LOC), p)) + // accumulator_2 = v5.(u + 1).[Z] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE Z_LOOKUP + { + let x := mload(Z_LOOKUP_X_LOC) + let y := mload(Z_LOOKUP_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V6_LOC), p)) + // accumulator_2 = v6.(u + 1).[Z_LOOKUP] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE Q1 + { + let x := mload(Q1_X_LOC) + let y := mload(Q1_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V7_LOC)) + // accumulator_2 = v7.[Q1] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE Q2 + { + let x := mload(Q2_X_LOC) + let y := mload(Q2_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V8_LOC)) + // accumulator_2 = v8.[Q2] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE Q3 + { + let x := mload(Q3_X_LOC) + let y := mload(Q3_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V9_LOC)) + // accumulator_2 = v9.[Q3] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE Q4 + { + let x := mload(Q4_X_LOC) + let y := mload(Q4_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V10_LOC)) + // accumulator_2 = v10.[Q4] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE QM + { + let x := mload(QM_X_LOC) + let y := mload(QM_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V11_LOC)) + // accumulator_2 = v11.[Q;] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE QC + { + let x := mload(QC_X_LOC) + let y := mload(QC_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V12_LOC)) + // accumulator_2 = v12.[QC] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE QARITH + { + let x := mload(QARITH_X_LOC) + let y := mload(QARITH_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V13_LOC)) + // accumulator_2 = v13.[QARITH] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE QSORT + { + let x := mload(QSORT_X_LOC) + let y := mload(QSORT_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V14_LOC)) + // accumulator_2 = v14.[QSORT] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE QELLIPTIC + { + let x := mload(QELLIPTIC_X_LOC) + let y := mload(QELLIPTIC_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V15_LOC)) + // accumulator_2 = v15.[QELLIPTIC] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE QAUX + { + let x := mload(QAUX_X_LOC) + let y := mload(QAUX_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V16_LOC)) + // accumulator_2 = v15.[Q_AUX] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE SIGMA1 + { + let x := mload(SIGMA1_X_LOC) + let y := mload(SIGMA1_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V17_LOC)) + // accumulator_2 = v17.[sigma1] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE SIGMA2 + { + let x := mload(SIGMA2_X_LOC) + let y := mload(SIGMA2_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V18_LOC)) + // accumulator_2 = v18.[sigma2] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE SIGMA3 + { + let x := mload(SIGMA3_X_LOC) + let y := mload(SIGMA3_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V19_LOC)) + // accumulator_2 = v19.[sigma3] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE SIGMA4 + { + let x := mload(SIGMA4_X_LOC) + let y := mload(SIGMA4_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V20_LOC)) + // accumulator_2 = v20.[sigma4] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE TABLE1 + { + let x := mload(TABLE1_X_LOC) + let y := mload(TABLE1_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V21_LOC), p)) + // accumulator_2 = u.[table1] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE TABLE2 + { + let x := mload(TABLE2_X_LOC) + let y := mload(TABLE2_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V22_LOC), p)) + // accumulator_2 = u.[table2] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE TABLE3 + { + let x := mload(TABLE3_X_LOC) + let y := mload(TABLE3_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V23_LOC), p)) + // accumulator_2 = u.[table3] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE TABLE4 + { + let x := mload(TABLE4_X_LOC) + let y := mload(TABLE4_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V24_LOC), p)) + // accumulator_2 = u.[table4] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE TABLE_TYPE + { + let x := mload(TABLE_TYPE_X_LOC) + let y := mload(TABLE_TYPE_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V25_LOC)) + // accumulator_2 = v25.[TableType] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE ID1 + { + let x := mload(ID1_X_LOC) + let y := mload(ID1_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V26_LOC)) + // accumulator_2 = v26.[ID1] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE ID2 + { + let x := mload(ID2_X_LOC) + let y := mload(ID2_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V27_LOC)) + // accumulator_2 = v27.[ID2] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE ID3 + { + let x := mload(ID3_X_LOC) + let y := mload(ID3_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V28_LOC)) + // accumulator_2 = v28.[ID3] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE ID4 + { + let x := mload(ID4_X_LOC) + let y := mload(ID4_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V29_LOC)) + // accumulator_2 = v29.[ID4] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + /** + * COMPUTE BATCH EVALUATION SCALAR MULTIPLIER + */ + { + /** + * batch_evaluation = v0 * (w_1_omega * u + w_1_eval) + * batch_evaluation += v1 * (w_2_omega * u + w_2_eval) + * batch_evaluation += v2 * (w_3_omega * u + w_3_eval) + * batch_evaluation += v3 * (w_4_omega * u + w_4_eval) + * batch_evaluation += v4 * (s_omega_eval * u + s_eval) + * batch_evaluation += v5 * (z_omega_eval * u + z_eval) + * batch_evaluation += v6 * (z_lookup_omega_eval * u + z_lookup_eval) + */ + let batch_evaluation := + mulmod( + mload(C_V0_LOC), + addmod(mulmod(mload(W1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W1_EVAL_LOC), p), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V1_LOC), + addmod(mulmod(mload(W2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W2_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V2_LOC), + addmod(mulmod(mload(W3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W3_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V3_LOC), + addmod(mulmod(mload(W4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W4_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V4_LOC), + addmod(mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(S_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V5_LOC), + addmod(mulmod(mload(Z_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V6_LOC), + addmod(mulmod(mload(Z_LOOKUP_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_LOOKUP_EVAL_LOC), p), + p + ), + p + ) + + /** + * batch_evaluation += v7 * Q1_EVAL + * batch_evaluation += v8 * Q2_EVAL + * batch_evaluation += v9 * Q3_EVAL + * batch_evaluation += v10 * Q4_EVAL + * batch_evaluation += v11 * QM_EVAL + * batch_evaluation += v12 * QC_EVAL + * batch_evaluation += v13 * QARITH_EVAL + * batch_evaluation += v14 * QSORT_EVAL_LOC + * batch_evaluation += v15 * QELLIPTIC_EVAL_LOC + * batch_evaluation += v16 * QAUX_EVAL_LOC + * batch_evaluation += v17 * SIGMA1_EVAL_LOC + * batch_evaluation += v18 * SIGMA2_EVAL_LOC + * batch_evaluation += v19 * SIGMA3_EVAL_LOC + * batch_evaluation += v20 * SIGMA4_EVAL_LOC + */ + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V7_LOC), mload(Q1_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V8_LOC), mload(Q2_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V9_LOC), mload(Q3_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V10_LOC), mload(Q4_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V11_LOC), mload(QM_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V12_LOC), mload(QC_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V13_LOC), mload(QARITH_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V14_LOC), mload(QSORT_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V15_LOC), mload(QELLIPTIC_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V16_LOC), mload(QAUX_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V17_LOC), mload(SIGMA1_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V18_LOC), mload(SIGMA2_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V19_LOC), mload(SIGMA3_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V20_LOC), mload(SIGMA4_EVAL_LOC), p), p) + + /** + * batch_evaluation += v21 * (table1(zw) * u + table1(z)) + * batch_evaluation += v22 * (table2(zw) * u + table2(z)) + * batch_evaluation += v23 * (table3(zw) * u + table3(z)) + * batch_evaluation += v24 * (table4(zw) * u + table4(z)) + * batch_evaluation += v25 * table_type_eval + * batch_evaluation += v26 * id1_eval + * batch_evaluation += v27 * id2_eval + * batch_evaluation += v28 * id3_eval + * batch_evaluation += v29 * id4_eval + * batch_evaluation += quotient_eval + */ + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V21_LOC), + addmod(mulmod(mload(TABLE1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE1_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V22_LOC), + addmod(mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE2_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V23_LOC), + addmod(mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE3_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := + addmod( + batch_evaluation, + mulmod( + mload(C_V24_LOC), + addmod(mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE4_EVAL_LOC), p), + p + ), + p + ) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V25_LOC), mload(TABLE_TYPE_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V26_LOC), mload(ID1_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V27_LOC), mload(ID2_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V28_LOC), mload(ID3_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V29_LOC), mload(ID4_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mload(QUOTIENT_EVAL_LOC), p) + + mstore(0x00, 0x01) // [1].x + mstore(0x20, 0x02) // [1].y + mstore(0x40, sub(p, batch_evaluation)) + // accumulator_2 = -[1].(batch_evaluation) + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + mstore(OPENING_COMMITMENT_SUCCESS_FLAG, success) + } + + /** + * PERFORM PAIRING PREAMBLE + */ + { + let u := mload(C_U_LOC) + let zeta := mload(C_ZETA_LOC) + // VALIDATE PI_Z + { + let x := mload(PI_Z_X_LOC) + let y := mload(PI_Z_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)) + mstore(0x00, x) + mstore(0x20, y) + } + // compute zeta.[PI_Z] and add into accumulator + mstore(0x40, zeta) + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + + // VALIDATE PI_Z_OMEGA + { + let x := mload(PI_Z_OMEGA_X_LOC) + let y := mload(PI_Z_OMEGA_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mulmod(mulmod(u, zeta, p), mload(OMEGA_LOC), p)) + // accumulator_2 = u.zeta.omega.[PI_Z_OMEGA] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // PAIRING_RHS = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, PAIRING_RHS_X_LOC, 0x40)) + + mstore(0x00, mload(PI_Z_X_LOC)) + mstore(0x20, mload(PI_Z_Y_LOC)) + mstore(0x40, mload(PI_Z_OMEGA_X_LOC)) + mstore(0x60, mload(PI_Z_OMEGA_Y_LOC)) + mstore(0x80, u) + success := and(success, staticcall(gas(), 7, 0x40, 0x60, 0x40, 0x40)) + // PAIRING_LHS = [PI_Z] + [PI_Z_OMEGA] * u + success := and(success, staticcall(gas(), 6, 0x00, 0x80, PAIRING_LHS_X_LOC, 0x40)) + // negate lhs y-coordinate + mstore(PAIRING_LHS_Y_LOC, sub(q, mload(PAIRING_LHS_Y_LOC))) + + if mload(CONTAINS_RECURSIVE_PROOF_LOC) { + // VALIDATE RECURSIVE P1 + { + let x := mload(RECURSIVE_P1_X_LOC) + let y := mload(RECURSIVE_P1_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + + // compute u.u.[recursive_p1] and write into 0x60 + mstore(0x40, mulmod(u, u, p)) + success := and(success, staticcall(gas(), 7, 0x00, 0x60, 0x60, 0x40)) + // VALIDATE RECURSIVE P2 + { + let x := mload(RECURSIVE_P2_X_LOC) + let y := mload(RECURSIVE_P2_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + // compute u.u.[recursive_p2] and write into 0x00 + // 0x40 still contains u*u + success := and(success, staticcall(gas(), 7, 0x00, 0x60, 0x00, 0x40)) + + // compute u.u.[recursiveP1] + rhs and write into rhs + mstore(0xa0, mload(PAIRING_RHS_X_LOC)) + mstore(0xc0, mload(PAIRING_RHS_Y_LOC)) + success := and(success, staticcall(gas(), 6, 0x60, 0x80, PAIRING_RHS_X_LOC, 0x40)) + + // compute u.u.[recursiveP2] + lhs and write into lhs + mstore(0x40, mload(PAIRING_LHS_X_LOC)) + mstore(0x60, mload(PAIRING_LHS_Y_LOC)) + success := and(success, staticcall(gas(), 6, 0x00, 0x80, PAIRING_LHS_X_LOC, 0x40)) + } + + if iszero(success) { + mstore(0x0, EC_SCALAR_MUL_FAILURE_SELECTOR) + revert(0x00, 0x04) + } + mstore(PAIRING_PREAMBLE_SUCCESS_FLAG, success) + } + + /** + * PERFORM PAIRING + */ + { + // rhs paired with [1]_2 + // lhs paired with [x]_2 + + mstore(0x00, mload(PAIRING_RHS_X_LOC)) + mstore(0x20, mload(PAIRING_RHS_Y_LOC)) + mstore(0x40, 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2) // this is [1]_2 + mstore(0x60, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed) + mstore(0x80, 0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b) + mstore(0xa0, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa) + + mstore(0xc0, mload(PAIRING_LHS_X_LOC)) + mstore(0xe0, mload(PAIRING_LHS_Y_LOC)) + mstore(0x100, mload(G2X_X0_LOC)) + mstore(0x120, mload(G2X_X1_LOC)) + mstore(0x140, mload(G2X_Y0_LOC)) + mstore(0x160, mload(G2X_Y1_LOC)) + + success := staticcall(gas(), 8, 0x00, 0x180, 0x00, 0x20) + mstore(PAIRING_SUCCESS_FLAG, success) + mstore(RESULT_FLAG, mload(0x00)) + } + if iszero( + and( + and(and(mload(PAIRING_SUCCESS_FLAG), mload(RESULT_FLAG)), mload(PAIRING_PREAMBLE_SUCCESS_FLAG)), + mload(OPENING_COMMITMENT_SUCCESS_FLAG) + ) + ) { + mstore(0x0, PROOF_FAILURE_SELECTOR) + revert(0x00, 0x04) + } + { + mstore(0x00, 0x01) + return(0x00, 0x20) // Proof succeeded! + } + } + } +} + +contract UltraVerifier is BaseUltraVerifier { + function getVerificationKeyHash() public pure override(BaseUltraVerifier) returns (bytes32) { + return UltraVerificationKey.verificationKeyHash(); + } + + function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) internal pure virtual override(BaseUltraVerifier) { + UltraVerificationKey.loadVerificationKey(vk, _omegaInverseLoc); + } +} diff --git a/tooling/acvm_backend_barretenberg/src/download.rs b/tooling/acvm_backend_barretenberg/src/download.rs new file mode 100644 index 00000000000..27aab7ef351 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/download.rs @@ -0,0 +1,54 @@ +use std::{ + io::{Cursor, ErrorKind}, + path::Path, +}; + +/// Downloads a zipped archive and unpacks the backend binary to `destination_path`. +/// +/// # Backend Requirements +/// +/// In order for a backend to be compatible with this function: +/// - `backend_url` must serve a gzipped tarball. +/// - The tarball must only contain the backend's binary. +/// - The binary file must be located at the archive root. +pub fn download_backend(backend_url: &str, destination_path: &Path) -> std::io::Result<()> { + use flate2::read::GzDecoder; + use tar::Archive; + use tempfile::tempdir; + + // Download sources + let compressed_file: Cursor> = download_binary_from_url(backend_url) + .map_err(|_| std::io::Error::from(ErrorKind::Other))?; + + // Unpack the tarball + let gz_decoder = GzDecoder::new(compressed_file); + let mut archive = Archive::new(gz_decoder); + + let temp_directory = tempdir()?; + archive.unpack(&temp_directory)?; + + // Assume that the archive contains a single file which is the backend binary. + let mut archive_files = std::fs::read_dir(&temp_directory)?; + let temp_binary_path = archive_files.next().unwrap()?.path(); + + // Create directory to place binary in. + std::fs::create_dir_all(destination_path.parent().unwrap())?; + + // Rename the binary to the desired name + std::fs::copy(temp_binary_path, destination_path)?; + + drop(temp_directory); + + Ok(()) +} + +/// Try to download the specified URL into a buffer which is returned. +fn download_binary_from_url(url: &str) -> Result>, reqwest::Error> { + let response = reqwest::blocking::get(url)?; + + let bytes = response.bytes()?; + + // TODO: Check SHA of downloaded binary + + Ok(Cursor::new(bytes.to_vec())) +} diff --git a/tooling/acvm_backend_barretenberg/src/lib.rs b/tooling/acvm_backend_barretenberg/src/lib.rs new file mode 100644 index 00000000000..e3fc4865d6d --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/lib.rs @@ -0,0 +1,111 @@ +#![warn(unused_crate_dependencies, unused_extern_crates)] +#![warn(unreachable_pub)] + +use std::path::PathBuf; + +mod cli; +mod download; +mod proof_system; +mod smart_contract; + +pub use download::download_backend; + +const BACKENDS_DIR: &str = ".nargo/backends"; +pub const ACVM_BACKEND_BARRETENBERG: &str = "acvm-backend-barretenberg"; + +pub fn backends_directory() -> PathBuf { + let home_directory = dirs::home_dir().unwrap(); + home_directory.join(BACKENDS_DIR) +} + +#[cfg(test)] +test_binary::build_test_binary_once!(mock_backend, "test-binaries"); + +#[cfg(test)] +fn get_mock_backend() -> Result { + std::env::set_var("NARGO_BACKEND_PATH", path_to_mock_backend()); + + let mock_backend = Backend::new("mock_backend".to_string()); + mock_backend.assert_binary_exists()?; + + Ok(mock_backend) +} + +#[derive(Debug, thiserror::Error)] +pub enum BackendError { + #[error(transparent)] + IoError(#[from] std::io::Error), + + #[error("Backend binary does not exist")] + MissingBinary, + + #[error("The backend responded with malformed data: {0:?}")] + MalformedResponse(Vec), + + #[error("The backend encountered an error")] + CommandFailed(Vec), +} + +#[derive(Debug)] +pub struct Backend { + name: String, + binary_path: PathBuf, +} + +impl Backend { + pub fn new(name: String) -> Backend { + let binary_path = if let Some(binary_path) = std::env::var_os("NARGO_BACKEND_PATH") { + PathBuf::from(binary_path) + } else { + const BINARY_NAME: &str = "backend_binary"; + + backends_directory().join(&name).join(BINARY_NAME) + }; + Backend { name, binary_path } + } + + fn binary_path(&self) -> &PathBuf { + &self.binary_path + } + + fn assert_binary_exists(&self) -> Result<&PathBuf, BackendError> { + let binary_path = self.binary_path(); + if binary_path.is_file() { + Ok(binary_path) + } else { + if self.name == ACVM_BACKEND_BARRETENBERG { + // If we're trying to use barretenberg, automatically go and install it. + let bb_url = std::env::var("BB_BINARY_URL") + .unwrap_or_else(|_| env!("BB_BINARY_URL").to_string()); + download_backend(&bb_url, binary_path)?; + return Ok(binary_path); + } + Err(BackendError::MissingBinary) + } + } + + fn backend_directory(&self) -> PathBuf { + self.binary_path() + .parent() + .expect("backend binary should have a parent directory") + .to_path_buf() + } + + fn crs_directory(&self) -> PathBuf { + self.backend_directory().join("crs") + } +} + +#[cfg(test)] +mod backend { + use crate::{Backend, BackendError}; + + #[test] + fn raises_error_on_missing_binary() { + let bad_backend = Backend::new("i_dont_exist".to_string()); + + let binary_path = bad_backend.assert_binary_exists(); + + assert!(matches!(binary_path, Err(BackendError::MissingBinary))); + } +} diff --git a/tooling/acvm_backend_barretenberg/src/proof_system.rs b/tooling/acvm_backend_barretenberg/src/proof_system.rs new file mode 100644 index 00000000000..a2700171abf --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/proof_system.rs @@ -0,0 +1,171 @@ +use std::fs::File; +use std::io::Write; +use std::path::Path; + +use acvm::acir::circuit::Opcode; +use acvm::acir::{circuit::Circuit, native_types::WitnessMap}; +use acvm::FieldElement; +use acvm::Language; +use tempfile::tempdir; + +use crate::cli::{GatesCommand, InfoCommand, ProveCommand, VerifyCommand, WriteVkCommand}; +use crate::{Backend, BackendError}; + +impl Backend { + pub fn get_exact_circuit_size(&self, circuit: &Circuit) -> Result { + let binary_path = self.assert_binary_exists()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory = temp_directory.path().to_path_buf(); + + // Create a temporary file for the circuit + let circuit_path = temp_directory.join("circuit").with_extension("bytecode"); + let serialized_circuit = serialize_circuit(circuit); + write_to_file(&serialized_circuit, &circuit_path); + + GatesCommand { crs_path: self.crs_directory(), bytecode_path: circuit_path } + .run(binary_path) + } + + pub fn get_backend_info( + &self, + ) -> Result<(Language, Box bool>), BackendError> { + let binary_path = self.assert_binary_exists()?; + InfoCommand { crs_path: self.crs_directory() }.run(binary_path) + } + + pub fn prove( + &self, + circuit: &Circuit, + witness_values: WitnessMap, + is_recursive: bool, + ) -> Result, BackendError> { + let binary_path = self.assert_binary_exists()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory = temp_directory.path().to_path_buf(); + + // Create a temporary file for the witness + let serialized_witnesses: Vec = + witness_values.try_into().expect("could not serialize witness map"); + let witness_path = temp_directory.join("witness").with_extension("tr"); + write_to_file(&serialized_witnesses, &witness_path); + + // Create a temporary file for the circuit + // + let bytecode_path = temp_directory.join("circuit").with_extension("bytecode"); + let serialized_circuit = serialize_circuit(circuit); + write_to_file(&serialized_circuit, &bytecode_path); + + // Create proof and store it in the specified path + let proof_with_public_inputs = ProveCommand { + crs_path: self.crs_directory(), + is_recursive, + bytecode_path, + witness_path, + } + .run(binary_path)?; + + // Barretenberg return the proof prepended with the public inputs. + // + // This is not how the API expects the proof to be formatted, + // so we remove the public inputs from the proof. + // + // TODO: As noted in the verification procedure, this is an abstraction leak + // TODO: and will need modifications to barretenberg + let proof = + remove_public_inputs(circuit.public_inputs().0.len(), &proof_with_public_inputs); + Ok(proof) + } + + pub fn verify( + &self, + proof: &[u8], + public_inputs: WitnessMap, + circuit: &Circuit, + is_recursive: bool, + ) -> Result { + let binary_path = self.assert_binary_exists()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory = temp_directory.path().to_path_buf(); + + // Unlike when proving, we omit any unassigned witnesses. + // Witness values should be ordered by their index but we skip over any indices without an assignment. + let flattened_public_inputs: Vec = + public_inputs.into_iter().map(|(_, el)| el).collect(); + + // Barretenberg expects the proof to be prepended with the public inputs. + // + // TODO: This is an abstraction leak and barretenberg's API should accept the public inputs + // TODO: separately and then prepend them internally + let proof_with_public_inputs = + prepend_public_inputs(proof.to_vec(), flattened_public_inputs.to_vec()); + + // Create a temporary file for the proof + let proof_path = temp_directory.join("proof").with_extension("proof"); + write_to_file(&proof_with_public_inputs, &proof_path); + + // Create a temporary file for the circuit + let bytecode_path = temp_directory.join("circuit").with_extension("bytecode"); + let serialized_circuit = serialize_circuit(circuit); + write_to_file(&serialized_circuit, &bytecode_path); + + // Create the verification key and write it to the specified path + let vk_path = temp_directory.join("vk"); + + WriteVkCommand { + crs_path: self.crs_directory(), + is_recursive, + bytecode_path, + vk_path_output: vk_path.clone(), + } + .run(binary_path)?; + + // Verify the proof + VerifyCommand { crs_path: self.crs_directory(), is_recursive, proof_path, vk_path } + .run(binary_path) + } +} + +pub(super) fn write_to_file(bytes: &[u8], path: &Path) -> String { + let display = path.display(); + + let mut file = match File::create(path) { + Err(why) => panic!("couldn't create {display}: {why}"), + Ok(file) => file, + }; + + match file.write_all(bytes) { + Err(why) => panic!("couldn't write to {display}: {why}"), + Ok(_) => display.to_string(), + } +} + +/// Removes the public inputs which are prepended to a proof by Barretenberg. +fn remove_public_inputs(num_pub_inputs: usize, proof: &[u8]) -> Vec { + // Barretenberg prepends the public inputs onto the proof so we need to remove + // the first `num_pub_inputs` field elements. + let num_bytes_to_remove = num_pub_inputs * (FieldElement::max_num_bytes() as usize); + proof[num_bytes_to_remove..].to_vec() +} + +/// Prepends a set of public inputs to a proof. +fn prepend_public_inputs(proof: Vec, public_inputs: Vec) -> Vec { + if public_inputs.is_empty() { + return proof; + } + + let public_inputs_bytes = + public_inputs.into_iter().flat_map(|assignment| assignment.to_be_bytes()); + + public_inputs_bytes.chain(proof).collect() +} + +// TODO: See nargo/src/artifacts/mod.rs +// TODO: This method should live in ACVM and be the default method for serializing/deserializing circuits +pub(super) fn serialize_circuit(circuit: &Circuit) -> Vec { + let mut circuit_bytes: Vec = Vec::new(); + circuit.write(&mut circuit_bytes).unwrap(); + circuit_bytes +} diff --git a/tooling/acvm_backend_barretenberg/src/smart_contract.rs b/tooling/acvm_backend_barretenberg/src/smart_contract.rs new file mode 100644 index 00000000000..e5018c69bd9 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/src/smart_contract.rs @@ -0,0 +1,76 @@ +use super::proof_system::{serialize_circuit, write_to_file}; +use crate::{ + cli::{ContractCommand, WriteVkCommand}, + Backend, BackendError, +}; +use acvm::acir::circuit::Circuit; +use tempfile::tempdir; + +/// Embed the Solidity verifier file +const ULTRA_VERIFIER_CONTRACT: &str = include_str!("contract.sol"); + +impl Backend { + pub fn eth_contract(&self, circuit: &Circuit) -> Result { + let binary_path = self.assert_binary_exists()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory_path = temp_directory.path().to_path_buf(); + + // Create a temporary file for the circuit + let bytecode_path = temp_directory_path.join("circuit").with_extension("bytecode"); + let serialized_circuit = serialize_circuit(circuit); + write_to_file(&serialized_circuit, &bytecode_path); + + // Create the verification key and write it to the specified path + let vk_path = temp_directory_path.join("vk"); + + WriteVkCommand { + crs_path: self.crs_directory(), + is_recursive: false, + bytecode_path, + vk_path_output: vk_path.clone(), + } + .run(binary_path)?; + + let verification_key_library = + ContractCommand { crs_path: self.crs_directory(), vk_path }.run(binary_path)?; + + drop(temp_directory); + Ok(format!("{verification_key_library}{ULTRA_VERIFIER_CONTRACT}")) + } +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeSet; + + use acvm::acir::{ + circuit::{Circuit, Opcode, PublicInputs}, + native_types::{Expression, Witness}, + }; + + use crate::{get_mock_backend, BackendError}; + + #[test] + fn test_smart_contract() -> Result<(), BackendError> { + let expression = &(Witness(1) + Witness(2)) - &Expression::from(Witness(3)); + let constraint = Opcode::Arithmetic(expression); + + let circuit = Circuit { + current_witness_index: 4, + opcodes: vec![constraint], + private_parameters: BTreeSet::from([Witness(1), Witness(2)]), + public_parameters: PublicInputs::default(), + return_values: PublicInputs::default(), + assert_messages: Default::default(), + }; + + let contract = get_mock_backend()?.eth_contract(&circuit)?; + + assert!(contract.contains("contract BaseUltraVerifier")); + assert!(contract.contains("contract UltraVerifier")); + assert!(contract.contains("library UltraVerificationKey")); + + Ok(()) + } +} diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/Cargo.lock b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/Cargo.lock new file mode 100644 index 00000000000..c43d1b84915 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/Cargo.lock @@ -0,0 +1,306 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "clap" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + +[[package]] +name = "mock_backend" +version = "0.1.0" +dependencies = [ + "clap", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "2.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/Cargo.toml b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/Cargo.toml new file mode 100644 index 00000000000..f527b03a7b9 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/Cargo.toml @@ -0,0 +1,11 @@ +[workspace] + +[package] +name = "mock_backend" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "4.3.19", features = ["derive"] } diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/contract_cmd.rs b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/contract_cmd.rs new file mode 100644 index 00000000000..fb8daf784f1 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/contract_cmd.rs @@ -0,0 +1,25 @@ +use clap::Args; +use std::io::Write; +use std::path::PathBuf; + +#[derive(Debug, Clone, Args)] +pub(crate) struct ContractCommand { + #[clap(short = 'c')] + pub(crate) crs_path: Option, + + #[clap(short = 'k')] + pub(crate) vk_path: PathBuf, + + #[clap(short = 'o')] + pub(crate) contract_path: PathBuf, +} + +pub(crate) fn run(args: ContractCommand) { + assert!(args.vk_path.is_file(), "Could not find vk file at provided path"); + + std::io::stdout() + .write_all( + b"contract BaseUltraVerifier contract UltraVerifier library UltraVerificationKey", + ) + .unwrap(); +} diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/gates_cmd.rs b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/gates_cmd.rs new file mode 100644 index 00000000000..3cc397d3292 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/gates_cmd.rs @@ -0,0 +1,18 @@ +use clap::Args; +use std::io::Write; +use std::path::PathBuf; + +#[derive(Debug, Clone, Args)] +pub(crate) struct GatesCommand { + #[clap(short = 'c')] + pub(crate) crs_path: Option, + + #[clap(short = 'b')] + pub(crate) bytecode_path: PathBuf, +} + +pub(crate) fn run(args: GatesCommand) { + assert!(args.bytecode_path.is_file(), "Could not find bytecode file at provided path"); + + std::io::stdout().write_all(&0u64.to_le_bytes()).unwrap(); +} diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/info_cmd.rs b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/info_cmd.rs new file mode 100644 index 00000000000..043cef5934c --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/info_cmd.rs @@ -0,0 +1,39 @@ +use clap::Args; +use std::io::Write; +use std::path::PathBuf; + +const INFO_RESPONSE: &str = r#"{ + "language": { + "name": "PLONK-CSAT", + "width": 3 + }, + "opcodes_supported": ["arithmetic", "directive", "brillig", "memory_init", "memory_op"], + "black_box_functions_supported": [ + "and", + "xor", + "range", + "sha256", + "blake2s", + "keccak256", + "schnorr_verify", + "pedersen", + "hash_to_field_128_security", + "ecdsa_secp256k1", + "ecdsa_secp256r1", + "fixed_base_scalar_mul", + "recursive_aggregation" + ] +}"#; + +#[derive(Debug, Clone, Args)] +pub(crate) struct InfoCommand { + #[clap(short = 'c')] + pub(crate) crs_path: Option, + + #[clap(short = 'o')] + pub(crate) info_path: Option, +} + +pub(crate) fn run(_args: InfoCommand) { + std::io::stdout().write_all(INFO_RESPONSE.as_bytes()).unwrap(); +} diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/main.rs b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/main.rs new file mode 100644 index 00000000000..ef8819af94b --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/main.rs @@ -0,0 +1,44 @@ +#![forbid(unsafe_code)] +#![warn(unreachable_pub)] +#![warn(clippy::semicolon_if_nothing_returned)] +#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] + +use clap::{Parser, Subcommand}; + +mod contract_cmd; +mod gates_cmd; +mod info_cmd; +mod prove_cmd; +mod verify_cmd; +mod write_vk_cmd; + +#[derive(Parser, Debug)] +#[command(name = "mock_backend")] +struct BackendCli { + #[command(subcommand)] + command: BackendCommand, +} + +#[derive(Subcommand, Clone, Debug)] +enum BackendCommand { + Info(info_cmd::InfoCommand), + Contract(contract_cmd::ContractCommand), + Gates(gates_cmd::GatesCommand), + Prove(prove_cmd::ProveCommand), + Verify(verify_cmd::VerifyCommand), + #[command(name = "write_vk")] + WriteVk(write_vk_cmd::WriteVkCommand), +} + +fn main() { + let BackendCli { command } = BackendCli::parse(); + + match command { + BackendCommand::Info(args) => info_cmd::run(args), + BackendCommand::Contract(args) => contract_cmd::run(args), + BackendCommand::Gates(args) => gates_cmd::run(args), + BackendCommand::Prove(args) => prove_cmd::run(args), + BackendCommand::Verify(args) => verify_cmd::run(args), + BackendCommand::WriteVk(args) => write_vk_cmd::run(args), + }; +} diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/prove_cmd.rs b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/prove_cmd.rs new file mode 100644 index 00000000000..3967778d4e8 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/prove_cmd.rs @@ -0,0 +1,25 @@ +use clap::Args; +use std::io::Write; +use std::path::PathBuf; + +#[derive(Debug, Clone, Args)] +pub(crate) struct ProveCommand { + #[clap(short = 'c')] + pub(crate) crs_path: Option, + + #[clap(short = 'b')] + pub(crate) bytecode_path: PathBuf, + + #[clap(short = 'w')] + pub(crate) witness_path: PathBuf, + + #[clap(short = 'o')] + pub(crate) proof_path: PathBuf, +} + +pub(crate) fn run(args: ProveCommand) { + assert!(args.bytecode_path.is_file(), "Could not find bytecode file at provided path"); + assert!(args.witness_path.is_file(), "Could not find witness file at provided path"); + + std::io::stdout().write_all(b"proof").unwrap(); +} diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/verify_cmd.rs b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/verify_cmd.rs new file mode 100644 index 00000000000..1a715eea880 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/verify_cmd.rs @@ -0,0 +1,24 @@ +use clap::Args; +use std::path::PathBuf; + +#[derive(Debug, Clone, Args)] +pub(crate) struct VerifyCommand { + #[clap(short = 'c')] + pub(crate) crs_path: Option, + + #[clap(short = 'p')] + pub(crate) proof_path: PathBuf, + + #[clap(short = 'k')] + pub(crate) vk_path: PathBuf, + + #[clap(short = 'r')] + pub(crate) is_recursive: bool, +} + +pub(crate) fn run(args: VerifyCommand) { + assert!(args.vk_path.is_file(), "Could not find verification key file at provided path"); + assert!(args.proof_path.is_file(), "Could not find proof file at provided path"); + + std::fs::write(args.proof_path, "proof").unwrap(); +} diff --git a/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/write_vk_cmd.rs b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/write_vk_cmd.rs new file mode 100644 index 00000000000..495aae27fc8 --- /dev/null +++ b/tooling/acvm_backend_barretenberg/test-binaries/mock_backend/src/write_vk_cmd.rs @@ -0,0 +1,23 @@ +use clap::Args; +use std::path::PathBuf; + +#[derive(Debug, Clone, Args)] +pub(crate) struct WriteVkCommand { + #[clap(short = 'c')] + pub(crate) crs_path: Option, + + #[clap(short = 'b')] + pub(crate) bytecode_path: PathBuf, + + #[clap(short = 'r')] + pub(crate) is_recursive: bool, + + #[clap(short = 'o')] + pub(crate) vk_path: PathBuf, +} + +pub(crate) fn run(args: WriteVkCommand) { + assert!(args.bytecode_path.is_file(), "Could not find bytecode file at provided path"); + + std::fs::write(args.vk_path, "vk").unwrap(); +} diff --git a/tooling/lsp/Cargo.toml b/tooling/lsp/Cargo.toml new file mode 100644 index 00000000000..9c48b243131 --- /dev/null +++ b/tooling/lsp/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "noir_lsp" +description = "Language server for Noir" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +acvm.workspace = true +codespan-lsp.workspace = true +codespan-reporting.workspace = true +fm.workspace = true +lsp-types.workspace = true +nargo.workspace = true +nargo_toml.workspace = true +noirc_driver.workspace = true +noirc_errors.workspace = true +noirc_frontend.workspace = true +serde.workspace = true +serde_json.workspace = true +toml.workspace = true +tower.workspace = true +async-lsp = { version = "0.0.5", default-features = false, features = ["omni-trait"] } + +[dev-dependencies] +tokio = { version = "1.0", features = ["macros"] } diff --git a/tooling/lsp/src/lib.rs b/tooling/lsp/src/lib.rs new file mode 100644 index 00000000000..ef06c3c291a --- /dev/null +++ b/tooling/lsp/src/lib.rs @@ -0,0 +1,742 @@ +use std::{ + future::{self, Future}, + ops::{self, ControlFlow}, + path::PathBuf, + pin::Pin, + task::{self, Poll}, +}; + +use async_lsp::{ + router::Router, AnyEvent, AnyNotification, AnyRequest, ClientSocket, Error, ErrorCode, + LanguageClient, LspService, ResponseError, +}; +use codespan_reporting::files; +use fm::FILE_EXTENSION; +use nargo::{ + ops::{run_test, TestStatus}, + prepare_package, +}; +use nargo_toml::{find_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_driver::{check_crate, CompileOptions}; +use noirc_errors::{DiagnosticKind, FileDiagnostic}; +use noirc_frontend::{ + graph::{CrateId, CrateName}, + hir::{Context, FunctionNameMatch}, +}; +use serde_json::Value as JsonValue; +use tower::Service; + +mod types; + +use types::{ + notification, request, CodeLens, CodeLensOptions, CodeLensParams, CodeLensResult, Command, + Diagnostic, DiagnosticSeverity, DidChangeConfigurationParams, DidChangeTextDocumentParams, + DidCloseTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams, + InitializeParams, InitializeResult, InitializedParams, LogMessageParams, MessageType, + NargoCapability, NargoPackageTests, NargoTest, NargoTestId, NargoTestRunParams, + NargoTestRunResult, NargoTestsOptions, NargoTestsParams, NargoTestsResult, Position, + PublishDiagnosticsParams, Range, ServerCapabilities, TextDocumentSyncOptions, Url, +}; + +const ARROW: &str = "▶\u{fe0e}"; +const TEST_COMMAND: &str = "nargo.test"; +const TEST_CODELENS_TITLE: &str = "Run Test"; +const COMPILE_COMMAND: &str = "nargo.compile"; +const COMPILE_CODELENS_TITLE: &str = "Compile"; +const EXECUTE_COMMAND: &str = "nargo.execute"; +const EXECUTE_CODELENS_TITLE: &str = "Execute"; + +// State for the LSP gets implemented on this struct and is internal to the implementation +pub struct LspState { + root_path: Option, + client: ClientSocket, +} + +impl LspState { + fn new(client: &ClientSocket) -> Self { + Self { client: client.clone(), root_path: None } + } +} + +pub struct NargoLspService { + router: Router, +} + +impl NargoLspService { + pub fn new(client: &ClientSocket) -> Self { + let state = LspState::new(client); + let mut router = Router::new(state); + router + .request::(on_initialize) + .request::(on_shutdown) + .request::(on_code_lens_request) + .request::(on_tests_request) + .request::(on_test_run_request) + .notification::(on_initialized) + .notification::(on_did_change_configuration) + .notification::(on_did_open_text_document) + .notification::(on_did_change_text_document) + .notification::(on_did_close_text_document) + .notification::(on_did_save_text_document) + .notification::(on_exit); + Self { router } + } +} + +// This trait implemented as a passthrough to the router, which makes +// our `NargoLspService` a normal Service as far as Tower is concerned. +impl Service for NargoLspService { + type Response = JsonValue; + type Error = ResponseError; + type Future = Pin> + Send>>; + + fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll> { + self.router.poll_ready(cx) + } + + fn call(&mut self, req: AnyRequest) -> Self::Future { + self.router.call(req) + } +} + +// This trait implemented as a passthrough to the router, which makes +// our `NargoLspService` able to accept the `async-lsp` middleware. +impl LspService for NargoLspService { + fn notify(&mut self, notification: AnyNotification) -> ControlFlow> { + self.router.notify(notification) + } + + fn emit(&mut self, event: AnyEvent) -> ControlFlow> { + self.router.emit(event) + } +} + +// Handlers +// The handlers for `request` are not `async` because it compiles down to lifetimes that can't be added to +// the router. To return a future that fits the trait, it is easiest wrap your implementations in an `async {}` +// block but you can also use `std::future::ready`. +// +// Additionally, the handlers for `notification` aren't async at all. +// +// They are not attached to the `NargoLspService` struct so they can be unit tested with only `LspState` +// and params passed in. + +fn on_initialize( + state: &mut LspState, + params: InitializeParams, +) -> impl Future> { + state.root_path = params.root_uri.and_then(|root_uri| root_uri.to_file_path().ok()); + + async { + let text_document_sync = + TextDocumentSyncOptions { save: Some(true.into()), ..Default::default() }; + + let code_lens = CodeLensOptions { resolve_provider: Some(false) }; + + let nargo = NargoCapability { + tests: Some(NargoTestsOptions { + fetch: Some(true), + run: Some(true), + update: Some(true), + }), + }; + + Ok(InitializeResult { + capabilities: ServerCapabilities { + text_document_sync: Some(text_document_sync.into()), + code_lens_provider: Some(code_lens), + nargo: Some(nargo), + }, + server_info: None, + }) + } +} + +fn on_test_run_request( + state: &mut LspState, + params: NargoTestRunParams, +) -> impl Future> { + let root_path = match &state.root_path { + Some(root) => root, + None => { + return future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + "Could not find project root", + ))) + } + }; + + let toml_path = match find_package_manifest(root_path, root_path) { + Ok(toml_path) => toml_path, + Err(err) => { + // If we cannot find a manifest, we can't run the test + return future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("{}", err), + ))); + } + }; + + let crate_name = params.id.crate_name(); + let function_name = params.id.function_name(); + + let workspace = match resolve_workspace_from_toml( + &toml_path, + PackageSelection::Selected(crate_name.clone()), + ) { + Ok(workspace) => workspace, + Err(err) => { + // If we found a manifest, but the workspace is invalid, we raise an error about it + return future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("{}", err), + ))); + } + }; + + // Since we filtered on crate name, this should be the only item in the iterator + match workspace.into_iter().next() { + Some(package) => { + let (mut context, crate_id) = prepare_package(package); + if check_crate(&mut context, crate_id, false).is_err() { + let result = NargoTestRunResult { + id: params.id.clone(), + result: "error".to_string(), + message: Some("The project failed to compile".into()), + }; + return future::ready(Ok(result)); + }; + + let test_functions = context.get_all_test_functions_in_crate_matching( + &crate_id, + FunctionNameMatch::Exact(function_name), + ); + + match test_functions.into_iter().next() { + Some((_, test_function)) => { + #[allow(deprecated)] + let blackbox_solver = acvm::blackbox_solver::BarretenbergSolver::new(); + let test_result = run_test( + &blackbox_solver, + &context, + test_function, + false, + &CompileOptions::default(), + ); + let result = match test_result { + TestStatus::Pass => NargoTestRunResult { + id: params.id.clone(), + result: "pass".to_string(), + message: None, + }, + TestStatus::Fail { message } => NargoTestRunResult { + id: params.id.clone(), + result: "fail".to_string(), + message: Some(message), + }, + TestStatus::CompileError(diag) => NargoTestRunResult { + id: params.id.clone(), + result: "error".to_string(), + message: Some(diag.diagnostic.message), + }, + }; + future::ready(Ok(result)) + } + None => future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("Could not locate test named: {function_name} in {crate_name}"), + ))), + } + } + None => future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("Could not locate package named: {crate_name}"), + ))), + } +} + +fn on_tests_request( + state: &mut LspState, + _params: NargoTestsParams, +) -> impl Future> { + let root_path = match &state.root_path { + Some(root) => root, + None => { + return future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + "Could not find project root", + ))) + } + }; + + let toml_path = match find_package_manifest(root_path, root_path) { + Ok(toml_path) => toml_path, + Err(err) => { + // If we cannot find a manifest, we log a warning but return no tests + // We can reconsider this when we can build a file without the need for a Nargo.toml file to resolve deps + let _ = state.client.log_message(LogMessageParams { + typ: MessageType::WARNING, + message: format!("{}", err), + }); + return future::ready(Ok(None)); + } + }; + let workspace = match resolve_workspace_from_toml(&toml_path, PackageSelection::All) { + Ok(workspace) => workspace, + Err(err) => { + // If we found a manifest, but the workspace is invalid, we raise an error about it + return future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("{}", err), + ))); + } + }; + + let mut package_tests = Vec::new(); + + for package in &workspace { + let (mut context, crate_id) = prepare_package(package); + // We ignore the warnings and errors produced by compilation for producing tests + // because we can still get the test functions even if compilation fails + let _ = check_crate(&mut context, crate_id, false); + + // We don't add test headings for a package if it contains no `#[test]` functions + if let Some(tests) = get_package_tests_in_crate(&context, &crate_id, &package.name) { + package_tests.push(NargoPackageTests { package: package.name.to_string(), tests }); + } + } + + let res = if package_tests.is_empty() { Ok(None) } else { Ok(Some(package_tests)) }; + + future::ready(res) +} + +fn on_shutdown( + _state: &mut LspState, + _params: (), +) -> impl Future> { + async { Ok(()) } +} + +fn on_code_lens_request( + state: &mut LspState, + params: CodeLensParams, +) -> impl Future> { + let file_path = match params.text_document.uri.to_file_path() { + Ok(file_path) => file_path, + Err(()) => { + return future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + "URI is not a valid file path", + ))) + } + }; + + let root_path = match &state.root_path { + Some(root) => root, + None => { + return future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + "Could not find project root", + ))) + } + }; + + let toml_path = match find_package_manifest(root_path, &file_path) { + Ok(toml_path) => toml_path, + Err(err) => { + // If we cannot find a manifest, we log a warning but return no code lenses + // We can reconsider this when we can build a file without the need for a Nargo.toml file to resolve deps + let _ = state.client.log_message(LogMessageParams { + typ: MessageType::WARNING, + message: format!("{err}"), + }); + return future::ready(Ok(None)); + } + }; + let workspace = match resolve_workspace_from_toml(&toml_path, PackageSelection::All) { + Ok(workspace) => workspace, + Err(err) => { + // If we found a manifest, but the workspace is invalid, we raise an error about it + return future::ready(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("{err}"), + ))); + } + }; + + let mut lenses: Vec = vec![]; + + for package in &workspace { + let (mut context, crate_id) = prepare_package(package); + // We ignore the warnings and errors produced by compilation for producing code lenses + // because we can still get the test functions even if compilation fails + let _ = check_crate(&mut context, crate_id, false); + + let fm = &context.file_manager; + let files = fm.as_file_map(); + let tests = context + .get_all_test_functions_in_crate_matching(&crate_id, FunctionNameMatch::Anything); + + for (func_name, test_function) in tests { + let location = context.function_meta(&test_function.get_id()).name.location; + let file_id = location.file; + + // Ignore diagnostics for any file that wasn't the file we saved + // TODO: In the future, we could create "related" diagnostics for these files + // TODO: This currently just appends the `.nr` file extension that we store as a constant, + // but that won't work if we accept other extensions + if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { + continue; + } + + let range = + byte_span_to_range(files, file_id, location.span.into()).unwrap_or_default(); + + let test_command = Command { + title: format!("{ARROW} {TEST_CODELENS_TITLE}"), + command: TEST_COMMAND.into(), + arguments: Some(vec![ + "--program-dir".into(), + format!("{}", workspace.root_dir.display()).into(), + "--package".into(), + format!("{}", package.name).into(), + "--exact".into(), + func_name.into(), + ]), + }; + + let test_lens = CodeLens { range, command: Some(test_command), data: None }; + + lenses.push(test_lens); + } + + if package.is_binary() { + if let Some(main_func_id) = context.get_main_function(&crate_id) { + let location = context.function_meta(&main_func_id).name.location; + let file_id = location.file; + + // Ignore diagnostics for any file that wasn't the file we saved + // TODO: In the future, we could create "related" diagnostics for these files + // TODO: This currently just appends the `.nr` file extension that we store as a constant, + // but that won't work if we accept other extensions + if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { + continue; + } + + let range = + byte_span_to_range(files, file_id, location.span.into()).unwrap_or_default(); + + let compile_command = Command { + title: format!("{ARROW} {COMPILE_CODELENS_TITLE}"), + command: COMPILE_COMMAND.into(), + arguments: Some(vec![ + "--program-dir".into(), + format!("{}", workspace.root_dir.display()).into(), + "--package".into(), + format!("{}", package.name).into(), + ]), + }; + + let compile_lens = CodeLens { range, command: Some(compile_command), data: None }; + + lenses.push(compile_lens); + + let execute_command = Command { + title: EXECUTE_CODELENS_TITLE.to_string(), + command: EXECUTE_COMMAND.into(), + arguments: Some(vec![ + "--program-dir".into(), + format!("{}", workspace.root_dir.display()).into(), + "--package".into(), + format!("{}", package.name).into(), + ]), + }; + + let execute_lens = CodeLens { range, command: Some(execute_command), data: None }; + + lenses.push(execute_lens); + } + } + + if package.is_contract() { + // Currently not looking to deduplicate this since we don't have a clear decision on if the Contract stuff is staying + for contract in context.get_all_contracts(&crate_id) { + let location = contract.location; + let file_id = location.file; + + // Ignore diagnostics for any file that wasn't the file we saved + // TODO: In the future, we could create "related" diagnostics for these files + // TODO: This currently just appends the `.nr` file extension that we store as a constant, + // but that won't work if we accept other extensions + if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { + continue; + } + + let range = + byte_span_to_range(files, file_id, location.span.into()).unwrap_or_default(); + + let compile_command = Command { + title: format!("{ARROW} {COMPILE_CODELENS_TITLE}"), + command: COMPILE_COMMAND.into(), + arguments: Some(vec![ + "--program-dir".into(), + format!("{}", workspace.root_dir.display()).into(), + "--package".into(), + format!("{}", package.name).into(), + ]), + }; + + let compile_lens = CodeLens { range, command: Some(compile_command), data: None }; + + lenses.push(compile_lens); + } + } + } + + let res = if lenses.is_empty() { Ok(None) } else { Ok(Some(lenses)) }; + + future::ready(res) +} + +fn on_initialized( + _state: &mut LspState, + _params: InitializedParams, +) -> ControlFlow> { + ControlFlow::Continue(()) +} + +fn on_did_change_configuration( + _state: &mut LspState, + _params: DidChangeConfigurationParams, +) -> ControlFlow> { + ControlFlow::Continue(()) +} + +fn on_did_open_text_document( + _state: &mut LspState, + _params: DidOpenTextDocumentParams, +) -> ControlFlow> { + ControlFlow::Continue(()) +} + +fn on_did_change_text_document( + _state: &mut LspState, + _params: DidChangeTextDocumentParams, +) -> ControlFlow> { + ControlFlow::Continue(()) +} + +fn on_did_close_text_document( + _state: &mut LspState, + _params: DidCloseTextDocumentParams, +) -> ControlFlow> { + ControlFlow::Continue(()) +} + +fn on_did_save_text_document( + state: &mut LspState, + params: DidSaveTextDocumentParams, +) -> ControlFlow> { + let file_path = match params.text_document.uri.to_file_path() { + Ok(file_path) => file_path, + Err(()) => { + return ControlFlow::Break(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + "URI is not a valid file path", + ) + .into())) + } + }; + + let root_path = match &state.root_path { + Some(root) => root, + None => { + return ControlFlow::Break(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + "Could not find project root", + ) + .into())); + } + }; + + let toml_path = match find_package_manifest(root_path, &file_path) { + Ok(toml_path) => toml_path, + Err(err) => { + // If we cannot find a manifest, we log a warning but return no diagnostics + // We can reconsider this when we can build a file without the need for a Nargo.toml file to resolve deps + let _ = state.client.log_message(LogMessageParams { + typ: MessageType::WARNING, + message: format!("{err}"), + }); + return ControlFlow::Continue(()); + } + }; + let workspace = match resolve_workspace_from_toml(&toml_path, PackageSelection::All) { + Ok(workspace) => workspace, + Err(err) => { + // If we found a manifest, but the workspace is invalid, we raise an error about it + return ControlFlow::Break(Err(ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("{err}"), + ) + .into())); + } + }; + + let mut diagnostics = Vec::new(); + + for package in &workspace { + let (mut context, crate_id) = prepare_package(package); + + let file_diagnostics = match check_crate(&mut context, crate_id, false) { + Ok(((), warnings)) => warnings, + Err(errors_and_warnings) => errors_and_warnings, + }; + + // We don't add test headings for a package if it contains no `#[test]` functions + if let Some(tests) = get_package_tests_in_crate(&context, &crate_id, &package.name) { + let _ = state.client.notify::(NargoPackageTests { + package: package.name.to_string(), + tests, + }); + } + + if !file_diagnostics.is_empty() { + let fm = &context.file_manager; + let files = fm.as_file_map(); + + for FileDiagnostic { file_id, diagnostic, call_stack: _ } in file_diagnostics { + // Ignore diagnostics for any file that wasn't the file we saved + // TODO: In the future, we could create "related" diagnostics for these files + // TODO: This currently just appends the `.nr` file extension that we store as a constant, + // but that won't work if we accept other extensions + if fm.path(file_id).with_extension(FILE_EXTENSION) != file_path { + continue; + } + + let mut range = Range::default(); + + // TODO: Should this be the first item in secondaries? Should we bail when we find a range? + for sec in diagnostic.secondaries { + // Not using `unwrap_or_default` here because we don't want to overwrite a valid range with a default range + if let Some(r) = byte_span_to_range(files, file_id, sec.span.into()) { + range = r + } + } + let severity = match diagnostic.kind { + DiagnosticKind::Error => Some(DiagnosticSeverity::ERROR), + DiagnosticKind::Warning => Some(DiagnosticSeverity::WARNING), + }; + diagnostics.push(Diagnostic { + range, + severity, + message: diagnostic.message, + ..Default::default() + }) + } + } + } + + // We need to refresh lenses when we compile since that's the only time they can be accurately reflected + std::mem::drop(state.client.code_lens_refresh(())); + + let _ = state.client.publish_diagnostics(PublishDiagnosticsParams { + uri: params.text_document.uri, + version: None, + diagnostics, + }); + + ControlFlow::Continue(()) +} + +fn on_exit(_state: &mut LspState, _params: ()) -> ControlFlow> { + ControlFlow::Continue(()) +} + +fn get_package_tests_in_crate( + context: &Context, + crate_id: &CrateId, + crate_name: &CrateName, +) -> Option> { + let fm = &context.file_manager; + let files = fm.as_file_map(); + let tests = + context.get_all_test_functions_in_crate_matching(crate_id, FunctionNameMatch::Anything); + + let mut package_tests = Vec::new(); + + for (func_name, test_function) in tests { + let location = context.function_meta(&test_function.get_id()).name.location; + let file_id = location.file; + + let file_path = fm.path(file_id).with_extension(FILE_EXTENSION); + let range = byte_span_to_range(files, file_id, location.span.into()).unwrap_or_default(); + + package_tests.push(NargoTest { + id: NargoTestId::new(crate_name.clone(), func_name.clone()), + label: func_name, + uri: Url::from_file_path(file_path) + .expect("Expected a valid file path that can be converted into a URI"), + range, + }) + } + + if package_tests.is_empty() { + None + } else { + Some(package_tests) + } +} + +fn byte_span_to_range<'a, F: files::Files<'a> + ?Sized>( + files: &'a F, + file_id: F::FileId, + span: ops::Range, +) -> Option { + if let Ok(codespan_range) = codespan_lsp::byte_span_to_range(files, file_id, span) { + // We have to manually construct a Range because the codespan_lsp restricts lsp-types to the wrong version range + // TODO: codespan is unmaintained and we should probably subsume it. Ref https://github.com/brendanzab/codespan/issues/345 + let range = Range { + start: Position { + line: codespan_range.start.line, + character: codespan_range.start.character, + }, + end: Position { + line: codespan_range.end.line, + character: codespan_range.end.character, + }, + }; + Some(range) + } else { + None + } +} + +#[cfg(test)] +mod lsp_tests { + use lsp_types::TextDocumentSyncCapability; + use tokio::test; + + use super::*; + + #[test] + async fn test_on_initialize() { + // Not available in published release yet + let client = ClientSocket::new_closed(); + let mut state = LspState::new(&client); + let params = InitializeParams::default(); + let response = on_initialize(&mut state, params).await.unwrap(); + assert!(matches!( + response.capabilities, + ServerCapabilities { + text_document_sync: Some(TextDocumentSyncCapability::Options( + TextDocumentSyncOptions { save: Some(_), .. } + )), + code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(false) }), + .. + } + )); + assert!(response.server_info.is_none()); + } +} diff --git a/tooling/lsp/src/types.rs b/tooling/lsp/src/types.rs new file mode 100644 index 00000000000..10f1764c63f --- /dev/null +++ b/tooling/lsp/src/types.rs @@ -0,0 +1,190 @@ +use noirc_frontend::graph::CrateName; +use serde::{Deserialize, Serialize}; + +// Re-providing lsp_types that we don't need to override +pub(crate) use lsp_types::{ + CodeLens, CodeLensOptions, CodeLensParams, Command, Diagnostic, DiagnosticSeverity, + DidChangeConfigurationParams, DidChangeTextDocumentParams, DidCloseTextDocumentParams, + DidOpenTextDocumentParams, DidSaveTextDocumentParams, InitializeParams, InitializedParams, + LogMessageParams, MessageType, Position, PublishDiagnosticsParams, Range, ServerInfo, + TextDocumentSyncCapability, TextDocumentSyncOptions, Url, +}; + +pub(crate) mod request { + use lsp_types::{request::Request, InitializeParams}; + + use super::{ + InitializeResult, NargoTestRunParams, NargoTestRunResult, NargoTestsParams, + NargoTestsResult, + }; + + // Re-providing lsp_types that we don't need to override + pub(crate) use lsp_types::request::{CodeLensRequest as CodeLens, Shutdown}; + + #[derive(Debug)] + pub(crate) struct Initialize; + impl Request for Initialize { + type Params = InitializeParams; + type Result = InitializeResult; + const METHOD: &'static str = "initialize"; + } + + #[derive(Debug)] + pub(crate) struct NargoTestRun; + impl Request for NargoTestRun { + type Params = NargoTestRunParams; + type Result = NargoTestRunResult; + const METHOD: &'static str = "nargo/tests/run"; + } + + #[derive(Debug)] + pub(crate) struct NargoTests; + impl Request for NargoTests { + type Params = NargoTestsParams; + type Result = NargoTestsResult; + const METHOD: &'static str = "nargo/tests"; + } +} + +pub(crate) mod notification { + use lsp_types::notification::Notification; + + use super::NargoPackageTests; + + // Re-providing lsp_types that we don't need to override + pub(crate) use lsp_types::notification::{ + DidChangeConfiguration, DidChangeTextDocument, DidCloseTextDocument, DidOpenTextDocument, + DidSaveTextDocument, Exit, Initialized, + }; + + pub(crate) struct NargoUpdateTests; + impl Notification for NargoUpdateTests { + type Params = NargoPackageTests; + const METHOD: &'static str = "nargo/tests/update"; + } +} + +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct NargoTestsOptions { + /// Tests can be requested from the server. + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) fetch: Option, + + /// Tests runs can be requested from the server. + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) run: Option, + + /// The server will send notifications to update tests. + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) update: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct NargoCapability { + /// The server will provide various features related to testing within Nargo. + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) tests: Option, +} + +#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ServerCapabilities { + /// Defines how text documents are synced. + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) text_document_sync: Option, + + /// The server provides code lens. + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) code_lens_provider: Option, + + /// The server handles and provides custom nargo messages. + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) nargo: Option, +} + +#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct InitializeResult { + /// The capabilities the language server provides. + pub(crate) capabilities: ServerCapabilities, + + /// Information about the server. + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) server_info: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(try_from = "String", into = "String")] +pub(crate) struct NargoTestId { + package: CrateName, + fully_qualified_path: String, +} + +impl TryFrom for NargoTestId { + type Error = String; + + fn try_from(value: String) -> Result { + if let Some((crate_name, function_name)) = value.split_once('/') { + let crate_name = crate_name.parse()?; + Ok(Self { package: crate_name, fully_qualified_path: function_name.to_string() }) + } else { + Err("NargoTestId should be serialized as package_name/fully_qualified_path".to_string()) + } + } +} + +impl From for String { + fn from(value: NargoTestId) -> Self { + format!("{}/{}", value.package, value.fully_qualified_path) + } +} + +impl NargoTestId { + pub(crate) fn new(crate_name: CrateName, function_name: String) -> Self { + Self { package: crate_name, fully_qualified_path: function_name } + } + + pub(crate) fn crate_name(&self) -> &CrateName { + &self.package + } + + pub(crate) fn function_name(&self) -> &String { + &self.fully_qualified_path + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct NargoTest { + pub(crate) id: NargoTestId, + /// Fully-qualified path to the test within the crate + pub(crate) label: String, + pub(crate) range: Range, + pub(crate) uri: Url, +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct NargoPackageTests { + pub(crate) package: String, + pub(crate) tests: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct NargoTestsParams {} + +pub(crate) type NargoTestsResult = Option>; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct NargoTestRunParams { + pub(crate) id: NargoTestId, +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct NargoTestRunResult { + pub(crate) id: NargoTestId, + pub(crate) result: String, + pub(crate) message: Option, +} + +pub(crate) type CodeLensResult = Option>; diff --git a/tooling/nargo/Cargo.toml b/tooling/nargo/Cargo.toml new file mode 100644 index 00000000000..c038ab6b1e4 --- /dev/null +++ b/tooling/nargo/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "nargo" +description = "Noir's package manager" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +rustc_version = "0.4.0" + +[dependencies] +acvm.workspace = true +fm.workspace = true +noirc_abi.workspace = true +noirc_driver.workspace = true +noirc_errors.workspace = true +noirc_frontend.workspace = true +noirc_printable_type.workspace = true +iter-extended.workspace = true +serde.workspace = true +thiserror.workspace = true +base64.workspace = true +codespan-reporting.workspace = true diff --git a/crates/nargo/build.rs b/tooling/nargo/build.rs similarity index 100% rename from crates/nargo/build.rs rename to tooling/nargo/build.rs diff --git a/tooling/nargo/src/artifacts/contract.rs b/tooling/nargo/src/artifacts/contract.rs new file mode 100644 index 00000000000..4db7d95731e --- /dev/null +++ b/tooling/nargo/src/artifacts/contract.rs @@ -0,0 +1,40 @@ +use acvm::acir::circuit::Circuit; +use noirc_abi::Abi; +use noirc_driver::ContractFunctionType; +use serde::{Deserialize, Serialize}; + +/// `PreprocessedContract` represents a Noir contract which has been preprocessed by a particular backend proving system. +/// +/// This differs from a generic Noir contract artifact in that: +/// - The ACIR bytecode has had an optimization pass applied to tailor it for the backend. +/// - Proving and verification keys have been pregenerated based on this ACIR. +#[derive(Serialize, Deserialize)] +pub struct PreprocessedContract { + /// The name of the contract. + pub name: String, + /// The identifier of the proving backend which this contract has been compiled for. + pub backend: String, + /// Each of the contract's functions are compiled into a separate program stored in this `Vec`. + pub functions: Vec, +} + +/// Each function in the contract will be compiled as a separate noir program. +/// +/// A contract function unlike a regular Noir program however can have additional properties. +/// One of these being a function type. +#[derive(Debug, Serialize, Deserialize)] +pub struct PreprocessedContractFunction { + pub name: String, + + pub function_type: ContractFunctionType, + + pub is_internal: bool, + + pub abi: Abi, + + #[serde( + serialize_with = "super::serialize_circuit", + deserialize_with = "super::deserialize_circuit" + )] + pub bytecode: Circuit, +} diff --git a/tooling/nargo/src/artifacts/debug.rs b/tooling/nargo/src/artifacts/debug.rs new file mode 100644 index 00000000000..3c173f34876 --- /dev/null +++ b/tooling/nargo/src/artifacts/debug.rs @@ -0,0 +1,76 @@ +use codespan_reporting::files::{Error, Files, SimpleFile}; +use noirc_driver::DebugFile; +use noirc_errors::debug_info::DebugInfo; +use serde::{Deserialize, Serialize}; +use std::{ + collections::{BTreeMap, BTreeSet}, + ops::Range, +}; + +use fm::{FileId, FileManager, PathString}; + +/// A Debug Artifact stores, for a given program, the debug info for every function +/// along with a map of file Id to the source code so locations in debug info can be mapped to source code they point to. +#[derive(Debug, Serialize, Deserialize)] +pub struct DebugArtifact { + pub debug_symbols: Vec, + pub file_map: BTreeMap, +} + +impl DebugArtifact { + pub fn new(debug_symbols: Vec, file_manager: &FileManager) -> Self { + let mut file_map = BTreeMap::new(); + + let files_with_debug_symbols: BTreeSet = debug_symbols + .iter() + .flat_map(|function_symbols| { + function_symbols + .locations + .values() + .filter_map(|call_stack| call_stack.last().map(|location| location.file)) + }) + .collect(); + + for file_id in files_with_debug_symbols { + let file_source = file_manager.fetch_file(file_id).source(); + + file_map.insert( + file_id, + DebugFile { + source: file_source.to_string(), + path: file_manager.path(file_id).to_path_buf(), + }, + ); + } + + Self { debug_symbols, file_map } + } +} + +impl<'a> Files<'a> for DebugArtifact { + type FileId = FileId; + type Name = PathString; + type Source = &'a str; + + fn name(&self, file_id: Self::FileId) -> Result { + self.file_map.get(&file_id).ok_or(Error::FileMissing).map(|file| file.path.clone().into()) + } + + fn source(&'a self, file_id: Self::FileId) -> Result { + self.file_map.get(&file_id).ok_or(Error::FileMissing).map(|file| file.source.as_ref()) + } + + fn line_index(&self, file_id: Self::FileId, byte_index: usize) -> Result { + self.file_map.get(&file_id).ok_or(Error::FileMissing).and_then(|file| { + SimpleFile::new(PathString::from(file.path.clone()), file.source.clone()) + .line_index((), byte_index) + }) + } + + fn line_range(&self, file_id: Self::FileId, line_index: usize) -> Result, Error> { + self.file_map.get(&file_id).ok_or(Error::FileMissing).and_then(|file| { + SimpleFile::new(PathString::from(file.path.clone()), file.source.clone()) + .line_range((), line_index) + }) + } +} diff --git a/crates/nargo/src/artifacts/mod.rs b/tooling/nargo/src/artifacts/mod.rs similarity index 100% rename from crates/nargo/src/artifacts/mod.rs rename to tooling/nargo/src/artifacts/mod.rs diff --git a/tooling/nargo/src/artifacts/program.rs b/tooling/nargo/src/artifacts/program.rs new file mode 100644 index 00000000000..be01b7bdec1 --- /dev/null +++ b/tooling/nargo/src/artifacts/program.rs @@ -0,0 +1,20 @@ +use acvm::acir::circuit::Circuit; +use noirc_abi::Abi; +use serde::{Deserialize, Serialize}; + +/// `PreprocessedProgram` represents a Noir program which has been preprocessed by a particular backend proving system. +/// +/// This differs from a generic Noir program artifact in that: +/// - The ACIR bytecode has had an optimization pass applied to tailor it for the backend. +/// - Proving and verification keys have been pregenerated based on this ACIR. +#[derive(Serialize, Deserialize, Debug)] +pub struct PreprocessedProgram { + pub backend: String, + pub abi: Abi, + + #[serde( + serialize_with = "super::serialize_circuit", + deserialize_with = "super::deserialize_circuit" + )] + pub bytecode: Circuit, +} diff --git a/crates/nargo/src/constants.rs b/tooling/nargo/src/constants.rs similarity index 100% rename from crates/nargo/src/constants.rs rename to tooling/nargo/src/constants.rs diff --git a/tooling/nargo/src/errors.rs b/tooling/nargo/src/errors.rs new file mode 100644 index 00000000000..466909db24d --- /dev/null +++ b/tooling/nargo/src/errors.rs @@ -0,0 +1,59 @@ +use acvm::{acir::circuit::OpcodeLocation, pwg::OpcodeResolutionError}; +use noirc_printable_type::ForeignCallError; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum NargoError { + /// Error while compiling Noir into ACIR. + #[error("Failed to compile circuit")] + CompilationError, + + /// ACIR circuit execution error + #[error(transparent)] + ExecutionError(#[from] ExecutionError), + + /// Oracle handling error + #[error(transparent)] + ForeignCallError(#[from] ForeignCallError), +} + +impl From for NargoError { + fn from(_: acvm::compiler::CompileError) -> Self { + NargoError::CompilationError + } +} + +impl NargoError { + /// Extracts the user defined failure message from the ExecutionError + /// If one exists. + /// + /// We want to extract the user defined error so that we can compare it + /// in tests to expected failure messages + pub fn user_defined_failure_message(&self) -> Option<&str> { + let execution_error = match self { + NargoError::ExecutionError(error) => error, + _ => return None, + }; + + match execution_error { + ExecutionError::AssertionFailed(message, _) => Some(message), + ExecutionError::SolvingError(error) => match error { + OpcodeResolutionError::IndexOutOfBounds { .. } + | OpcodeResolutionError::UnsupportedBlackBoxFunc(_) + | OpcodeResolutionError::OpcodeNotSolvable(_) + | OpcodeResolutionError::UnsatisfiedConstrain { .. } => None, + OpcodeResolutionError::BrilligFunctionFailed { message, .. } => Some(message), + OpcodeResolutionError::BlackBoxFunctionFailed(_, reason) => Some(reason), + }, + } + } +} + +#[derive(Debug, Error)] +pub enum ExecutionError { + #[error("Failed assertion: '{}'", .0)] + AssertionFailed(String, Vec), + + #[error(transparent)] + SolvingError(#[from] OpcodeResolutionError), +} diff --git a/tooling/nargo/src/lib.rs b/tooling/nargo/src/lib.rs new file mode 100644 index 00000000000..3bc1ecd7a80 --- /dev/null +++ b/tooling/nargo/src/lib.rs @@ -0,0 +1,56 @@ +#![forbid(unsafe_code)] +#![warn(unused_crate_dependencies, unused_extern_crates)] +#![warn(unreachable_pub)] +#![warn(clippy::semicolon_if_nothing_returned)] + +//! Nargo is the package manager for Noir +//! This name was used because it sounds like `cargo` and +//! Noir Package Manager abbreviated is npm, which is already taken. + +pub mod artifacts; +pub mod constants; +pub mod errors; +pub mod ops; +pub mod package; +pub mod workspace; + +use std::collections::BTreeMap; + +use fm::FileManager; +use noirc_driver::{add_dep, prepare_crate, prepare_dependency}; +use noirc_frontend::{ + graph::{CrateGraph, CrateId, CrateName}, + hir::Context, +}; +use package::{Dependency, Package}; + +pub use self::errors::NargoError; + +pub fn prepare_dependencies( + context: &mut Context, + parent_crate: CrateId, + dependencies: &BTreeMap, +) { + for (dep_name, dep) in dependencies.iter() { + match dep { + Dependency::Remote { package } | Dependency::Local { package } => { + let crate_id = prepare_dependency(context, &package.entry_path); + add_dep(context, parent_crate, crate_id, dep_name.clone()); + prepare_dependencies(context, crate_id, &package.dependencies); + } + } + } +} + +pub fn prepare_package(package: &Package) -> (Context, CrateId) { + // TODO: FileManager continues to leak into various crates + let fm = FileManager::new(&package.root_dir); + let graph = CrateGraph::default(); + let mut context = Context::new(fm, graph); + + let crate_id = prepare_crate(&mut context, &package.entry_path); + + prepare_dependencies(&mut context, crate_id, &package.dependencies); + + (context, crate_id) +} diff --git a/tooling/nargo/src/ops/execute.rs b/tooling/nargo/src/ops/execute.rs new file mode 100644 index 00000000000..33f41ebe819 --- /dev/null +++ b/tooling/nargo/src/ops/execute.rs @@ -0,0 +1,68 @@ +use acvm::pwg::{ACVMStatus, ErrorLocation, OpcodeResolutionError, ACVM}; +use acvm::BlackBoxFunctionSolver; +use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; + +use crate::errors::ExecutionError; +use crate::NargoError; + +use super::foreign_calls::ForeignCall; + +pub fn execute_circuit( + blackbox_solver: &B, + circuit: Circuit, + initial_witness: WitnessMap, + show_output: bool, +) -> Result { + let mut acvm = ACVM::new(blackbox_solver, circuit.opcodes, initial_witness); + + // Assert messages are not a map due to https://github.com/noir-lang/acvm/issues/522 + let get_assert_message = |opcode_location| { + circuit + .assert_messages + .iter() + .find(|(loc, _)| loc == opcode_location) + .map(|(_, message)| message.clone()) + }; + + loop { + let solver_status = acvm.solve(); + + match solver_status { + ACVMStatus::Solved => break, + ACVMStatus::InProgress => { + unreachable!("Execution should not stop while in `InProgress` state.") + } + ACVMStatus::Failure(error) => { + let call_stack = match &error { + OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Resolved(opcode_location), + } => Some(vec![*opcode_location]), + OpcodeResolutionError::BrilligFunctionFailed { call_stack, .. } => { + Some(call_stack.clone()) + } + _ => None, + }; + + return Err(NargoError::ExecutionError(match call_stack { + Some(call_stack) => { + if let Some(assert_message) = get_assert_message( + call_stack.last().expect("Call stacks should not be empty"), + ) { + ExecutionError::AssertionFailed(assert_message, call_stack) + } else { + ExecutionError::SolvingError(error) + } + } + None => ExecutionError::SolvingError(error), + })); + } + ACVMStatus::RequiresForeignCall(foreign_call) => { + let foreign_call_result = ForeignCall::execute(&foreign_call, show_output)?; + acvm.resolve_pending_foreign_call(foreign_call_result); + } + } + } + + let solved_witness = acvm.finalize(); + Ok(solved_witness) +} diff --git a/crates/nargo/src/ops/foreign_calls.rs b/tooling/nargo/src/ops/foreign_calls.rs similarity index 97% rename from crates/nargo/src/ops/foreign_calls.rs rename to tooling/nargo/src/ops/foreign_calls.rs index 8eac516a7e9..db8cdceb20a 100644 --- a/crates/nargo/src/ops/foreign_calls.rs +++ b/tooling/nargo/src/ops/foreign_calls.rs @@ -73,7 +73,7 @@ impl ForeignCall { ], }) } - None => panic!("unexpected foreign call {:?}", foreign_call_name), + None => panic!("unexpected foreign call {foreign_call_name:?}"), } } diff --git a/tooling/nargo/src/ops/mod.rs b/tooling/nargo/src/ops/mod.rs new file mode 100644 index 00000000000..f789455577c --- /dev/null +++ b/tooling/nargo/src/ops/mod.rs @@ -0,0 +1,8 @@ +pub use self::execute::execute_circuit; +pub use self::optimize::{optimize_contract, optimize_program}; +pub use self::test::{run_test, TestStatus}; + +mod execute; +mod foreign_calls; +mod optimize; +mod test; diff --git a/tooling/nargo/src/ops/optimize.rs b/tooling/nargo/src/ops/optimize.rs new file mode 100644 index 00000000000..54e2432aa40 --- /dev/null +++ b/tooling/nargo/src/ops/optimize.rs @@ -0,0 +1,34 @@ +use acvm::{acir::circuit::Opcode, Language}; +use iter_extended::try_vecmap; +use noirc_driver::{CompiledContract, CompiledProgram}; + +use crate::NargoError; + +pub fn optimize_program( + mut program: CompiledProgram, + np_language: Language, + is_opcode_supported: &impl Fn(&Opcode) -> bool, +) -> Result { + let (optimized_circuit, location_map) = + acvm::compiler::compile(program.circuit, np_language, is_opcode_supported)?; + + program.circuit = optimized_circuit; + program.debug.update_acir(location_map); + Ok(program) +} + +pub fn optimize_contract( + contract: CompiledContract, + np_language: Language, + is_opcode_supported: &impl Fn(&Opcode) -> bool, +) -> Result { + let functions = try_vecmap(contract.functions, |mut func| { + let (optimized_bytecode, location_map) = + acvm::compiler::compile(func.bytecode, np_language, is_opcode_supported)?; + func.bytecode = optimized_bytecode; + func.debug.update_acir(location_map); + Ok::<_, NargoError>(func) + })?; + + Ok(CompiledContract { functions, ..contract }) +} diff --git a/tooling/nargo/src/ops/test.rs b/tooling/nargo/src/ops/test.rs new file mode 100644 index 00000000000..512780cc271 --- /dev/null +++ b/tooling/nargo/src/ops/test.rs @@ -0,0 +1,122 @@ +use acvm::{acir::native_types::WitnessMap, BlackBoxFunctionSolver}; +use noirc_driver::{compile_no_check, CompileOptions}; +use noirc_errors::FileDiagnostic; +use noirc_frontend::hir::{def_map::TestFunction, Context}; + +use crate::NargoError; + +use super::execute_circuit; + +pub enum TestStatus { + Pass, + Fail { message: String }, + CompileError(FileDiagnostic), +} + +pub fn run_test( + blackbox_solver: &B, + context: &Context, + test_function: TestFunction, + show_output: bool, + config: &CompileOptions, +) -> TestStatus { + let program = compile_no_check(context, config, test_function.get_id()); + match program { + Ok(program) => { + // Run the backend to ensure the PWG evaluates functions like std::hash::pedersen, + // otherwise constraints involving these expressions will not error. + let circuit_execution = + execute_circuit(blackbox_solver, program.circuit, WitnessMap::new(), show_output); + test_status_program_compile_pass(test_function, circuit_execution) + } + Err(diag) => test_status_program_compile_fail(diag, test_function), + } +} + +/// Test function failed to compile +/// +/// Note: This could be because the compiler was able to deduce +/// that a constraint was never satisfiable. +/// An example of this is the program `assert(false)` +/// In that case, we check if the test function should fail, and if so, we return `TestStatus::Pass`. +fn test_status_program_compile_fail( + diag: FileDiagnostic, + test_function: TestFunction, +) -> TestStatus { + // The test has failed compilation, but it should never fail. Report error. + if !test_function.should_fail() { + return TestStatus::CompileError(diag); + } + + // The test has failed compilation, check if it is because the program is never satisfiable. + // If it is never satisfiable, then this is the expected behavior. + let program_is_never_satisfiable = diag.diagnostic.message.contains("Failed constraint"); + if !program_is_never_satisfiable { + // The test has failed compilation, but its a compilation error. Report error + return TestStatus::CompileError(diag); + } + + check_expected_failure_message(test_function, &diag.diagnostic.message) +} + +/// The test function compiled successfully. +/// +/// We now check whether execution passed/failed and whether it should have +/// passed/failed to determine the test status. +fn test_status_program_compile_pass( + test_function: TestFunction, + circuit_execution: Result, +) -> TestStatus { + let circuit_execution_err = match circuit_execution { + // Circuit execution was successful; ie no errors or unsatisfied constraints + // were encountered. + Ok(_) => { + if test_function.should_fail() { + return TestStatus::Fail { + message: "error: Test passed when it should have failed".to_string(), + }; + } + return TestStatus::Pass; + } + Err(err) => err, + }; + + // If we reach here, then the circuit execution failed. + // + // Check if the function should have passed + let test_should_have_passed = !test_function.should_fail(); + if test_should_have_passed { + return TestStatus::Fail { message: circuit_execution_err.to_string() }; + } + + check_expected_failure_message( + test_function, + circuit_execution_err.user_defined_failure_message().unwrap_or_default(), + ) +} + +fn check_expected_failure_message(test_function: TestFunction, got_error: &str) -> TestStatus { + // Extract the expected failure message, if there was one + // + // #[test(should_fail)] will not produce any message + // #[test(should_fail_with = "reason")] will produce a message + // + let expected_failure_message = match test_function.failure_reason() { + Some(reason) => reason, + None => return TestStatus::Pass, + }; + + let expected_failure_message_matches = got_error == expected_failure_message; + if expected_failure_message_matches { + return TestStatus::Pass; + } + + // The expected failure message does not match the actual failure message + TestStatus::Fail { + message: format!( + "\nerror: Test failed with the wrong message. \nExpected: {} \nGot: {}", + test_function.failure_reason().unwrap_or_default(), + got_error.trim_matches('\'') + ), + } +} diff --git a/crates/nargo/src/package.rs b/tooling/nargo/src/package.rs similarity index 100% rename from crates/nargo/src/package.rs rename to tooling/nargo/src/package.rs diff --git a/crates/nargo/src/workspace.rs b/tooling/nargo/src/workspace.rs similarity index 100% rename from crates/nargo/src/workspace.rs rename to tooling/nargo/src/workspace.rs diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml new file mode 100644 index 00000000000..0b85c66b6fa --- /dev/null +++ b/tooling/nargo_cli/Cargo.toml @@ -0,0 +1,81 @@ +[package] +name = "nargo_cli" +description = "Noir's package manager" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +# Rename binary from `nargo_cli` to `nargo` +[[bin]] +name = "nargo" +path = "src/main.rs" + +[build-dependencies] +rustc_version = "0.4.0" +build-data = "0.1.3" +toml.workspace = true + +[dependencies] +clap.workspace = true +fm.workspace = true +iter-extended.workspace = true +nargo.workspace = true +nargo_toml.workspace = true +noir_lsp.workspace = true +noirc_driver.workspace = true +noirc_frontend.workspace = true +noirc_abi.workspace = true +noirc_errors.workspace = true +acvm.workspace = true +toml.workspace = true +serde.workspace = true +serde_json.workspace = true +prettytable-rs = "0.10" +rayon = "1.7.0" +thiserror.workspace = true +tower.workspace = true +async-lsp = { version = "0.0.5", default-features = false, features = [ + "client-monitor", + "stdio", + "tracing", + "tokio", +] } +const_format = "0.2.30" +hex = "0.4.2" +termcolor = "1.1.2" +color-eyre = "0.6.2" +tokio = { version = "1.0", features = ["io-std"] } + +# Backends +acvm-backend-barretenberg = { path = "../acvm_backend_barretenberg" } + +[target.'cfg(not(unix))'.dependencies] +tokio-util = { version = "0.7.8", features = ["compat"] } + +[dev-dependencies] +tempfile = "3.6.0" +dirs.workspace = true +assert_cmd = "2.0.8" +assert_fs = "1.0.10" +predicates = "2.1.5" +fm.workspace = true +criterion = "0.5.0" +paste = "1.0.14" +pprof = { version = "0.12", features = [ + "flamegraph", + "frame-pointer", + "criterion", +] } +iai = "0.1.1" +test-binary = "3.0.1" + +[[bench]] +name = "criterion" +harness = false + +[[bench]] +name = "iai" +harness = false diff --git a/crates/nargo_cli/benches/criterion.rs b/tooling/nargo_cli/benches/criterion.rs similarity index 100% rename from crates/nargo_cli/benches/criterion.rs rename to tooling/nargo_cli/benches/criterion.rs diff --git a/crates/nargo_cli/benches/iai.rs b/tooling/nargo_cli/benches/iai.rs similarity index 100% rename from crates/nargo_cli/benches/iai.rs rename to tooling/nargo_cli/benches/iai.rs diff --git a/crates/nargo_cli/benches/utils.rs b/tooling/nargo_cli/benches/utils.rs similarity index 100% rename from crates/nargo_cli/benches/utils.rs rename to tooling/nargo_cli/benches/utils.rs diff --git a/tooling/nargo_cli/build.rs b/tooling/nargo_cli/build.rs new file mode 100644 index 00000000000..ff941e41f36 --- /dev/null +++ b/tooling/nargo_cli/build.rs @@ -0,0 +1,211 @@ +use rustc_version::{version, Version}; +use std::fs::File; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::{env, fs}; + +fn check_rustc_version() { + assert!( + version().unwrap() >= Version::parse("1.66.0").unwrap(), + "The minimal supported rustc version is 1.66.0." + ); +} + +const GIT_COMMIT: &&str = &"GIT_COMMIT"; + +fn main() { + // Rebuild if the tests have changed + println!("cargo:rerun-if-changed=tests"); + + check_rustc_version(); + + // Only use build_data if the environment variable isn't set + // The environment variable is always set when working via Nix + if std::env::var(GIT_COMMIT).is_err() { + build_data::set_GIT_COMMIT(); + build_data::set_GIT_DIRTY(); + build_data::no_debug_rebuilds(); + } + + let out_dir = env::var("OUT_DIR").unwrap(); + let destination = Path::new(&out_dir).join("execute.rs"); + let mut test_file = File::create(destination).unwrap(); + + // Try to find the directory that Cargo sets when it is running; otherwise fallback to assuming the CWD + // is the root of the repository and append the crate path + let manifest_dir = match std::env::var("CARGO_MANIFEST_DIR") { + Ok(dir) => PathBuf::from(dir), + Err(_) => std::env::current_dir().unwrap().join("crates").join("nargo_cli"), + }; + let test_dir = manifest_dir.join("tests"); + + generate_execution_success_tests(&mut test_file, &test_dir); + generate_compile_success_empty_tests(&mut test_file, &test_dir); + generate_compile_success_contract_tests(&mut test_file, &test_dir); + generate_compile_failure_tests(&mut test_file, &test_dir); +} + +fn generate_execution_success_tests(test_file: &mut File, test_data_dir: &Path) { + let test_sub_dir = "execution_success"; + let test_data_dir = test_data_dir.join(test_sub_dir); + + let test_case_dirs = + fs::read_dir(test_data_dir).unwrap().flatten().filter(|c| c.path().is_dir()); + + for test_dir in test_case_dirs { + let test_name = + test_dir.file_name().into_string().expect("Directory can't be converted to string"); + if test_name.contains('-') { + panic!( + "Invalid test directory: {test_name}. Cannot include `-`, please convert to `_`" + ); + }; + let test_dir = &test_dir.path(); + + write!( + test_file, + r#" +#[test] +fn execution_success_{test_name}() {{ + let test_program_dir = PathBuf::from("{test_dir}"); + + let mut cmd = Command::cargo_bin("nargo").unwrap(); + cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); + cmd.arg("--program-dir").arg(test_program_dir); + cmd.arg("execute"); + + cmd.assert().success(); +}} + "#, + test_dir = test_dir.display(), + ) + .expect("Could not write templated test file."); + } +} + +fn generate_compile_success_empty_tests(test_file: &mut File, test_data_dir: &Path) { + let test_sub_dir = "compile_success_empty"; + let test_data_dir = test_data_dir.join(test_sub_dir); + + let test_case_dirs = + fs::read_dir(test_data_dir).unwrap().flatten().filter(|c| c.path().is_dir()); + + for test_dir in test_case_dirs { + let test_name = + test_dir.file_name().into_string().expect("Directory can't be converted to string"); + if test_name.contains('-') { + panic!( + "Invalid test directory: {test_name}. Cannot include `-`, please convert to `_`" + ); + }; + let test_dir = &test_dir.path(); + + write!( + test_file, + r#" +#[test] +fn compile_success_empty_{test_name}() {{ + + // We use a mocked backend for this test as we do not rely on the returned circuit size + // but we must call a backend as part of querying the number of opcodes in the circuit. + + let test_program_dir = PathBuf::from("{test_dir}"); + let mut cmd = Command::cargo_bin("nargo").unwrap(); + cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); + cmd.arg("--program-dir").arg(test_program_dir); + cmd.arg("info"); + cmd.arg("--json"); + + let output = cmd.output().expect("Failed to execute command"); + + if !output.status.success() {{ + panic!("`nargo info` failed with: {{}}", String::from_utf8(output.stderr).unwrap()); + }} + + // `compile_success_empty` tests should be able to compile down to an empty circuit. + let json: serde_json::Value = serde_json::from_slice(&output.stdout).expect("JSON was not well-formatted"); + let num_opcodes = &json["programs"][0]["acir_opcodes"]; + assert_eq!(num_opcodes.as_u64().unwrap(), 0); +}} + "#, + test_dir = test_dir.display(), + ) + .expect("Could not write templated test file."); + } +} + +fn generate_compile_success_contract_tests(test_file: &mut File, test_data_dir: &Path) { + let test_sub_dir = "compile_success_contract"; + let test_data_dir = test_data_dir.join(test_sub_dir); + + let test_case_dirs = + fs::read_dir(test_data_dir).unwrap().flatten().filter(|c| c.path().is_dir()); + + for test_dir in test_case_dirs { + let test_name = + test_dir.file_name().into_string().expect("Directory can't be converted to string"); + if test_name.contains('-') { + panic!( + "Invalid test directory: {test_name}. Cannot include `-`, please convert to `_`" + ); + }; + let test_dir = &test_dir.path(); + + write!( + test_file, + r#" +#[test] +fn compile_success_contract_{test_name}() {{ + let test_program_dir = PathBuf::from("{test_dir}"); + + let mut cmd = Command::cargo_bin("nargo").unwrap(); + cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); + cmd.arg("--program-dir").arg(test_program_dir); + cmd.arg("compile"); + + cmd.assert().success(); +}} + "#, + test_dir = test_dir.display(), + ) + .expect("Could not write templated test file."); + } +} + +fn generate_compile_failure_tests(test_file: &mut File, test_data_dir: &Path) { + let test_sub_dir = "compile_failure"; + let test_data_dir = test_data_dir.join(test_sub_dir); + + let test_case_dirs = + fs::read_dir(test_data_dir).unwrap().flatten().filter(|c| c.path().is_dir()); + + for test_dir in test_case_dirs { + let test_name = + test_dir.file_name().into_string().expect("Directory can't be converted to string"); + if test_name.contains('-') { + panic!( + "Invalid test directory: {test_name}. Cannot include `-`, please convert to `_`" + ); + }; + let test_dir = &test_dir.path(); + + write!( + test_file, + r#" +#[test] +fn compile_failure_{test_name}() {{ + let test_program_dir = PathBuf::from("{test_dir}"); + + let mut cmd = Command::cargo_bin("nargo").unwrap(); + cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); + cmd.arg("--program-dir").arg(test_program_dir); + cmd.arg("execute"); + + cmd.assert().failure().stderr(predicate::str::contains("The application panicked (crashed).").not()); +}} + "#, + test_dir = test_dir.display(), + ) + .expect("Could not write templated test file."); + } +} diff --git a/tooling/nargo_cli/src/backends.rs b/tooling/nargo_cli/src/backends.rs new file mode 100644 index 00000000000..8ca8305e180 --- /dev/null +++ b/tooling/nargo_cli/src/backends.rs @@ -0,0 +1,39 @@ +use std::path::PathBuf; + +use acvm_backend_barretenberg::backends_directory; +pub(crate) use acvm_backend_barretenberg::Backend; + +fn active_backend_file_path() -> PathBuf { + backends_directory().join(".selected_backend") +} + +pub(crate) const ACVM_BACKEND_BARRETENBERG: &str = "acvm-backend-barretenberg"; + +pub(crate) fn clear_active_backend() { + let active_backend_file = active_backend_file_path(); + if active_backend_file.is_file() { + std::fs::remove_file(active_backend_file_path()) + .expect("should delete active backend file"); + } +} + +pub(crate) fn set_active_backend(backend_name: &str) { + let active_backend_file = active_backend_file_path(); + let backends_directory = + active_backend_file.parent().expect("active backend file should have parent"); + + std::fs::create_dir_all(backends_directory).expect("Could not create backends directory"); + std::fs::write(active_backend_file, backend_name.as_bytes()) + .expect("Could not write to active backend file"); +} + +pub(crate) fn get_active_backend() -> String { + let active_backend_file = active_backend_file_path(); + + if !active_backend_file.is_file() { + set_active_backend(ACVM_BACKEND_BARRETENBERG); + return ACVM_BACKEND_BARRETENBERG.to_string(); + } + + std::fs::read_to_string(active_backend_file).expect("Could not read active backend file") +} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/current_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/current_cmd.rs new file mode 100644 index 00000000000..5aba00764d3 --- /dev/null +++ b/tooling/nargo_cli/src/cli/backend_cmd/current_cmd.rs @@ -0,0 +1,13 @@ +use clap::Args; + +use crate::{backends::get_active_backend, errors::CliError}; + +/// Prints the name of the currently active backend +#[derive(Debug, Clone, Args)] +pub(crate) struct CurrentCommand; + +pub(crate) fn run(_args: CurrentCommand) -> Result<(), CliError> { + println!("{}", get_active_backend()); + + Ok(()) +} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/install_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/install_cmd.rs new file mode 100644 index 00000000000..99bca29d3b7 --- /dev/null +++ b/tooling/nargo_cli/src/cli/backend_cmd/install_cmd.rs @@ -0,0 +1,30 @@ +use clap::Args; + +use acvm_backend_barretenberg::{backends_directory, download_backend}; + +use crate::errors::{BackendError, CliError}; + +use super::ls_cmd::get_available_backends; + +/// Install a new backend from a URL. +#[derive(Debug, Clone, Args)] +pub(crate) struct InstallCommand { + /// The name of the backend to install. + backend: String, + + /// The URL from which to download the backend. + url: String, +} + +pub(crate) fn run(args: InstallCommand) -> Result<(), CliError> { + let installed_backends = get_available_backends(); + + if installed_backends.contains(&args.backend) { + return Err(BackendError::AlreadyInstalled(args.backend).into()); + } + + download_backend(&args.url, &backends_directory().join(args.backend).join("backend_binary")) + .map_err(BackendError::from)?; + + Ok(()) +} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/ls_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/ls_cmd.rs new file mode 100644 index 00000000000..38ff6d3b744 --- /dev/null +++ b/tooling/nargo_cli/src/cli/backend_cmd/ls_cmd.rs @@ -0,0 +1,34 @@ +use acvm_backend_barretenberg::backends_directory; +use clap::Args; + +use crate::errors::CliError; + +/// Prints the list of currently installed backends +#[derive(Debug, Clone, Args)] +pub(crate) struct LsCommand; + +pub(crate) fn run(_args: LsCommand) -> Result<(), CliError> { + for backend in get_available_backends() { + println!("{backend}"); + } + + Ok(()) +} + +pub(super) fn get_available_backends() -> Vec { + let backend_directory_contents = std::fs::read_dir(backends_directory()) + .expect("Could not read backends directory contents"); + + // TODO: Highlight the currently active backend. + backend_directory_contents + .into_iter() + .filter_map(|entry| { + let path = entry.ok()?.path(); + if path.is_dir() { + path.file_name().map(|name| name.to_string_lossy().to_string()) + } else { + None + } + }) + .collect() +} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/mod.rs b/tooling/nargo_cli/src/cli/backend_cmd/mod.rs new file mode 100644 index 00000000000..985dbbdb934 --- /dev/null +++ b/tooling/nargo_cli/src/cli/backend_cmd/mod.rs @@ -0,0 +1,41 @@ +use clap::{Args, Subcommand}; + +use crate::errors::CliError; + +mod current_cmd; +mod install_cmd; +mod ls_cmd; +mod uninstall_cmd; +mod use_cmd; + +#[non_exhaustive] +#[derive(Args, Clone, Debug)] +/// Install and select custom backends used to generate and verify proofs. +pub(crate) struct BackendCommand { + #[command(subcommand)] + command: BackendCommands, +} + +#[non_exhaustive] +#[derive(Subcommand, Clone, Debug)] +pub(crate) enum BackendCommands { + Current(current_cmd::CurrentCommand), + Ls(ls_cmd::LsCommand), + Use(use_cmd::UseCommand), + Install(install_cmd::InstallCommand), + Uninstall(uninstall_cmd::UninstallCommand), +} + +pub(crate) fn run(cmd: BackendCommand) -> Result<(), CliError> { + let BackendCommand { command } = cmd; + + match command { + BackendCommands::Current(args) => current_cmd::run(args), + BackendCommands::Ls(args) => ls_cmd::run(args), + BackendCommands::Use(args) => use_cmd::run(args), + BackendCommands::Install(args) => install_cmd::run(args), + BackendCommands::Uninstall(args) => uninstall_cmd::run(args), + }?; + + Ok(()) +} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/uninstall_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/uninstall_cmd.rs new file mode 100644 index 00000000000..469f099de28 --- /dev/null +++ b/tooling/nargo_cli/src/cli/backend_cmd/uninstall_cmd.rs @@ -0,0 +1,59 @@ +use clap::Args; + +use acvm_backend_barretenberg::backends_directory; + +use crate::{ + backends::{ + clear_active_backend, get_active_backend, set_active_backend, ACVM_BACKEND_BARRETENBERG, + }, + errors::{BackendError, CliError}, +}; + +use super::ls_cmd::get_available_backends; + +/// Uninstalls a backend +#[derive(Debug, Clone, Args)] +pub(crate) struct UninstallCommand { + /// The name of the backend to uninstall. + backend: String, +} + +pub(crate) fn run(args: UninstallCommand) -> Result<(), CliError> { + let installed_backends = get_available_backends(); + + if !installed_backends.contains(&args.backend) { + return Err(BackendError::UnknownBackend(args.backend).into()); + } + + let active_backend = get_active_backend(); + + // Handle the case where we're uninstalling the currently active backend. + if active_backend == args.backend { + let barretenberg_is_installed = + installed_backends.iter().any(|backend_name| backend_name == ACVM_BACKEND_BARRETENBERG); + + let new_active_backend = + if args.backend != ACVM_BACKEND_BARRETENBERG && barretenberg_is_installed { + // Prefer switching to barretenberg if possible. + Some(ACVM_BACKEND_BARRETENBERG) + } else { + // Otherwise pick the first backend which isn't being uninstalled. + installed_backends + .iter() + .find(|&backend_name| backend_name != &args.backend) + .map(|name| name.as_str()) + }; + + if let Some(backend) = new_active_backend { + set_active_backend(backend); + } else { + // We've deleted the last backend. Clear the active backend file to be recreated once we install a new one. + clear_active_backend(); + } + } + + std::fs::remove_dir_all(backends_directory().join(args.backend)) + .expect("backend directory should be deleted"); + + Ok(()) +} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/use_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/use_cmd.rs new file mode 100644 index 00000000000..66a129c2148 --- /dev/null +++ b/tooling/nargo_cli/src/cli/backend_cmd/use_cmd.rs @@ -0,0 +1,26 @@ +use clap::Args; + +use crate::{ + backends::set_active_backend, + errors::{BackendError, CliError}, +}; + +use super::ls_cmd::get_available_backends; + +/// Select the backend to use +#[derive(Debug, Clone, Args)] +pub(crate) struct UseCommand { + backend: String, +} + +pub(crate) fn run(args: UseCommand) -> Result<(), CliError> { + let backends = get_available_backends(); + + if !backends.contains(&args.backend) { + return Err(BackendError::UnknownBackend(args.backend).into()); + } + + set_active_backend(&args.backend); + + Ok(()) +} diff --git a/crates/nargo_cli/src/cli/check_cmd.rs b/tooling/nargo_cli/src/cli/check_cmd.rs similarity index 94% rename from crates/nargo_cli/src/cli/check_cmd.rs rename to tooling/nargo_cli/src/cli/check_cmd.rs index b5e7b0ac604..2d3a9f6a2ba 100644 --- a/crates/nargo_cli/src/cli/check_cmd.rs +++ b/tooling/nargo_cli/src/cli/check_cmd.rs @@ -1,5 +1,6 @@ +use crate::backends::Backend; use crate::errors::{CliError, CompileError}; -use acvm::Backend; + use clap::Args; use iter_extended::btree_map; use nargo::{package::Package, prepare_package}; @@ -29,11 +30,11 @@ pub(crate) struct CheckCommand { compile_options: CompileOptions, } -pub(crate) fn run( - _backend: &B, +pub(crate) fn run( + _backend: &Backend, args: CheckCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -135,7 +136,7 @@ mod tests { typed_param( "d", AbiType::Struct { - name: String::from("MyStruct"), + path: String::from("MyStruct"), fields: vec![ (String::from("d1"), AbiType::Field), ( @@ -170,6 +171,6 @@ pub(crate) fn check_crate_and_report_errors( crate_id: CrateId, deny_warnings: bool, ) -> Result<(), CompileError> { - let result = check_crate(context, crate_id, deny_warnings).map(|warnings| ((), warnings)); - super::compile_cmd::report_errors(result, context, deny_warnings) + let result = check_crate(context, crate_id, deny_warnings); + super::compile_cmd::report_errors(result, &context.file_manager, deny_warnings) } diff --git a/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs b/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs new file mode 100644 index 00000000000..16ff311f704 --- /dev/null +++ b/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs @@ -0,0 +1,97 @@ +use std::path::PathBuf; + +use super::NargoConfig; +use super::{ + compile_cmd::compile_bin_package, + fs::{create_named_dir, program::read_program_from_file, write_to_file}, +}; +use crate::backends::Backend; +use crate::errors::CliError; + +use acvm::acir::circuit::Opcode; +use acvm::Language; +use clap::Args; +use nargo::artifacts::program::PreprocessedProgram; +use nargo::package::Package; +use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_driver::CompileOptions; +use noirc_frontend::graph::CrateName; + +// TODO(#1388): pull this from backend. +const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; + +/// Generates a Solidity verifier smart contract for the program +#[derive(Debug, Clone, Args)] +pub(crate) struct CodegenVerifierCommand { + /// The name of the package to codegen + #[clap(long, conflicts_with = "workspace")] + package: Option, + + /// Codegen all packages in the workspace + #[clap(long, conflicts_with = "package")] + workspace: bool, + + #[clap(flatten)] + compile_options: CompileOptions, +} + +pub(crate) fn run( + backend: &Backend, + args: CodegenVerifierCommand, + config: NargoConfig, +) -> Result<(), CliError> { + let toml_path = get_package_manifest(&config.program_dir)?; + let default_selection = + if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; + let selection = args.package.map_or(default_selection, PackageSelection::Selected); + let workspace = resolve_workspace_from_toml(&toml_path, selection)?; + + let (np_language, is_opcode_supported) = backend.get_backend_info()?; + for package in &workspace { + let circuit_build_path = workspace.package_build_path(package); + + let smart_contract_string = smart_contract_for_package( + backend, + package, + circuit_build_path, + &args.compile_options, + np_language, + &is_opcode_supported, + )?; + + let contract_dir = workspace.contracts_directory_path(package); + create_named_dir(&contract_dir, "contract"); + let contract_path = contract_dir.join("plonk_vk").with_extension("sol"); + + let path = write_to_file(smart_contract_string.as_bytes(), &contract_path); + println!("[{}] Contract successfully created and located at {path}", package.name); + } + + Ok(()) +} + +fn smart_contract_for_package( + backend: &Backend, + package: &Package, + circuit_build_path: PathBuf, + compile_options: &CompileOptions, + np_language: Language, + is_opcode_supported: &impl Fn(&Opcode) -> bool, +) -> Result { + let preprocessed_program = if circuit_build_path.exists() { + read_program_from_file(circuit_build_path)? + } else { + let program = + compile_bin_package(package, compile_options, np_language, &is_opcode_supported)?; + + PreprocessedProgram { + backend: String::from(BACKEND_IDENTIFIER), + abi: program.abi, + bytecode: program.circuit, + } + }; + + let smart_contract_string = backend.eth_contract(&preprocessed_program.bytecode)?; + + Ok(smart_contract_string) +} diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs new file mode 100644 index 00000000000..c769cb68ba5 --- /dev/null +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -0,0 +1,267 @@ +use std::path::Path; + +use acvm::acir::circuit::Opcode; +use acvm::Language; +use fm::FileManager; +use iter_extended::vecmap; +use nargo::artifacts::contract::PreprocessedContract; +use nargo::artifacts::contract::PreprocessedContractFunction; +use nargo::artifacts::debug::DebugArtifact; +use nargo::artifacts::program::PreprocessedProgram; +use nargo::package::Package; +use nargo::prepare_package; +use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_driver::{CompilationResult, CompileOptions, CompiledContract, CompiledProgram}; +use noirc_frontend::graph::CrateName; + +use clap::Args; + +use crate::backends::Backend; +use crate::errors::{CliError, CompileError}; + +use super::fs::program::{ + save_contract_to_file, save_debug_artifact_to_file, save_program_to_file, +}; +use super::NargoConfig; +use rayon::prelude::*; + +// TODO(#1388): pull this from backend. +const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; + +/// Compile the program and its secret execution trace into ACIR format +#[derive(Debug, Clone, Args)] +pub(crate) struct CompileCommand { + /// Include Proving and Verification keys in the build artifacts. + #[arg(long)] + include_keys: bool, + + /// Output debug files + #[arg(long, hide = true)] + output_debug: bool, + + /// The name of the package to compile + #[clap(long, conflicts_with = "workspace")] + package: Option, + + /// Compile all packages in the workspace + #[clap(long, conflicts_with = "package")] + workspace: bool, + + #[clap(flatten)] + compile_options: CompileOptions, +} + +pub(crate) fn run( + backend: &Backend, + args: CompileCommand, + config: NargoConfig, +) -> Result<(), CliError> { + let toml_path = get_package_manifest(&config.program_dir)?; + let default_selection = + if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; + let selection = args.package.map_or(default_selection, PackageSelection::Selected); + let workspace = resolve_workspace_from_toml(&toml_path, selection)?; + let circuit_dir = workspace.target_directory_path(); + + let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace + .into_iter() + .filter(|package| !package.is_library()) + .cloned() + .partition(|package| package.is_binary()); + + let (compiled_programs, compiled_contracts) = + compile_workspace(backend, &binary_packages, &contract_packages, &args.compile_options)?; + + // Save build artifacts to disk. + for (package, program) in binary_packages.into_iter().zip(compiled_programs) { + save_program(program, &package, &circuit_dir, args.output_debug); + } + for (package, contract) in contract_packages.into_iter().zip(compiled_contracts) { + save_contract(contract, &package, &circuit_dir, args.output_debug); + } + + Ok(()) +} + +pub(super) fn compile_workspace( + backend: &Backend, + binary_packages: &[Package], + contract_packages: &[Package], + compile_options: &CompileOptions, +) -> Result<(Vec, Vec), CliError> { + let (np_language, is_opcode_supported) = backend.get_backend_info()?; + + // Compile all of the packages in parallel. + let program_results: Vec<(FileManager, CompilationResult)> = binary_packages + .par_iter() + .map(|package| compile_program(package, compile_options, np_language, &is_opcode_supported)) + .collect(); + let contract_results: Vec<(FileManager, CompilationResult)> = + contract_packages + .par_iter() + .map(|package| { + compile_contract(package, compile_options, np_language, &is_opcode_supported) + }) + .collect(); + + // Report any warnings/errors which were encountered during compilation. + let compiled_programs: Vec = program_results + .into_iter() + .map(|(file_manager, compilation_result)| { + report_errors(compilation_result, &file_manager, compile_options.deny_warnings) + }) + .collect::>()?; + let compiled_contracts: Vec = contract_results + .into_iter() + .map(|(file_manager, compilation_result)| { + report_errors(compilation_result, &file_manager, compile_options.deny_warnings) + }) + .collect::>()?; + + Ok((compiled_programs, compiled_contracts)) +} + +pub(crate) fn compile_bin_package( + package: &Package, + compile_options: &CompileOptions, + np_language: Language, + is_opcode_supported: &impl Fn(&Opcode) -> bool, +) -> Result { + if package.is_library() { + return Err(CompileError::LibraryCrate(package.name.clone()).into()); + } + + let (file_manager, compilation_result) = + compile_program(package, compile_options, np_language, &is_opcode_supported); + + let program = report_errors(compilation_result, &file_manager, compile_options.deny_warnings)?; + + Ok(program) +} + +fn compile_program( + package: &Package, + compile_options: &CompileOptions, + np_language: Language, + is_opcode_supported: &impl Fn(&Opcode) -> bool, +) -> (FileManager, CompilationResult) { + let (mut context, crate_id) = prepare_package(package); + + let (program, warnings) = + match noirc_driver::compile_main(&mut context, crate_id, compile_options) { + Ok(program_and_warnings) => program_and_warnings, + Err(errors) => { + return (context.file_manager, Err(errors)); + } + }; + + // Apply backend specific optimizations. + let optimized_program = + nargo::ops::optimize_program(program, np_language, &is_opcode_supported) + .expect("Backend does not support an opcode that is in the IR"); + + (context.file_manager, Ok((optimized_program, warnings))) +} + +fn compile_contract( + package: &Package, + compile_options: &CompileOptions, + np_language: Language, + is_opcode_supported: &impl Fn(&Opcode) -> bool, +) -> (FileManager, CompilationResult) { + let (mut context, crate_id) = prepare_package(package); + let (contract, warnings) = + match noirc_driver::compile_contract(&mut context, crate_id, compile_options) { + Ok(contracts_and_warnings) => contracts_and_warnings, + Err(errors) => { + return (context.file_manager, Err(errors)); + } + }; + + let optimized_contract = + nargo::ops::optimize_contract(contract, np_language, &is_opcode_supported) + .expect("Backend does not support an opcode that is in the IR"); + + (context.file_manager, Ok((optimized_contract, warnings))) +} + +fn save_program( + program: CompiledProgram, + package: &Package, + circuit_dir: &Path, + output_debug: bool, +) { + let preprocessed_program = PreprocessedProgram { + backend: String::from(BACKEND_IDENTIFIER), + abi: program.abi, + bytecode: program.circuit, + }; + + save_program_to_file(&preprocessed_program, &package.name, circuit_dir); + + if output_debug { + let debug_artifact = + DebugArtifact { debug_symbols: vec![program.debug], file_map: program.file_map }; + let circuit_name: String = (&package.name).into(); + save_debug_artifact_to_file(&debug_artifact, &circuit_name, circuit_dir); + } +} + +fn save_contract( + contract: CompiledContract, + package: &Package, + circuit_dir: &Path, + output_debug: bool, +) { + // TODO(#1389): I wonder if it is incorrect for nargo-core to know anything about contracts. + // As can be seen here, It seems like a leaky abstraction where ContractFunctions (essentially CompiledPrograms) + // are compiled via nargo-core and then the PreprocessedContract is constructed here. + // This is due to EACH function needing it's own CRS, PKey, and VKey from the backend. + let debug_artifact = DebugArtifact { + debug_symbols: contract.functions.iter().map(|function| function.debug.clone()).collect(), + file_map: contract.file_map, + }; + + let preprocessed_functions = vecmap(contract.functions, |func| PreprocessedContractFunction { + name: func.name, + function_type: func.function_type, + is_internal: func.is_internal, + abi: func.abi, + bytecode: func.bytecode, + }); + + let preprocessed_contract = PreprocessedContract { + name: contract.name, + backend: String::from(BACKEND_IDENTIFIER), + functions: preprocessed_functions, + }; + + save_contract_to_file( + &preprocessed_contract, + &format!("{}-{}", package.name, preprocessed_contract.name), + circuit_dir, + ); + + if output_debug { + save_debug_artifact_to_file( + &debug_artifact, + &format!("{}-{}", package.name, preprocessed_contract.name), + circuit_dir, + ); + } +} + +/// Helper function for reporting any errors in a `CompilationResult` +/// structure that is commonly used as a return result in this file. +pub(crate) fn report_errors( + result: CompilationResult, + file_manager: &FileManager, + deny_warnings: bool, +) -> Result { + let (t, warnings) = result.map_err(|errors| { + noirc_errors::reporter::report_all(file_manager.as_file_map(), &errors, deny_warnings) + })?; + + noirc_errors::reporter::report_all(file_manager.as_file_map(), &warnings, deny_warnings); + Ok(t) +} diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs new file mode 100644 index 00000000000..8c434f8fe21 --- /dev/null +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -0,0 +1,210 @@ +use acvm::acir::circuit::OpcodeLocation; +use acvm::acir::{circuit::Circuit, native_types::WitnessMap}; +use acvm::pwg::{ErrorLocation, OpcodeResolutionError}; +use clap::Args; + +use nargo::artifacts::debug::DebugArtifact; +use nargo::constants::PROVER_INPUT_FILE; +use nargo::errors::{ExecutionError, NargoError}; +use nargo::package::Package; +use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_abi::input_parser::{Format, InputValue}; +use noirc_abi::{Abi, InputMap}; +use noirc_driver::{CompileOptions, CompiledProgram}; +use noirc_errors::CustomDiagnostic; +use noirc_frontend::graph::CrateName; + +use super::compile_cmd::compile_bin_package; +use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir}; +use super::NargoConfig; +use crate::backends::Backend; +use crate::errors::CliError; + +/// Executes a circuit to calculate its return value +#[derive(Debug, Clone, Args)] +pub(crate) struct ExecuteCommand { + /// Write the execution witness to named file + witness_name: Option, + + /// The name of the toml file which contains the inputs for the prover + #[clap(long, short, default_value = PROVER_INPUT_FILE)] + prover_name: String, + + /// The name of the package to execute + #[clap(long, conflicts_with = "workspace")] + package: Option, + + /// Execute all packages in the workspace + #[clap(long, conflicts_with = "package")] + workspace: bool, + + #[clap(flatten)] + compile_options: CompileOptions, +} + +pub(crate) fn run( + backend: &Backend, + args: ExecuteCommand, + config: NargoConfig, +) -> Result<(), CliError> { + let toml_path = get_package_manifest(&config.program_dir)?; + let default_selection = + if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; + let selection = args.package.map_or(default_selection, PackageSelection::Selected); + let workspace = resolve_workspace_from_toml(&toml_path, selection)?; + let target_dir = &workspace.target_directory_path(); + + let (np_language, is_opcode_supported) = backend.get_backend_info()?; + for package in &workspace { + let compiled_program = + compile_bin_package(package, &args.compile_options, np_language, &is_opcode_supported)?; + + let (return_value, solved_witness) = + execute_program_and_decode(compiled_program, package, &args.prover_name)?; + + println!("[{}] Circuit witness successfully solved", package.name); + if let Some(return_value) = return_value { + println!("[{}] Circuit output: {return_value:?}", package.name); + } + if let Some(witness_name) = &args.witness_name { + let witness_path = save_witness_to_dir(solved_witness, witness_name, target_dir)?; + + println!("[{}] Witness saved to {}", package.name, witness_path.display()); + } + } + Ok(()) +} + +fn execute_program_and_decode( + program: CompiledProgram, + package: &Package, + prover_name: &str, +) -> Result<(Option, WitnessMap), CliError> { + let CompiledProgram { abi, circuit, debug, file_map } = program; + let debug_artifact = DebugArtifact { debug_symbols: vec![debug], file_map }; + + // Parse the initial witness values from Prover.toml + let (inputs_map, _) = + read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &abi)?; + let solved_witness = execute_program(circuit, &abi, &inputs_map, Some(debug_artifact))?; + let public_abi = abi.public_abi(); + let (_, return_value) = public_abi.decode(&solved_witness)?; + + Ok((return_value, solved_witness)) +} + +/// There are certain errors that contain an [acvm::pwg::ErrorLocation]. +/// We need to determine whether the error location has been resolving during execution. +/// If the location has been resolved we return the contained [OpcodeLocation]. +fn extract_opcode_error_from_nargo_error( + nargo_err: &NargoError, +) -> Option<(Vec, &ExecutionError)> { + let execution_error = match nargo_err { + NargoError::ExecutionError(err) => err, + _ => return None, + }; + + match execution_error { + ExecutionError::SolvingError(OpcodeResolutionError::BrilligFunctionFailed { + call_stack, + .. + }) + | ExecutionError::AssertionFailed(_, call_stack) => { + Some((call_stack.clone(), execution_error)) + } + ExecutionError::SolvingError(OpcodeResolutionError::IndexOutOfBounds { + opcode_location: error_location, + .. + }) + | ExecutionError::SolvingError(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: error_location, + }) => match error_location { + ErrorLocation::Unresolved => { + unreachable!("Cannot resolve index for unsatisfied constraint") + } + ErrorLocation::Resolved(opcode_location) => { + Some((vec![*opcode_location], execution_error)) + } + }, + _ => None, + } +} + +/// Resolve the vector of [OpcodeLocation] that caused an execution error using the debug information +/// generated during compilation to determine the complete call stack for an error. Then report the error using +/// the resolved call stack and any other relevant error information returned from the ACVM. +fn report_error_with_opcode_locations( + opcode_err_info: Option<(Vec, &ExecutionError)>, + debug_artifact: &DebugArtifact, +) { + if let Some((opcode_locations, opcode_err)) = opcode_err_info { + let source_locations: Vec<_> = opcode_locations + .iter() + .flat_map(|opcode_location| { + // This assumes that we're executing the circuit which corresponds to the first `DebugInfo`. + // This holds for all binary crates as there is only one `DebugInfo`. + assert_eq!(debug_artifact.debug_symbols.len(), 1); + let locations = debug_artifact.debug_symbols[0].opcode_location(opcode_location); + locations.unwrap_or_default() + }) + .collect(); + // The location of the error itself will be the location at the top + // of the call stack (the last item in the Vec). + if let Some(location) = source_locations.last() { + let message = match opcode_err { + ExecutionError::AssertionFailed(message, _) => { + format!("Assertion failed: '{message}'") + } + ExecutionError::SolvingError(OpcodeResolutionError::IndexOutOfBounds { + index, + array_size, + .. + }) => { + format!( + "Index out of bounds, array has size {array_size:?}, but index was {index:?}" + ) + } + ExecutionError::SolvingError(OpcodeResolutionError::UnsatisfiedConstrain { + .. + }) => "Failed constraint".into(), + _ => { + // All other errors that do not have corresponding opcode locations + // should not be reported in this method. + // If an error with an opcode location is not handled in this match statement + // the basic message attached to the original error from the ACVM should be reported. + return; + } + }; + CustomDiagnostic::simple_error(message, String::new(), location.span) + .in_file(location.file) + .with_call_stack(source_locations) + .report(debug_artifact, false); + } + } +} + +pub(crate) fn execute_program( + circuit: Circuit, + abi: &Abi, + inputs_map: &InputMap, + debug_data: Option, +) -> Result { + #[allow(deprecated)] + let blackbox_solver = acvm::blackbox_solver::BarretenbergSolver::new(); + + let initial_witness = abi.encode(inputs_map, None)?; + + let solved_witness_err = + nargo::ops::execute_circuit(&blackbox_solver, circuit, initial_witness, true); + match solved_witness_err { + Ok(solved_witness) => Ok(solved_witness), + Err(err) => { + if let Some(debug_data) = debug_data { + let opcode_err_info = extract_opcode_error_from_nargo_error(&err); + report_error_with_opcode_locations(opcode_err_info, &debug_data); + } + + Err(crate::errors::CliError::NargoError(err)) + } + } +} diff --git a/crates/nargo_cli/src/cli/fs/inputs.rs b/tooling/nargo_cli/src/cli/fs/inputs.rs similarity index 97% rename from crates/nargo_cli/src/cli/fs/inputs.rs rename to tooling/nargo_cli/src/cli/fs/inputs.rs index fd2afdefa12..f3f0baf10f4 100644 --- a/crates/nargo_cli/src/cli/fs/inputs.rs +++ b/tooling/nargo_cli/src/cli/fs/inputs.rs @@ -75,13 +75,13 @@ mod tests { input_parser::{Format, InputValue}, Abi, AbiParameter, AbiType, AbiVisibility, }; - use tempdir::TempDir; + use tempfile::TempDir; use super::{read_inputs_from_file, write_inputs_to_file}; #[test] fn write_and_read_recovers_inputs_and_return_value() { - let input_dir = TempDir::new("input_dir").unwrap().into_path(); + let input_dir = TempDir::new().unwrap().into_path(); // We purposefully test a simple ABI here as we're focussing on `fs`. // Tests for serializing complex types should exist in `noirc_abi`. diff --git a/tooling/nargo_cli/src/cli/fs/mod.rs b/tooling/nargo_cli/src/cli/fs/mod.rs new file mode 100644 index 00000000000..4ebce3b3325 --- /dev/null +++ b/tooling/nargo_cli/src/cli/fs/mod.rs @@ -0,0 +1,42 @@ +use std::{ + fs::File, + io::Write, + path::{Path, PathBuf}, +}; + +use crate::errors::FilesystemError; + +pub(super) mod inputs; +pub(super) mod program; +pub(super) mod proof; +pub(super) mod witness; + +pub(super) fn create_named_dir(named_dir: &Path, name: &str) -> PathBuf { + std::fs::create_dir_all(named_dir) + .unwrap_or_else(|_| panic!("could not create the `{name}` directory")); + + PathBuf::from(named_dir) +} + +pub(super) fn write_to_file(bytes: &[u8], path: &Path) -> String { + let display = path.display(); + + let mut file = match File::create(path) { + Err(why) => panic!("couldn't create {display}: {why}"), + Ok(file) => file, + }; + + match file.write_all(bytes) { + Err(why) => panic!("couldn't write to {display}: {why}"), + Ok(_) => display.to_string(), + } +} + +pub(super) fn load_hex_data>(path: P) -> Result, FilesystemError> { + let hex_data: Vec<_> = std::fs::read(&path) + .map_err(|_| FilesystemError::PathNotValid(path.as_ref().to_path_buf()))?; + + let raw_bytes = hex::decode(hex_data).map_err(FilesystemError::HexArtifactNotValid)?; + + Ok(raw_bytes) +} diff --git a/tooling/nargo_cli/src/cli/fs/program.rs b/tooling/nargo_cli/src/cli/fs/program.rs new file mode 100644 index 00000000000..ac5e6c5c32f --- /dev/null +++ b/tooling/nargo_cli/src/cli/fs/program.rs @@ -0,0 +1,62 @@ +use std::path::{Path, PathBuf}; + +use nargo::artifacts::{ + contract::PreprocessedContract, debug::DebugArtifact, program::PreprocessedProgram, +}; +use noirc_frontend::graph::CrateName; + +use crate::errors::FilesystemError; + +use super::{create_named_dir, write_to_file}; + +pub(crate) fn save_program_to_file>( + compiled_program: &PreprocessedProgram, + crate_name: &CrateName, + circuit_dir: P, +) -> PathBuf { + let circuit_name: String = crate_name.into(); + save_build_artifact_to_file(compiled_program, &circuit_name, circuit_dir) +} + +pub(crate) fn save_contract_to_file>( + compiled_contract: &PreprocessedContract, + circuit_name: &str, + circuit_dir: P, +) -> PathBuf { + save_build_artifact_to_file(compiled_contract, circuit_name, circuit_dir) +} + +pub(crate) fn save_debug_artifact_to_file>( + debug_artifact: &DebugArtifact, + circuit_name: &str, + circuit_dir: P, +) -> PathBuf { + let artifact_name = format!("debug_{circuit_name}"); + save_build_artifact_to_file(debug_artifact, &artifact_name, circuit_dir) +} + +fn save_build_artifact_to_file, T: ?Sized + serde::Serialize>( + build_artifact: &T, + artifact_name: &str, + circuit_dir: P, +) -> PathBuf { + create_named_dir(circuit_dir.as_ref(), "target"); + let circuit_path = circuit_dir.as_ref().join(artifact_name).with_extension("json"); + + write_to_file(&serde_json::to_vec(build_artifact).unwrap(), &circuit_path); + + circuit_path +} + +pub(crate) fn read_program_from_file>( + circuit_path: P, +) -> Result { + let file_path = circuit_path.as_ref().with_extension("json"); + + let input_string = + std::fs::read(&file_path).map_err(|_| FilesystemError::PathNotValid(file_path))?; + + let program = serde_json::from_slice(&input_string).expect("could not deserialize program"); + + Ok(program) +} diff --git a/crates/nargo_cli/src/cli/fs/proof.rs b/tooling/nargo_cli/src/cli/fs/proof.rs similarity index 100% rename from crates/nargo_cli/src/cli/fs/proof.rs rename to tooling/nargo_cli/src/cli/fs/proof.rs diff --git a/crates/nargo_cli/src/cli/fs/witness.rs b/tooling/nargo_cli/src/cli/fs/witness.rs similarity index 100% rename from crates/nargo_cli/src/cli/fs/witness.rs rename to tooling/nargo_cli/src/cli/fs/witness.rs diff --git a/tooling/nargo_cli/src/cli/info_cmd.rs b/tooling/nargo_cli/src/cli/info_cmd.rs new file mode 100644 index 00000000000..ffa522d25b4 --- /dev/null +++ b/tooling/nargo_cli/src/cli/info_cmd.rs @@ -0,0 +1,199 @@ +use acvm::Language; +use acvm_backend_barretenberg::BackendError; +use clap::Args; +use iter_extended::vecmap; +use nargo::package::Package; +use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_driver::{CompileOptions, CompiledContract, CompiledProgram}; +use noirc_frontend::graph::CrateName; +use prettytable::{row, table, Row}; +use rayon::prelude::*; +use serde::Serialize; + +use crate::backends::Backend; +use crate::errors::CliError; + +use super::{compile_cmd::compile_workspace, NargoConfig}; + +/// Provides detailed information on a circuit +/// +/// Current information provided: +/// 1. The number of ACIR opcodes +/// 2. Counts the final number gates in the circuit used by a backend +#[derive(Debug, Clone, Args)] +pub(crate) struct InfoCommand { + /// The name of the package to detail + #[clap(long, conflicts_with = "workspace")] + package: Option, + + /// Detail all packages in the workspace + #[clap(long, conflicts_with = "package")] + workspace: bool, + + /// Output a JSON formatted report. Changes to this format are not currently considered breaking. + #[clap(long, hide = true)] + json: bool, + + #[clap(flatten)] + compile_options: CompileOptions, +} + +pub(crate) fn run( + backend: &Backend, + args: InfoCommand, + config: NargoConfig, +) -> Result<(), CliError> { + let toml_path = get_package_manifest(&config.program_dir)?; + let default_selection = + if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; + let selection = args.package.map_or(default_selection, PackageSelection::Selected); + let workspace = resolve_workspace_from_toml(&toml_path, selection)?; + + let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace + .into_iter() + .filter(|package| !package.is_library()) + .cloned() + .partition(|package| package.is_binary()); + + let (compiled_programs, compiled_contracts) = + compile_workspace(backend, &binary_packages, &contract_packages, &args.compile_options)?; + + let (np_language, _) = backend.get_backend_info()?; + let program_info = binary_packages + .into_par_iter() + .zip(compiled_programs) + .map(|(package, program)| { + count_opcodes_and_gates_in_program(backend, program, &package, np_language) + }) + .collect::>()?; + + let contract_info = compiled_contracts + .into_par_iter() + .map(|contract| count_opcodes_and_gates_in_contract(backend, contract, np_language)) + .collect::>()?; + + let info_report = InfoReport { programs: program_info, contracts: contract_info }; + + if args.json { + // Expose machine-readable JSON data. + println!("{}", serde_json::to_string(&info_report).unwrap()); + } else { + // Otherwise print human-readable table. + if !info_report.programs.is_empty() { + let mut program_table = table!([Fm->"Package", Fm->"Language", Fm->"ACIR Opcodes", Fm->"Backend Circuit Size"]); + + for program in info_report.programs { + program_table.add_row(program.into()); + } + program_table.printstd(); + } + if !info_report.contracts.is_empty() { + let mut contract_table = table!([ + Fm->"Contract", + Fm->"Function", + Fm->"Language", + Fm->"ACIR Opcodes", + Fm->"Backend Circuit Size" + ]); + for contract_info in info_report.contracts { + let contract_rows: Vec = contract_info.into(); + for row in contract_rows { + contract_table.add_row(row); + } + } + + contract_table.printstd(); + } + } + + Ok(()) +} + +#[derive(Debug, Default, Serialize)] +struct InfoReport { + programs: Vec, + contracts: Vec, +} + +#[derive(Debug, Serialize)] +struct ProgramInfo { + name: String, + #[serde(skip)] + language: Language, + acir_opcodes: usize, + circuit_size: u32, +} + +impl From for Row { + fn from(program_info: ProgramInfo) -> Self { + row![ + Fm->format!("{}", program_info.name), + format!("{:?}", program_info.language), + Fc->format!("{}", program_info.acir_opcodes), + Fc->format!("{}", program_info.circuit_size), + ] + } +} + +#[derive(Debug, Serialize)] +struct ContractInfo { + name: String, + #[serde(skip)] + language: Language, + functions: Vec, +} + +#[derive(Debug, Serialize)] +struct FunctionInfo { + name: String, + acir_opcodes: usize, + circuit_size: u32, +} + +impl From for Vec { + fn from(contract_info: ContractInfo) -> Self { + vecmap(contract_info.functions, |function| { + row![ + Fm->format!("{}", contract_info.name), + Fc->format!("{}", function.name), + format!("{:?}", contract_info.language), + Fc->format!("{}", function.acir_opcodes), + Fc->format!("{}", function.circuit_size), + ] + }) + } +} + +fn count_opcodes_and_gates_in_program( + backend: &Backend, + compiled_program: CompiledProgram, + package: &Package, + language: Language, +) -> Result { + Ok(ProgramInfo { + name: package.name.to_string(), + language, + acir_opcodes: compiled_program.circuit.opcodes.len(), + circuit_size: backend.get_exact_circuit_size(&compiled_program.circuit)?, + }) +} + +fn count_opcodes_and_gates_in_contract( + backend: &Backend, + contract: CompiledContract, + language: Language, +) -> Result { + let functions = contract + .functions + .into_par_iter() + .map(|function| -> Result<_, BackendError> { + Ok(FunctionInfo { + name: function.name, + acir_opcodes: function.bytecode.opcodes.len(), + circuit_size: backend.get_exact_circuit_size(&function.bytecode)?, + }) + }) + .collect::>()?; + + Ok(ContractInfo { name: contract.name, language, functions }) +} diff --git a/crates/nargo_cli/src/cli/init_cmd.rs b/tooling/nargo_cli/src/cli/init_cmd.rs similarity index 97% rename from crates/nargo_cli/src/cli/init_cmd.rs rename to tooling/nargo_cli/src/cli/init_cmd.rs index e6020e3cfd9..2091ac89f9c 100644 --- a/crates/nargo_cli/src/cli/init_cmd.rs +++ b/tooling/nargo_cli/src/cli/init_cmd.rs @@ -1,8 +1,8 @@ +use crate::backends::Backend; use crate::errors::CliError; use super::fs::{create_named_dir, write_to_file}; use super::{NargoConfig, CARGO_PKG_VERSION}; -use acvm::Backend; use clap::Args; use nargo::constants::{PKG_FILE, SRC_DIR}; use nargo::package::PackageType; @@ -62,12 +62,12 @@ fn test_my_util() { } "#; -pub(crate) fn run( +pub(crate) fn run( // Backend is currently unused, but we might want to use it to inform the "new" template in the future - _backend: &B, + _backend: &Backend, args: InitCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let package_name = match args.name { Some(name) => name, None => { diff --git a/crates/nargo_cli/src/cli/lsp_cmd.rs b/tooling/nargo_cli/src/cli/lsp_cmd.rs similarity index 95% rename from crates/nargo_cli/src/cli/lsp_cmd.rs rename to tooling/nargo_cli/src/cli/lsp_cmd.rs index ac15f4f8a9f..7350c5c3099 100644 --- a/crates/nargo_cli/src/cli/lsp_cmd.rs +++ b/tooling/nargo_cli/src/cli/lsp_cmd.rs @@ -1,4 +1,3 @@ -use acvm::Backend; use async_lsp::{ client_monitor::ClientProcessMonitorLayer, concurrency::ConcurrencyLayer, panic::CatchUnwindLayer, server::LifecycleLayer, tracing::TracingLayer, @@ -8,6 +7,7 @@ use noir_lsp::NargoLspService; use tower::ServiceBuilder; use super::NargoConfig; +use crate::backends::Backend; use crate::errors::CliError; /// Starts the Noir LSP server @@ -18,12 +18,12 @@ use crate::errors::CliError; #[derive(Debug, Clone, Args)] pub(crate) struct LspCommand; -pub(crate) fn run( +pub(crate) fn run( // Backend is currently unused, but we might want to use it to inform the lsp in the future - _backend: &B, + _backend: &Backend, _args: LspCommand, _config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { use tokio::runtime::Builder; let runtime = Builder::new_current_thread().enable_all().build().unwrap(); diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs new file mode 100644 index 00000000000..56d36095518 --- /dev/null +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -0,0 +1,106 @@ +use clap::{Args, Parser, Subcommand}; +use const_format::formatcp; +use nargo_toml::find_package_root; +use std::path::PathBuf; + +use color_eyre::eyre; + +use crate::backends::get_active_backend; + +mod fs; + +mod backend_cmd; +mod check_cmd; +mod codegen_verifier_cmd; +mod compile_cmd; +mod execute_cmd; +mod info_cmd; +mod init_cmd; +mod lsp_cmd; +mod new_cmd; +mod prove_cmd; +mod test_cmd; +mod verify_cmd; + +const GIT_HASH: &str = env!("GIT_COMMIT"); +const IS_DIRTY: &str = env!("GIT_DIRTY"); +const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); + +static VERSION_STRING: &str = + formatcp!("{} (git version hash: {}, is dirty: {})", CARGO_PKG_VERSION, GIT_HASH, IS_DIRTY); + +#[derive(Parser, Debug)] +#[command(name="nargo", author, version=VERSION_STRING, about, long_about = None)] +struct NargoCli { + #[command(subcommand)] + command: NargoCommand, + + #[clap(flatten)] + config: NargoConfig, +} + +#[non_exhaustive] +#[derive(Args, Clone, Debug)] +pub(crate) struct NargoConfig { + // REMINDER: Also change this flag in the LSP test lens if renamed + #[arg(long, hide = true, global = true, default_value = "./")] + program_dir: PathBuf, +} + +#[non_exhaustive] +#[derive(Subcommand, Clone, Debug)] +enum NargoCommand { + Backend(backend_cmd::BackendCommand), + Check(check_cmd::CheckCommand), + CodegenVerifier(codegen_verifier_cmd::CodegenVerifierCommand), + #[command(alias = "build")] + Compile(compile_cmd::CompileCommand), + New(new_cmd::NewCommand), + Init(init_cmd::InitCommand), + Execute(execute_cmd::ExecuteCommand), + Prove(prove_cmd::ProveCommand), + Verify(verify_cmd::VerifyCommand), + Test(test_cmd::TestCommand), + Info(info_cmd::InfoCommand), + Lsp(lsp_cmd::LspCommand), +} + +pub(crate) fn start_cli() -> eyre::Result<()> { + let NargoCli { command, mut config } = NargoCli::parse(); + + // If the provided `program_dir` is relative, make it absolute by joining it to the current directory. + if !config.program_dir.is_absolute() { + config.program_dir = std::env::current_dir().unwrap().join(config.program_dir); + } + + // Search through parent directories to find package root if necessary. + if !matches!( + command, + NargoCommand::New(_) + | NargoCommand::Init(_) + | NargoCommand::Lsp(_) + | NargoCommand::Backend(_) + ) { + config.program_dir = find_package_root(&config.program_dir)?; + } + + let active_backend = get_active_backend(); + let backend = crate::backends::Backend::new(active_backend); + + match command { + NargoCommand::New(args) => new_cmd::run(&backend, args, config), + NargoCommand::Init(args) => init_cmd::run(&backend, args, config), + NargoCommand::Check(args) => check_cmd::run(&backend, args, config), + NargoCommand::Compile(args) => compile_cmd::run(&backend, args, config), + NargoCommand::Execute(args) => execute_cmd::run(&backend, args, config), + NargoCommand::Prove(args) => prove_cmd::run(&backend, args, config), + NargoCommand::Verify(args) => verify_cmd::run(&backend, args, config), + NargoCommand::Test(args) => test_cmd::run(&backend, args, config), + NargoCommand::Info(args) => info_cmd::run(&backend, args, config), + NargoCommand::CodegenVerifier(args) => codegen_verifier_cmd::run(&backend, args, config), + NargoCommand::Backend(args) => backend_cmd::run(args), + NargoCommand::Lsp(args) => lsp_cmd::run(&backend, args, config), + }?; + + Ok(()) +} diff --git a/crates/nargo_cli/src/cli/new_cmd.rs b/tooling/nargo_cli/src/cli/new_cmd.rs similarity index 94% rename from crates/nargo_cli/src/cli/new_cmd.rs rename to tooling/nargo_cli/src/cli/new_cmd.rs index d6a9d00257b..b4c823d0c1e 100644 --- a/crates/nargo_cli/src/cli/new_cmd.rs +++ b/tooling/nargo_cli/src/cli/new_cmd.rs @@ -1,7 +1,7 @@ +use crate::backends::Backend; use crate::errors::CliError; use super::{init_cmd::initialize_project, NargoConfig}; -use acvm::Backend; use clap::Args; use nargo::package::PackageType; use noirc_frontend::graph::CrateName; @@ -30,12 +30,12 @@ pub(crate) struct NewCommand { pub(crate) contract: bool, } -pub(crate) fn run( +pub(crate) fn run( // Backend is currently unused, but we might want to use it to inform the "new" template in the future - _backend: &B, + _backend: &Backend, args: NewCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let package_dir = config.program_dir.join(&args.path); if package_dir.exists() { diff --git a/tooling/nargo_cli/src/cli/prove_cmd.rs b/tooling/nargo_cli/src/cli/prove_cmd.rs new file mode 100644 index 00000000000..03146d3919c --- /dev/null +++ b/tooling/nargo_cli/src/cli/prove_cmd.rs @@ -0,0 +1,153 @@ +use std::path::{Path, PathBuf}; + +use acvm::acir::circuit::Opcode; +use acvm::Language; +use clap::Args; +use nargo::artifacts::debug::DebugArtifact; +use nargo::artifacts::program::PreprocessedProgram; +use nargo::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE}; +use nargo::package::Package; +use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_abi::input_parser::Format; +use noirc_driver::CompileOptions; +use noirc_frontend::graph::CrateName; + +use super::compile_cmd::compile_bin_package; +use super::fs::{ + inputs::{read_inputs_from_file, write_inputs_to_file}, + program::read_program_from_file, + proof::save_proof_to_dir, +}; +use super::NargoConfig; +use crate::{backends::Backend, cli::execute_cmd::execute_program, errors::CliError}; + +// TODO(#1388): pull this from backend. +const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; + +/// Create proof for this program. The proof is returned as a hex encoded string. +#[derive(Debug, Clone, Args)] +pub(crate) struct ProveCommand { + /// The name of the toml file which contains the inputs for the prover + #[clap(long, short, default_value = PROVER_INPUT_FILE)] + prover_name: String, + + /// The name of the toml file which contains the inputs for the verifier + #[clap(long, short, default_value = VERIFIER_INPUT_FILE)] + verifier_name: String, + + /// Verify proof after proving + #[arg(long)] + verify: bool, + + /// The name of the package to prove + #[clap(long, conflicts_with = "workspace")] + package: Option, + + /// Prove all packages in the workspace + #[clap(long, conflicts_with = "package")] + workspace: bool, + + #[clap(flatten)] + compile_options: CompileOptions, +} + +pub(crate) fn run( + backend: &Backend, + args: ProveCommand, + config: NargoConfig, +) -> Result<(), CliError> { + let toml_path = get_package_manifest(&config.program_dir)?; + let default_selection = + if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; + let selection = args.package.map_or(default_selection, PackageSelection::Selected); + let workspace = resolve_workspace_from_toml(&toml_path, selection)?; + let proof_dir = workspace.proofs_directory_path(); + + let (np_language, is_opcode_supported) = backend.get_backend_info()?; + for package in &workspace { + let circuit_build_path = workspace.package_build_path(package); + + prove_package( + backend, + package, + &args.prover_name, + &args.verifier_name, + &proof_dir, + circuit_build_path, + args.verify, + &args.compile_options, + np_language, + &is_opcode_supported, + )?; + } + + Ok(()) +} + +#[allow(clippy::too_many_arguments)] +pub(crate) fn prove_package( + backend: &Backend, + package: &Package, + prover_name: &str, + verifier_name: &str, + proof_dir: &Path, + circuit_build_path: PathBuf, + check_proof: bool, + compile_options: &CompileOptions, + np_language: Language, + is_opcode_supported: &impl Fn(&Opcode) -> bool, +) -> Result<(), CliError> { + let (preprocessed_program, debug_data) = if circuit_build_path.exists() { + let program = read_program_from_file(circuit_build_path)?; + + (program, None) + } else { + let program = + compile_bin_package(package, compile_options, np_language, &is_opcode_supported)?; + let preprocessed_program = PreprocessedProgram { + backend: String::from(BACKEND_IDENTIFIER), + abi: program.abi, + bytecode: program.circuit, + }; + let debug_artifact = + DebugArtifact { debug_symbols: vec![program.debug], file_map: program.file_map }; + + (preprocessed_program, Some(debug_artifact)) + }; + + let PreprocessedProgram { abi, bytecode, .. } = preprocessed_program; + + // Parse the initial witness values from Prover.toml + let (inputs_map, _) = + read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &abi)?; + + let solved_witness = execute_program(bytecode.clone(), &abi, &inputs_map, debug_data)?; + + // Write public inputs into Verifier.toml + let public_abi = abi.public_abi(); + let (public_inputs, return_value) = public_abi.decode(&solved_witness)?; + + write_inputs_to_file( + &public_inputs, + &return_value, + &public_abi, + &package.root_dir, + verifier_name, + Format::Toml, + )?; + + let proof = backend.prove(&bytecode, solved_witness, false)?; + + if check_proof { + let public_inputs = public_abi.encode(&public_inputs, return_value)?; + let valid_proof = backend.verify(&proof, public_inputs, &bytecode, false)?; + + if !valid_proof { + return Err(CliError::InvalidProof("".into())); + } + } + + save_proof_to_dir(&proof, &String::from(&package.name), proof_dir)?; + + Ok(()) +} diff --git a/tooling/nargo_cli/src/cli/test_cmd.rs b/tooling/nargo_cli/src/cli/test_cmd.rs new file mode 100644 index 00000000000..78e3b4c16a0 --- /dev/null +++ b/tooling/nargo_cli/src/cli/test_cmd.rs @@ -0,0 +1,141 @@ +use std::io::Write; + +use acvm::BlackBoxFunctionSolver; +use clap::Args; +use nargo::{ + ops::{run_test, TestStatus}, + package::Package, + prepare_package, +}; +use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_driver::CompileOptions; +use noirc_frontend::{graph::CrateName, hir::FunctionNameMatch}; +use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; + +use crate::{backends::Backend, cli::check_cmd::check_crate_and_report_errors, errors::CliError}; + +use super::NargoConfig; + +/// Run the tests for this program +#[derive(Debug, Clone, Args)] +pub(crate) struct TestCommand { + /// If given, only tests with names containing this string will be run + test_name: Option, + + /// Display output of `println` statements + #[arg(long)] + show_output: bool, + + /// Only run tests that match exactly + #[clap(long)] + exact: bool, + + /// The name of the package to test + #[clap(long, conflicts_with = "workspace")] + package: Option, + + /// Test all packages in the workspace + #[clap(long, conflicts_with = "package")] + workspace: bool, + + #[clap(flatten)] + compile_options: CompileOptions, +} + +pub(crate) fn run( + _backend: &Backend, + args: TestCommand, + config: NargoConfig, +) -> Result<(), CliError> { + let toml_path = get_package_manifest(&config.program_dir)?; + let default_selection = + if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; + let selection = args.package.map_or(default_selection, PackageSelection::Selected); + let workspace = resolve_workspace_from_toml(&toml_path, selection)?; + + let pattern = match &args.test_name { + Some(name) => { + if args.exact { + FunctionNameMatch::Exact(name) + } else { + FunctionNameMatch::Contains(name) + } + } + None => FunctionNameMatch::Anything, + }; + + #[allow(deprecated)] + let blackbox_solver = acvm::blackbox_solver::BarretenbergSolver::new(); + for package in &workspace { + // By unwrapping here with `?`, we stop the test runner upon a package failing + // TODO: We should run the whole suite even if there are failures in a package + run_tests(&blackbox_solver, package, pattern, args.show_output, &args.compile_options)?; + } + + Ok(()) +} + +fn run_tests( + blackbox_solver: &S, + package: &Package, + test_name: FunctionNameMatch, + show_output: bool, + compile_options: &CompileOptions, +) -> Result<(), CliError> { + let (mut context, crate_id) = prepare_package(package); + check_crate_and_report_errors(&mut context, crate_id, compile_options.deny_warnings)?; + + let test_functions = context.get_all_test_functions_in_crate_matching(&crate_id, test_name); + + println!("[{}] Running {} test functions", package.name, test_functions.len()); + let mut failing = 0; + + let writer = StandardStream::stderr(ColorChoice::Always); + let mut writer = writer.lock(); + + for (test_name, test_function) in test_functions { + write!(writer, "[{}] Testing {test_name}... ", package.name) + .expect("Failed to write to stdout"); + writer.flush().expect("Failed to flush writer"); + + match run_test(blackbox_solver, &context, test_function, show_output, compile_options) { + TestStatus::Pass { .. } => { + writer + .set_color(ColorSpec::new().set_fg(Some(Color::Green))) + .expect("Failed to set color"); + writeln!(writer, "ok").expect("Failed to write to stdout"); + } + TestStatus::Fail { message } => { + let writer = StandardStream::stderr(ColorChoice::Always); + let mut writer = writer.lock(); + writer + .set_color(ColorSpec::new().set_fg(Some(Color::Red))) + .expect("Failed to set color"); + writeln!(writer, "{message}").expect("Failed to write to stdout"); + writer.reset().expect("Failed to reset writer"); + failing += 1; + } + TestStatus::CompileError(err) => { + noirc_errors::reporter::report_all( + context.file_manager.as_file_map(), + &[err], + compile_options.deny_warnings, + ); + failing += 1; + } + } + writer.reset().expect("Failed to reset writer"); + } + + if failing == 0 { + write!(writer, "[{}] ", package.name).expect("Failed to write to stdout"); + writer.set_color(ColorSpec::new().set_fg(Some(Color::Green))).expect("Failed to set color"); + writeln!(writer, "All tests passed").expect("Failed to write to stdout"); + } else { + let plural = if failing == 1 { "" } else { "s" }; + return Err(CliError::Generic(format!("[{}] {failing} test{plural} failed", package.name))); + } + + writer.reset().expect("Failed to reset writer"); + Ok(()) +} diff --git a/tooling/nargo_cli/src/cli/verify_cmd.rs b/tooling/nargo_cli/src/cli/verify_cmd.rs new file mode 100644 index 00000000000..452d58ff667 --- /dev/null +++ b/tooling/nargo_cli/src/cli/verify_cmd.rs @@ -0,0 +1,115 @@ +use super::NargoConfig; +use super::{ + compile_cmd::compile_bin_package, + fs::{inputs::read_inputs_from_file, load_hex_data, program::read_program_from_file}, +}; +use crate::{backends::Backend, errors::CliError}; + +use acvm::acir::circuit::Opcode; +use acvm::Language; +use clap::Args; +use nargo::constants::{PROOF_EXT, VERIFIER_INPUT_FILE}; +use nargo::{artifacts::program::PreprocessedProgram, package::Package}; +use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_abi::input_parser::Format; +use noirc_driver::CompileOptions; +use noirc_frontend::graph::CrateName; +use std::path::{Path, PathBuf}; + +// TODO(#1388): pull this from backend. +const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; + +/// Given a proof and a program, verify whether the proof is valid +#[derive(Debug, Clone, Args)] +pub(crate) struct VerifyCommand { + /// The name of the toml file which contains the inputs for the verifier + #[clap(long, short, default_value = VERIFIER_INPUT_FILE)] + verifier_name: String, + + /// The name of the package verify + #[clap(long, conflicts_with = "workspace")] + package: Option, + + /// Verify all packages in the workspace + #[clap(long, conflicts_with = "package")] + workspace: bool, + + #[clap(flatten)] + compile_options: CompileOptions, +} + +pub(crate) fn run( + backend: &Backend, + args: VerifyCommand, + config: NargoConfig, +) -> Result<(), CliError> { + let toml_path = get_package_manifest(&config.program_dir)?; + let default_selection = + if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; + let selection = args.package.map_or(default_selection, PackageSelection::Selected); + let workspace = resolve_workspace_from_toml(&toml_path, selection)?; + let proofs_dir = workspace.proofs_directory_path(); + + let (np_language, is_opcode_supported) = backend.get_backend_info()?; + for package in &workspace { + let circuit_build_path = workspace.package_build_path(package); + + let proof_path = proofs_dir.join(String::from(&package.name)).with_extension(PROOF_EXT); + + verify_package( + backend, + package, + &proof_path, + circuit_build_path, + &args.verifier_name, + &args.compile_options, + np_language, + &is_opcode_supported, + )?; + } + + Ok(()) +} + +#[allow(clippy::too_many_arguments)] +fn verify_package( + backend: &Backend, + package: &Package, + proof_path: &Path, + circuit_build_path: PathBuf, + verifier_name: &str, + compile_options: &CompileOptions, + np_language: Language, + is_opcode_supported: &impl Fn(&Opcode) -> bool, +) -> Result<(), CliError> { + let preprocessed_program = if circuit_build_path.exists() { + read_program_from_file(circuit_build_path)? + } else { + let program = + compile_bin_package(package, compile_options, np_language, &is_opcode_supported)?; + + PreprocessedProgram { + backend: String::from(BACKEND_IDENTIFIER), + abi: program.abi, + bytecode: program.circuit, + } + }; + + let PreprocessedProgram { abi, bytecode, .. } = preprocessed_program; + + // Load public inputs (if any) from `verifier_name`. + let public_abi = abi.public_abi(); + let (public_inputs_map, return_value) = + read_inputs_from_file(&package.root_dir, verifier_name, Format::Toml, &public_abi)?; + + let public_inputs = public_abi.encode(&public_inputs_map, return_value)?; + let proof = load_hex_data(proof_path)?; + + let valid_proof = backend.verify(&proof, public_inputs, &bytecode, false)?; + + if valid_proof { + Ok(()) + } else { + Err(CliError::InvalidProof(proof_path.to_path_buf())) + } +} diff --git a/tooling/nargo_cli/src/errors.rs b/tooling/nargo_cli/src/errors.rs new file mode 100644 index 00000000000..205f68f624e --- /dev/null +++ b/tooling/nargo_cli/src/errors.rs @@ -0,0 +1,107 @@ +use acvm::acir::native_types::WitnessMapError; +use hex::FromHexError; +use nargo::NargoError; +use nargo_toml::ManifestError; +use noirc_abi::errors::{AbiError, InputParserError}; +use noirc_errors::reporter::ReportedErrors; +use noirc_frontend::graph::CrateName; +use std::path::PathBuf; +use thiserror::Error; + +#[derive(Debug, Error)] +pub(crate) enum FilesystemError { + #[error("Error: {} is not a valid path\nRun either `nargo compile` to generate missing build artifacts or `nargo prove` to construct a proof", .0.display())] + PathNotValid(PathBuf), + #[error("Error: could not parse hex build artifact (proof, proving and/or verification keys, ACIR checksum) ({0})")] + HexArtifactNotValid(FromHexError), + #[error( + " Error: cannot find {0}.toml file.\n Expected location: {1:?} \n Please generate this file at the expected location." + )] + MissingTomlFile(String, PathBuf), + + /// Input parsing error + #[error(transparent)] + InputParserError(#[from] InputParserError), + + /// WitnessMap serialization error + #[error(transparent)] + WitnessMapSerialization(#[from] WitnessMapError), +} + +#[derive(Debug, Error)] +pub(crate) enum CliError { + #[error("{0}")] + Generic(String), + #[error("Error: destination {} already exists", .0.display())] + DestinationAlreadyExists(PathBuf), + + #[error("Failed to verify proof {}", .0.display())] + InvalidProof(PathBuf), + + #[error("Invalid package name {0}. Did you mean to use `--name`?")] + InvalidPackageName(String), + + /// ABI encoding/decoding error + #[error(transparent)] + AbiError(#[from] AbiError), + + /// Filesystem errors + #[error(transparent)] + FilesystemError(#[from] FilesystemError), + + #[error(transparent)] + LspError(#[from] async_lsp::Error), + + /// Error from Nargo + #[error(transparent)] + NargoError(#[from] NargoError), + + /// Error from Manifest + #[error(transparent)] + ManifestError(#[from] ManifestError), + + /// Error from the compilation pipeline + #[error(transparent)] + CompileError(#[from] CompileError), + + /// Error related to backend selection/installation. + #[error(transparent)] + BackendError(#[from] BackendError), + + /// Error related to communication with backend. + #[error(transparent)] + BackendCommunicationError(#[from] acvm_backend_barretenberg::BackendError), +} + +#[derive(Debug, thiserror::Error)] +pub(crate) enum BackendError { + #[error("No backend is installed with the name {0}")] + UnknownBackend(String), + + #[error("The backend {0} is already installed")] + AlreadyInstalled(String), + + #[error("Backend installation failed: {0}")] + InstallationError(#[from] std::io::Error), +} + +/// Errors covering situations where a package cannot be compiled. +#[derive(Debug, Error)] +pub(crate) enum CompileError { + #[error("Package `{0}` has type `lib` but only `bin` types can be compiled")] + LibraryCrate(CrateName), + + #[error("Package `{0}` is expected to have a `main` function but it does not")] + MissingMainFunction(CrateName), + + /// Errors encountered while compiling the Noir program. + /// These errors are already written to stderr. + #[error("Aborting due to {} previous error{}", .0.error_count, if .0.error_count == 1 { "" } else { "s" })] + ReportedErrors(ReportedErrors), +} + +impl From for CompileError { + fn from(errors: ReportedErrors) -> Self { + Self::ReportedErrors(errors) + } +} diff --git a/tooling/nargo_cli/src/main.rs b/tooling/nargo_cli/src/main.rs new file mode 100644 index 00000000000..f4d1e1862fc --- /dev/null +++ b/tooling/nargo_cli/src/main.rs @@ -0,0 +1,25 @@ +#![forbid(unsafe_code)] +#![warn(unreachable_pub)] +#![warn(clippy::semicolon_if_nothing_returned)] +#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] + +//! Nargo is the package manager for Noir +//! This name was used because it sounds like `cargo` and +//! Noir Package Manager abbreviated is npm, which is already taken. + +mod backends; +mod cli; +mod errors; + +use color_eyre::{config::HookBuilder, eyre}; + +const PANIC_MESSAGE: &str = "This is a bug. We may have already fixed this in newer versions of Nargo so try searching for similar issues at https://github.com/noir-lang/noir/issues/.\nIf there isn't an open issue for this bug, consider opening one at https://github.com/noir-lang/noir/issues/new?labels=bug&template=bug_report.yml"; + +fn main() -> eyre::Result<()> { + // Register a panic hook to display more readable panic messages to end-users + let (panic_hook, _) = + HookBuilder::default().display_env_section(false).panic_section(PANIC_MESSAGE).into_hooks(); + panic_hook.install(); + + cli::start_cli() +} diff --git a/crates/nargo_cli/tests/README.md b/tooling/nargo_cli/tests/README.md similarity index 100% rename from crates/nargo_cli/tests/README.md rename to tooling/nargo_cli/tests/README.md diff --git a/tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/acir.gz new file mode 100644 index 00000000000..5d296af254b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz new file mode 100644 index 00000000000..46db025c3c7 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/witness.gz new file mode 100644 index 00000000000..ffbbbd8a483 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz new file mode 100644 index 00000000000..a45dbe7e40d Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/2_div/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/2_div/target/witness.gz new file mode 100644 index 00000000000..a56f646c14d Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/2_div/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz new file mode 100644 index 00000000000..73b60810519 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/3_add/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/3_add/target/witness.gz new file mode 100644 index 00000000000..d871f412010 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/3_add/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz new file mode 100644 index 00000000000..d28c95e99f8 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/witness.gz new file mode 100644 index 00000000000..d968b23674c Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz new file mode 100644 index 00000000000..5e448f8afe9 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/5_over/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/5_over/target/witness.gz new file mode 100644 index 00000000000..c063eb5651b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/5_over/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/6/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/6/target/acir.gz new file mode 100644 index 00000000000..42bfbbaed0e Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/6/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/6/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/6/target/witness.gz new file mode 100644 index 00000000000..5c060e1b469 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/6/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz new file mode 100644 index 00000000000..05d33bd7ce3 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/6_array/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/6_array/target/witness.gz new file mode 100644 index 00000000000..fbb8e0115f3 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/6_array/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/7/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/7/target/acir.gz new file mode 100644 index 00000000000..3238e1bc26b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/7/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/7/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/7/target/witness.gz new file mode 100644 index 00000000000..d51356eb6c1 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/7/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz new file mode 100644 index 00000000000..eb0132dc063 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/7_function/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/7_function/target/witness.gz new file mode 100644 index 00000000000..02ea81fbc1f Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/7_function/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/acir.gz new file mode 100644 index 00000000000..3045571f758 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/witness.gz new file mode 100644 index 00000000000..0df10c44eaa Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/acir.gz new file mode 100644 index 00000000000..5e277296609 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/witness.gz new file mode 100644 index 00000000000..21d41a12a4c Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz new file mode 100644 index 00000000000..4f874bb01db Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/witness.gz new file mode 100644 index 00000000000..77ee10b4d4f Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz new file mode 100644 index 00000000000..78e27fb7119 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/witness.gz new file mode 100644 index 00000000000..2622c55c676 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/acir.gz new file mode 100644 index 00000000000..3209865ae28 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/witness.gz new file mode 100644 index 00000000000..f000e986c3d Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_len/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/array_len/target/acir.gz new file mode 100644 index 00000000000..691299e7baf Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_len/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_len/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/array_len/target/witness.gz new file mode 100644 index 00000000000..c1ca0b90f05 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_len/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz new file mode 100644 index 00000000000..e55fac6b6f3 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/array_neq/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_neq/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/array_neq/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz new file mode 100644 index 00000000000..6001b7e4bb8 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/witness.gz new file mode 100644 index 00000000000..47e9d08f889 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/assert/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/assert/target/acir.gz new file mode 100644 index 00000000000..21b9f6fdb15 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/assert/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/bool_not/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/assert/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/bool_not/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/assert/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/acir.gz new file mode 100644 index 00000000000..6d208fe704b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/witness.gz new file mode 100644 index 00000000000..3e073aac635 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/acir.gz new file mode 100644 index 00000000000..851e429e7f0 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz new file mode 100644 index 00000000000..a3db36d28ca Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/witness.gz new file mode 100644 index 00000000000..ba27f611f48 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz new file mode 100644 index 00000000000..ceb1a1a613a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/witness.gz new file mode 100644 index 00000000000..b9283fbd0be Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz new file mode 100644 index 00000000000..9314658a5ae Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/witness.gz new file mode 100644 index 00000000000..7e88d1f9071 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/acir.gz new file mode 100644 index 00000000000..1ac995acfe9 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/witness.gz new file mode 100644 index 00000000000..16880cedea2 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bool_or/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/bool_or/target/acir.gz new file mode 100644 index 00000000000..c3193e9b4e4 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/bool_or/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/submodules/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/bool_or/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/submodules/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/bool_or/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz new file mode 100644 index 00000000000..297ad64a9ec Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/witness.gz new file mode 100644 index 00000000000..ae8f583ce97 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz new file mode 100644 index 00000000000..1077aca8e7b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_arrays/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_arrays/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz new file mode 100644 index 00000000000..c9316354d45 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/witness.gz new file mode 100644 index 00000000000..f173f3c5625 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz new file mode 100644 index 00000000000..f3ffc6c9059 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/witness.gz new file mode 100644 index 00000000000..d51356eb6c1 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz new file mode 100644 index 00000000000..d431b2284d1 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/witness.gz new file mode 100644 index 00000000000..ae8f583ce97 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz new file mode 100644 index 00000000000..12986ecc1c6 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/witness.gz new file mode 100644 index 00000000000..266c94d043a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz new file mode 100644 index 00000000000..669cb15f683 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/witness.gz new file mode 100644 index 00000000000..3e7c051ffc4 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz new file mode 100644 index 00000000000..c75b63980e5 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/witness.gz new file mode 100644 index 00000000000..b998e51d692 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz new file mode 100644 index 00000000000..ef22f99cc20 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_ecdsa/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_ecdsa/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz new file mode 100644 index 00000000000..c6da0c97dd5 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/witness.gz new file mode 100644 index 00000000000..a7d28d780d2 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz new file mode 100644 index 00000000000..bf59013d233 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_hash_to_field/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_hash_to_field/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz new file mode 100644 index 00000000000..622f321136e Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/witness.gz new file mode 100644 index 00000000000..9a911d62512 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz new file mode 100644 index 00000000000..59aa76b5fdb Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/witness.gz new file mode 100644 index 00000000000..0f7d857c3b7 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/acir.gz new file mode 100644 index 00000000000..1e04c51b0f7 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/witness.gz new file mode 100644 index 00000000000..6e9e8ecd1d0 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz new file mode 100644 index 00000000000..33e37658fa1 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/witness.gz new file mode 100644 index 00000000000..87cf83430f7 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz new file mode 100644 index 00000000000..321a0ddc970 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_slices/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_nested_slices/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz new file mode 100644 index 00000000000..69f6d860aef Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/witness.gz new file mode 100644 index 00000000000..457a006e849 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz new file mode 100644 index 00000000000..f1199536501 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_oracle/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_oracle/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz new file mode 100644 index 00000000000..8fa443e37cc Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_pedersen/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_pedersen/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz new file mode 100644 index 00000000000..bd7acdd501a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/witness.gz new file mode 100644 index 00000000000..46e192995f3 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz new file mode 100644 index 00000000000..46c4767aa3a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_references/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_references/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz new file mode 100644 index 00000000000..244ba764db2 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_scalar_mul/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz new file mode 100644 index 00000000000..d6c31f996d2 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/witness.gz new file mode 100644 index 00000000000..8992e084146 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz new file mode 100644 index 00000000000..1bff7454a7c Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/witness.gz new file mode 100644 index 00000000000..118042d5841 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz new file mode 100644 index 00000000000..59dc0bcadf6 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_slices/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_slices/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz new file mode 100644 index 00000000000..6633577c695 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz new file mode 100644 index 00000000000..48d01aed773 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz new file mode 100644 index 00000000000..52c21fa08a0 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz new file mode 100644 index 00000000000..c61f3cc89a4 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/brillig_top_level/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_top_level/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz new file mode 100644 index 00000000000..5b8a657e5bc Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/witness.gz new file mode 100644 index 00000000000..fa79236ad55 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/acir.gz new file mode 100644 index 00000000000..e2e04f5fb42 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/witness.gz new file mode 100644 index 00000000000..37c6d67fada Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/acir.gz new file mode 100644 index 00000000000..ea36782c233 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/constant_return/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/constant_return/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/constant_return/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/acir.gz new file mode 100644 index 00000000000..21b9f6fdb15 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/witness.gz new file mode 100644 index 00000000000..16880cedea2 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz new file mode 100644 index 00000000000..f0990c560cb Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/witness.gz new file mode 100644 index 00000000000..3199dac0924 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/acir.gz new file mode 100644 index 00000000000..e9a4783cb82 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/diamond_deps_0/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/diamond_deps_0/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/acir.gz new file mode 100644 index 00000000000..bca04661d30 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/distinct_keyword/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/distinct_keyword/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/acir.gz new file mode 100644 index 00000000000..b955dca361a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/witness.gz new file mode 100644 index 00000000000..b250bdfe7bc Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/acir.gz new file mode 100644 index 00000000000..a5aeebe7fcf Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/witness.gz new file mode 100644 index 00000000000..a094ba3246b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/acir.gz new file mode 100644 index 00000000000..39aabcbf301 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz new file mode 100644 index 00000000000..39b67fe46b9 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/witness.gz new file mode 100644 index 00000000000..102f119ea30 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/generics/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/generics/target/acir.gz new file mode 100644 index 00000000000..468587714e3 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/generics/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/generics/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/generics/target/witness.gz new file mode 100644 index 00000000000..4d120219b14 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/generics/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz new file mode 100644 index 00000000000..eb9875c8fef Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/witness.gz new file mode 100644 index 00000000000..4d4faba6cb6 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/acir.gz new file mode 100644 index 00000000000..6ec14e066fa Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/hash_to_field/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/hash_to_field/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz new file mode 100644 index 00000000000..50036c797d9 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz new file mode 100644 index 00000000000..252e179b7a5 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz new file mode 100644 index 00000000000..377d3a94464 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/witness.gz new file mode 100644 index 00000000000..4ae6ee035f2 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz new file mode 100644 index 00000000000..c3f579f7cc0 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/import/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/import/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/import/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/import/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/acir.gz new file mode 100644 index 00000000000..bcef795065a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/integer_array_indexing/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/integer_array_indexing/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz new file mode 100644 index 00000000000..103eb91fe85 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/witness.gz new file mode 100644 index 00000000000..51a5b73c88b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz new file mode 100644 index 00000000000..dce2019c75b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/main_bool_arg/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/main_bool_arg/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/main_return/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/main_return/target/acir.gz new file mode 100644 index 00000000000..d5d8b6dba85 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/main_return/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/main_return/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/main_return/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/main_return/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/main_return/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz new file mode 100644 index 00000000000..b4177c73e7c Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/witness.gz new file mode 100644 index 00000000000..78e92c59029 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz new file mode 100644 index 00000000000..b0523be6e92 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/modules/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/modules/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/modules/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz new file mode 100644 index 00000000000..c3f579f7cc0 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/modules_more/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules_more/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/modules_more/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz new file mode 100644 index 00000000000..2135a5c0eb6 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz new file mode 100644 index 00000000000..57691426484 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz new file mode 100644 index 00000000000..2578e60c8ae Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/witness.gz new file mode 100644 index 00000000000..67c96f0da95 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/acir.gz new file mode 100644 index 00000000000..5846defb902 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/witness.gz new file mode 100644 index 00000000000..0b48ba0aeb2 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/acir.gz new file mode 100644 index 00000000000..ef1911d1095 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/witness.gz new file mode 100644 index 00000000000..f4fbaec7ccf Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/acir.gz new file mode 100644 index 00000000000..2737018de8e Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/witness.gz new file mode 100644 index 00000000000..d7e732d7ee1 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz new file mode 100644 index 00000000000..5b8a657e5bc Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/pred_eq/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/pred_eq/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/references/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/references/target/acir.gz new file mode 100644 index 00000000000..937b81e9ef6 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/references/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/references/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/references/target/witness.gz new file mode 100644 index 00000000000..bf62ea672eb Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/references/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/references_aliasing/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/references_aliasing/target/acir.gz new file mode 100644 index 00000000000..f27a429a80f Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/references_aliasing/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/references_aliasing/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/references_aliasing/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz new file mode 100644 index 00000000000..cd99055837a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/regression/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/regression/target/witness.gz new file mode 100644 index 00000000000..cbb756470b3 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/regression/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz new file mode 100644 index 00000000000..f029de3a84f Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/witness.gz new file mode 100644 index 00000000000..4e90289d5e1 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz new file mode 100644 index 00000000000..ec786bac1f9 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/witness.gz new file mode 100644 index 00000000000..1d7bfd63739 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz new file mode 100644 index 00000000000..b0099027030 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/witness.gz new file mode 100644 index 00000000000..d7aa71c0446 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz new file mode 100644 index 00000000000..279e4edf44d Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha256/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/sha256/target/witness.gz new file mode 100644 index 00000000000..1e88e682b72 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/sha256/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/acir.gz new file mode 100644 index 00000000000..62479a7035f Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/witness.gz new file mode 100644 index 00000000000..44cdea653b1 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz new file mode 100644 index 00000000000..5db49355157 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/witness.gz new file mode 100644 index 00000000000..bae2217f391 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz new file mode 100644 index 00000000000..b26cef3993e Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/witness.gz new file mode 100644 index 00000000000..7aeb670e9ed Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/acir.gz new file mode 100644 index 00000000000..6a2322de7db Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/simple_print/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_print/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/acir.gz new file mode 100644 index 00000000000..1aa1f33cd77 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/simple_array_param/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_array_param/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz new file mode 100644 index 00000000000..2b1f825fd5a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/witness.gz new file mode 100644 index 00000000000..78f39a7d112 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz new file mode 100644 index 00000000000..55c23c46dd8 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/witness.gz new file mode 100644 index 00000000000..63bf586cfa9 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/acir.gz new file mode 100644 index 00000000000..78d246c6861 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/simple_mut/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_mut/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_not/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_not/target/acir.gz new file mode 100644 index 00000000000..ce3e632afe6 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_not/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/simple_not/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/simple_not/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_not/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/simple_not/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz new file mode 100644 index 00000000000..8ddcf94c704 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/witness.gz new file mode 100644 index 00000000000..35e05b7622b Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/acir.gz new file mode 100644 index 00000000000..6a2322de7db Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/simple_program_addition/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_program_addition/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz new file mode 100644 index 00000000000..656b636c637 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/witness.gz new file mode 100644 index 00000000000..e3ba9bd1428 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz new file mode 100644 index 00000000000..a34e79fc3a6 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/witness.gz new file mode 100644 index 00000000000..d07e36549ea Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz new file mode 100644 index 00000000000..5164f54d87a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/witness.gz new file mode 100644 index 00000000000..eb28de51576 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz new file mode 100644 index 00000000000..b7e1fb4beae Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz new file mode 100644 index 00000000000..e4611fdd14f Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz new file mode 100644 index 00000000000..3d899c46572 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slices/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/slices/target/witness.gz new file mode 100644 index 00000000000..d1e63b18d37 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/slices/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz new file mode 100644 index 00000000000..0976e9f2b2e Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/strings/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/strings/target/witness.gz new file mode 100644 index 00000000000..8ee2f7c9148 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/strings/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/struct/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/struct/target/acir.gz new file mode 100644 index 00000000000..eb913661993 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/struct/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/struct/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/struct/target/witness.gz new file mode 100644 index 00000000000..a8e277ea795 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/struct/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/acir.gz new file mode 100644 index 00000000000..19621ede7d6 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/struct_array_inputs/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_array_inputs/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/acir.gz new file mode 100644 index 00000000000..d9a07903860 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/witness.gz new file mode 100644 index 00000000000..e2eb3145306 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz new file mode 100644 index 00000000000..06aa93a1e03 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/witness.gz new file mode 100644 index 00000000000..34ebbb74de2 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/submodules/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/submodules/target/acir.gz new file mode 100644 index 00000000000..c3193e9b4e4 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/submodules/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/submodules/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/submodules/target/witness.gz new file mode 100644 index 00000000000..10cffba7141 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/submodules/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz new file mode 100644 index 00000000000..0a6b73ede0a Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz new file mode 100644 index 00000000000..27fe7ec8d02 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz new file mode 100644 index 00000000000..75dde3237b3 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/witness.gz new file mode 100644 index 00000000000..66202f79cd0 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz new file mode 100644 index 00000000000..b0238934a54 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/witness.gz new file mode 100644 index 00000000000..0d9d7d619bb Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz new file mode 100644 index 00000000000..94d1e673ec4 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/witness.gz new file mode 100644 index 00000000000..f7824210634 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz new file mode 100644 index 00000000000..b680ed268d1 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/tuples/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/tuples/target/witness.gz new file mode 100644 index 00000000000..10cffba7141 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/tuples/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz new file mode 100644 index 00000000000..d3b2c7e67ad Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/witness.gz new file mode 100644 index 00000000000..754e75edb48 Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz new file mode 100644 index 00000000000..5298ffbcdef Binary files /dev/null and b/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz differ diff --git a/crates/nargo_cli/tests/execution_success/xor/target/witness.tr b/tooling/nargo_cli/tests/acir_artifacts/xor/target/witness.gz similarity index 100% rename from crates/nargo_cli/tests/execution_success/xor/target/witness.tr rename to tooling/nargo_cli/tests/acir_artifacts/xor/target/witness.gz diff --git a/crates/nargo_cli/tests/codegen-verifier.rs b/tooling/nargo_cli/tests/codegen-verifier.rs similarity index 100% rename from crates/nargo_cli/tests/codegen-verifier.rs rename to tooling/nargo_cli/tests/codegen-verifier.rs diff --git a/crates/nargo_cli/tests/compile_failure/assert_constant_fail/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/assert_constant_fail/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/assert_constant_fail/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/assert_constant_fail/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/assert_constant_fail/src/main.nr b/tooling/nargo_cli/tests/compile_failure/assert_constant_fail/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/assert_constant_fail/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/assert_constant_fail/src/main.nr diff --git a/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/Nargo.toml new file mode 100644 index 00000000000..055c23234ce --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "assert_eq_struct" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/src/main.nr b/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/src/main.nr new file mode 100644 index 00000000000..c2eac091733 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/src/main.nr @@ -0,0 +1,6 @@ +struct myStruct {} + +// `assert_eq` should not allow asserting equality between types for which `==` is not defined. +fn main(x : myStruct, y : pub myStruct) { + assert_eq(x, y); +} diff --git a/crates/nargo_cli/tests/compile_failure/brillig_assert_fail/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/brillig_assert_fail/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/brillig_assert_fail/Prover.toml b/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/brillig_assert_fail/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/Prover.toml diff --git a/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/src/main.nr b/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/src/main.nr new file mode 100644 index 00000000000..801a818c816 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/src/main.nr @@ -0,0 +1,11 @@ +// Tests a very simple program. +// +// The features being tested is using assert on brillig +fn main(x: Field) { + assert(1 == conditional(x as bool)); +} + +unconstrained fn conditional(x : bool) -> Field { + assert(x); + 1 +} diff --git a/crates/nargo_cli/tests/compile_failure/constrain_typo/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/constrain_typo/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/constrain_typo/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/constrain_typo/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/constrain_typo/src/main.nr b/tooling/nargo_cli/tests/compile_failure/constrain_typo/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/constrain_typo/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/constrain_typo/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/custom_entry_not_found/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/custom_entry_not_found/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/custom_entry_not_found/Prover.toml b/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/custom_entry_not_found/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/custom_entry_not_found/src/main.nr b/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/custom_entry_not_found/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/dep_impl_primitive/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/dep_impl_primitive/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/dep_impl_primitive/Prover.toml b/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/dep_impl_primitive/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/dep_impl_primitive/src/main.nr b/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/dep_impl_primitive/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/depend_on_bin/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/depend_on_bin/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/depend_on_bin/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/depend_on_bin/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/depend_on_bin/Prover.toml b/tooling/nargo_cli/tests/compile_failure/depend_on_bin/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/depend_on_bin/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/depend_on_bin/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/depend_on_bin/src/main.nr b/tooling/nargo_cli/tests/compile_failure/depend_on_bin/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/depend_on_bin/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/depend_on_bin/src/main.nr diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Nargo.toml new file mode 100644 index 00000000000..55e36368845 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "divide_by_zero" +type = "bin" +authors = [""] +compiler_version = "0.10.3" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Prover.toml b/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Prover.toml diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/src/main.nr b/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/src/main.nr new file mode 100644 index 00000000000..2259d51e6de --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/src/main.nr @@ -0,0 +1,6 @@ +use dep::std; + +fn main() { + let a: Field = 3 / 0; + std::println(a); +} \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Nargo.toml new file mode 100644 index 00000000000..d3b69d8c41b --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "div_by_zero_modulo" +type = "bin" +authors = [""] +compiler_version = "0.10.5" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Prover.toml b/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Prover.toml diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/src/main.nr b/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/src/main.nr new file mode 100644 index 00000000000..f20c39486e0 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/src/main.nr @@ -0,0 +1,7 @@ +fn main() { + let a: u32 = 6; + let b = 3; + let c = 0; + let res = (a*b) % c; + assert(res != 5); +} \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Nargo.toml new file mode 100644 index 00000000000..58a60a38a0c --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "div_by_zero_numerator_witness" +type = "bin" +authors = [""] +compiler_version = "0.10.3" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_success_empty/simple_range/Prover.toml b/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/simple_range/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Prover.toml diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/src/main.nr b/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/src/main.nr new file mode 100644 index 00000000000..f51b26d5ba1 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/src/main.nr @@ -0,0 +1,6 @@ +use dep::std; + +fn main(x: Field) { + let a: Field = x / 0; + std::println(a); +} diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Nargo.toml new file mode 100644 index 00000000000..08dbe74f018 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "div_by_zero_witness" +type = "bin" +authors = [""] +compiler_version = "0.10.3" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Prover.toml b/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Prover.toml new file mode 100644 index 00000000000..a1f166bf325 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Prover.toml @@ -0,0 +1,2 @@ +x = "3" +y = "0" diff --git a/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/src/main.nr b/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/src/main.nr new file mode 100644 index 00000000000..4ce567e49a6 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/src/main.nr @@ -0,0 +1,7 @@ +use dep::std; + +// It is expected that `y` must be equal to 0. +fn main(x : Field, y : pub Field) { + let a: Field = x / y; + std::println(a); +} diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_declaration/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/dup_trait_declaration/Nargo.toml new file mode 100644 index 00000000000..214116185f4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_declaration/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "dup_trait_declaration" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/simple_print/Prover.toml b/tooling/nargo_cli/tests/compile_failure/dup_trait_declaration/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_print/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/dup_trait_declaration/Prover.toml diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_declaration/src/main.nr b/tooling/nargo_cli/tests/compile_failure/dup_trait_declaration/src/main.nr new file mode 100644 index 00000000000..f4c246c786a --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_declaration/src/main.nr @@ -0,0 +1,26 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: x, array: [x,y] } + } +} + +// Duplicate trait declarations should not compile +trait Default { + fn default(x: Field) -> Self; +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + assert(first.bar == x); +} diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/Nargo.toml new file mode 100644 index 00000000000..708e26777d6 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "dup_trait_implementation" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/Prover.toml b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/src/main.nr b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/src/main.nr new file mode 100644 index 00000000000..cfc098a6ff7 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation/src/main.nr @@ -0,0 +1,28 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +// Duplicate trait implementations should not compile +impl Default for Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: x, array: [x,y] } + } +} + +// Duplicate trait implementations should not compile +impl Default for Foo { + fn default(x: Field, y: Field) -> Self { + Self { bar: y, array: [y,x] } + } +} + + +fn main(x: Field, y: Field) { +} diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/Nargo.toml new file mode 100644 index 00000000000..2276db5c741 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "dup_trait_implementation_2" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/Prover.toml b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/src/main.nr b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/src/main.nr new file mode 100644 index 00000000000..80b544b8e54 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_2/src/main.nr @@ -0,0 +1,18 @@ +trait Default { +} + +struct Foo { + bar: Field, +} + +// Duplicate trait implementations should not compile +impl Default for Foo { +} + +// Duplicate trait implementations should not compile +impl Default for Foo { +} + + +fn main(x: Field, y: Field) { +} diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/Nargo.toml new file mode 100644 index 00000000000..ac04d9fac4d --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "dup_trait_implementation_3" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/Prover.toml b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/src/main.nr b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/src/main.nr new file mode 100644 index 00000000000..2996b6a00bb --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_3/src/main.nr @@ -0,0 +1,19 @@ +trait Default { +} + +struct MyStruct { +} + +type MyType = MyStruct; + +// Duplicate trait implementations should not compile +impl Default for MyStruct { +} + +// Duplicate trait implementations should not compile +impl Default for MyType { +} + + +fn main(x: Field, y: Field) { +} diff --git a/crates/nargo_cli/tests/compile_failure/duplicate_declaration/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/duplicate_declaration/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/duplicate_declaration/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/duplicate_declaration/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/duplicate_declaration/src/main.nr b/tooling/nargo_cli/tests/compile_failure/duplicate_declaration/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/duplicate_declaration/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/duplicate_declaration/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/dynamic_index_failure/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/dynamic_index_failure/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/dynamic_index_failure/Prover.toml b/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/dynamic_index_failure/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/dynamic_index_failure/src/main.nr b/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/dynamic_index_failure/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/src/main.nr diff --git a/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/Nargo.toml new file mode 100644 index 00000000000..3c6943f1ce1 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "impl_struct_not_trait" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/Prover.toml b/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/src/main.nr b/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/src/main.nr new file mode 100644 index 00000000000..e25465378b1 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/impl_struct_not_trait/src/main.nr @@ -0,0 +1,23 @@ +use dep::std; + +struct Foo { + bar: Field, + array: [Field; 2], +} + +struct Default { + x: Field, + z: Field, +} + +// Default is struct not a trait +impl Default for Foo { + fn default(x: Field, y: Field) -> Self { + Self { bar: x, array: [x,y] } + } +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + assert(first.bar == x); +} diff --git a/crates/nargo_cli/tests/compile_failure/invalid_dependency_name/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/invalid_dependency_name/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/invalid_dependency_name/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/invalid_dependency_name/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/invalid_dependency_name/src/main.nr b/tooling/nargo_cli/tests/compile_failure/invalid_dependency_name/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/invalid_dependency_name/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/invalid_dependency_name/src/main.nr diff --git a/tooling/nargo_cli/tests/compile_failure/multiple_contracts/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/multiple_contracts/Nargo.toml new file mode 100644 index 00000000000..c71c86c664b --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/multiple_contracts/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "multiple_contracts" +type = "contract" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] diff --git a/tooling/nargo_cli/tests/compile_failure/multiple_contracts/src/main.nr b/tooling/nargo_cli/tests/compile_failure/multiple_contracts/src/main.nr new file mode 100644 index 00000000000..0562ca9ccd5 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/multiple_contracts/src/main.nr @@ -0,0 +1,4 @@ +contract Foo {} + + +contract Bar {} diff --git a/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/Nargo.toml new file mode 100644 index 00000000000..7e699d4bbe0 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "multiple_primary_attributes_fail" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/src/main.nr b/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/src/main.nr new file mode 100644 index 00000000000..c8d8b0a1969 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/src/main.nr @@ -0,0 +1,6 @@ + +#[oracle(oracleName)] +#[builtin(builtinName)] +fn main(x: Field) -> pub Field { + x + 1 +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_failure/overflowing_assignment/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/overflowing_assignment/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/overflowing_assignment/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/overflowing_assignment/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/overflowing_assignment/src/main.nr b/tooling/nargo_cli/tests/compile_failure/overflowing_assignment/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/overflowing_assignment/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/overflowing_assignment/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/package_name_empty/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/package_name_empty/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/package_name_empty/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/package_name_empty/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/package_name_empty/src/main.nr b/tooling/nargo_cli/tests/compile_failure/package_name_empty/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/package_name_empty/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/package_name_empty/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/package_name_hyphen/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/package_name_hyphen/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/package_name_hyphen/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/package_name_hyphen/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/package_name_hyphen/src/main.nr b/tooling/nargo_cli/tests/compile_failure/package_name_hyphen/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/package_name_hyphen/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/package_name_hyphen/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/slice_access_failure/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/slice_access_failure/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/slice_access_failure/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/slice_access_failure/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/slice_access_failure/Prover.toml b/tooling/nargo_cli/tests/compile_failure/slice_access_failure/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/slice_access_failure/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/slice_access_failure/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/slice_access_failure/src/main.nr b/tooling/nargo_cli/tests/compile_failure/slice_access_failure/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/slice_access_failure/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/slice_access_failure/src/main.nr diff --git a/tooling/nargo_cli/tests/compile_failure/trait_missing_implementation/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/trait_missing_implementation/Nargo.toml new file mode 100644 index 00000000000..75fb80c4bfa --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_missing_implementation/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/compile_failure/trait_missing_implementation/src/main.nr b/tooling/nargo_cli/tests/compile_failure/trait_missing_implementation/src/main.nr new file mode 100644 index 00000000000..bc74b328592 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_missing_implementation/src/main.nr @@ -0,0 +1,24 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; + + fn method2(x: Field) -> Field; + +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: x, array: [x,y] } + } +} + +fn main(x: Field) { + let first = Foo::method2(x); + assert(first == x); +} diff --git a/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/Nargo.toml new file mode 100644 index 00000000000..22d31e22e29 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_not_in_scope" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] diff --git a/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/Prover.toml b/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/src/main.nr b/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/src/main.nr new file mode 100644 index 00000000000..9dc57ee395f --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_not_in_scope/src/main.nr @@ -0,0 +1,18 @@ +use dep::std; + +struct Foo { + bar: Field, + array: [Field; 2], +} + +// Default trait does not exist +impl Default for Foo { + fn default(x: Field, y: Field) -> Self { + Self { bar: x, array: [x,y] } + } +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + assert(first.bar == x); +} diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/Nargo.toml new file mode 100644 index 00000000000..c84f1f3c1c7 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_wrong_method_name" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/Prover.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/src/main.nr b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/src/main.nr new file mode 100644 index 00000000000..0ba10815efa --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_name/src/main.nr @@ -0,0 +1,22 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +// wrong trait name method should not compile +impl Default for Foo { + fn default_wrong_name(x: Field, y: Field) -> Self { + Self { bar: x, array: [x,y] } + } +} + +fn main(x: Field, y: Field) { + let first = Foo::default_wrong_name(x,y); + assert(first.bar == x); +} diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/Nargo.toml new file mode 100644 index 00000000000..95e3e222ca3 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_wrong_method_return_type" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/Prover.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/src/main.nr b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/src/main.nr new file mode 100644 index 00000000000..acd930a6d49 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_method_return_type/src/main.nr @@ -0,0 +1,21 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field, y: Field) -> Field { + x + } +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + assert(first.bar == x); +} diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/Nargo.toml new file mode 100644 index 00000000000..7299ec69e7a --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_wrong_parameter" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/Prover.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/src/main.nr b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/src/main.nr new file mode 100644 index 00000000000..2975aa6b1dd --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter/src/main.nr @@ -0,0 +1,21 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field, y: Foo) -> Self { + Self { bar: x, array: [x, y.bar] } + } +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + assert(first.bar == x); +} diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/Nargo.toml new file mode 100644 index 00000000000..95e3e222ca3 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_wrong_method_return_type" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/Prover.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/src/main.nr b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/src/main.nr new file mode 100644 index 00000000000..2ba1ee13e70 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameter_type/src/main.nr @@ -0,0 +1,7 @@ +trait Default { + fn default(x: Field, y: NotAType) -> Field; +} + +fn main(x: Field, y: Field) { + assert(y == x); +} diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/Nargo.toml new file mode 100644 index 00000000000..a60cf09e828 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_wrong_parameters_count" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/Prover.toml b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/src/main.nr b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/src/main.nr new file mode 100644 index 00000000000..92469ae8fdb --- /dev/null +++ b/tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/src/main.nr @@ -0,0 +1,21 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field) -> Self { + Self { bar: x, array: [x, x] } + } +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + assert(first.bar == x); +} diff --git a/crates/nargo_cli/tests/compile_failure/workspace_fail/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/workspace_fail/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_fail/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_fail/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Prover.toml b/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_fail/crates/a/src/main.nr b/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_fail/crates/a/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Prover.toml b/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_fail/crates/b/src/main.nr b/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_fail/crates/b/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/workspace_missing_toml/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_missing_toml/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/Prover.toml b/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/src/main.nr b/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Nargo.toml b/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Nargo.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Prover.toml b/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Prover.toml rename to tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Prover.toml diff --git a/crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/src/main.nr b/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/src/main.nr rename to tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_contract/simple_contract/Nargo.toml b/tooling/nargo_cli/tests/compile_success_contract/simple_contract/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_contract/simple_contract/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_contract/simple_contract/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_contract/simple_contract/src/main.nr b/tooling/nargo_cli/tests/compile_success_contract/simple_contract/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_contract/simple_contract/src/main.nr rename to tooling/nargo_cli/tests/compile_success_contract/simple_contract/src/main.nr diff --git a/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/Nargo.toml new file mode 100644 index 00000000000..96b221d6c9b --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "attributes_multiple" +type = "bin" +authors = [""] +compiler_version = "0.10.5" + +[dependencies] diff --git a/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/src/main.nr new file mode 100644 index 00000000000..46b761065ff --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/src/main.nr @@ -0,0 +1,8 @@ + +fn main() { + another_func() +} + +#[aztec(private)] +#[internal] +fn another_func() {} \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_cast/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/brillig_cast/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_cast/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/brillig_cast/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_cast/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/brillig_cast/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_cast/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/brillig_cast/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_modulo/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_modulo/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Prover.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/let_stmt/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/let_stmt/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Prover.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_modulo/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_modulo/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/numeric_generics/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/numeric_generics/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/Prover.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_modulo/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_modulo/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/brillig_to_bits/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/brillig_to_bits/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/Nargo.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/src/main.nr new file mode 100644 index 00000000000..a2ab0d4bc5a --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/src/main.nr @@ -0,0 +1,24 @@ +use dep::std; + +unconstrained fn main() { + let field = 1000; + let be_bits = field.to_be_bits(16); + let le_bits = field.to_le_bits(16); + + for i in 0..16 { + let x = be_bits[i]; + let y = le_bits[15-i]; + assert(x == y); + } + + let x = 3; + let be_bits_x = x.to_be_bits(4); + let le_bits_x = x.to_le_bits(4); + + for i in 0..4 { + let be_bit = be_bits_x[i]; + let le_bit = le_bits_x[3-i]; + assert(be_bit == le_bit); + } + +} diff --git a/crates/nargo_cli/tests/compile_success_empty/closure_explicit_types/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/closure_explicit_types/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/Nargo.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/src/main.nr new file mode 100644 index 00000000000..133bc1b4206 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/src/main.nr @@ -0,0 +1,80 @@ + +fn ret_normal_lambda1() -> fn() -> Field { + || 10 +} + +// return lamda that captures a thing +fn ret_closure1() -> fn[(Field,)]() -> Field { + let x = 20; + || x + 10 +} + +// return lamda that captures two things +fn ret_closure2() -> fn[(Field,Field)]() -> Field { + let x = 20; + let y = 10; + || x + y + 10 +} + +// return lamda that captures two things with different types +fn ret_closure3() -> fn[(u32,u64)]() -> u64 { + let x: u32 = 20; + let y: u64 = 10; + || x as u64 + y + 10 +} + +// accepts closure that has 1 thing in its env, calls it and returns the result +fn accepts_closure1(f: fn[(Field,)]() -> Field) -> Field { + f() +} + +// accepts closure that has 1 thing in its env and returns it +fn accepts_closure2(f: fn[(Field,)]() -> Field) -> fn[(Field,)]() -> Field { + f +} + +// accepts closure with different types in the capture group +fn accepts_closure3(f: fn[(u32, u64)]() -> u64) -> u64 { + f() +} + +// generic over closure environments +fn add_results(f1: fn[Env1]() -> Field, f2: fn[Env2]() -> Field) -> Field { + f1() + f2() +} + +// a *really* generic function +fn map(arr: [T; N], f: fn[Env](T) -> U) -> [U; N] { + let first_elem = f(arr[0]); + let mut ret = [first_elem; N]; + + for i in 1 .. N { + ret[i] = f(arr[i]); + } + + ret +} + +fn main() { + assert(ret_normal_lambda1()() == 10); + assert(ret_closure1()() == 30); + assert(ret_closure2()() == 40); + assert(ret_closure3()() == 40); + + let x = 50; + assert(accepts_closure1(|| x) == 50); + assert(accepts_closure2(|| x + 10)() == 60); + + let y: u32 = 30; + let z: u64 = 40; + assert(accepts_closure3(|| y as u64 + z) == 70); + + let w = 50; + assert(add_results(|| 100, || x ) == 150); + assert(add_results(|| x + 100, || w + x ) == 250); + + let arr = [1,2,3,4]; + + assert(map(arr, |n| n + 1) == [2, 3, 4, 5]); + assert(map(arr, |n| n + x) == [51, 52, 53, 54]); +} diff --git a/crates/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Prover.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/comptime_sort/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/comptime_sort/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/comptime_sort/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/comptime_sort/Nargo.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/comptime_sort/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/comptime_sort/src/main.nr new file mode 100644 index 00000000000..f8bd38654c0 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/comptime_sort/src/main.nr @@ -0,0 +1,8 @@ + +fn main() { + let unsorted: [u8; 3] = [3,1,2]; + let sorted = unsorted.sort(); + assert(sorted[0] == 1); + assert(sorted[1] == 2); + assert(sorted[2] == 3); +} diff --git a/crates/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/src/main.nr diff --git a/tooling/nargo_cli/tests/compile_success_empty/generators/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/generators/Nargo.toml new file mode 100644 index 00000000000..0f05b6e5759 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/generators/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "generators" +type = "bin" +authors = [""] +compiler_version = "0.10.3" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_success_empty/generators/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/generators/src/main.nr new file mode 100644 index 00000000000..2f6f90a8c57 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/generators/src/main.nr @@ -0,0 +1,57 @@ +// TODO? +// the syntax for these return types is very difficult to get right :/ +// for arguments this can be handled with a generic Env (or with Fn traits when we add them) +// but for return types neither fo these will help, you need to type out the exact type +fn make_counter() -> fn[(&mut Field,)]() -> Field { + let mut x = &mut 0; + + || { + *x = *x + 1; + *x + } +} + +fn fibonacci_generator() -> fn[(&mut Field, &mut Field)]() -> Field { + let mut x = &mut 1; + let mut y = &mut 2; + + || { + let old_x = *x; + let old_y = *y; + + *y = *x + *y; + *x = old_y; + + old_x + } +} + +// we'll be able to un-hardcode the array length if we have the ::<> syntax proposed in https://github.com/noir-lang/noir/issues/2458 +fn get_some(generator: fn[Env]() -> Field) -> [Field; 5] { + [0,0,0,0,0].map(|_| generator()) +} + +fn test_fib() { + let fib = fibonacci_generator(); + + assert(fib() == 1); + assert(fib() == 2); + assert(fib() == 3); + assert(fib() == 5); + + assert(get_some(fib) == [8, 13, 21, 34, 55]); +} + +fn test_counter() { + let counter = make_counter(); + assert(counter() == 1); + assert(counter() == 2); + assert(counter() == 3); + + assert(get_some(counter) == [4, 5, 6, 7, 8]); +} + +fn main() { + test_fib(); + test_counter(); +} diff --git a/crates/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/Nargo.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/src/main.nr new file mode 100644 index 00000000000..e1a13919f4c --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/src/main.nr @@ -0,0 +1,38 @@ + +fn g(x: &mut Field) -> () { + *x *= 2; +} + +fn h(x: &mut Field) -> () { + *x *= 3; +} + +fn selector(flag: &mut bool) -> fn(&mut Field) -> () { + let my_func = if *flag { + g + } else { + h + }; + + // Flip the flag for the next function call + *flag = !(*flag); + my_func +} + +fn main() { + + let mut flag: bool = true; + + let mut x: Field = 100; + let returned_func = selector(&mut flag); + returned_func(&mut x); + + assert(x == 200); + + let mut y: Field = 100; + let returned_func2 = selector(&mut flag); + returned_func2(&mut y); + + assert(y == 300); + +} diff --git a/crates/nargo_cli/tests/compile_success_empty/inner_outer_cl/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/inner_outer_cl/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/inner_outer_cl/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/inner_outer_cl/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/inner_outer_cl/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/inner_outer_cl/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/inner_outer_cl/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/inner_outer_cl/src/main.nr diff --git a/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Nargo.toml new file mode 100644 index 00000000000..615bc6254e2 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "instruction_deduplication" +type = "bin" +authors = [""] +compiler_version = "0.8.0" + +[dependencies] diff --git a/crates/nargo_cli/tests/execution_success/higher_order_functions/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/higher_order_functions/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Prover.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/src/main.nr new file mode 100644 index 00000000000..43a6da8d6e4 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/src/main.nr @@ -0,0 +1,5 @@ +fn main(x : Field) { + // This is a regression test for #2450. + // The compiler should recognise that the `(x as u32)` instructions are duplicates and so have the same output. + assert(x as u32 == x as u32); +} diff --git a/crates/nargo_cli/tests/compile_success_empty/intrinsic_die/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/intrinsic_die/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/Nargo.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/src/main.nr new file mode 100644 index 00000000000..08c5cce4034 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/src/main.nr @@ -0,0 +1,11 @@ +use dep::std; + +// This test checks that we perform dead-instruction-elimination on intrinsic functions. + +fn main(x: Field) { + let bytes = x.to_be_bytes(32); + + let hash = std::hash::pedersen([x]); + let _p1 = std::scalar_mul::fixed_base_embedded_curve(x, 0); + +} diff --git a/crates/nargo_cli/tests/compile_success_empty/let_stmt/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/let_stmt/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/let_stmt/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/let_stmt/Nargo.toml diff --git a/crates/nargo_cli/tests/test_libraries/bad_name/src/lib.nr b/tooling/nargo_cli/tests/compile_success_empty/let_stmt/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/test_libraries/bad_name/src/lib.nr rename to tooling/nargo_cli/tests/compile_success_empty/let_stmt/Prover.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/let_stmt/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/let_stmt/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/let_stmt/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/let_stmt/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/numeric_generics/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/numeric_generics/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/numeric_generics/Nargo.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/Prover.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/crates/nargo_cli/tests/compile_success_empty/numeric_generics/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/numeric_generics/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/numeric_generics/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/option/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/option/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/option/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/option/Nargo.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/option/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/option/src/main.nr new file mode 100644 index 00000000000..22229014eef --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/option/src/main.nr @@ -0,0 +1,64 @@ +use dep::std::option::Option; + +fn main() { + let ten = 10; // giving this a name, to ensure that the Option functions work with closures + + let none = Option::none(); + let some = Option::some(3); + + assert(none.is_none()); + assert(some.is_some()); + + assert(some.unwrap() == 3); + + assert(none.unwrap_or(2) == 2); + assert(some.unwrap_or(2) == 3); + + assert(none.unwrap_or_else(|| 5) == 5); + assert(some.unwrap_or_else(|| 5) == 3); + assert(none.unwrap_or_else(|| ten + 5) == 15); + assert(some.unwrap_or_else(|| ten + 5) == 3); + + assert(none.map(|x| x * 2).is_none()); + assert(some.map(|x| x * 2).unwrap() == 6); + assert(some.map(|x| x * ten).unwrap() == 30); + + assert(none.map_or(0, |x| x * 2) == 0); + assert(some.map_or(0, |x| x * 2) == 6); + assert(none.map_or(0, |x| x * ten) == 0); + assert(some.map_or(0, |x| x * ten) == 30); + + assert(none.map_or_else(|| 0, |x| x * 2) == 0); + assert(some.map_or_else(|| 0, |x| x * 2) == 6); + assert(none.map_or_else(|| 0, |x| x * ten) == 0); + assert(some.map_or_else(|| ten, |x| x * 2) == 6); + + assert(none.and(none).is_none()); + assert(none.and(some).is_none()); + assert(some.and(none).is_none()); + assert(some.and(some).is_some()); + + let add1_u64 = |value: Field| Option::some(value as u64 + 1); + + assert(none.and_then(|_value| Option::none()).is_none()); + assert(none.and_then(add1_u64).is_none()); + assert(some.and_then(|_value| Option::none()).is_none()); + assert(some.and_then(add1_u64).unwrap() == 4); + assert(some.and_then(|x| Option::some(x + ten)).unwrap() == 13); + + assert(none.or(none).is_none()); + assert(none.or(some).is_some()); + assert(some.or(none).is_some()); + assert(some.or(some).is_some()); + + assert(none.or_else(|| Option::none()).is_none()); + assert(none.or_else(|| Option::some(5)).is_some()); + assert(some.or_else(|| Option::none()).is_some()); + assert(some.or_else(|| Option::some(5)).is_some()); + assert(some.or_else(|| Option::some(ten)).is_some()); + + assert(none.xor(none).is_none()); + assert(none.xor(some).is_some()); + assert(some.xor(none).is_some()); + assert(some.xor(some).is_none()); +} diff --git a/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Nargo.toml new file mode 100644 index 00000000000..b95c3998483 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "references_aliasing" +type = "bin" +authors = [""] +compiler_version = "0.5.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Prover.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/src/main.nr new file mode 100644 index 00000000000..4582444c8f7 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/src/main.nr @@ -0,0 +1,10 @@ +fn increment(mut r: &mut Field) { + *r = *r + 1; +} + +fn main() { + let mut x = 100; + let mut xref = &mut x; + increment(xref); + assert(*xref == 101); +} diff --git a/crates/nargo_cli/tests/compile_success_empty/regression_2099/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/regression_2099/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/regression_2099/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/regression_2099/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/regression_2099/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/regression_2099/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/regression_2099/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/regression_2099/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Prover.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/src/main.nr new file mode 100644 index 00000000000..a368dc58529 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/src/main.nr @@ -0,0 +1,37 @@ +fn f(x: Field) -> Field { + x + 1 +} + +fn ret_fn() -> fn(Field) -> Field { + f +} + +// TODO: in the advanced implicitly generic function with closures branch +// which would support higher-order functions in a better way +// support returning closures: +// +// fn ret_closure() -> fn(Field) -> Field { +// let y = 1; +// let inner_closure = |z| -> Field{ +// z + y +// }; +// inner_closure +// } + +fn ret_lambda() -> fn(Field) -> Field { + let cl = |z: Field| -> Field { + z + 1 + }; + cl +} + +fn main(x : Field) { + let result_fn = ret_fn(); + assert(result_fn(x) == x + 1); + + // let result_closure = ret_closure(); + // assert(result_closure(x) == x + 1); + + let result_lambda = ret_lambda(); + assert(result_lambda(x) == x + 1); +} diff --git a/crates/nargo_cli/tests/execution_success/simple_program_no_body/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_program_no_body/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_program_no_body/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_program_no_body/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_program_no_body/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_program_no_body/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/simple_range/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/simple_range/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/simple_range/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/simple_range/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/distinct_keyword/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/simple_range/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/distinct_keyword/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/simple_range/Prover.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/simple_range/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/simple_range/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/simple_range/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/simple_range/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/str_as_bytes/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/str_as_bytes/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/str_as_bytes/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/str_as_bytes/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/str_as_bytes/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/str_as_bytes/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/str_as_bytes/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/str_as_bytes/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/to_bits/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/to_bits/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/to_bits/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/to_bits/Nargo.toml diff --git a/tooling/nargo_cli/tests/compile_success_empty/to_bits/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/to_bits/src/main.nr new file mode 100644 index 00000000000..65ff9dcac01 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/to_bits/src/main.nr @@ -0,0 +1,23 @@ + +fn main() { + let field = 1000; + let be_bits = field.to_be_bits(16); + let le_bits = field.to_le_bits(16); + + for i in 0..16 { + let x = be_bits[i]; + let y = le_bits[15-i]; + assert(x == y); + } + + let x = 3; + let be_bits_x = x.to_be_bits(4); + let le_bits_x = x.to_le_bits(4); + + for i in 0..4 { + let be_bit = be_bits_x[i]; + let le_bit = le_bits_x[3-i]; + assert(be_bit == le_bit); + } + +} diff --git a/tooling/nargo_cli/tests/compile_success_empty/traits/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/traits/Nargo.toml new file mode 100644 index 00000000000..75fb80c4bfa --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/traits/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/compile_success_empty/traits/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/traits/Prover.toml new file mode 100644 index 00000000000..71805e71e8e --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/traits/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "1" \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_success_empty/traits/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/traits/src/main.nr new file mode 100644 index 00000000000..2333c5da244 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/traits/src/main.nr @@ -0,0 +1,21 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: x, array: [x,y] } + } +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + assert(first.bar == x); +} diff --git a/tooling/nargo_cli/tests/compile_success_empty/unary_operators/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/unary_operators/Nargo.toml new file mode 100644 index 00000000000..65ad7c1c70c --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/unary_operators/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unary_operators" +type = "bin" +authors = [""] +compiler_version = "0.10.3" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_success_empty/unary_operators/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/unary_operators/src/main.nr new file mode 100644 index 00000000000..1c9145fd81f --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/unary_operators/src/main.nr @@ -0,0 +1,7 @@ +fn main() { + let x = -1; + assert(x == 1 - 2); + + let y: i32 = -1; + assert(x == 1 - 2); +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_success_empty/unconstrained_empty/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/unconstrained_empty/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/unconstrained_empty/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/unconstrained_empty/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/unconstrained_empty/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/unconstrained_empty/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/unconstrained_empty/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/unconstrained_empty/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/unit/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/unit/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/unit/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/unit/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/unit/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/unit/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/unit/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/unit/src/main.nr diff --git a/crates/nargo_cli/tests/compile_success_empty/unused_variables/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/unused_variables/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/unused_variables/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/unused_variables/Nargo.toml diff --git a/crates/nargo_cli/tests/compile_success_empty/unused_variables/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/unused_variables/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/compile_success_empty/unused_variables/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/unused_variables/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/vectors/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/vectors/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/vectors/Nargo.toml rename to tooling/nargo_cli/tests/compile_success_empty/vectors/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_slices/Prover.toml b/tooling/nargo_cli/tests/compile_success_empty/vectors/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_slices/Prover.toml rename to tooling/nargo_cli/tests/compile_success_empty/vectors/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/vectors/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/vectors/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/vectors/src/main.nr rename to tooling/nargo_cli/tests/compile_success_empty/vectors/src/main.nr diff --git a/tooling/nargo_cli/tests/execute.rs b/tooling/nargo_cli/tests/execute.rs new file mode 100644 index 00000000000..9e02951573d --- /dev/null +++ b/tooling/nargo_cli/tests/execute.rs @@ -0,0 +1,22 @@ +#[allow(unused_imports)] +#[cfg(test)] +mod tests { + // Some of these imports are consumed by the injected tests + use assert_cmd::prelude::*; + use predicates::prelude::*; + + use std::collections::BTreeMap; + use std::fs; + use std::path::PathBuf; + use std::process::Command; + + use super::*; + + test_binary::build_test_binary_once!( + mock_backend, + "../acvm_backend_barretenberg/test-binaries" + ); + + // include tests generated by `build.rs` + include!(concat!(env!("OUT_DIR"), "/execute.rs")); +} diff --git a/crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/Nargo.toml b/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/Prover.toml b/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/Prover.toml rename to tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/src/main.nr b/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/1327_concrete_in_generic/src/main.nr rename to tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/1_mul/Nargo.toml b/tooling/nargo_cli/tests/execution_success/1_mul/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/1_mul/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/1_mul/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/1_mul/Prover.toml b/tooling/nargo_cli/tests/execution_success/1_mul/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/1_mul/Prover.toml rename to tooling/nargo_cli/tests/execution_success/1_mul/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/1_mul/src/main.nr b/tooling/nargo_cli/tests/execution_success/1_mul/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/1_mul/src/main.nr rename to tooling/nargo_cli/tests/execution_success/1_mul/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/2_div/Nargo.toml b/tooling/nargo_cli/tests/execution_success/2_div/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/2_div/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/2_div/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/2_div/Prover.toml b/tooling/nargo_cli/tests/execution_success/2_div/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/2_div/Prover.toml rename to tooling/nargo_cli/tests/execution_success/2_div/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/2_div/src/main.nr b/tooling/nargo_cli/tests/execution_success/2_div/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/2_div/src/main.nr rename to tooling/nargo_cli/tests/execution_success/2_div/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/3_add/Nargo.toml b/tooling/nargo_cli/tests/execution_success/3_add/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/3_add/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/3_add/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/3_add/Prover.toml b/tooling/nargo_cli/tests/execution_success/3_add/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/3_add/Prover.toml rename to tooling/nargo_cli/tests/execution_success/3_add/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/3_add/src/main.nr b/tooling/nargo_cli/tests/execution_success/3_add/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/3_add/src/main.nr rename to tooling/nargo_cli/tests/execution_success/3_add/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/4_sub/Nargo.toml b/tooling/nargo_cli/tests/execution_success/4_sub/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/4_sub/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/4_sub/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/4_sub/Prover.toml b/tooling/nargo_cli/tests/execution_success/4_sub/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/4_sub/Prover.toml rename to tooling/nargo_cli/tests/execution_success/4_sub/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/4_sub/src/main.nr b/tooling/nargo_cli/tests/execution_success/4_sub/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/4_sub/src/main.nr rename to tooling/nargo_cli/tests/execution_success/4_sub/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/5_over/Nargo.toml b/tooling/nargo_cli/tests/execution_success/5_over/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/5_over/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/5_over/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/5_over/Prover.toml b/tooling/nargo_cli/tests/execution_success/5_over/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/5_over/Prover.toml rename to tooling/nargo_cli/tests/execution_success/5_over/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/5_over/src/main.nr b/tooling/nargo_cli/tests/execution_success/5_over/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/5_over/src/main.nr rename to tooling/nargo_cli/tests/execution_success/5_over/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/6/Nargo.toml b/tooling/nargo_cli/tests/execution_success/6/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/6/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/6/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/6/Prover.toml b/tooling/nargo_cli/tests/execution_success/6/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/6/Prover.toml rename to tooling/nargo_cli/tests/execution_success/6/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/6/src/main.nr b/tooling/nargo_cli/tests/execution_success/6/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/6/src/main.nr rename to tooling/nargo_cli/tests/execution_success/6/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/6_array/Nargo.toml b/tooling/nargo_cli/tests/execution_success/6_array/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/6_array/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/6_array/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/6_array/Prover.toml b/tooling/nargo_cli/tests/execution_success/6_array/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/6_array/Prover.toml rename to tooling/nargo_cli/tests/execution_success/6_array/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/6_array/src/main.nr b/tooling/nargo_cli/tests/execution_success/6_array/src/main.nr new file mode 100644 index 00000000000..cfdcf34d3ad --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/6_array/src/main.nr @@ -0,0 +1,58 @@ +//Basic tests for arrays +fn main(x: [u32; 5], y: [u32; 5], mut z: u32, t: u32) { + let mut c = 2301; + z = y[4]; + //Test 1: + for i in 0..5 { + c = z*z*y[i]; + z -= c; + } + assert(z == 0); //y[4]=0, so c and z are always 0 + + //Test 2: + c = 2301 as u32; + for i in 0..5 { + c = t+2 as u32; + c = z*z*x[i]; + z += x[i]*y[i] - c; + } + assert(z == 3814912846); + + //Test 3: + c = 2300001 as u32; + z = y[4]; + for i in 0..5 { + z = z + x[i]*y[i]; + for _i in 0..3 { + c = i as u32 - 2 as u32; + z *= c; + } + } + assert(z == 41472); + + //Test 4: + z = y[4]; + for i in 0..3 { + z += x[i] * y[i]; + for j in 0..2 { + z += x[i+j] - y[i+j]; + } + } + assert(z == 11539); + + //Test 5: + let cc = if z < 1 { x } else { y }; + assert(cc[0] == y[0]); + + // Test 6: for-each loops + for y_elem in y { + for x_elem in x { + assert(x_elem != y_elem); + } + } + + // Test 7: Arrays of tuples/structs + let mut tuple_array = [(1, 2), (3, 4), (5, 6)]; + tuple_array[1] = (7, 8); + assert(tuple_array[1].1 == 8); +} diff --git a/crates/nargo_cli/tests/execution_success/7/Nargo.toml b/tooling/nargo_cli/tests/execution_success/7/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/7/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/7/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/7/Prover.toml b/tooling/nargo_cli/tests/execution_success/7/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/7/Prover.toml rename to tooling/nargo_cli/tests/execution_success/7/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/7/src/main.nr b/tooling/nargo_cli/tests/execution_success/7/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/7/src/main.nr rename to tooling/nargo_cli/tests/execution_success/7/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/7_function/Nargo.toml b/tooling/nargo_cli/tests/execution_success/7_function/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/7_function/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/7_function/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/7_function/Prover.toml b/tooling/nargo_cli/tests/execution_success/7_function/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/7_function/Prover.toml rename to tooling/nargo_cli/tests/execution_success/7_function/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/7_function/src/main.nr b/tooling/nargo_cli/tests/execution_success/7_function/src/main.nr new file mode 100644 index 00000000000..c664a791636 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/7_function/src/main.nr @@ -0,0 +1,149 @@ +//Tests for function calling +fn f1(mut x: Field) -> Field { + x = x + 1; + x = f2(x); + x +} + +fn f2(mut x: Field) -> Field{ + x += 2; + x +} + +// Simple example +fn test0(mut a: Field) { + a = f2(a); + assert(a == 3); +} + +// Nested call +fn test1(mut a: Field) { + a = f1(a); + assert(a == 4); +} + +fn test2(z: Field, t: u32 ) { + let a = z + t as Field; + assert(a == 64); + let e = pow(z, t as Field); + assert(e == 714924299); +} + +fn pow(base: Field, exponent: Field) -> Field { + let mut r = 1 as Field; + let b = exponent.to_le_bits(32 as u32); + for i in 1..33 { + r = r*r; + r = (b[32-i] as Field) * (r * base) + (1 - b[32-i] as Field) * r; + } + r +} + +fn test3(x: [u8; 3]) -> [u8; 3] { + let mut buffer = [0 as u8; 3]; + for i in 0..3 { + buffer[i] = x[i]; + } + assert(buffer == x); + buffer +} + +fn test_multiple(x: u32, y: u32) -> (u32, u32) { + (y,x) +} + +fn test_multiple2() -> my_struct { + my_struct { a: 5 as u32, b: 7 as u32 } +} + +fn test_multiple3(x: u32, y: u32) { + assert(x == y); +} + +struct my_struct { + a: u32, + b: u32, +} + +struct my2 { + aa: my_struct, + bb: my_struct, +} + +fn test_multiple4(s: my_struct) { + assert(s.a == s.b+2); +} + +fn test_multiple5(a: (u32, u32)) { + assert(a.0 == a.1+2); +} + + +fn test_multiple6(a: my2, b: my_struct, c: (my2, my_struct)) { + test_multiple4(a.aa); + test_multiple5((b.a, b.b)); + assert(c.0.aa.a == c.1.a); +} + + + +fn foo(a: [Field; N]) -> [Field; N] { + a +} + +fn bar() -> [Field; 1] { + foo([0]) +} + +fn main(x: u32 , y: u32 , a: Field, arr1: [u32; 9], arr2: [u32; 9]) { + let mut ss: my_struct = my_struct { b: x, a: x+2, }; + test_multiple4(ss); + test_multiple5((ss.a,ss.b)); + let my = my2 { + aa: ss, + bb: ss, + }; + ss.a = 61; + test_multiple6(my, ss, (my,ss)); + + let my_block = { + let mut ab = f2(a); + ab = ab + a; + (x,ab) + }; + assert(my_block.1 == 4); + + test0(a); + test1(a); + test2(x as Field, y); + assert(bar()[0] == 0); + + let mut b = [0 as u8, 5 as u8, 2 as u8]; + let c = test3(b); + assert(b == c); + b[0] = 1 as u8; + let cc = test3(b); + assert(c != cc); + let e = test_multiple(x, y); + assert(e.1 == e.0 + 54 as u32); + let d = test_multiple2(); + assert(d.b == d.a + 2 as u32); + test_multiple3(y, y); + + //Regression test for issue #628: + let result = first(arr_to_field(arr1), arr_to_field(arr2)); + assert(result[0] == arr1[0] as Field); +} + +// Issue #628 +fn arr_to_field(arr: [u32; 9]) -> [Field; 9] { + let mut as_field: [Field; 9] = [0 as Field; 9]; + for i in 0..9 { + as_field[i] = arr[i] as Field; + } + as_field +} + +fn first(a: [Field; 9], _b: [Field; 9]) -> [Field; 9] { + a +} diff --git a/crates/nargo_cli/tests/execution_success/8_integration/Nargo.toml b/tooling/nargo_cli/tests/execution_success/8_integration/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/8_integration/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/8_integration/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/8_integration/Prover.toml b/tooling/nargo_cli/tests/execution_success/8_integration/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/8_integration/Prover.toml rename to tooling/nargo_cli/tests/execution_success/8_integration/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/8_integration/src/main.nr b/tooling/nargo_cli/tests/execution_success/8_integration/src/main.nr new file mode 100644 index 00000000000..52f53efd3aa --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/8_integration/src/main.nr @@ -0,0 +1,283 @@ +fn matrix_mul_2(a: [u32; 4], b: [u32; 4]) ->[u32; 4] { + let mut c = [0 as u32; 4]; + for i in 0..2 { + for j in 0..2 { + c[i+2*j] = 0; + for k in 0..2 { + c[i+2*j] += a[i+2*k] * b[k+2*j]; + } + } + } + c +} + +fn matrix_mul_10(a: [u32; 100], b: [u32; 100]) -> [u32; 100] { + let mut c = [0 as u32; 100]; + for i in 0..10 { + for j in 0..10 { + c[i+10*j] = 0 as u32; + + for k in 0..10 { + c[i+10*j] += a[i+10*k] * b[k+10*j]; + } + } + } + c +} + + +fn siggy(x: u32) -> u32 { + x * (10 as u32) +} + + +fn test4 (mut a: [u32; 4]) -> [u32; 4] { + for i in 3..4 { + a[i] = siggy(a[i-2]); + } + a +} + +fn iterate1(mut a0: u32) -> u32{ + let mut t1 = 0 as u32; + let mut t2 = 0 as u32; + let mut a = 1 as u32; + let mut f = 2 as u32; + let mut g = 3 as u32; + let mut h = 4 as u32; + + for _i in 0..2 { + t1 = h; + h = g; + g = f; + a = t1 + t2; + } + a0 += a; + a0 +} + +fn array_noteq(a: [u32; 4], b: [u32; 4]) { + assert(a != b); +} + +fn test3(mut b: [Field; 4]) -> [Field; 4] { + for i in 0..4 { + b[i] = i; + } + b +} + +fn iterate2(mut hash: [u32; 8]) -> [u32; 8] { + let mut t1 = 0 as u32; + + let mut a = hash[0]; + let mut e = hash[4]; + let mut f = hash[5]; + let mut g = hash[6]; + let mut h = hash[7]; + + for _i in 0..2 { + t1 = ch2(e, f); + h = g; + g = f; + a = t1; + } + + hash[0] = hash[0] + a; + hash +} + +fn iterate3( mut hash: [u32; 8]) -> [u32; 8] { + let mut t1 = 0 as u32; + let mut t2 = 0 as u32; + let mut a = hash[0]; + let mut b = hash[1]; + let mut c = hash[2]; + let mut d = hash[3]; + let mut e = hash[4]; + let mut f = hash[5]; + let mut g = hash[6]; + let mut h = hash[7]; + + for _i in 0..3 { + t1 = ep2(e)+ch2(e, f); + h = g; + g = f; + a = t1+t2; + } + assert(a == 2470696267); + hash[0] = hash[0] + a; + hash[1] = hash[1] + b; + hash[2] = hash[2] + c; + hash[3] = hash[3] + d; + hash[4] = hash[4] + e; + hash[5] = hash[5] + f; + hash[6] = hash[6] + g; + hash[7] = hash[7] + h; + hash +} + + +fn test5() { + let mut sha_hash = [ + 0 as u32, 1, 2, 3, + 4, 5, 6, 7 + ]; + + sha_hash = iterate2(sha_hash); + + assert(sha_hash[0] == 9); +} + + +fn ch2(x: u32, y: u32) -> u32 { + x + y +} + +fn ep2(x: u32) -> u32 { + (2 as u32) * too(x) +} + +fn too(x: u32) -> u32 { + (x + 17 as u32) * (x + 3 as u32) +} + +fn test6(x: [u8; 32]) -> [u32; 8] { + let mut sha_m = [0 as u32; 64]; + + let mut sha_hash = [ + 1 as u32, 2, 3, 4, 5, 6, 7, 8 + ]; + + let mut buffer = [0 as u8; 64]; + for i in 0..32 { + buffer[i] = x[i]; + } + + sha_m = iterate6_1(sha_m, buffer); + sha_hash = iterate6_2(sha_m, sha_hash); + sha_hash +} + +fn iterate6_1(mut sha_m: [u32; 64], next_chunk: [u8; 64]) -> [u32; 64] { + let mut j = 0; + for i in 0..16 { + j = (i ) * 4; + sha_m[i] = ((next_chunk[j] as u32) << 24 as u32) + | ((next_chunk[j + 1] as u32) << 16 as u32) + | ((next_chunk[j + 2] as u32) << 8 as u32) + | (next_chunk[j + 3] as u32); + } + for i in 16..64 { + sha_m[i] = sig1(sha_m[i - 2])+(sha_m[i - 7])+(sig0(sha_m[i - 15]))+(sha_m[i - 16]); + } + sha_m +} + +fn iterate6_2(sha_m: [u32; 64], mut hash: [u32; 8]) -> [u32; 8] { + let mut t1 = 0 as u32; + let mut t2 = 0 as u32; + let mut a = 1 as u32; + let mut b = 2 as u32; + let mut c = 3 as u32; + let mut d = 4 as u32; + let mut e = 5 as u32; + let mut f = 6 as u32; + let mut g = 7 as u32; + let mut h = 8 as u32; + + for i in 0..11 { + t1 = h + ep1(e) + ch(e, f, g) + sha_m[i]; + t2 = epo(a) + maj(a, b, c); + h = g; + g = f; + f = e; + e = d+t1; + d = c; + c = b; + b = a; + a = t1+t2; + } + + hash[0] = hash[0]+a; + hash[1] = hash[1]+b; + hash[2] = hash[2]+c; + hash[3] = hash[3]+d; + hash[4] = hash[4]+e; + hash[5] = hash[5]+f; + hash[6] = hash[6]+g; + hash[7] = hash[7]+h; + hash +} + +fn rot_right(a: u32, b: u32) -> u32 { + ((a >> b) | (a << (32 as u32 - b))) +} + + +fn ch(x: u32, y: u32, z: u32) -> u32 { + ((x & y) ^ (!x & z)) +} + + +fn maj(x: u32, y: u32, z: u32) -> u32 { + ((x & y) ^ (x & z) ^ (y & z)) +} + + +fn epo(x: u32) -> u32 { + (rot_right(x, 2) ^ rot_right(x, 13) ^ rot_right(x, 22)) +} + +fn ep1(x: u32) -> u32 { + (rot_right(x, 6) ^ rot_right(x, 11) ^ rot_right(x, 25)) +} + +fn sig0(x: u32) -> u32 { + (rot_right(x, 7) ^ rot_right(x, 18) ^ (x >> 3)) +} + +fn sig1(x: u32) -> u32 { + (rot_right(x, 17) ^ rot_right(x, 19) ^ (x >> 10)) +} + + +fn main(a: [u32; 100], b: [u32; 100], c: [u32; 4], mut d: [u32; 4], m: [u8; 32]) { + let e = matrix_mul_10(a,b); + assert(e[6] == 1866842232); + let f = matrix_mul_2(c,d); + assert(f[3] == 2082554100); + + let mut a = [1 as u32, 2, 3, 4]; + a = test4(a); + assert(a[3] == 20); + a = test4(c); + assert(a[3] == c[1] * 10); + + d[0] += c[0]; + d[0] += c[1]; + assert(d[0] == 2739986880); + + let h = iterate1(1); + assert(h == 4); + + let x = d; + array_noteq(x, [d[0], d[1], d[2], 0]); + + let mut h5 = [d[0] as Field, d[1] as Field, d[2] as Field, d[3] as Field]; + let t5 = test3(h5); + assert(t5[3] == 3); + h5 = test3(h5); + assert(h5[3] == 3); + + test5(); + + let mut sha_hash = [ + 0x6a09e667 as u32, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 + ]; + sha_hash = iterate3(sha_hash); + + let h6 = test6(m); + assert(h6[0] == 523008072); //31.. 3800709683 +} diff --git a/crates/nargo_cli/tests/execution_success/9_conditional/Nargo.toml b/tooling/nargo_cli/tests/execution_success/9_conditional/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/9_conditional/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/9_conditional/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/9_conditional/Prover.toml b/tooling/nargo_cli/tests/execution_success/9_conditional/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/9_conditional/Prover.toml rename to tooling/nargo_cli/tests/execution_success/9_conditional/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/9_conditional/src/main.nr b/tooling/nargo_cli/tests/execution_success/9_conditional/src/main.nr new file mode 100644 index 00000000000..c1091304e03 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/9_conditional/src/main.nr @@ -0,0 +1,277 @@ +use dep::std; + +fn sort(mut a: [u32; 4]) -> [u32; 4] { + for i in 1..4 { + for j in 0..i { + if a[i] < a[j] { + let c = a[j]; + a[j] = a[i]; + a[i] = c; + } + } + } + a +} + +fn call_intrinsic(x: [u8; 5], result: [u8; 32]) { + let mut digest = std::hash::sha256(x); + digest[0] = 5 as u8; + digest = std::hash::sha256(x); + assert(digest == result); +} + +fn must_be_zero(x: u8) { + assert(x == 0); +} + +fn test3 (x: u8) { + if x == 0 { + must_be_zero(x); + } +} + +fn test4() -> [u32; 4] { + let b: [u32; 4] = [1,2,3,4]; + b +} + +fn main(a: u32, mut c: [u32; 4], x: [u8; 5], result: pub [u8; 32]){ + // Regression test for issue #547 + // Warning: it must be kept at the start of main + let arr: [u8; 2] = [1, 2]; + if arr[0] != arr[1] { + for i in 0..1 { + assert(i != 2); + } + } + + //Issue reported in #421 + if a == c[0] { + assert(c[0] == 0); + } else { + if a == c[1] { + assert(c[1] == 0); + } else { + if a == c[2] { + assert(c[2] == 0); + } + } + } + + //Regression for to_le_bits() constant evaluation + // binary array representation of u8 1 + let as_bits_hardcode_1 = [1, 0]; + let mut c1 = 0; + for i in 0..2 { + let mut as_bits = (arr[i] as Field).to_le_bits(2); + c1 = c1 + as_bits[0] as Field; + + if i == 0 { + assert(arr[i] == 1);// 1 + for k in 0..2 { + assert(as_bits_hardcode_1[k] == as_bits[k]); + } + } + if i == 1 { + assert(arr[i] == 2);//2 + for k in 0..2 { + assert(as_bits_hardcode_1[k] != as_bits[k]); + } + } + } + assert(c1 == 1); + + //Regression for Issue #579 + let result1_true = test(true); + assert(result1_true.array_param[0] == 1); + let result1_false = test(false); + assert(result1_false.array_param[0] == 0); + + //Test case for short-circuit + let mut data = [0 as u32; 32]; + let mut ba = a; + for i in 0..32 { + let i_u32 = i as u32; + if i_u32 == a { + for j in 0..4 { + data[i + j] = c[4 - 1 - j]; + for k in 0..4 { + ba = ba +data[k]; + } + if ba == 4864 { + c[3]=ba; + } + } + } + } + assert(data[31] == 0); + assert(ba != 13); + //regression for short-circuit2 + if 35 == a { + assert(false); + } + bar(a as Field); + + if a == 3 { + c = test4(); + } + assert(c[1] != 2); + call_intrinsic(x, result); + + //Test case for conditional with arrays from function parameters + let b = sort([1,2,3,4]); + assert(b[0] == 1); + + if a == 0 { + must_be_zero(0); + c[0] = 3; + } else { + must_be_zero(1); + c[0] = 1; + c[1] = c[2] / a + 11 % a; + let f1 = a as Field; + assert(10/f1 != 0); + } + assert(c[0] == 3); + + let mut y = 0; + if a == 0 { + let digest = std::hash::sha256(x); + y = digest[0]; + } else { + y = 5; + } + assert(y == result[0]); + c = sort(c); + assert(c[0] == 0); + + //test 1 + let mut x: u32 = 0; + if a == 0 { + c[0] = 12; + if a != 0 { + x = 6; + } else { + x = 2; + assert(x == 2); + } + } else { + x = 5; + assert(x == 5); + } + if c[0] == 0 { + x = 3; + } + assert(x == 2); + + //test2: loops! + x = 0; + x = a - a; + for i in 0..4 { + if c[i] == 0 { + x = i as u32 +2; + } + } + assert(x == 0); + + test3(1); + + if a == 0 { + c = test4(); + } else { + assert(c[1] != 2); + } + if false { + c[1] = 5; + } + assert(c[1] == 2); + + test5(4); + + // Regression for issue #661: + let mut c_661 :[u32;1]=[0]; + if a > 5 { + c_661 = issue_661_foo(issue_661_bar(c), a); + } else { + c_661 = issue_661_foo(issue_661_bar(c), x); + } + assert(c_661[0] < 20000); + + // Test case for function synchronisation + let mut c_sync = 0; + if a == 42 { + c_sync = foo2(); + } else { + c_sync = foo2() + foo2(); + } + assert(c_sync == 6); + + // Regression for predicate simplification + safe_inverse(0); +} + +fn test5(a : u32) { + if a > 1 { + let q = a / 2; + assert(q == 2); + } +} + + + +fn foo() { + let mut x = 1; + x /= 0; +} + +fn bar(x:Field) { + if x == 15 { + foo(); + } +} + + +struct MyStruct579 { + array_param: [u32; 2] +} + +impl MyStruct579 { + fn new(array_param: [u32; 2]) -> MyStruct579 { + MyStruct579 { + array_param: array_param + } + } +} + +fn test(flag: bool) -> MyStruct579 { + let mut my_struct = MyStruct579::new([0; 2]); + + if flag == true { + my_struct= MyStruct579::new([1; 2]); + } + my_struct +} + +fn issue_661_foo(array: [u32;4], b:u32) ->[u32;1] { + [array[0]+b] +} + +fn issue_661_bar(a : [u32;4]) ->[u32;4] { + let mut b:[u32;4] = [0;4]; + b[0]=a[0]+1; + b +} + +fn foo2() -> Field { + 3 +} + +fn safe_inverse(n: Field) -> Field +{ + if n == 0 { + 0 + } + else { + 1 / n + } +} diff --git a/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/Nargo.toml b/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/Prover.toml b/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/arithmetic_binary_operations/Prover.toml rename to tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/src/main.nr b/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/src/main.nr new file mode 100644 index 00000000000..201353393a6 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/src/main.nr @@ -0,0 +1,16 @@ +// Tests a very simple program. +// +// The features being tested are: +// Binary addition, multiplication, division, constant modulo +// x = 3, y = 4, z = 5 +fn main(x : Field, y : Field, z : Field) -> pub Field { + //constant modulo + assert(x % 2 == 1); + assert(y as u1 == 0); + + let a = x + x; // 3 + 3 = 6 + let b = a - y; // 6 - 4 = 2 + let c = b * z; // 2 * 5 = 10 + let d = c / a; // 10 / 6 (This uses field inversion, so we test it by multiplying by `a`) + d * a +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/array_dynamic/Nargo.toml b/tooling/nargo_cli/tests/execution_success/array_dynamic/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_dynamic/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/array_dynamic/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/array_dynamic/Prover.toml b/tooling/nargo_cli/tests/execution_success/array_dynamic/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_dynamic/Prover.toml rename to tooling/nargo_cli/tests/execution_success/array_dynamic/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/array_dynamic/src/main.nr b/tooling/nargo_cli/tests/execution_success/array_dynamic/src/main.nr new file mode 100644 index 00000000000..db8f10b27e9 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/array_dynamic/src/main.nr @@ -0,0 +1,32 @@ + +fn main(x: [u32; 5], mut z: u32, t: u32, index: [Field;5], index2: [Field;5], offset: Field, sublen: Field) { + let idx = (z - 5*t - 5) as Field; + //dynamic array test + dyn_array(x, idx, idx - 3); + + //regression for issue 1283 + let mut s = 0; + let x3 = [246,159,32,176,8]; + for i in 0..5 { + s += x3[index[i]]; + } + assert(s!=0); + + if 3 < (sublen as u32) { + assert(index[offset + 3] == index2[3]); + } +} + +fn dyn_array(mut x: [u32; 5], y: Field, z: Field) { + assert(x[y] == 111); + assert(x[z] == 101); + x[z] = 0; + assert(x[y] == 111); + assert(x[1] == 0); + if y as u32 < 10 { + x[y] = x[y] - 2; + } else { + x[y] = 0; + } + assert(x[4] == 109); +} diff --git a/tooling/nargo_cli/tests/execution_success/array_eq/Nargo.toml b/tooling/nargo_cli/tests/execution_success/array_eq/Nargo.toml new file mode 100644 index 00000000000..4a9bd6293c0 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/array_eq/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "array_eq" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/execution_success/array_eq/Prover.toml b/tooling/nargo_cli/tests/execution_success/array_eq/Prover.toml new file mode 100644 index 00000000000..ecfed7de213 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/array_eq/Prover.toml @@ -0,0 +1,2 @@ +a = [77,75,108,209,54,16,50,202,155,210,174,185,217,0,170,77,69,217,234,216,10,201,66,51,116,196,81,167,37,77,7,102] +b = [77,75,108,209,54,16,50,202,155,210,174,185,217,0,170,77,69,217,234,216,10,201,66,51,116,196,81,167,37,77,7,102] diff --git a/tooling/nargo_cli/tests/execution_success/array_eq/src/main.nr b/tooling/nargo_cli/tests/execution_success/array_eq/src/main.nr new file mode 100644 index 00000000000..d1771ed91a6 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/array_eq/src/main.nr @@ -0,0 +1,4 @@ +// Simple example of checking where two arrays are equal +fn main(a: [Field; 32], b: [Field; 32]) { + assert(a == b); +} diff --git a/crates/nargo_cli/tests/execution_success/array_len/Nargo.toml b/tooling/nargo_cli/tests/execution_success/array_len/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_len/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/array_len/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/array_len/Prover.toml b/tooling/nargo_cli/tests/execution_success/array_len/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_len/Prover.toml rename to tooling/nargo_cli/tests/execution_success/array_len/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/array_len/src/main.nr b/tooling/nargo_cli/tests/execution_success/array_len/src/main.nr new file mode 100644 index 00000000000..3e9d3603311 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/array_len/src/main.nr @@ -0,0 +1,26 @@ +fn len_plus_1(array: [T; N]) -> Field { + array.len() + 1 +} + +fn add_lens(a: [T; N], b: [Field; M]) -> Field { + a.len() + b.len() +} + +fn nested_call(b: [Field; N]) -> Field { + len_plus_1(b) +} + +fn main(x: Field, len3: [u8; 3], len4: [Field; 4]) { + assert(len_plus_1(len3) == 4); + assert(len_plus_1(len4) == 5); + assert(add_lens(len3, len4) == 7); + assert(nested_call(len4) == 5); + + // std::array::len returns a compile-time known value + assert(len4[len3.len()] == 4); + + // Regression for #1023, ensure .len still works after calling to_le_bytes on a witness. + // This was needed because normally .len is evaluated before acir-gen where to_le_bytes + // on a witness is only evaluated during/after acir-gen. + assert(x.to_le_bytes(8).len() != 0); +} diff --git a/crates/nargo_cli/tests/execution_success/array_neq/Nargo.toml b/tooling/nargo_cli/tests/execution_success/array_neq/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_neq/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/array_neq/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/array_neq/Prover.toml b/tooling/nargo_cli/tests/execution_success/array_neq/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_neq/Prover.toml rename to tooling/nargo_cli/tests/execution_success/array_neq/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/array_neq/src/main.nr b/tooling/nargo_cli/tests/execution_success/array_neq/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_neq/src/main.nr rename to tooling/nargo_cli/tests/execution_success/array_neq/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/array_sort/Nargo.toml b/tooling/nargo_cli/tests/execution_success/array_sort/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_sort/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/array_sort/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/array_sort/Prover.toml b/tooling/nargo_cli/tests/execution_success/array_sort/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_sort/Prover.toml rename to tooling/nargo_cli/tests/execution_success/array_sort/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/array_sort/src/main.nr b/tooling/nargo_cli/tests/execution_success/array_sort/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/array_sort/src/main.nr rename to tooling/nargo_cli/tests/execution_success/array_sort/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/assert/Nargo.toml b/tooling/nargo_cli/tests/execution_success/assert/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/assert/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/assert/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/assert/Prover.toml b/tooling/nargo_cli/tests/execution_success/assert/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/assert/Prover.toml rename to tooling/nargo_cli/tests/execution_success/assert/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/assert/src/main.nr b/tooling/nargo_cli/tests/execution_success/assert/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/assert/src/main.nr rename to tooling/nargo_cli/tests/execution_success/assert/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/assert_statement/Nargo.toml b/tooling/nargo_cli/tests/execution_success/assert_statement/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/assert_statement/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/assert_statement/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/assert_statement/Prover.toml b/tooling/nargo_cli/tests/execution_success/assert_statement/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/assert_statement/Prover.toml rename to tooling/nargo_cli/tests/execution_success/assert_statement/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/assert_statement/src/main.nr b/tooling/nargo_cli/tests/execution_success/assert_statement/src/main.nr new file mode 100644 index 00000000000..74e93249741 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/assert_statement/src/main.nr @@ -0,0 +1,7 @@ +// Tests a very simple program. +// +// The features being tested is assertion +fn main(x : Field, y : Field) { + assert(x == y, "x and y are not equal"); + assert_eq(x, y, "x and y are not equal"); +} diff --git a/crates/nargo_cli/tests/execution_success/assign_ex/Nargo.toml b/tooling/nargo_cli/tests/execution_success/assign_ex/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/assign_ex/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/assign_ex/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/assign_ex/Prover.toml b/tooling/nargo_cli/tests/execution_success/assign_ex/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/assign_ex/Prover.toml rename to tooling/nargo_cli/tests/execution_success/assign_ex/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/assign_ex/src/main.nr b/tooling/nargo_cli/tests/execution_success/assign_ex/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/assign_ex/src/main.nr rename to tooling/nargo_cli/tests/execution_success/assign_ex/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/bit_and/Nargo.toml b/tooling/nargo_cli/tests/execution_success/bit_and/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bit_and/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/bit_and/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/bit_and/Prover.toml b/tooling/nargo_cli/tests/execution_success/bit_and/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bit_and/Prover.toml rename to tooling/nargo_cli/tests/execution_success/bit_and/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/bit_and/src/main.nr b/tooling/nargo_cli/tests/execution_success/bit_and/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/bit_and/src/main.nr rename to tooling/nargo_cli/tests/execution_success/bit_and/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/Nargo.toml b/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bit_shifts_comptime/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_comptime/Prover.toml b/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bit_shifts_comptime/Prover.toml rename to tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/src/main.nr b/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/src/main.nr new file mode 100644 index 00000000000..e4ca1bd92cc --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/src/main.nr @@ -0,0 +1,23 @@ +fn main(x: u64) { + let two: u64 = 2; + let three: u64 = 3; + + // shifts on constant values + assert(two << 2 == 8); + assert((two << 3) / 8 == two); + assert((three >> 1) == 1); + + // shifts on runtime values + assert(x << 1 == 128); + assert(x >> 2 == 16); + + regression_2250(); +} + +fn regression_2250() { + let a: u1 = 1 >> 1; + assert(a == 0); + + let b: u32 = 1 >> 32; + assert(b == 0); +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/Nargo.toml b/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bit_shifts_runtime/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/Prover.toml b/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bit_shifts_runtime/Prover.toml rename to tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/bit_shifts_runtime/src/main.nr b/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/bit_shifts_runtime/src/main.nr rename to tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/bool_not/Nargo.toml b/tooling/nargo_cli/tests/execution_success/bool_not/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bool_not/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/bool_not/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/bool_not/Prover.toml b/tooling/nargo_cli/tests/execution_success/bool_not/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bool_not/Prover.toml rename to tooling/nargo_cli/tests/execution_success/bool_not/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/bool_not/src/main.nr b/tooling/nargo_cli/tests/execution_success/bool_not/src/main.nr new file mode 100644 index 00000000000..a0afe770121 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/bool_not/src/main.nr @@ -0,0 +1,4 @@ +fn main(x: u1) { + assert(!x == 0); +} + diff --git a/crates/nargo_cli/tests/execution_success/bool_or/Nargo.toml b/tooling/nargo_cli/tests/execution_success/bool_or/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bool_or/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/bool_or/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/bool_or/Prover.toml b/tooling/nargo_cli/tests/execution_success/bool_or/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/bool_or/Prover.toml rename to tooling/nargo_cli/tests/execution_success/bool_or/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/bool_or/src/main.nr b/tooling/nargo_cli/tests/execution_success/bool_or/src/main.nr new file mode 100644 index 00000000000..87d7e870063 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/bool_or/src/main.nr @@ -0,0 +1,6 @@ +fn main(x: u1, y: u1) { + assert(x | y == 1); + + assert(x | y | x == 1); +} + diff --git a/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_acir_as_brillig/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_arrays/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_arrays/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_arrays/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_arrays/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_arrays/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_arrays/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_arrays/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_arrays/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_arrays/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_arrays/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_arrays/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_arrays/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_assert/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_assert/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_assert/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_assert/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_assert/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_assert/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_assert/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_assert/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_assert/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_assert/src/main.nr new file mode 100644 index 00000000000..632c72f2393 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_assert/src/main.nr @@ -0,0 +1,12 @@ +// Tests a very simple program. +// +// The features being tested is using assert on brillig +fn main(x: Field) { + assert(1 == conditional(x as bool)); +} + +unconstrained fn conditional(x : bool) -> Field { + assert(x, "x is false"); + assert_eq(x, true, "x is false"); + 1 +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_blake2s/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_blake2s/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_blake2s/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_blake2s/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_blake2s/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_blake2s/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_blake2s/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_blake2s/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_blake2s/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_blake2s/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_blake2s/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_blake2s/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_calls/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_calls/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_calls/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_calls/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_calls/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_calls/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_calls/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_calls/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_calls/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_array/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_calls_array/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_calls_array/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_calls_array/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_array/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_calls_array/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_calls_array/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_calls_array/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_calls_array/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_calls_array/src/main.nr new file mode 100644 index 00000000000..3af825c38f9 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_calls_array/src/main.nr @@ -0,0 +1,33 @@ +// Tests a very simple program. +// +// The features being tested is brillig calls passing arrays around +fn main(x: [u32; 3]) { + assert(entry_point(x) == 9); + another_entry_point(x); +} + +unconstrained fn inner(x : [u32; 3]) -> [u32; 3] { + [x[0] + 1, x[1] + 1, x[2] + 1] +} + +unconstrained fn entry_point(x : [u32; 3]) -> u32 { + let y = inner(x); + y[0] + y[1] + y[2] +} + +unconstrained fn nested_fn_that_allocates(value: u32) -> u32 { + let x = [value, value, value]; + let y = inner(x); + y[0] + y[1] + y[2] +} + +unconstrained fn another_entry_point(x: [u32; 3]) { + assert(x[0] == 1); + assert(x[1] == 2); + assert(x[2] == 3); + assert(nested_fn_that_allocates(1) == 6); + // x should be unchanged + assert(x[0] == 1); + assert(x[1] == 2); + assert(x[2] == 3); +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_calls_conditionals/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_conditional/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_conditional/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_conditional/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_conditional/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_conditional/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_conditional/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_conditional/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_conditional/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_conditional/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_conditional/src/main.nr new file mode 100644 index 00000000000..96e5217ca65 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_conditional/src/main.nr @@ -0,0 +1,14 @@ +// Tests a very simple program. +// +// The features being tested is basic conditonal on brillig +fn main(x: Field) { + assert(4 == conditional(x == 1)); +} + +unconstrained fn conditional(x : bool) -> Field { + if x { + 4 + }else { + 5 + } +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_ecdsa/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_ecdsa/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_ecdsa/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_ecdsa/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_ecdsa/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_ecdsa/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/src/main.nr new file mode 100644 index 00000000000..9b4627adf40 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/src/main.nr @@ -0,0 +1,12 @@ +use dep::std; + +// Tests a very simple program. +// +// The features being tested is ecdsa in brillig +fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + assert(ecdsa(hashed_message, pub_key_x, pub_key_y, signature)); +} + +unconstrained fn ecdsa(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) -> bool { + std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message) +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_fns_as_values/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_fns_as_values/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_fns_as_values/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/src/main.nr new file mode 100644 index 00000000000..d0985a9012d --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/src/main.nr @@ -0,0 +1,34 @@ +struct MyStruct { + operation: fn (u32) -> u32, +} + +fn main(x: u32) { + assert(wrapper(increment, x) == x + 1); + assert(wrapper(increment_acir, x) == x + 1); + assert(wrapper(decrement, x) == x - 1); + assert(wrapper_with_struct(MyStruct { operation: increment }, x) == x + 1); + assert(wrapper_with_struct(MyStruct { operation: decrement }, x) == x - 1); + // https://github.com/noir-lang/noir/issues/1975 + assert(increment(x) == x + 1); +} + +unconstrained fn wrapper(func: fn (u32) -> u32, param: u32) -> u32 { + func(param) +} + +unconstrained fn increment(x: u32) -> u32 { + x + 1 +} + +unconstrained fn decrement(x: u32) -> u32 { + x - 1 +} + +unconstrained fn wrapper_with_struct(my_struct: MyStruct, param: u32) -> u32 { + let func = my_struct.operation; + func(param) +} + +fn increment_acir(x: u32) -> u32 { + x + 1 +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_hash_to_field/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_hash_to_field/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_hash_to_field/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_hash_to_field/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_hash_to_field/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_hash_to_field/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_identity_function/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_identity_function/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_identity_function/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_identity_function/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_identity_function/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_identity_function/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_identity_function/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_identity_function/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_identity_function/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_identity_function/src/main.nr new file mode 100644 index 00000000000..f711c5e86ba --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_identity_function/src/main.nr @@ -0,0 +1,33 @@ +struct myStruct { + foo: Field, + foo_arr: [Field; 2], +} + +// Tests a very simple program. +// +// The features being tested is the identity function in Brillig +fn main(x : Field) { + assert(x == identity(x)); + // TODO: add support for array comparison + let arr = identity_array([x, x]); + assert(x == arr[0]); + assert(x == arr[1]); + + let s = myStruct { foo: x, foo_arr: [x, x] }; + let identity_struct = identity_struct(s); + assert(x == identity_struct.foo); + assert(x == identity_struct.foo_arr[0]); + assert(x == identity_struct.foo_arr[1]); +} + +unconstrained fn identity(x : Field) -> Field { + x +} + +unconstrained fn identity_array(arr : [Field; 2]) -> [Field; 2] { + arr +} + +unconstrained fn identity_struct(s : myStruct) -> myStruct { + s +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_keccak/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_keccak/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_keccak/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_keccak/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_keccak/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_keccak/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_keccak/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_keccak/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_keccak/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_keccak/src/main.nr new file mode 100644 index 00000000000..fcc2a772d10 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_keccak/src/main.nr @@ -0,0 +1,27 @@ +use dep::std; + +// Tests a very simple program. +// +// The features being tested is keccak256 in brillig +fn main(x: Field, result: [u8; 32]) { + // We use the `as` keyword here to denote the fact that we want to take just the first byte from the x Field + // The padding is taken care of by the program + let digest = keccak256([x as u8], 1); + assert(digest == result); + + //#1399: variable meesage size + let message_size = 4; + let hash_a = keccak256([1,2,3,4], message_size); + let hash_b = keccak256([1,2,3,4,0,0,0,0], message_size); + + assert(hash_a == hash_b); + + let message_size_big = 8; + let hash_c = keccak256([1,2,3,4,0,0,0,0], message_size_big); + + assert(hash_a != hash_c); +} + +unconstrained fn keccak256(data: [u8; N], msg_len: u32) -> [u8; 32] { + std::hash::keccak256(data, msg_len) +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_loop/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_loop/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_loop/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_loop/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_loop/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_loop/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_loop/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_loop/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_loop/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_loop/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_loop/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_loop/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_nested_arrays/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_nested_arrays/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_arrays/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_nested_arrays/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_slices/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_nested_slices/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_nested_slices/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_nested_slices/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_nested_slices/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_nested_slices/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/src/main.nr new file mode 100644 index 00000000000..3d8a6748ccf --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/src/main.nr @@ -0,0 +1,72 @@ +use dep::std::slice; +// Tests nested slice passing to/from functions +unconstrained fn push_back_to_slice(slice: [T], item: T) -> [T] { + slice.push_back(item) +} + +struct NestedSliceStruct { + id: Field, + arr: [Field] +} + +unconstrained fn create_foo(id: Field, value: Field) -> NestedSliceStruct { + let mut arr = [id]; + arr = arr.push_back(value); + NestedSliceStruct { id, arr } +} + +unconstrained fn main(a: Field, b: Field) { + let mut slice = [create_foo(a, b), create_foo(b, a)]; + assert(slice.len() == 2); + + assert(slice[0].id == a); + assert(slice[0].arr[0] == a); + assert(slice[1].id == b); + assert(slice[1].arr[1] == a); + + slice = push_back_to_slice(slice, create_foo(0, 42)); + assert(slice.len() == 3); + + assert(slice[0].id == a); + assert(slice[0].arr[0] == a); + assert(slice[1].id == b); + assert(slice[1].arr[1] == a); + + assert(slice[2].id == 0); + assert(slice[2].arr[0] == 0); + assert(slice[2].arr[1] == 42); + + slice = slice.push_front(create_foo(1, 43)); + slice = slice.push_back(create_foo(2, 44)); + + assert(slice.len() == 5); + + let pop_front_result = slice.pop_front(); + slice = pop_front_result.1; + assert(pop_front_result.0.id == 1); + + let pop_back_result = slice.pop_back(); + slice = pop_back_result.0; + assert(pop_back_result.1.id == 2); + + assert(slice.len() == 3); + + let mut remove_result = slice.remove(0); + slice = remove_result.0; + let mut removed_item = remove_result.1; + assert(removed_item.arr[0] == a); + + remove_result = slice.remove(1); + slice = remove_result.0; + removed_item = remove_result.1; + assert(removed_item.arr[0] == 0); + + let last_item = slice[0]; + + assert(last_item.id == b); + slice = slice.insert(1, removed_item); + + assert(slice.len() == 2); + assert(slice[0].id == b); + assert(slice[1].id == 0); +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_not/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_not/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_not/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_not/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_not/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_not/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_not/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_not/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_not/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_not/src/main.nr new file mode 100644 index 00000000000..0466649f67c --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_not/src/main.nr @@ -0,0 +1,11 @@ +// Tests a very simple Brillig function. +// +// The features being tested is not instruction on brillig +fn main(x: Field, y : Field) { + assert(false == not_operator(x as bool)); + assert(true == not_operator(y as bool)); +} + +unconstrained fn not_operator(x : bool) -> bool { + !x +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_oracle/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_oracle/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_oracle/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_oracle/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_oracle/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_oracle/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_oracle/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_oracle/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_oracle/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_oracle/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_oracle/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_oracle/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_pedersen/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_pedersen/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_pedersen/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_pedersen/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_pedersen/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_pedersen/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_pedersen/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_pedersen/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_pedersen/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_pedersen/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_pedersen/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_pedersen/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_recursion/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_recursion/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_recursion/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_recursion/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_recursion/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_recursion/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_recursion/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_recursion/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_recursion/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_recursion/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_recursion/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_recursion/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_references/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_references/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_references/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_references/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_references/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_references/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_references/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_references/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_references/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_references/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_references/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_references/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_scalar_mul/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_scalar_mul/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_scalar_mul/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/src/main.nr new file mode 100644 index 00000000000..8383c7fd2e5 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/src/main.nr @@ -0,0 +1,22 @@ +use dep::std; + +unconstrained fn main( + a: Field, + a_pub_x: pub Field, + a_pub_y: pub Field, + b: Field, + b_pub_x: pub Field, + b_pub_y: pub Field +) { + let mut priv_key = a; + let mut pub_x: Field = a_pub_x; + let mut pub_y: Field = a_pub_y; + if a != 1 { // Change `a` in Prover.toml to test input `b` + priv_key = b; + pub_x = b_pub_x; + pub_y = b_pub_y; + } + let res = std::scalar_mul::fixed_base_embedded_curve(priv_key, 0); + assert(res[0] == pub_x); + assert(res[1] == pub_y); +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_schnorr/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_schnorr/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_schnorr/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_schnorr/Nargo.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_schnorr/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_schnorr/Prover.toml new file mode 100644 index 00000000000..5fe6bd2546f --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_schnorr/Prover.toml @@ -0,0 +1,10 @@ +message = [0,1,2,3,4,5,6,7,8,9] +message_field = "0x010203040506070809" +pub_key_x = "0x17cbd3ed3151ccfd170efe1d54280a6a4822640bf5c369908ad74ea21518a9c5" +pub_key_y = "0x0e0456e3795c1a31f20035b741cd6158929eeccd320d299cfcac962865a6bc74" +signature = [ + 5, 202, 31, 146, 81, 242, 246, 69, 43, 107, 249, 153, 198, 44, 14, 111, 191, 121, 137, 166, + 160, 103, 18, 181, 243, 233, 226, 95, 67, 16, 37, 128, 85, 76, 19, 253, 30, 77, 192, 53, 138, + 205, 69, 33, 236, 163, 83, 194, 84, 137, 184, 221, 176, 121, 179, 27, 63, 70, 54, 16, 176, + 250, 39, 239, +] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/brillig_schnorr/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_schnorr/src/main.nr new file mode 100644 index 00000000000..4212839601f --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_schnorr/src/main.nr @@ -0,0 +1,21 @@ +use dep::std; + +// Note: If main has any unsized types, then the verifier will never be able +// to figure out the circuit instance +unconstrained fn main(message: [u8; 10], message_field: Field, pub_key_x: Field, pub_key_y: Field, signature: [u8; 64]) { + // Regression for issue #2421 + // We want to make sure that we can accurately verify a signature whose message is a slice vs. an array + let message_field_bytes = message_field.to_be_bytes(10); + for i in 0..10 { + assert(message[i] == message_field_bytes[i]); + } + // Is there ever a situation where someone would want + // to ensure that a signature was invalid? + // Check that passing a slice as the message is valid + let valid_signature = std::schnorr::verify_signature(pub_key_x,pub_key_y,signature, message_field_bytes); + assert(valid_signature); + + // Check that passing an array as the message is valid + let valid_signature = std::schnorr::verify_signature(pub_key_x,pub_key_y,signature, message); + assert(valid_signature); +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_sha256/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_sha256/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_sha256/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_sha256/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_sha256/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_sha256/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_sha256/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_sha256/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_sha256/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_sha256/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_sha256/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_sha256/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/brillig_slices/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_slices/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_slices/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_slices/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/debug_logs/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_slices/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/debug_logs/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_slices/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_slices/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_slices/src/main.nr new file mode 100644 index 00000000000..403956bc23d --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_slices/src/main.nr @@ -0,0 +1,150 @@ +use dep::std::slice; +unconstrained fn main(x: Field, y: Field) { + let mut slice: [Field] = [y, x]; + assert(slice.len() == 2); + + slice = slice.push_back(7); + assert(slice.len() == 3); + assert(slice[0] == y); + assert(slice[1] == x); + assert(slice[2] == 7); + + // Array set on slice target + slice[0] = x; + slice[1] = y; + slice[2] = 1; + + assert(slice[0] == x); + assert(slice[1] == y); + assert(slice[2] == 1); + + slice = push_front_to_slice(slice, 2); + assert(slice.len() == 4); + assert(slice[0] == 2); + assert(slice[1] == x); + assert(slice[2] == y); + assert(slice[3] == 1); + + let (item, popped_front_slice) = slice.pop_front(); + slice = popped_front_slice; + assert(item == 2); + + assert(slice.len() == 3); + assert(slice[0] == x); + assert(slice[1] == y); + assert(slice[2] == 1); + + let (popped_back_slice, another_item) = slice.pop_back(); + slice = popped_back_slice; + assert(another_item == 1); + + assert(slice.len() == 2); + assert(slice[0] == x); + assert(slice[1] == y); + + slice = slice.insert(1, 2); + assert(slice.len() == 3); + assert(slice[0] == x); + assert(slice[1] == 2); + assert(slice[2] == y); + + let (removed_slice, should_be_2) = slice.remove(1); + slice = removed_slice; + assert(should_be_2 == 2); + + assert(slice.len() == 2); + assert(slice[0] == x); + assert(slice[1] == y); + + let (slice_with_only_x, should_be_y) = slice.remove(1); + slice = slice_with_only_x; + assert(should_be_y == y); + + assert(slice.len() == 1); + assert(slice[0] == x); + + let (empty_slice, should_be_x) = slice.remove(0); + assert(should_be_x == x); + assert(empty_slice.len() == 0); + + regression_merge_slices(x, y); +} + +// Tests slice passing to/from functions +unconstrained fn push_front_to_slice(slice: [T], item: T) -> [T] { + slice.push_front(item) +} + +// The parameters to this function must come from witness values (inputs to main) +unconstrained fn regression_merge_slices(x: Field, y: Field) { + merge_slices_if(x, y); + merge_slices_else(x); +} + +unconstrained fn merge_slices_if(x: Field, y: Field) { + let slice = merge_slices_return(x, y); + assert(slice[2] == 10); + assert(slice.len() == 3); + + let slice = merge_slices_mutate(x, y); + assert(slice[3] == 5); + assert(slice.len() == 4); + + let slice = merge_slices_mutate_in_loop(x, y); + assert(slice[6] == 4); + assert(slice.len() == 7); +} + +unconstrained fn merge_slices_else(x: Field) { + let slice = merge_slices_return(x, 5); + assert(slice[0] == 0); + assert(slice[1] == 0); + assert(slice.len() == 2); + + let slice = merge_slices_mutate(x, 5); + assert(slice[2] == 5); + assert(slice.len() == 3); + + let slice = merge_slices_mutate_in_loop(x, 5); + assert(slice[2] == 5); + assert(slice.len() == 3); +} + +// Test returning a merged slice without a mutation +unconstrained fn merge_slices_return(x: Field, y: Field) -> [Field] { + let slice = [0; 2]; + if x != y { + if x != 20 { + slice.push_back(y) + } else { + slice + } + } else { + slice + } +} + +// Test mutating a slice inside of an if statement +unconstrained fn merge_slices_mutate(x: Field, y: Field) -> [Field] { + let mut slice = [0; 2]; + if x != y { + slice = slice.push_back(y); + slice = slice.push_back(x); + } else { + slice = slice.push_back(x); + } + slice +} + +// Test mutating a slice inside of a loop in an if statement +unconstrained fn merge_slices_mutate_in_loop(x: Field, y: Field) -> [Field] { + let mut slice = [0; 2]; + if x != y { + for i in 0..5 { + slice = slice.push_back(i); + } + } else { + slice = slice.push_back(x); + } + slice +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_be_bytes/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/src/main.nr new file mode 100644 index 00000000000..d1e1cb9c9a5 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/src/main.nr @@ -0,0 +1,12 @@ +unconstrained fn main(x : Field) -> pub [u8; 31] { + // The result of this byte array will be big-endian + let byte_array = x.to_be_bytes(31); + let mut bytes = [0; 31]; + for i in 0..31 { + bytes[i] = byte_array[i]; + } + assert(bytes[30] == 60); + assert(bytes[29] == 33); + assert(bytes[28] == 31); + bytes +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/src/main.nr new file mode 100644 index 00000000000..08986867dfc --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/src/main.nr @@ -0,0 +1,27 @@ +use dep::std; + +unconstrained fn main(x : Field, _y: Field) { + // The result of this byte array will be big-endian + let y: Field = 2040124; + let be_byte_array = y.to_be_bytes(31); + // The result of this byte array will be little-endian + let le_byte_array = x.to_le_bytes(31); + + assert(le_byte_array[0] == 60); + assert(le_byte_array[0] == be_byte_array[30]); + assert(le_byte_array[1] == be_byte_array[29]); + assert(le_byte_array[2] == be_byte_array[28]); + + let z = 0 - 1; + let p_bytes = std::field::modulus_le_bytes(); + let z_bytes = z.to_le_bytes(32); + assert(p_bytes[10] == z_bytes[10]); + assert(p_bytes[0] == z_bytes[0] as u8 + 1 as u8); + + let p_bits = std::field::modulus_le_bits(); + let z_bits = z.to_le_bits(std::field::modulus_num_bits() as u32); + assert(z_bits[0] == 0); + assert(p_bits[100] == z_bits[100]); + + _y.to_le_bits(std::field::modulus_num_bits() as u32); +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_to_le_bytes/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/src/main.nr new file mode 100644 index 00000000000..1b1315ea411 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/src/main.nr @@ -0,0 +1,10 @@ +unconstrained fn main(x : Field) -> pub [u8; 31] { + // The result of this byte array will be little-endian + let byte_array = x.to_le_bytes(31); + assert(byte_array.len() == 31); + let mut bytes = [0; 31]; + for i in 0..31 { + bytes[i] = byte_array[i]; + } + bytes +} diff --git a/crates/nargo_cli/tests/execution_success/brillig_top_level/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_top_level/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_top_level/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/brillig_top_level/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_top_level/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_top_level/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_top_level/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_top_level/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/brillig_top_level/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_top_level/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/brillig_top_level/src/main.nr rename to tooling/nargo_cli/tests/execution_success/brillig_top_level/src/main.nr diff --git a/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Nargo.toml b/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Nargo.toml new file mode 100644 index 00000000000..c7045d0b816 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "brillig_unitialised_arrays" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/crates/nargo_cli/tests/execution_success/submodules/Prover.toml b/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/submodules/Prover.toml rename to tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/src/main.nr b/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/src/main.nr new file mode 100644 index 00000000000..e0efbad1f42 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/src/main.nr @@ -0,0 +1,13 @@ + +fn main(x: Field, y: Field) -> pub Field { + let notes = create_notes(x, y); + sum_x(notes, x, y) +} + +fn sum_x(notes: [Field; 2], x: Field, y: Field) -> Field { + notes[x] + notes[y] +} + +unconstrained fn create_notes(x: Field, y: Field) -> [Field; 2] { + [x,y] +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/cast_bool/Nargo.toml b/tooling/nargo_cli/tests/execution_success/cast_bool/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/cast_bool/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/cast_bool/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/cast_bool/Prover.toml b/tooling/nargo_cli/tests/execution_success/cast_bool/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/cast_bool/Prover.toml rename to tooling/nargo_cli/tests/execution_success/cast_bool/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/cast_bool/src/main.nr b/tooling/nargo_cli/tests/execution_success/cast_bool/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/cast_bool/src/main.nr rename to tooling/nargo_cli/tests/execution_success/cast_bool/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/closures_mut_ref/Nargo.toml b/tooling/nargo_cli/tests/execution_success/closures_mut_ref/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/closures_mut_ref/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/closures_mut_ref/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/closures_mut_ref/Prover.toml b/tooling/nargo_cli/tests/execution_success/closures_mut_ref/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/closures_mut_ref/Prover.toml rename to tooling/nargo_cli/tests/execution_success/closures_mut_ref/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/closures_mut_ref/src/main.nr b/tooling/nargo_cli/tests/execution_success/closures_mut_ref/src/main.nr new file mode 100644 index 00000000000..2888745a96e --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/closures_mut_ref/src/main.nr @@ -0,0 +1,31 @@ +fn main(mut x: Field) { + let one = 1; + let add1 = |z| { + *z = *z + one; + }; + + let two = 2; + let add2 = |z| { + *z = *z + two; + }; + + add1(&mut x); + assert(x == 1); + + add2(&mut x); + assert(x == 3); + + issue_2120(); +} + +// https://github.com/noir-lang/noir/issues/2120 +fn issue_2120() { + let x1 = &mut 42; + let set_x1 = |y| { *x1 = y; }; + + assert(*x1 == 42); + set_x1(44); + assert(*x1 == 44); + set_x1(*x1); + assert(*x1 == 44); +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/constant_return/Nargo.toml b/tooling/nargo_cli/tests/execution_success/constant_return/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/constant_return/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/constant_return/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/constant_return/Prover.toml b/tooling/nargo_cli/tests/execution_success/constant_return/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/constant_return/Prover.toml rename to tooling/nargo_cli/tests/execution_success/constant_return/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/constant_return/src/main.nr b/tooling/nargo_cli/tests/execution_success/constant_return/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/constant_return/src/main.nr rename to tooling/nargo_cli/tests/execution_success/constant_return/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/custom_entry/Nargo.toml b/tooling/nargo_cli/tests/execution_success/custom_entry/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/custom_entry/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/custom_entry/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/custom_entry/Prover.toml b/tooling/nargo_cli/tests/execution_success/custom_entry/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/custom_entry/Prover.toml rename to tooling/nargo_cli/tests/execution_success/custom_entry/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/custom_entry/src/foobarbaz.nr b/tooling/nargo_cli/tests/execution_success/custom_entry/src/foobarbaz.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/custom_entry/src/foobarbaz.nr rename to tooling/nargo_cli/tests/execution_success/custom_entry/src/foobarbaz.nr diff --git a/crates/nargo_cli/tests/execution_success/debug_logs/Nargo.toml b/tooling/nargo_cli/tests/execution_success/debug_logs/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/debug_logs/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/debug_logs/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/slices/Prover.toml b/tooling/nargo_cli/tests/execution_success/debug_logs/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/slices/Prover.toml rename to tooling/nargo_cli/tests/execution_success/debug_logs/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/debug_logs/src/main.nr b/tooling/nargo_cli/tests/execution_success/debug_logs/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/debug_logs/src/main.nr rename to tooling/nargo_cli/tests/execution_success/debug_logs/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/diamond_deps_0/Nargo.toml b/tooling/nargo_cli/tests/execution_success/diamond_deps_0/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/diamond_deps_0/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/diamond_deps_0/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/diamond_deps_0/Prover.toml b/tooling/nargo_cli/tests/execution_success/diamond_deps_0/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/diamond_deps_0/Prover.toml rename to tooling/nargo_cli/tests/execution_success/diamond_deps_0/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/diamond_deps_0/src/main.nr b/tooling/nargo_cli/tests/execution_success/diamond_deps_0/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/diamond_deps_0/src/main.nr rename to tooling/nargo_cli/tests/execution_success/diamond_deps_0/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/distinct_keyword/Nargo.toml b/tooling/nargo_cli/tests/execution_success/distinct_keyword/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/distinct_keyword/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/distinct_keyword/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_program_addition/Prover.toml b/tooling/nargo_cli/tests/execution_success/distinct_keyword/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_program_addition/Prover.toml rename to tooling/nargo_cli/tests/execution_success/distinct_keyword/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/distinct_keyword/src/main.nr b/tooling/nargo_cli/tests/execution_success/distinct_keyword/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/distinct_keyword/src/main.nr rename to tooling/nargo_cli/tests/execution_success/distinct_keyword/src/main.nr diff --git a/tooling/nargo_cli/tests/execution_success/double_verify_proof/Nargo.toml b/tooling/nargo_cli/tests/execution_success/double_verify_proof/Nargo.toml new file mode 100644 index 00000000000..61aaabfcf5b --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/double_verify_proof/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "double_verify_proof" +type = "bin" +authors = [""] +compiler_version = "0.6.0" + +[dependencies] diff --git a/tooling/nargo_cli/tests/execution_success/double_verify_proof/Prover.toml b/tooling/nargo_cli/tests/execution_success/double_verify_proof/Prover.toml new file mode 100644 index 00000000000..3b4ca3c198f --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/double_verify_proof/Prover.toml @@ -0,0 +1,6 @@ +input_aggregation_object = ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"] +key_hash = "0x284158f92a5305f662f78fc36a397fb8eb44d229fd22152e2dc085cad142c3c2" +proof = ["0x000000000000000000000000000000000000000000000000000000000000000a","0x0000000000000000000000000000005e77a294b0829c1233b25f34cbd1e36ca5","0x00000000000000000000000000000000001efb564c6d131a2005503e7bc96dfd","0x0000000000000000000000000000003a2960d64558302ab11263ac1d4e99c792","0x000000000000000000000000000000000027934be1b834b8444d8974e4c1c9bb","0x000000000000000000000000000000a5e281184b833e3567ce8e285c80bd7dfc","0x00000000000000000000000000000000002ef660bd670bea9dc8e18192cb71fa","0x00000000000000000000000000000075b29302806ec08bb2c7af1b5463fc34fa","0x00000000000000000000000000000000001138c220233f7b40034a4f49a23ae6","0x000000000000000000000000000000c24fb0b91d6ea29b55a925f221c5b285d8","0x000000000000000000000000000000000013ff3e12b86654ca896bfd6bbedd69","0x0000000000000000000000000000005709282fede94015f85bce4c39d859e34a","0x00000000000000000000000000000000000fb8a86b7540bfdc1c2784d7943400","0x00000000000000000000000000000020bf9ff7ac6ddadf43c1f9128f13f66481","0x000000000000000000000000000000000012f42d353e8a008c1c65650aea9720","0x0000000000000000000000000000009b8c079fcd0a17aecbda82b255ac26131b","0x000000000000000000000000000000000027fe6ea46f3898befbae77137e493e","0x0000000000000000000000000000002a66a58be32207d7ac2e318e6d3235edac","0x00000000000000000000000000000000000fa3dfdf2bbf7c51f39b861dc44be6","0x0000000000000000000000000000003746eb9ded01fcafcc65c5d87f49141ee5","0x00000000000000000000000000000000001e65f8c6b1af063d4103022b38cd3e","0x00000000000000000000000000000046c520b61b4608d1bc2c98ca800765ebd7","0x000000000000000000000000000000000020434f43987d0f71d0a1aa2ed8f270","0x000000000000000000000000000000827b6b7c3b2a9c71a45a253a2a298c47f4","0x000000000000000000000000000000000009e45e0d42b0e22cbde0f4667e6288","0x000000000000000000000000000000c8150ed84dd7b794ce5427fe99040bcd3d","0x00000000000000000000000000000000002696a5d48bf45b5a80619ef91013d4","0x0000000000000000000000000000003a1caa16acc8da5032b2e836770312009d","0x0000000000000000000000000000000000237a8423952c1c64e1e7c75da9d7cf","0x0000000000000000000000000000000d8eb5fa6490a4cd67943b646d05bd0859","0x0000000000000000000000000000000000159ebdb4a5c764c0346287984ed47d","0x000000000000000000000000000000e862c821c535a49e93959d08dc9f2645b5","0x00000000000000000000000000000000000c440edae454a8865dc27c8de51090","0x000000000000000000000000000000a6973dd133a0e974b564e76d185a4b06b0","0x000000000000000000000000000000000016248ed7566da68af6f2bc248763b4","0x000000000000000000000000000000a568fd8430c974e995915c9265ac74617d","0x000000000000000000000000000000000006e205349a7913be4af0af8778a0fd","0x00000000000000000000000000000009fd63b6ca1767490d4ce191e7332fbdd6","0x00000000000000000000000000000000000f95d28c7e720dc455fd46a532731e","0x00000000000000000000000000000008d1b9d51b2425ddf4a15bc5307ea911b4","0x000000000000000000000000000000000001131845742cefc926b7d2b7dc4b9c","0x0000000000000000000000000000008dbc181365f1a3db87a66d527ca9d81ca5","0x00000000000000000000000000000000000a6f78cdcd1e2177580e6c89c23235","0x0000000000000000000000000000004723acbe295108f00ff760c0671d2d4bbf","0x000000000000000000000000000000000006058d93abb1d596501ee4c3f62971","0x08bacf9fdaba383e584559b8cd64ae8c04e670d9203f90c6b49efac7f00f5003","0x18541473055ebbcaefe15759125b820ed1c6b932af2659c5280bdf70bd5c09cc","0x161e0a0cb1aa6028cabb8ccb98646a9b0976618cad99bb1145c4d25cecef50be","0x0d353ffc0833fd6e1947133f5391544ed7dde0fbfa0109ec7a54baafb117b1ca","0x1a5209fd1dcf2705b7081b4e3bf7b2c33dd00ac4b2becfdf8ee7927703ea0357","0x1d247635110c48df6f62387026c5823f0eb9d843848fe7b8e1a9a96b1c6ad763","0x1cc4a7a8be5edc32432191b0ee2a9051d3b6384313c6b9e5efe8cd8712c872f2","0x2c8b6fa617041faeb2e814b39c288ff607ac03d746f3c0e622860720dfb24b83","0x1ecc99a77fda5d79a6426b18049876b36ad1a1aba693518b1b976360630c2f55","0x2f75dc15bb6fdd3d9762fe74485c5ead7a5476c11cd44ed9f43324028cd2dd68","0x0e20add7931c78604ef7986fe7b286ab582842a23b4c09e8ec03d8d88a31969c","0x2467bb747466b69b6b4deeaac4a82e32ca7585194cd838912a65d12f912b5c6c","0x23edab06b87cf9fd4a5f0161287283d97a9bcdbdd68779e08cad3e763420bd20","0x2817c054ad1ac5454f58ff525196ed920ba54fbb4d86820a5a414aaa61d7d1b1","0x12d63d1f6ed0a080694a209534ee08e4758b0382f9bab7e13aafcbcb62ecc8d0","0x153104c35caab490767364a7db8bca01043c63f358f20edd6205c544cf4a61ea","0x178bcc674a84c8a0839ca8ba82298b1d92edc463b82965d9895bbebe3ba7fb04","0x1224834d4b8a36290e11b8b153d81062ba503c36d6e7ef41916b647517a6e632","0x13112373ea4e5bf7e041a7312167b4f82653ead2f5e5e3d4d07bafd79ca690b6","0x26b7669e3463c6d162363b2cd0e8f6720aa97f9cdb04a8340fce7ead2421af56","0x120d09593529a665d992bf009fc6268a9088c95f401784f939d5ed1649a4e779","0x1c415baf2638f0c09def30dfcf650d56b0508544769813d1d807b1b114632d38","0x1e9c2353141304d0ab1874f27602ce733f01e5b4d5cf6acdff5dab2a80c0c652","0x20f6eaf701ed18e0b841b9051ca08f8fcdb346253506c1ca26b3a4a3ed1e5f6c","0x2351b29aefc72cf0c56afd17c33e50ac5c64a695943e18c64e099e1d597bf886","0x19e6940b385edcb090c5eccd28c74c3a219f24d41760bcd5b0b1b837a805941e","0x2cd7e4b967101d6ee0f2a33521762cace8ffe35930bc210554e8307df664c899","0x041f06de46e4862d5d59c363c119a79629261d6aa18aa737c288ac7f4bfb4153","0x2dc39620da58c2822418179ba6f61de6d31ee938c79a5ca15c473aef7ca1e824","0x00000000000000000000000000000000ffbd168649f4e00f0baef4ec3a08615f","0x18fbeff26a87cb38f373584bbd02d016fed78aefc6462811a23006679509b3a9","0x1888e78ad37d146406e710ae2dbd244877263b133875d090f7615a1e9c0ac083","0x2196fbe28ce9ce0e0e202bbf1268cabdcd0a2c03588e118765ba1ee1a16f2dc7","0x0137bc731354b1531dbdcbfc83802605035f69f937f9a7311a57e6d7126368ba","0x19f38da8f0717fe78812addd655ef59411805d70eb731d5da309ad111698e8d0","0x155452e2824d5bd4fd8f8e5feaa4bd7abe783613d6b78cf88377a48e9f7e70c2","0x2396966b07a6e535a9ae30883a97e854ff2425c6dcfa34bda164394ba919191f","0x09374f47b862065ac0ac49ceb02b5cc0d925af1980ab2bd5f4d9df555e8c4c91","0x26366e50b5c7244ffc3ecdf50a65180742b1c53092659bd1db852bdd726d52f3","0x12d13ee6d1faa21b7f810c64e31d7af08409f2ff2a669b3c7e4e82d1964e5954","0x2fd05defcf5fc010bb13908b3d573636ed9609163c210b3864f9cf59aa2f5fb6","0x00000000000000000000000000000046955fdfd58ca9013b39025ae688416131","0x00000000000000000000000000000000001d335d2fb9857cbc49e72cf34e86a5","0x0000000000000000000000000000000c6a8930092b36c72dbd0a7f4b65533c19","0x00000000000000000000000000000000000d099ff72ffae0f73756528d629a5e","0x0000000000000000000000000000008c8d80c3f2886519cb37a563f88f166cb8","0x00000000000000000000000000000000000393e9f6fdc31492e4b3da33fa5fe4","0x000000000000000000000000000000417fb818a6933554bf3ff602f1f450728d","0x00000000000000000000000000000000002074eb75888a752047676f72f5343f"] +public_inputs = ["0x000000000000000000000000000000000000000000000000000000000000000a"] +verification_key = ["0x21082ca216cbbf4e1c6e4f4594dd508c996dfbe1174efb98b11509c6e306460b","0x0000000000000000000000000000000000000000000000000000000000000010","0x0000000000000000000000000000000000000000000000000000000000000005","0x0000000000000000000000000000000000000000000000000000000000000010","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000004cf4015c3a5297f556c3b72581f2dca64d","0x00000000000000000000000000000000000a67b44462aa65528a3e3b181e0bcd","0x00000000000000000000000000000091507f347e13f13eec9d9f327ac25ada11","0x00000000000000000000000000000000001993946f40247aa93aedba75857f3e","0x0000000000000000000000000000005d340a5ecb1a33c0b7055734ef91200c97","0x00000000000000000000000000000000001eebbe1207643a8bd1669b999e8226","0x0000000000000000000000000000006b27d5d1ffba12754d0718481e1a9a419a","0x00000000000000000000000000000000002f08a6a07ed616c588bcf4e3555c00","0x0000000000000000000000000000003cbc8e573c1299e8ba491bd2218a413bd7","0x0000000000000000000000000000000000192b586ec6fb3b1b6d063a00a86c65","0x000000000000000000000000000000c4516b3cffabe3dcdd074d74f595c81c04","0x000000000000000000000000000000000021142418da600cf97a5248cbd45524","0x000000000000000000000000000000c292117b1a17fefe9de0bfd9edf1a84bf9","0x000000000000000000000000000000000002d6fd9e84dbe74b7531e1801405a1","0x000000000000000000000000000000459a3b2a0b768da45ac7af7f2aec40fc42","0x0000000000000000000000000000000000293c6ab3c06a0669af13393a82c60a","0x0000000000000000000000000000006c845044cca9a2d9dbf94039a11d999aaa","0x00000000000000000000000000000000000efe5ad29f99fce939416b6638dff2","0x000000000000000000000000000000587f768022c11ac8e37cd9dce243d01ef2","0x00000000000000000000000000000000000a44bf49517a4b66ae6b51eee6ac68","0x00000000000000000000000000000059d49ef10107e88711fc0919e244e17a08","0x0000000000000000000000000000000000132d159fdf1907b0619b9809904594","0x00000000000000000000000000000016d9bd1186bcef7a31846ce703eb4cb5b2","0x0000000000000000000000000000000000291c00ed4a7689fec327330104b85c","0x0000000000000000000000000000004b6c55389300451eb2a2deddf244129e7a","0x000000000000000000000000000000000018c3e78f81e83b52719158e4ac4c2f","0x0000000000000000000000000000008d7beb75f905a5894e18d27c42c62fd797","0x00000000000000000000000000000000000002e9c902fe5cd49b64563cadf3bb","0x0000000000000000000000000000000d9e28aa6d00e046852781a5f20816645c","0x00000000000000000000000000000000002cbce7beee3076b78dace04943d69d","0x000000000000000000000000000000fd915d11bfedbdc0e59de09e5b28952080","0x00000000000000000000000000000000002bc27ec2e1612ea284b08bcc55b6f2","0x000000000000000000000000000000be6ed4f4d252a79059e505f9abc1bdf3ed","0x00000000000000000000000000000000000ad34b5e8db72a5acf4427546c7294","0x00000000000000000000000000000090a049f42a3852acd45e6f521f24b4900e","0x00000000000000000000000000000000001e5b26790a26eb340217dd9ad28dbf","0x000000000000000000000000000000ac27e570ae50bc180509764eb3fef94815","0x0000000000000000000000000000000000155a0f51fec78c33ffceb7364d69d7","0x000000000000000000000000000000b644999713a8d3c66e9054aa5726324c76","0x00000000000000000000000000000000001c1c4720bed44a591d97cbc72b6e44","0x000000000000000000000000000000058cc5ad51753faec2a5908155d472e429","0x00000000000000000000000000000000000f7261cf55a71f4d0d7b961dda9ddb","0x0000000000000000000000000000004a36df78f0d50144437ef26f8bbfe69ac1","0x00000000000000000000000000000000001b7b1a10c1e638ce11d8c84b831aca","0x000000000000000000000000000000826ba5b1d1ddd8d6bb960f01cd1321a169","0x0000000000000000000000000000000000163a9c8b67447afccc64e9ccba9d9e","0x0000000000000000000000000000007653a773088aba5c6b1337f435188d72c4","0x000000000000000000000000000000000019256311d43dbc795f746c63b20966","0x000000000000000000000000000000df58a7bad9afe3651be67bc6c298092e11","0x00000000000000000000000000000000001fa51a0d75363b3af4e259e0dbb2c5","0x000000000000000000000000000000c8b5836b29551d41dbc04bdb1fcf1a1868","0x000000000000000000000000000000000021915198840ad9c3666122b2837aea","0x0000000000000000000000000000005df0e69d7efdbc7898b3762f0a0ed976ad","0x00000000000000000000000000000000000cee6b75dcf02a07c50939e8ca3cf3","0x00000000000000000000000000000066a493be1ea69d2b335152719acd54d735","0x000000000000000000000000000000000027e49262bd388ce2d0f193988f3b8f","0x000000000000000000000000000000dd783bff1a1cfc999bb29859cfb16c46fc","0x000000000000000000000000000000000002c397073c8abce6d4140c9b961209","0x000000000000000000000000000000750599be670db593af86e1923fe8a1bb18","0x00000000000000000000000000000000002b7bba2d1efffce0d033f596b4d030","0x0000000000000000000000000000008ffb571a4b3cf83533f3f71b99a04f6e6b","0x00000000000000000000000000000000002c71c58b66498f903b3bbbda3d05ce","0x0000000000000000000000000000002afaefbcbd080c84dcea90b54f4e0a858f","0x0000000000000000000000000000000000039dce37f94d1bbd97ccea32a224fe","0x00000000000000000000000000000075783c73cfe56847d848fd93b63bf32083","0x000000000000000000000000000000000027dc44977efe6b3746a290706f4f72","0x000000000000000000000000000000de0cbf2edc8f085b16d73652b15eced8f5","0x00000000000000000000000000000000000a5366266dd7b71a10b356030226a2","0x00000000000000000000000000000000a7588ec4d6809c90bb451005a3de3077","0x0000000000000000000000000000000000136097d79e1b0ae373255e8760c499","0x000000000000000000000000000000f2595d77bdf72e4acdb0b0b43969860d98","0x000000000000000000000000000000000013dd7515ccac4095302d204f06f0bf","0x000000000000000000000000000000057fe211dad1b706e49a3b55920fac20ec","0x000000000000000000000000000000000016ff3501369121d410b445929239ba","0x000000000000000000000000000000eb8007673c1ed10b834a695adf0068522a","0x00000000000000000000000000000000001e190987ebd9cf480f608b82134a00","0x0000000000000000000000000000000944f94301aa6da3016a226de04de52f4c","0x00000000000000000000000000000000001e44194e60f0ab4ee0f77adc50f422","0x0000000000000000000000000000006c2c7bea37dfbd20be6bed19efd743397a","0x00000000000000000000000000000000002a017d0d9f40d0aeb5c8152ffddec5","0x0000000000000000000000000000007f43efe5631bf48c872c317bed3b8bf12b","0x000000000000000000000000000000000027579be0883627093cf8bdec0b72e7","0x000000000000000000000000000000cef6108b89e89b35679431d113f3be7dff","0x00000000000000000000000000000000000ddb2d01ec88ed69144177a4af3850","0x0000000000000000000000000000000083e7ab1f26781948b36d131759f7c8c9","0x00000000000000000000000000000000000a7fe830f1cb7a5d49d71877dd226a","0x0000000000000000000000000000001834ecd1ce1e8e80812bdd95f960a45e57","0x00000000000000000000000000000000002db7a5185064e6501ef61e989895a0","0x000000000000000000000000000000363f0c994e91cecad25835338edee2294f","0x00000000000000000000000000000000002eea648c8732596b1314fe2a4d2f05","0x000000000000000000000000000000b2671d2ae51d31c1210433c3972bb64578","0x00000000000000000000000000000000000ab49886c2b94bd0bd3f6ed1dbbe2c"] +proof_b = ["0x000000000000000000000000000000000000000000000000000000000000000a","0x000000000000000000000000000000522e2d3071a75aa35d1e477d9e0ad3c0c2","0x000000000000000000000000000000000027bd4377f2ede7bc0133dde7d3b79d","0x000000000000000000000000000000df15ed61667d6fc6b99b97daafc3f7eddb","0x000000000000000000000000000000000003572ca7295a3ee92dc2ddafed48cd","0x000000000000000000000000000000b5dfb839be2c47c3d0e289df3c482bf286","0x00000000000000000000000000000000002471c02fbda062e36bcc7fbdf42dce","0x000000000000000000000000000000e3cbbbc33fb43fb006bd9f8e02dfd4cf9b","0x00000000000000000000000000000000000b3eb6b7a756351688c2561977d618","0x00000000000000000000000000000058d410d526cbd3adbee65868596758007f","0x0000000000000000000000000000000000289c7fe794a87811176d6b8a3973b3","0x000000000000000000000000000000deebf1d6b009435d734b2399d3558eb3f7","0x000000000000000000000000000000000023b6573225d811337c37b16691b872","0x000000000000000000000000000000c29b8cb5048472631403ee526a725ac163","0x0000000000000000000000000000000000206bff7bf596fde59255e7b85f9c7a","0x000000000000000000000000000000d8907ebb05228e706b57826cfc8207af57","0x0000000000000000000000000000000000305f614425315c05fc891c9a92a743","0x000000000000000000000000000000f183e5285136ab6c87d28dcfb65a99b02c","0x00000000000000000000000000000000000383ca0c47e2c56d39f5b58b9726a4","0x000000000000000000000000000000cc11844c28848bcdb1575af5bbae6eafa5","0x000000000000000000000000000000000018b1f820411130433f38ede2bd9158","0x000000000000000000000000000000821bd5681fdbbc82311485f9750ecda390","0x0000000000000000000000000000000000064257d786e839c16aa159b3672cc8","0x0000000000000000000000000000000e5205d207323e06ea8a18111dff8354af","0x00000000000000000000000000000000001254044ff7e569e4002f38956d2762","0x0000000000000000000000000000004591d851f6226ffe1a8a63456ee13411f7","0x00000000000000000000000000000000002b118f2b6639c3f776ed6847f98863","0x000000000000000000000000000000a0a0f63e73dd651c139b2fc3f45e9f4a94","0x00000000000000000000000000000000002669baf309d743d8c94871745bb19a","0x0000000000000000000000000000004cafdee2031bda8c4a2be55862c864524e","0x000000000000000000000000000000000002e68b1c1d2454113f78a184434cf2","0x000000000000000000000000000000899c0497e76b6b345776d9990c8eee4160","0x00000000000000000000000000000000000ec802d07823d277acf631b5c451f3","0x000000000000000000000000000000d5f1fa88434b81dd239ca62a3d168ff20e","0x000000000000000000000000000000000028511b798a4e506da8219fefcfe462","0x000000000000000000000000000000597adcfba2064c09a9e57b37d6a50fe775","0x00000000000000000000000000000000001f691d6d4cbed7b749f55e9af17403","0x00000000000000000000000000000071c78d719253bf3165591474d0a27a50ac","0x000000000000000000000000000000000024858bf4aff0e08df3c03fae341fc0","0x000000000000000000000000000000d0e80eafe0f0d2c1f760bd98087a069da0","0x0000000000000000000000000000000000266239c233e34815ca720e2e378f21","0x000000000000000000000000000000ad6462e3eca1c9a94e4dd30f3cecba48ad","0x0000000000000000000000000000000000147e1bff29ff6979f76ab6d840ded4","0x00000000000000000000000000000047cd629558a91f9db60c63944fa3835cdb","0x00000000000000000000000000000000002531925eaa902131ef11542fb5b20a","0x198e99c9dbc6f3ca902d080fdafb51410ee129edf20015c8337964f3f92b0376","0x2f04d8358d5740b6fa3aca9893cac185d641f2a00089b2bc428401ac21343d2c","0x2d5e2a67dee4e227ca84367a7d7ecd4860b1586a0d1eb799a41ee1042857e46a","0x2651bde5af62489c373d5fa812d6140b60df4569c6184d0d38f6f55dd49ec439","0x10e9e9d0cb817c09034cf3a4dbc9a44ed7a2618fd0281bf0d07a30b12facc6ea","0x11256980eccf0e654c61db759c8d71b04cd9a7c74d44165beaca2978aae075a9","0x2360ce983c2edb38f60b84a7f5ade89eed1fdb65363227e737dffbb8acba96e6","0x06c2d6ce83f1dc608f2cd267b351faa80bae0f688b3e2c6689235365ac05d614","0x1954b4ab315a061b176b67c8adb73d8ef4cc795951c506549ee17f0db90cca9a","0x1a738a34c81c0875d1fe2c68fb111bb55194edcf6c879e9ec99b4c93c5bac76b","0x012434d4aa45c5fb67f138a86116447befa784435b50fc1e67c74f07223480ef","0x1da9f41af8143f464c89dfae2b802ab73f0e64bcd71e5a18574bb4afa391a80f","0x1c41b34f51bf6cfddc0572770164eadcbf2fc4e7959f0fc7a4f19dc11780380a","0x0a6692e54ad790aa12bd9e225e116bfe1d068459dcd66eeac3ff646c672a0372","0x01859bc6385d07f9dfec4b8b2c1db0a53f8a05af246bfad33509beb42d9b5694","0x19e876787001790df811f7d7d26212e87b953a8945d632763d9bf154ab4ec167","0x01e702b7c67449f857e75e6df7251cce8f6c871aed86f988024c2e6139022c39","0x008b6178e573502eac46923d9df263b57cafa83bb14e7b91080370cf82750f75","0x2ea063d2aad0c7bcadf7fd7493e0cb8352c308a4e4101f128a7c4eb6dd80b118","0x099650fcf5f0c4f8f75189d335f9f176f8d1355ac6a31274782c21345d1f9c2a","0x1b8b6888ec0de5154a5ec2b3ebd4ace865dc035253532ebed5abf575a9e89763","0x024869a9548b8bf6cfe27150c22c88f7df4f0886b6a1f83ccf8e9e0e446901de","0x1aab445b8c2ffd0ae8081d9d6870eb3b1b5a3d60d80c2fdfd820d0aec21c6cb1","0x02a9d09ae2a2cdf547dd84338d33f5212f3189f27fbcf6f19cd10dbb4fcfd783","0x1b0cab4d1a473f0960033080337857646b3cbecca1272e94a563405bcd834256","0x1a49dd69fe18bb0c700d0aba9d697f11cb77bbf50ef1312b0ade6101b6b5970c","0x17a899e0aaba06df5f640dee973615b2a1c2b1a302c36432c0e496c0e1fc12d4","0x29416ace9513e527f7896ed30c14f92cbab613f3eebe6c87f810369c846023f3","0x13aca814f98cc1ba1c8818827876a6b782a579ab0494e03e190ebf6bd448e005","0x00000000000000000000000000000000d00591628e7f3bc935d0615c0808e684","0x0e1e573fd4e227709e85770ce6b1ec54c62a4563a360a85cafa285ef0de23f65","0x0df2626fd4c3b1352933f185d2ea12e6bfafced47ecea438cade894cc6e2db56","0x024a1e3b18a149a7643d0a7413a9f9a859534acb1075a49d79f80ab4b54d2a54","0x1ddc4265b93c17d06fa34332906e26b193c22fca27979dfe1dc7a3481ca26368","0x162ace72663cfa6de2e9f04e51dc9b391a9842df5c390ea45c830cb9ffe41170","0x0495b2a1fdf4505e043a1f14d28d3183875c756190b4f3d573ddcca45271c578","0x108711fd3a535631ffedab15afa2b45462d0109de6a5ce207b728da7fb0cc861","0x12f61ffde0a5cdd06d99615a9a13e9c35c9acf021c34d945a43911d6b5bc7357","0x1892fe8746226c4ff0c22f46b1b5af461256b39da8b35f6ce23b5274ee36d249","0x1e2fdd10ab9f0acf73eafd32c95774c8c81298393531e594203d931326b1313b","0x23ccbb9a111ba94ef713cb1ee0f93a4b7dce7cd4c1b06bbb5e3fd3b15f2b902d","0x00000000000000000000000000000012c0034de11daf4073d7347808aeaa15c3","0x00000000000000000000000000000000002467b5b5f10cf216361cdc1e6ec924","0x00000000000000000000000000000009d0e5bd1b7ed299b7150dd860562b575f","0x00000000000000000000000000000000000121e299f7c5b7b9a264a0237ba9c0","0x000000000000000000000000000000e52730fdae3a174391fede8b22ca59d266","0x000000000000000000000000000000000011e9a259a74f701d565dfbc05db520","0x000000000000000000000000000000e7574bc9af75e9f84a887d120d72b60507","0x000000000000000000000000000000000006f7685fea564d498d183eb56236b0"] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr b/tooling/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr new file mode 100644 index 00000000000..39b8c142ace --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr @@ -0,0 +1,32 @@ +use dep::std; + +fn main( + verification_key : [Field; 114], + proof : [Field; 94], + public_inputs : [Field; 1], + key_hash : Field, + input_aggregation_object : [Field; 16], + proof_b : [Field; 94], +) -> pub [Field; 16] { + let output_aggregation_object_a = std::verify_proof( + verification_key.as_slice(), + proof.as_slice(), + public_inputs.as_slice(), + key_hash, + input_aggregation_object + ); + + let output_aggregation_object = std::verify_proof( + verification_key.as_slice(), + proof_b.as_slice(), + public_inputs.as_slice(), + key_hash, + output_aggregation_object_a + ); + + let mut output = [0; 16]; + for i in 0..16 { + output[i] = output_aggregation_object[i]; + } + output +} diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/Nargo.toml b/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/Prover.toml b/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/ecdsa_secp256k1/Prover.toml rename to tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/src/main.nr b/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/src/main.nr new file mode 100644 index 00000000000..2512531cb04 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/src/main.nr @@ -0,0 +1,10 @@ +use dep::std; + +fn main(message : [u8;38],hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + // Hash the message, since secp256k1 expects a hashed_message + let expected= std::hash::sha256(message); + assert(hashed_message == expected); + + let valid_signature = std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); +} diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/Nargo.toml b/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/Prover.toml b/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/ecdsa_secp256r1/Prover.toml rename to tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/src/main.nr b/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/src/main.nr new file mode 100644 index 00000000000..e81d84fd902 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/src/main.nr @@ -0,0 +1,6 @@ +use dep::std; + +fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + let valid_signature = std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); +} diff --git a/crates/nargo_cli/tests/execution_success/eddsa/Nargo.toml b/tooling/nargo_cli/tests/execution_success/eddsa/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/eddsa/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/eddsa/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/eddsa/Prover.toml b/tooling/nargo_cli/tests/execution_success/eddsa/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/eddsa/Prover.toml rename to tooling/nargo_cli/tests/execution_success/eddsa/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/eddsa/src/main.nr b/tooling/nargo_cli/tests/execution_success/eddsa/src/main.nr new file mode 100644 index 00000000000..870a20fe01a --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/eddsa/src/main.nr @@ -0,0 +1,53 @@ +use dep::std::compat; +use dep::std::ec::consts::te::baby_jubjub; +use dep::std::hash; +use dep::std::eddsa::eddsa_poseidon_verify; +fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { + // Skip this test for non-bn254 backends + if compat::is_bn254() { + let bjj = baby_jubjub(); + + let pub_key_a = bjj.curve.mul(_priv_key_a, bjj.curve.gen); + // let pub_key_b = bjj.curve.mul(_priv_key_b, bjj.curve.gen); + + // Manually computed as fields can't use modulo. Importantantly the commitment is within + // the subgroup order. Note that choice of hash is flexible for this step. + // let r_a = hash::pedersen([_priv_key_a, msg])[0] % bjj.suborder; // modulus computed manually + let r_a = 1414770703199880747815475415092878800081323795074043628810774576767372531818; + // let r_b = hash::pedersen([_priv_key_b, msg])[0] % bjj.suborder; // modulus computed manually + let r_b = 571799555715456644614141527517766533395606396271089506978608487688924659618; + + let r8_a = bjj.curve.mul(r_a, bjj.base8); + let r8_b = bjj.curve.mul(r_b, bjj.base8); + + // let h_a: [Field; 6] = hash::poseidon::bn254::hash_5([ + // r8_a.x, + // r8_a.y, + // pub_key_a.x, + // pub_key_a.y, + // msg, + // ]); + + // let h_b: [Field; 6] = hash::poseidon::bn254::hash_5([ + // r8_b.x, + // r8_b.y, + // pub_key_b.x, + // pub_key_b.y, + // msg, + // ]); + + // let s_a = (r_a + _priv_key_a * h_a) % bjj.suborder; // modulus computed manually + let s_a = 30333430637424319196043722294837632681219980330991241982145549329256671548; + // let s_b = (r_b + _priv_key_b * h_b) % bjj.suborder; // modulus computed manually + let s_b = 1646085314320208098241070054368798527940102577261034947654839408482102287019; + + // User A verifies their signature over the message + assert(eddsa_poseidon_verify(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg)); + + // User B's signature over the message can't be used with user A's pub key + assert(!eddsa_poseidon_verify(pub_key_a.x, pub_key_a.y, s_b, r8_b.x, r8_b.y, msg)); + + // User A's signature over the message can't be used with another message + assert(!eddsa_poseidon_verify(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg + 1)); + } +} diff --git a/crates/nargo_cli/tests/execution_success/generics/Nargo.toml b/tooling/nargo_cli/tests/execution_success/generics/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/generics/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/generics/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/generics/Prover.toml b/tooling/nargo_cli/tests/execution_success/generics/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/generics/Prover.toml rename to tooling/nargo_cli/tests/execution_success/generics/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/generics/src/main.nr b/tooling/nargo_cli/tests/execution_success/generics/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/generics/src/main.nr rename to tooling/nargo_cli/tests/execution_success/generics/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/global_consts/Nargo.toml b/tooling/nargo_cli/tests/execution_success/global_consts/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/global_consts/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/global_consts/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/global_consts/Prover.toml b/tooling/nargo_cli/tests/execution_success/global_consts/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/global_consts/Prover.toml rename to tooling/nargo_cli/tests/execution_success/global_consts/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/global_consts/src/baz.nr b/tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr similarity index 98% rename from crates/nargo_cli/tests/execution_success/global_consts/src/baz.nr rename to tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr index e52efc52eae..626477a89d0 100644 --- a/crates/nargo_cli/tests/execution_success/global_consts/src/baz.nr +++ b/tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr @@ -2,4 +2,4 @@ fn from_baz(x : [Field; crate::foo::MAGIC_NUMBER]) { for i in 0..crate::foo::MAGIC_NUMBER { assert(x[i] == crate::foo::MAGIC_NUMBER); }; -} \ No newline at end of file +} diff --git a/crates/nargo_cli/tests/execution_success/global_consts/src/foo.nr b/tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr similarity index 98% rename from crates/nargo_cli/tests/execution_success/global_consts/src/foo.nr rename to tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr index 2db74fb1ff7..6aa27be61ca 100644 --- a/crates/nargo_cli/tests/execution_success/global_consts/src/foo.nr +++ b/tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr @@ -8,4 +8,4 @@ fn from_foo(x : [Field; bar::N]) { for i in 0..bar::N { assert(x[i] == bar::N); }; -} \ No newline at end of file +} diff --git a/crates/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr b/tooling/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr rename to tooling/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr diff --git a/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr b/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr new file mode 100644 index 00000000000..b4c72d1cff9 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr @@ -0,0 +1,93 @@ +mod foo; +mod baz; + +global M: Field = 32; +global L: Field = 10; // Unused globals currently allowed +global N: Field = 5; +global T_LEN = 2; // Type inference is allowed on globals +//global N: Field = 5; // Uncomment to see duplicate globals error + +struct Dummy { + x: [Field; N], + y: [Field; foo::MAGIC_NUMBER] +} + +struct Test { + v: Field, +} +global VALS: [Test; 1] = [Test { v: 100 }]; +global NESTED = [VALS, VALS]; + +fn main(a: [Field; M + N - N], b: [Field; 30 + N / 2], c : pub [Field; foo::MAGIC_NUMBER], d: [Field; foo::bar::N]) { + let test_struct = Dummy { x: d, y: c }; + + for i in 0..foo::MAGIC_NUMBER { + assert(c[i] == foo::MAGIC_NUMBER); + assert(test_struct.y[i] == foo::MAGIC_NUMBER); + assert(test_struct.y[i] != NESTED[1][0].v); + } + + assert(N != M); + + let expected: u32 = 42; + assert(foo::TYPE_INFERRED == expected); + + let mut y = 5; + let mut x = M; + for i in 0..N*N { + let M: Field = 10; + x = M; + + y = i; + } + assert(y == 24); + assert(x == 10); + + let q = multiplyByM(3); + assert(q == 96); + + arrays_neq(a, b); + + let t: [Field; T_LEN] = [N, M]; + assert(t[1] == 32); + + assert(15 == mysubmodule::my_helper()); + + let add_submodules_N = mysubmodule::N + foo::bar::N; + assert(15 == add_submodules_N); + let add_from_bar_N = mysubmodule::N + foo::bar::from_bar(1); + assert(15 == add_from_bar_N); + + // Example showing an array filled with (mysubmodule::N + 2) 0's + let sugared = [0; mysubmodule::N + 2]; + assert(sugared[mysubmodule::N + 1] == 0); + + let arr: [Field; mysubmodule::N] = [N; 10]; + assert((arr[0] == 5) & (arr[9] == 5)); + + foo::from_foo(d); + baz::from_baz(c); +} + +fn multiplyByM(x: Field) -> Field { + x * M +} + +fn arrays_neq(a: [Field; M], b: [Field; M]) { + assert(a != b); +} + +mod mysubmodule { + global N: Field = 10; + global L: Field = 50; + + fn my_bool_or(x: u1, y: u1) { + assert(x | y == 1); + } + + fn my_helper() -> Field { + let N: Field = 15; // Like in Rust, local variables override globals + let x = N; + x + } +} diff --git a/crates/nargo_cli/tests/execution_success/hash_to_field/Nargo.toml b/tooling/nargo_cli/tests/execution_success/hash_to_field/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/hash_to_field/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/hash_to_field/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/hash_to_field/Prover.toml b/tooling/nargo_cli/tests/execution_success/hash_to_field/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/hash_to_field/Prover.toml rename to tooling/nargo_cli/tests/execution_success/hash_to_field/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/hash_to_field/src/main.nr b/tooling/nargo_cli/tests/execution_success/hash_to_field/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/hash_to_field/src/main.nr rename to tooling/nargo_cli/tests/execution_success/hash_to_field/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/higher_order_functions/Nargo.toml b/tooling/nargo_cli/tests/execution_success/higher_order_functions/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/higher_order_functions/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/higher_order_functions/Nargo.toml diff --git a/tooling/nargo_cli/tests/execution_success/higher_order_functions/Prover.toml b/tooling/nargo_cli/tests/execution_success/higher_order_functions/Prover.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tooling/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr b/tooling/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr new file mode 100644 index 00000000000..ce61a4d572d --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr @@ -0,0 +1,113 @@ +fn main() -> pub Field { + let f = if 3 * 7 > 200 as u32 { foo } else { bar }; + assert(f()[1] == 2); + // Lambdas: + assert(twice(|x| x * 2, 5) == 20); + assert((|x, y| x + y + 1)(2, 3) == 6); + + // nested lambdas + assert((|a, b| { + a + (|c| c + 2)(b) + })(0, 1) == 3); + + + // Closures: + let a = 42; + let g = || a; + assert(g() == 42); + + // When you copy mutable variables, + // the capture of the copies shouldn't change: + let mut x = 2; + x = x + 1; + let z = x; + + // Add extra mutations to ensure we can mutate x without the + // captured z changing. + x = x + 1; + assert((|y| y + z)(1) == 4); + + // When you capture mutable variables, + // again, the captured variable doesn't change: + let closure_capturing_mutable = (|y| y + x); + assert(closure_capturing_mutable(1) == 5); + x += 1; + assert(closure_capturing_mutable(1) == 5); + + regression_2154(); + + let ret = twice(add1, 3); + + test_array_functions(); + ret +} + +/// Test the array functions in std::array +fn test_array_functions() { + let two = 2; // giving this a name, to ensure that the Option functions work with closures + + let myarray: [i32; 3] = [1, 2, 3]; + assert(myarray.any(|n| n > 2)); + assert(myarray.any(|n| n > two)); + + let evens: [i32; 3] = myarray.map(|n| n * two); // [2, 4, 6] + + assert(evens.all(|n| n > 1)); + assert(evens.all(|n| n >= two)); + + assert(evens.fold(0, |a, b| a + b) == 12); + assert(evens.fold(0, |a, b| a + b + two) == 18); + assert(evens.reduce(|a, b| a + b) == 12); + assert(evens.reduce(|a, b| a + b + two) == 16); + + // TODO: is this a sort_via issue with the new backend, + // or something more general? + // + // currently it fails only with `--experimental-ssa` with + // "not yet implemented: Cast into signed" + // but it worked with the original ssa backend + // (before dropping it) + // + // opened #2121 for it + // https://github.com/noir-lang/noir/issues/2121 + + // let descending = myarray.sort_via(|a, b| a > b); + // assert(descending == [3, 2, 1]); + + assert(evens.map(|n| n / 2) == myarray); + assert(evens.map(|n| n / two) == myarray); +} + +fn foo() -> [u32; 2] { + [1, 3] +} + +fn bar() -> [u32; 2] { + [3, 2] +} + +fn add1(x: Field) -> Field { + x + 1 +} + +fn twice(f: fn(Field) -> Field, x: Field) -> Field { + f(f(x)) +} + +// Fixing an ICE, where rewriting the closures +// during monomorphization didn't correspond +// to an internal `if` type +// found by @jfecher: +// https://github.com/noir-lang/noir/pull/1959#issuecomment-1658992989 +// issue https://github.com/noir-lang/noir/issues/2154 +fn regression_2154() { + let x: u32 = 32; + + let closure_if_else = if x > 2 { + || x + } else { + || x + 2342 + }; + + assert(closure_if_else() == 32); +} diff --git a/crates/nargo_cli/tests/execution_success/if_else_chain/Nargo.toml b/tooling/nargo_cli/tests/execution_success/if_else_chain/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/if_else_chain/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/if_else_chain/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/if_else_chain/Prover.toml b/tooling/nargo_cli/tests/execution_success/if_else_chain/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/if_else_chain/Prover.toml rename to tooling/nargo_cli/tests/execution_success/if_else_chain/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/if_else_chain/src/main.nr b/tooling/nargo_cli/tests/execution_success/if_else_chain/src/main.nr new file mode 100644 index 00000000000..f83ba2dde0e --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/if_else_chain/src/main.nr @@ -0,0 +1,15 @@ +fn main(a: u32, mut c: [u32; 4]){ + if a == c[0] { + assert(c[0] == 0); + } else if a == c[1] { + assert(c[1] == 0); + } else if a == c[2] { + assert(c[2] == 0); + } else if a == c[3] { + // expect to match this case + assert(c[3] == 0); + } else { + assert(c[0] == 10); + } +} + diff --git a/crates/nargo_cli/tests/execution_success/import/Nargo.toml b/tooling/nargo_cli/tests/execution_success/import/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/import/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/import/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/import/Prover.toml b/tooling/nargo_cli/tests/execution_success/import/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/import/Prover.toml rename to tooling/nargo_cli/tests/execution_success/import/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/import/src/import.nr b/tooling/nargo_cli/tests/execution_success/import/src/import.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/import/src/import.nr rename to tooling/nargo_cli/tests/execution_success/import/src/import.nr diff --git a/crates/nargo_cli/tests/execution_success/import/src/main.nr b/tooling/nargo_cli/tests/execution_success/import/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/import/src/main.nr rename to tooling/nargo_cli/tests/execution_success/import/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/integer_array_indexing/Nargo.toml b/tooling/nargo_cli/tests/execution_success/integer_array_indexing/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/integer_array_indexing/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/integer_array_indexing/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/integer_array_indexing/Prover.toml b/tooling/nargo_cli/tests/execution_success/integer_array_indexing/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/integer_array_indexing/Prover.toml rename to tooling/nargo_cli/tests/execution_success/integer_array_indexing/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/integer_array_indexing/src/main.nr b/tooling/nargo_cli/tests/execution_success/integer_array_indexing/src/main.nr new file mode 100644 index 00000000000..1e0ec518b9f --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/integer_array_indexing/src/main.nr @@ -0,0 +1,12 @@ +global ARRAY_LEN: u32 = 3; + +fn main(arr: [Field; ARRAY_LEN], x: u32) -> pub Field { + + let mut value = arr[ARRAY_LEN - 1]; + + value += arr[0 as u32]; + value += arr[1 as Field]; + + value + (x as Field) + +} diff --git a/crates/nargo_cli/tests/execution_success/keccak256/Nargo.toml b/tooling/nargo_cli/tests/execution_success/keccak256/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/keccak256/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/keccak256/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/keccak256/Prover.toml b/tooling/nargo_cli/tests/execution_success/keccak256/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/keccak256/Prover.toml rename to tooling/nargo_cli/tests/execution_success/keccak256/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/keccak256/src/main.nr b/tooling/nargo_cli/tests/execution_success/keccak256/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/keccak256/src/main.nr rename to tooling/nargo_cli/tests/execution_success/keccak256/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/main_bool_arg/Nargo.toml b/tooling/nargo_cli/tests/execution_success/main_bool_arg/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/main_bool_arg/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/main_bool_arg/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/main_bool_arg/Prover.toml b/tooling/nargo_cli/tests/execution_success/main_bool_arg/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/main_bool_arg/Prover.toml rename to tooling/nargo_cli/tests/execution_success/main_bool_arg/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/main_bool_arg/src/main.nr b/tooling/nargo_cli/tests/execution_success/main_bool_arg/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/main_bool_arg/src/main.nr rename to tooling/nargo_cli/tests/execution_success/main_bool_arg/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/main_return/Nargo.toml b/tooling/nargo_cli/tests/execution_success/main_return/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/main_return/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/main_return/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/main_return/Prover.toml b/tooling/nargo_cli/tests/execution_success/main_return/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/main_return/Prover.toml rename to tooling/nargo_cli/tests/execution_success/main_return/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/main_return/src/main.nr b/tooling/nargo_cli/tests/execution_success/main_return/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/main_return/src/main.nr rename to tooling/nargo_cli/tests/execution_success/main_return/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/merkle_insert/Nargo.toml b/tooling/nargo_cli/tests/execution_success/merkle_insert/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/merkle_insert/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/merkle_insert/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/merkle_insert/Prover.toml b/tooling/nargo_cli/tests/execution_success/merkle_insert/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/merkle_insert/Prover.toml rename to tooling/nargo_cli/tests/execution_success/merkle_insert/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/merkle_insert/src/main.nr b/tooling/nargo_cli/tests/execution_success/merkle_insert/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/merkle_insert/src/main.nr rename to tooling/nargo_cli/tests/execution_success/merkle_insert/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/modules/Nargo.toml b/tooling/nargo_cli/tests/execution_success/modules/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/modules/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/modules/Prover.toml b/tooling/nargo_cli/tests/execution_success/modules/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules/Prover.toml rename to tooling/nargo_cli/tests/execution_success/modules/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/modules/src/foo.nr b/tooling/nargo_cli/tests/execution_success/modules/src/foo.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules/src/foo.nr rename to tooling/nargo_cli/tests/execution_success/modules/src/foo.nr diff --git a/crates/nargo_cli/tests/execution_success/modules/src/main.nr b/tooling/nargo_cli/tests/execution_success/modules/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules/src/main.nr rename to tooling/nargo_cli/tests/execution_success/modules/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/modules_more/Nargo.toml b/tooling/nargo_cli/tests/execution_success/modules_more/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules_more/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/modules_more/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/modules_more/Prover.toml b/tooling/nargo_cli/tests/execution_success/modules_more/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules_more/Prover.toml rename to tooling/nargo_cli/tests/execution_success/modules_more/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/modules_more/src/foo.nr b/tooling/nargo_cli/tests/execution_success/modules_more/src/foo.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules_more/src/foo.nr rename to tooling/nargo_cli/tests/execution_success/modules_more/src/foo.nr diff --git a/crates/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr b/tooling/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr rename to tooling/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr diff --git a/crates/nargo_cli/tests/execution_success/modules_more/src/main.nr b/tooling/nargo_cli/tests/execution_success/modules_more/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/modules_more/src/main.nr rename to tooling/nargo_cli/tests/execution_success/modules_more/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/modulus/Nargo.toml b/tooling/nargo_cli/tests/execution_success/modulus/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/modulus/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/modulus/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/modulus/Prover.toml b/tooling/nargo_cli/tests/execution_success/modulus/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/modulus/Prover.toml rename to tooling/nargo_cli/tests/execution_success/modulus/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/modulus/src/main.nr b/tooling/nargo_cli/tests/execution_success/modulus/src/main.nr new file mode 100644 index 00000000000..bb1a0ff5478 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/modulus/src/main.nr @@ -0,0 +1,27 @@ +use dep::std; + +fn main(bn254_modulus_be_bytes : [u8; 32], bn254_modulus_be_bits : [u1; 254]) -> pub Field { + let modulus_size = std::field::modulus_num_bits(); + // NOTE: The constraints used in this circuit will only work when testing nargo with the plonk bn254 backend + assert(modulus_size == 254); + + let modulus_be_byte_array = std::field::modulus_be_bytes(); + for i in 0..32 { + assert(modulus_be_byte_array[i] == bn254_modulus_be_bytes[i]); + } + let modulus_le_byte_array = std::field::modulus_le_bytes(); + for i in 0..32 { + assert(modulus_le_byte_array[i] == bn254_modulus_be_bytes[31-i]); + } + + let modulus_be_bits = std::field::modulus_be_bits(); + for i in 0..254 { + assert(modulus_be_bits[i] == bn254_modulus_be_bits[i]); + } + let modulus_le_bits = std::field::modulus_le_bits(); + for i in 0..254 { + assert(modulus_le_bits[i] == bn254_modulus_be_bits[253-i]); + } + + modulus_size +} diff --git a/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Nargo.toml b/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Prover.toml b/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Prover.toml rename to tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/src/main.nr b/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/nested_arrays_from_brillig/src/main.nr rename to tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/pedersen_check/Nargo.toml b/tooling/nargo_cli/tests/execution_success/pedersen_check/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/pedersen_check/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/pedersen_check/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/pedersen_check/Prover.toml b/tooling/nargo_cli/tests/execution_success/pedersen_check/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/pedersen_check/Prover.toml rename to tooling/nargo_cli/tests/execution_success/pedersen_check/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/pedersen_check/src/main.nr b/tooling/nargo_cli/tests/execution_success/pedersen_check/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/pedersen_check/src/main.nr rename to tooling/nargo_cli/tests/execution_success/pedersen_check/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/Nargo.toml b/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/Prover.toml b/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/Prover.toml rename to tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/src/main.nr b/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/poseidon_bn254_hash/src/main.nr rename to tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Nargo.toml b/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Prover.toml b/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Prover.toml rename to tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/src/main.nr b/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/poseidonsponge_x5_254/src/main.nr rename to tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/pred_eq/Nargo.toml b/tooling/nargo_cli/tests/execution_success/pred_eq/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/pred_eq/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/pred_eq/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/pred_eq/Prover.toml b/tooling/nargo_cli/tests/execution_success/pred_eq/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/pred_eq/Prover.toml rename to tooling/nargo_cli/tests/execution_success/pred_eq/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/pred_eq/src/main.nr b/tooling/nargo_cli/tests/execution_success/pred_eq/src/main.nr new file mode 100644 index 00000000000..d1e79a3e408 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/pred_eq/src/main.nr @@ -0,0 +1,4 @@ +fn main(x: Field, y: Field) { + let p = x == y; + assert(p == true); +} diff --git a/crates/nargo_cli/tests/execution_success/references/Nargo.toml b/tooling/nargo_cli/tests/execution_success/references/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/references/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/references/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/references/Prover.toml b/tooling/nargo_cli/tests/execution_success/references/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/references/Prover.toml rename to tooling/nargo_cli/tests/execution_success/references/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/references/src/main.nr b/tooling/nargo_cli/tests/execution_success/references/src/main.nr new file mode 100644 index 00000000000..be02f2b10d6 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/references/src/main.nr @@ -0,0 +1,245 @@ +fn main(mut x: Field) { + add1(&mut x); + assert(x == 3); + + let mut s = S { y: x }; + s.add2(); + assert(s.y == 5); + + // Regression for #1946: Method resolution error when calling &mut methods with a variable of type &mut T + let s_ref = &mut s; + s_ref.add2(); + assert(s.y == 7); + + // Test that normal mutable variables are still copied + let mut a = 0; + mutate_copy(a); + assert(a == 0); + + // Test something 3 allocations deep + let mut nested_allocations = Nested { y: &mut &mut 0 }; + add1(*nested_allocations.y); + assert(**nested_allocations.y == 1); + + // Test nested struct allocations with a mutable reference to an array. + let mut c = C { + foo: 0, + bar: &mut C2 { + array: &mut [1, 2], + }, + }; + *c.bar.array = [3, 4]; + assert(*c.bar.array == [3, 4]); + + regression_1887(); + regression_2054(); + regression_2030(); + regression_2255(); + + assert(x == 3); + regression_2218_if_inner_if(x, 10); + regression_2218_if_inner_else(20, x); + regression_2218_else(x, 3); + regression_2218_loop(x, 10); + + regression_2560(s_ref); +} + +fn add1(x: &mut Field) { + *x += 1; +} + +struct S { y: Field } + +struct Nested { y: &mut &mut Field } + +struct C { + foo: Field, + bar: &mut C2, +} + +struct C2 { + array: &mut [Field; 2] +} + +impl S { + fn add2(&mut self) { + self.y += 2; + } + + fn get_y(self) -> Field { + self.y + } +} + +fn mutate_copy(mut a: Field) { + a = 7; +} + +// Previously the `foo.bar` in `foo.bar.mutate()` would insert an automatic dereference +// of `foo` which caused the method to wrongly be mutating a copy of bar rather than the original. +fn regression_1887() { + let foo = &mut Foo { bar: Bar { x: 0 } }; + foo.bar.mutate(); + assert(foo.bar.x == 32); +} + +struct Foo { bar: Bar } +struct Bar { x: Field } + +impl Bar { + fn mutate(&mut self) { + self.x = 32; + } +} + +// Ensure that mutating a variable does not also mutate its copy +fn regression_2054() { + let mut x = 2; + let z = x; + + x += 1; + assert(z == 2); +} + +// The compiler was still trying to convert an LValue from an array of structs to struct of arrays indexing, +// even though this conversion was mostly removed elsewhere. +fn regression_2030() { + let ref = &mut 0; + let mut array = [ref, ref]; + let _ = *array[0]; + *array[0] = 1; +} + +// The `mut x: &mut ...` caught a bug handling lvalues where a double-dereference would occur internally +// in one step rather than being tracked by two separate steps. This lead to assigning the 1 value to the +// incorrect outer `mut` reference rather than the correct `&mut` reference. +fn regression_2255() { + let x = &mut 0; + regression_2255_helper(x); + assert(*x == 1); +} + +fn regression_2255_helper(mut x: &mut Field) { + *x = 1; +} + +fn regression_2218(x: Field, y: Field) -> Field { + let q = &mut &mut 0; + let q1 = *q; + let q2 = *q; + + if x != y { + *q1 = 1; + // Make sure that we correct load reference aliases through multiple blocks + if x != 20 { + *q1 = 10; + *q2 = 2; // now we'd expect q1 == q2 == 2 + + assert(*q1 == 2); + } else { + *q2 = 15; + assert(*q1 == 15); + } + } else { + *q2 = 20; + assert(*q1 == 20); + } + // Have to assign value to return it + let value = *q1; + value +} + +fn regression_2218_if_inner_if(x: Field, y: Field) { + let value = regression_2218(x, y); + assert(value == 2); +} + +fn regression_2218_if_inner_else(x: Field, y: Field) { + let value = regression_2218(x, y); + assert(value == 15); +} + +fn regression_2218_else(x: Field, y: Field) { + let value = regression_2218(x, y); + assert(value == 20); +} + +fn regression_2218_loop(x: Field, y: Field) { + let q = &mut &mut 0; + let q1 = *q; + let q2 = *q; + + for _ in 0..1 { + if x != y { + *q1 = 10; + *q2 = 2; // now we'd expect q1 == q2 == 2 + + assert(*q1 == 2); + } else { + *q2 = 20; + assert(*q1 == 20); + } + } + assert(*q1 == 2); + + for _ in 0..1 { + for _ in 0..5 { + if x != y { + *q1 = 1; + // Make sure that we correct load reference aliases through multiple blocks + if x != 20 { + *q1 = 10; + *q2 = 2; // now we'd expect q1 == q2 == 2 + + assert(*q1 == 2); + } + } else { + *q2 = 20; + assert(*q1 == 20); + } + } + if x != y { + *q1 = 1; + for _ in 0..5 { + // Make sure that we correct load reference aliases through multiple blocks + if x != 20 { + *q1 = 10; + *q2 = 2; // now we'd expect q1 == q2 == 2 + + assert(*q1 == 2); + } + } + } else { + *q2 = 20; + assert(*q1 == 20); + } + } + assert(*q1 == 2); + + if x != y { + for _ in 0..5 { + if x != y { + *q1 = 1; + // Make sure that we correct load reference aliases through multiple blocks + if x != 20 { + *q1 = 10; + *q2 = 2; // now we'd expect q1 == q2 == 2 + + assert(*q1 == 2); + } + } + } + } else { + *q2 = 20; + assert(*q1 == 20); + } + assert(*q1 == 2); +} + +// This is more a feature test than a proper regression. +// Before, we never automatically dereferenced objects in method calls to their value types. +// Now, we insert as many `*` as necessary to get to `S`. +fn regression_2560(s_ref: &mut S) { + assert(s_ref.get_y() == 7); +} diff --git a/tooling/nargo_cli/tests/execution_success/references_aliasing/Nargo.toml b/tooling/nargo_cli/tests/execution_success/references_aliasing/Nargo.toml new file mode 100644 index 00000000000..b95c3998483 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/references_aliasing/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "references_aliasing" +type = "bin" +authors = [""] +compiler_version = "0.5.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/execution_success/references_aliasing/Prover.toml b/tooling/nargo_cli/tests/execution_success/references_aliasing/Prover.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tooling/nargo_cli/tests/execution_success/references_aliasing/src/main.nr b/tooling/nargo_cli/tests/execution_success/references_aliasing/src/main.nr new file mode 100644 index 00000000000..02057732f35 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/references_aliasing/src/main.nr @@ -0,0 +1,29 @@ +fn main() { + let mut x = 100; + let mut xref = &mut x; + increment(xref); + assert(*xref == 101); + + regression_2445(); +} + +fn increment(mut r: &mut Field) { + *r = *r + 1; +} + +// If aliasing within arrays and constant folding within the mem2reg pass aren't +// handled, we'll fail to optimize out all the references in this function. +fn regression_2445() { + let mut var = 0; + let ref = &mut &mut var; + + let mut array = [ref, ref]; + + **array[0] = 1; + **array[1] = 2; + + assert(var == 2); + assert(**ref == 2); + assert(**array[0] == 2); + assert(**array[1] == 2); +} diff --git a/crates/nargo_cli/tests/execution_success/regression/Nargo.toml b/tooling/nargo_cli/tests/execution_success/regression/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/regression/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/regression/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/regression/Prover.toml b/tooling/nargo_cli/tests/execution_success/regression/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/regression/Prover.toml rename to tooling/nargo_cli/tests/execution_success/regression/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/regression/src/main.nr b/tooling/nargo_cli/tests/execution_success/regression/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/regression/src/main.nr rename to tooling/nargo_cli/tests/execution_success/regression/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Nargo.toml b/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Prover.toml b/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Prover.toml rename to tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/src/main.nr b/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/regression_method_cannot_be_found/src/main.nr rename to tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/scalar_mul/Nargo.toml b/tooling/nargo_cli/tests/execution_success/scalar_mul/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/scalar_mul/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/scalar_mul/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/scalar_mul/Prover.toml b/tooling/nargo_cli/tests/execution_success/scalar_mul/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/scalar_mul/Prover.toml rename to tooling/nargo_cli/tests/execution_success/scalar_mul/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/scalar_mul/src/main.nr b/tooling/nargo_cli/tests/execution_success/scalar_mul/src/main.nr new file mode 100644 index 00000000000..37f3ac410f0 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/scalar_mul/src/main.nr @@ -0,0 +1,22 @@ +use dep::std; + +fn main( + a: Field, + a_pub_x: pub Field, + a_pub_y: pub Field, + b: Field, + b_pub_x: pub Field, + b_pub_y: pub Field +) { + let mut priv_key = a; + let mut pub_x: Field = a_pub_x; + let mut pub_y: Field = a_pub_y; + if a != 1 { // Change `a` in Prover.toml to test input `b` + priv_key = b; + pub_x = b_pub_x; + pub_y = b_pub_y; + } + let res = std::scalar_mul::fixed_base_embedded_curve(priv_key, 0); + assert(res[0] == pub_x); + assert(res[1] == pub_y); +} diff --git a/crates/nargo_cli/tests/execution_success/schnorr/Nargo.toml b/tooling/nargo_cli/tests/execution_success/schnorr/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/schnorr/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/schnorr/Nargo.toml diff --git a/tooling/nargo_cli/tests/execution_success/schnorr/Prover.toml b/tooling/nargo_cli/tests/execution_success/schnorr/Prover.toml new file mode 100644 index 00000000000..5fe6bd2546f --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/schnorr/Prover.toml @@ -0,0 +1,10 @@ +message = [0,1,2,3,4,5,6,7,8,9] +message_field = "0x010203040506070809" +pub_key_x = "0x17cbd3ed3151ccfd170efe1d54280a6a4822640bf5c369908ad74ea21518a9c5" +pub_key_y = "0x0e0456e3795c1a31f20035b741cd6158929eeccd320d299cfcac962865a6bc74" +signature = [ + 5, 202, 31, 146, 81, 242, 246, 69, 43, 107, 249, 153, 198, 44, 14, 111, 191, 121, 137, 166, + 160, 103, 18, 181, 243, 233, 226, 95, 67, 16, 37, 128, 85, 76, 19, 253, 30, 77, 192, 53, 138, + 205, 69, 33, 236, 163, 83, 194, 84, 137, 184, 221, 176, 121, 179, 27, 63, 70, 54, 16, 176, + 250, 39, 239, +] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/schnorr/src/main.nr b/tooling/nargo_cli/tests/execution_success/schnorr/src/main.nr new file mode 100644 index 00000000000..3c8881b2f39 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/schnorr/src/main.nr @@ -0,0 +1,21 @@ +use dep::std; + +// Note: If main has any unsized types, then the verifier will never be able +// to figure out the circuit instance +fn main(message: [u8; 10], message_field: Field, pub_key_x: Field, pub_key_y: Field, signature: [u8; 64]) { + // Regression for issue #2421 + // We want to make sure that we can accurately verify a signature whose message is a slice vs. an array + let message_field_bytes = message_field.to_be_bytes(10); + for i in 0..10 { + assert(message[i] == message_field_bytes[i]); + } + // Is there ever a situation where someone would want + // to ensure that a signature was invalid? + // Check that passing a slice as the message is valid + let valid_signature = std::schnorr::verify_signature(pub_key_x,pub_key_y,signature, message_field_bytes); + assert(valid_signature); + + // Check that passing an array as the message is valid + let valid_signature = std::schnorr::verify_signature(pub_key_x,pub_key_y,signature, message); + assert(valid_signature); +} diff --git a/crates/nargo_cli/tests/execution_success/sha256/Nargo.toml b/tooling/nargo_cli/tests/execution_success/sha256/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha256/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/sha256/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/sha256/Prover.toml b/tooling/nargo_cli/tests/execution_success/sha256/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha256/Prover.toml rename to tooling/nargo_cli/tests/execution_success/sha256/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/sha256/src/main.nr b/tooling/nargo_cli/tests/execution_success/sha256/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha256/src/main.nr rename to tooling/nargo_cli/tests/execution_success/sha256/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/sha2_blocks/Nargo.toml b/tooling/nargo_cli/tests/execution_success/sha2_blocks/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha2_blocks/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/sha2_blocks/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/sha2_blocks/Prover.toml b/tooling/nargo_cli/tests/execution_success/sha2_blocks/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha2_blocks/Prover.toml rename to tooling/nargo_cli/tests/execution_success/sha2_blocks/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/sha2_blocks/src/main.nr b/tooling/nargo_cli/tests/execution_success/sha2_blocks/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha2_blocks/src/main.nr rename to tooling/nargo_cli/tests/execution_success/sha2_blocks/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/sha2_byte/Nargo.toml b/tooling/nargo_cli/tests/execution_success/sha2_byte/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha2_byte/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/sha2_byte/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/sha2_byte/Prover.toml b/tooling/nargo_cli/tests/execution_success/sha2_byte/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha2_byte/Prover.toml rename to tooling/nargo_cli/tests/execution_success/sha2_byte/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/sha2_byte/src/main.nr b/tooling/nargo_cli/tests/execution_success/sha2_byte/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/sha2_byte/src/main.nr rename to tooling/nargo_cli/tests/execution_success/sha2_byte/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/signed_division/Nargo.toml b/tooling/nargo_cli/tests/execution_success/signed_division/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/signed_division/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/signed_division/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/signed_division/Prover.toml b/tooling/nargo_cli/tests/execution_success/signed_division/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/signed_division/Prover.toml rename to tooling/nargo_cli/tests/execution_success/signed_division/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/signed_division/src/main.nr b/tooling/nargo_cli/tests/execution_success/signed_division/src/main.nr new file mode 100644 index 00000000000..7bc6d7fc936 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/signed_division/src/main.nr @@ -0,0 +1,23 @@ +// Testing signed integer division: +// 7/3 = 2 +// -7/3 = -2 +// -7/-3 = 2 +// 7/-3 = -2 +fn main(mut x: i32, mut y: i32, mut z: i32) { + // 7/3 = 2 + assert(x / y == z); + + // -7/3 = -2 + let minus_x = 0-x; + let minus_z = 0-z; + let minus_y = 0-y; + assert(x+minus_x == 0); + assert(z+minus_z == 0); + assert(minus_x / y == minus_z); + + // -7/-3 = 2 + assert(minus_x / minus_y == z); + + // 7/-3 = -2 + assert(x / minus_y == minus_z); +} diff --git a/crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_add_and_ret_arr/src/main.nr rename to tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/simple_array_param/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_array_param/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_array_param/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_array_param/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_array_param/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_array_param/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_array_param/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_array_param/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_array_param/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_array_param/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_array_param/src/main.nr rename to tooling/nargo_cli/tests/execution_success/simple_array_param/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/simple_bitwise/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_bitwise/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_bitwise/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_bitwise/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_bitwise/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_bitwise/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_bitwise/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_bitwise/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_bitwise/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_bitwise/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_bitwise/src/main.nr rename to tooling/nargo_cli/tests/execution_success/simple_bitwise/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/simple_comparison/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_comparison/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_comparison/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_comparison/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_comparison/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_comparison/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_comparison/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_comparison/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_comparison/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_comparison/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_comparison/src/main.nr rename to tooling/nargo_cli/tests/execution_success/simple_comparison/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/simple_mut/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_mut/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_mut/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_mut/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_mut/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_mut/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_mut/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_mut/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_mut/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_mut/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_mut/src/main.nr rename to tooling/nargo_cli/tests/execution_success/simple_mut/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/simple_not/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_not/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_not/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_not/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_not/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_not/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_not/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_not/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_not/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_not/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_not/src/main.nr rename to tooling/nargo_cli/tests/execution_success/simple_not/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/simple_print/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_print/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_print/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_print/Nargo.toml diff --git a/tooling/nargo_cli/tests/execution_success/simple_print/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_print/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/simple_print/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/crates/nargo_cli/tests/execution_success/simple_print/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_print/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_print/src/main.nr rename to tooling/nargo_cli/tests/execution_success/simple_print/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/simple_program_addition/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_program_addition/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_program_addition/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_program_addition/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_shift_left_right/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_program_addition/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_shift_left_right/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_program_addition/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_program_addition/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_program_addition/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_program_addition/src/main.nr rename to tooling/nargo_cli/tests/execution_success/simple_program_addition/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/simple_radix/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_radix/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_radix/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_radix/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_radix/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_radix/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_radix/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_radix/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/simple_radix/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_radix/src/main.nr new file mode 100644 index 00000000000..9ce6d86f13a --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/simple_radix/src/main.nr @@ -0,0 +1,8 @@ +// Simple program to test to_radix + +fn main(x : Field) { + let bits = x.to_le_bits(3); + assert(bits[0] == 0); + assert(bits[1] == 1); + assert(bits[2] == 0); +} diff --git a/crates/nargo_cli/tests/execution_success/simple_shield/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_shield/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_shield/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_shield/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/simple_shield/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_shield/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_shield/Prover.toml rename to tooling/nargo_cli/tests/execution_success/simple_shield/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/simple_shield/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_shield/src/main.nr new file mode 100644 index 00000000000..c26a53d56cd --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/simple_shield/src/main.nr @@ -0,0 +1,35 @@ +use dep::std; + +fn main( + // Public key of note + // all notes have the same denomination + priv_key: Field, + + // Merkle membership proof + note_root: pub Field, + index: Field, + note_hash_path: [Field; 3], + + // Receiver public key + to_pubkey_x: Field, + to_pubkey_y: Field, +) -> pub [Field; 2] { + // Compute public key from private key to show ownership + let pubkey = std::scalar_mul::fixed_base_embedded_curve(priv_key, 0); + let pubkey_x = pubkey[0]; + let pubkey_y = pubkey[1]; + + // Compute input note commitment + let note_commitment = std::hash::pedersen([pubkey_x, pubkey_y]); + + // Compute input note nullifier + let nullifier = std::hash::pedersen([note_commitment[0], index, priv_key]); + + // Compute output note nullifier + let receiver_note_commitment = std::hash::pedersen([to_pubkey_x, to_pubkey_y]); + + // Check that the input note nullifier is in the root + assert(note_root == std::merkle::compute_merkle_root(note_commitment[0], index, note_hash_path)); + + [nullifier[0], receiver_note_commitment[0]] +} diff --git a/crates/nargo_cli/tests/execution_success/simple_shift_left_right/Nargo.toml b/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/simple_shift_left_right/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Nargo.toml diff --git a/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Prover.toml b/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Prover.toml new file mode 100644 index 00000000000..07890234a19 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Prover.toml @@ -0,0 +1 @@ +x = "3" diff --git a/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/src/main.nr b/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/src/main.nr new file mode 100644 index 00000000000..f12b2d8bf20 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/src/main.nr @@ -0,0 +1,8 @@ +// Tests a very simple program. +// +// The features being tested are left and right shifts. +fn main(x : u32) { + let z = x >> 4; + let t = x << 4; + assert(z == t >> 8); +} diff --git a/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Nargo.toml b/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Nargo.toml new file mode 100644 index 00000000000..08322784151 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "slice_dynamic_index" +type = "bin" +authors = [""] +compiler_version = "0.10.3" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Prover.toml b/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Prover.toml new file mode 100644 index 00000000000..0e5dfd5638d --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Prover.toml @@ -0,0 +1 @@ +x = "5" diff --git a/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr b/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr new file mode 100644 index 00000000000..de5b4caef29 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr @@ -0,0 +1,252 @@ +fn main(x : Field) { + // The parameters to this function must come directly from witness values (inputs to main). + regression_dynamic_slice_index(x - 1, x - 4); +} + +fn regression_dynamic_slice_index(x: Field, y: Field) { + let mut slice = []; + for i in 0..5 { + slice = slice.push_back(i); + } + assert(slice.len() == 5); + + dynamic_slice_index_set_if(slice, x, y); + dynamic_slice_index_set_else(slice, x, y); + dynamic_slice_index_set_nested_if_else_else(slice, x, y); + dynamic_slice_index_set_nested_if_else_if(slice, x, y + 1); + dynamic_slice_index_if(slice, x); + dynamic_array_index_if([0, 1, 2, 3, 4], x); + dynamic_slice_index_else(slice, x); + + dynamic_slice_merge_if(slice, x); + dynamic_slice_merge_else(slice, x); + dynamic_slice_merge_two_ifs(slice, x); +} + +fn dynamic_slice_index_set_if(mut slice: [Field], x: Field, y: Field) { + assert(slice[x] == 4); + assert(slice[y] == 1); + slice[y] = 0; + assert(slice[x] == 4); + assert(slice[1] == 0); + if x as u32 < 10 { + assert(slice[x] == 4); + slice[x] = slice[x] - 2; + slice[x - 1] = slice[x]; + } else { + slice[x] = 0; + } + assert(slice[3] == 2); + assert(slice[4] == 2); +} + +fn dynamic_slice_index_set_else(mut slice: [Field], x: Field, y: Field) { + assert(slice[x] == 4); + assert(slice[y] == 1); + slice[y] = 0; + assert(slice[x] == 4); + assert(slice[1] == 0); + if x as u32 > 10 { + assert(slice[x] == 4); + slice[x] = slice[x] - 2; + slice[x - 1] = slice[x]; + } else { + slice[x] = 0; + } + assert(slice[4] == 0); +} + +// This tests the case of missing a store instruction in the else branch +// of merging slices +fn dynamic_slice_index_if(mut slice: [Field], x: Field) { + if x as u32 < 10 { + assert(slice[x] == 4); + slice[x] = slice[x] - 2; + } else { + assert(slice[x] == 0); + } + assert(slice[4] == 2); +} + +fn dynamic_array_index_if(mut array: [Field; 5], x: Field) { + if x as u32 < 10 { + assert(array[x] == 4); + array[x] = array[x] - 2; + } else { + assert(array[x] == 0); + } + assert(array[4] == 2); +} + +// This tests the case of missing a store instruction in the then branch +// of merging slices +fn dynamic_slice_index_else(mut slice: [Field], x: Field) { + if x as u32 > 10 { + assert(slice[x] == 0); + } else { + assert(slice[x] == 4); + slice[x] = slice[x] - 2; + } + assert(slice[4] == 2); +} + + +fn dynamic_slice_merge_if(mut slice: [Field], x: Field) { + if x as u32 < 10 { + assert(slice[x] == 4); + slice[x] = slice[x] - 2; + + slice = slice.push_back(10); + // Having an array set here checks whether we appropriately + // handle a slice length that is not yet resolving to a constant + // during flattening + slice[x] = 10; + assert(slice[slice.len() - 1] == 10); + assert(slice.len() == 6); + + slice[x] = 20; + slice[x] = slice[x] + 10; + + slice = slice.push_front(11); + assert(slice[0] == 11); + assert(slice.len() == 7); + assert(slice[5] == 30); + + slice = slice.push_front(12); + assert(slice[0] == 12); + assert(slice.len() == 8); + assert(slice[6] == 30); + + let (popped_slice, last_elem) = slice.pop_back(); + assert(last_elem == 10); + assert(popped_slice.len() == 7); + + let (first_elem, rest_of_slice) = popped_slice.pop_front(); + assert(first_elem == 12); + assert(rest_of_slice.len() == 6); + + // TODO(#2462): SliceInsert and SliceRemove with a dynamic index are not yet implemented in ACIR gen + slice = rest_of_slice.insert(2, 20); + assert(slice[2] == 20); + assert(slice[6] == 30); + assert(slice.len() == 7); + + // TODO(#2462): SliceInsert and SliceRemove with a dynamic index are not yet implemented in ACIR gen + let (removed_slice, removed_elem) = slice.remove(3); + // The deconstructed tuple assigns to the slice but is not seen outside of the if statement + // without a direct assignment + slice = removed_slice; + + assert(removed_elem == 1); + assert(slice.len() == 6); + } else { + assert(slice[x] == 0); + slice = slice.push_back(20); + } + + assert(slice.len() == 6); + assert(slice[slice.len() - 1] == 30); +} + +fn dynamic_slice_merge_else(mut slice: [Field], x: Field) { + if x as u32 > 10 { + assert(slice[x] == 0); + slice[x] = 2; + } else { + assert(slice[x] == 4); + slice[x] = slice[x] - 2; + slice = slice.push_back(10); + } + assert(slice.len() == 6); + assert(slice[slice.len() - 1] == 10); + + slice = slice.push_back(20); + assert(slice.len() == 7); + assert(slice[slice.len() - 1] == 20); +} + +fn dynamic_slice_merge_two_ifs(mut slice: [Field], x: Field) { + if x as u32 > 10 { + assert(slice[x] == 0); + slice[x] = 2; + } else { + assert(slice[x] == 4); + slice[x] = slice[x] - 2; + slice = slice.push_back(10); + } + + assert(slice.len() == 6); + assert(slice[slice.len() - 1] == 10); + + if x == 20 { + slice = slice.push_back(20); + } else { + slice = slice.push_back(15); + } + // TODO(#2599): Breaks if the push back happens without the else case + // slice = slice.push_back(15); + + assert(slice.len() == 7); + assert(slice[slice.len() - 1] == 15); + + slice = slice.push_back(20); + assert(slice.len() == 8); + assert(slice[slice.len() - 1] == 20); +} + +fn dynamic_slice_index_set_nested_if_else_else(mut slice: [Field], x: Field, y: Field) { + assert(slice[x] == 4); + assert(slice[y] == 1); + slice[y] = 0; + assert(slice[x] == 4); + assert(slice[1] == 0); + if x as u32 < 10 { + slice[x] = slice[x] - 2; + if y != 1 { + slice[x] = slice[x] + 20; + } else { + if x == 5 { + // We should not hit this case + assert(slice[x] == 22); + } else { + slice[x] = 10; + slice = slice.push_back(15); + assert(slice.len() == 6); + } + assert(slice[4] == 10); + } + } else { + slice[x] = 0; + } + assert(slice[4] == 10); + assert(slice.len() == 6); + assert(slice[slice.len() - 1] == 15); + + slice = slice.push_back(20); + assert(slice.len() == 7); + assert(slice[slice.len() - 1] == 20); +} + +fn dynamic_slice_index_set_nested_if_else_if(mut slice: [Field], x: Field, y: Field) { + assert(slice[x] == 4); + assert(slice[y] == 2); + slice[y] = 0; + assert(slice[x] == 4); + assert(slice[2] == 0); + if x as u32 < 10 { + slice[x] = slice[x] - 2; + // TODO: this panics as we have a load for the slice in flattening + if y == 1 { + slice[x] = slice[x] + 20; + } else { + if x == 4 { + slice[x] = 5; + } + assert(slice[4] == 5); + } + } else { + slice[x] = 0; + } + assert(slice[4] == 5); +} + diff --git a/crates/nargo_cli/tests/execution_success/slices/Nargo.toml b/tooling/nargo_cli/tests/execution_success/slices/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/slices/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/slices/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/vectors/Prover.toml b/tooling/nargo_cli/tests/execution_success/slices/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/vectors/Prover.toml rename to tooling/nargo_cli/tests/execution_success/slices/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/slices/src/main.nr b/tooling/nargo_cli/tests/execution_success/slices/src/main.nr new file mode 100644 index 00000000000..8fbe14bfea3 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/slices/src/main.nr @@ -0,0 +1,213 @@ +use dep::std::slice; +use dep::std; + +fn main(x : Field, y : pub Field) { + let mut slice = [0; 2]; + assert(slice[0] == 0); + assert(slice[0] != 1); + slice[0] = x; + assert(slice[0] == x); + + let slice_plus_10 = slice.push_back(y); + assert(slice_plus_10[2] == 10); + assert(slice_plus_10[2] != 8); + assert(slice_plus_10.len() == 3); + + let mut new_slice = []; + for i in 0..5 { + new_slice = new_slice.push_back(i); + } + assert(new_slice.len() == 5); + + new_slice = new_slice.push_front(20); + assert(new_slice[0] == 20); + assert(new_slice.len() == 6); + + let (popped_slice, last_elem) = new_slice.pop_back(); + assert(last_elem == 4); + assert(popped_slice.len() == 5); + + let (first_elem, rest_of_slice) = popped_slice.pop_front(); + assert(first_elem == 20); + assert(rest_of_slice.len() == 4); + + new_slice = rest_of_slice.insert(2, 100); + assert(new_slice[2] == 100); + assert(new_slice[4] == 3); + assert(new_slice.len() == 5); + + let (remove_slice, removed_elem) = new_slice.remove(3); + assert(removed_elem == 2); + assert(remove_slice[3] == 3); + assert(remove_slice.len() == 4); + + let append = [1, 2].append([3, 4, 5]); + assert(append.len() == 5); + assert(append[0] == 1); + assert(append[4] == 5); + + regression_2083(); + // The parameters to this function must come from witness values (inputs to main) + regression_merge_slices(x, y); +} + +// Ensure that slices of struct/tuple values work. +fn regression_2083() { + let y = [(1, 2)]; + let y = y.push_back((3, 4)); // [(1, 2), (3, 4)] + let y = y.push_back((5, 6)); // [(1, 2), (3, 4), (5, 6)] + assert(y[2].1 == 6); + + let y = y.push_front((10, 11)); // [(10, 11), (1, 2), (3, 4), (5, 6)] + let y = y.push_front((12, 13)); // [(12, 13), (10, 11), (1, 2), (3, 4), (5, 6)] + + assert(y[1].0 == 10); + + let y = y.insert(1, (55, 56)); // [(12, 13), (55, 56), (10, 11), (1, 2), (3, 4), (5, 6)] + assert(y[0].1 == 13); + assert(y[1].1 == 56); + assert(y[2].0 == 10); + + let (y, x) = y.remove(2); // [(12, 13), (55, 56), (1, 2), (3, 4), (5, 6)] + assert(y[2].0 == 1); + assert(x.0 == 10); + assert(x.1 == 11); + + let (x, y) = y.pop_front(); // [(55, 56), (1, 2), (3, 4), (5, 6)] + assert(y[0].0 == 55); + assert(x.0 == 12); + assert(x.1 == 13); + + let (y, x) = y.pop_back(); // [(55, 56), (1, 2), (3, 4)] + assert(y.len() == 3); + assert(x.0 == 5); + assert(x.1 == 6); +} + +// The parameters to this function must come from witness values (inputs to main) +fn regression_merge_slices(x: Field, y: Field) { + merge_slices_if(x, y); + merge_slices_else(x); +} + +fn merge_slices_if(x: Field, y: Field) { + let slice = merge_slices_return(x, y); + assert(slice[2] == 10); + assert(slice.len() == 3); + + let slice = merge_slices_mutate(x, y); + assert(slice[3] == 5); + assert(slice.len() == 4); + + let slice = merge_slices_mutate_in_loop(x, y); + assert(slice[6] == 4); + assert(slice.len() == 7); + + let slice = merge_slices_mutate_two_ifs(x, y); + assert(slice.len() == 6); + assert(slice[3] == 5); + assert(slice[4] == 15); + assert(slice[5] == 30); + + let slice = merge_slices_mutate_between_ifs(x, y); + assert(slice.len() == 6); + assert(slice[3] == 5); + assert(slice[4] == 30); + assert(slice[5] == 15); +} + +fn merge_slices_else(x: Field) { + let slice = merge_slices_return(x, 5); + assert(slice[0] == 0); + assert(slice[1] == 0); + assert(slice.len() == 2); + + let slice = merge_slices_mutate(x, 5); + assert(slice[2] == 5); + assert(slice.len() == 3); + + let slice = merge_slices_mutate_in_loop(x, 5); + assert(slice[2] == 5); + assert(slice.len() == 3); +} + +// Test returning a merged slice without a mutation +fn merge_slices_return(x: Field, y: Field) -> [Field] { + let slice = [0; 2]; + if x != y { + if x != 20 { + slice.push_back(y) + } else { + slice + } + } else { + slice + } +} + +// Test mutating a slice inside of an if statement +fn merge_slices_mutate(x: Field, y: Field) -> [Field] { + let mut slice = [0; 2]; + if x != y { + slice = slice.push_back(y); + slice = slice.push_back(x); + } else { + slice = slice.push_back(x); + } + slice +} + +// Test mutating a slice inside of a loop in an if statement +fn merge_slices_mutate_in_loop(x: Field, y: Field) -> [Field] { + let mut slice = [0; 2]; + if x != y { + for i in 0..5 { + slice = slice.push_back(i); + } + } else { + slice = slice.push_back(x); + } + slice +} + +fn merge_slices_mutate_two_ifs(x: Field, y: Field) -> [Field] { + let mut slice = [0; 2]; + if x != y { + slice = slice.push_back(y); + slice = slice.push_back(x); + } else { + slice = slice.push_back(x); + } + if x == 20 { + slice = slice.push_back(20); + } else { + slice = slice.push_back(15); + } + // TODO(#2599): Breaks if the push back happens without the else case + // slice = slice.push_back(15); + slice = slice.push_back(30); + + slice +} + +fn merge_slices_mutate_between_ifs(x: Field, y: Field) -> [Field] { + let mut slice = [0; 2]; + if x != y { + slice = slice.push_back(y); + slice = slice.push_back(x); + } else { + slice = slice.push_back(x); + } + + slice = slice.push_back(30); + + if x == 20 { + slice = slice.push_back(20); + } else { + slice = slice.push_back(15); + } + // TODO(#2599): Breaks if the push back happens without the else case + // slice = slice.push_back(15); + + slice +} diff --git a/crates/nargo_cli/tests/execution_success/strings/Nargo.toml b/tooling/nargo_cli/tests/execution_success/strings/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/strings/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/strings/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/strings/Prover.toml b/tooling/nargo_cli/tests/execution_success/strings/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/strings/Prover.toml rename to tooling/nargo_cli/tests/execution_success/strings/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/strings/src/main.nr b/tooling/nargo_cli/tests/execution_success/strings/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/strings/src/main.nr rename to tooling/nargo_cli/tests/execution_success/strings/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/struct/Nargo.toml b/tooling/nargo_cli/tests/execution_success/struct/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/struct/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/struct/Prover.toml b/tooling/nargo_cli/tests/execution_success/struct/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct/Prover.toml rename to tooling/nargo_cli/tests/execution_success/struct/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/struct/src/main.nr b/tooling/nargo_cli/tests/execution_success/struct/src/main.nr new file mode 100644 index 00000000000..5e3530e8364 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/struct/src/main.nr @@ -0,0 +1,77 @@ +struct Foo { + bar: Field, + array: [Field; 2], +} + +struct Pair { + first: Foo, + second: Field, +} + +impl Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: 0, array: [x,y] } + } +} + +impl Pair { + fn foo(p: Self) -> Foo { + p.first + } + + fn bar(self) -> Field { + self.foo().bar + } +} + +struct Nested { + a: Field, + b: Field +} +struct MyStruct { + my_bool: bool, + my_int: u32, + my_nest: Nested, +} +fn test_struct_in_tuple(a_bool : bool,x:Field, y:Field) -> (MyStruct, bool) { + let my_struct = MyStruct { + my_bool: a_bool, + my_int: 5, + my_nest: Nested{a:x,b:y}, + }; + (my_struct, a_bool) +} + +struct Animal { + legs: Field, + eyes: u8, +} + +fn get_dog() -> Animal { + let dog = Animal { legs: 4, eyes: 2 }; + dog +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + let p = Pair { first, second: 1 }; + + assert(p.bar() == x); + assert(p.second == y); + assert(p.first.array[0] != p.first.array[1]); + + // Nested structs + let (struct_from_tuple, a_bool) = test_struct_in_tuple(true,x,y); + assert(struct_from_tuple.my_bool == true); + assert(a_bool == true); + assert(struct_from_tuple.my_int == 5); + assert(struct_from_tuple.my_nest.a == 0); + + // Regression test for issue #670 + let Animal { legs, eyes } = get_dog(); + let six = legs + eyes as Field; + + assert(six == 6); + + let Animal { legs: _, eyes: _ } = get_dog(); +} diff --git a/crates/nargo_cli/tests/execution_success/struct_array_inputs/Nargo.toml b/tooling/nargo_cli/tests/execution_success/struct_array_inputs/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_array_inputs/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/struct_array_inputs/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/struct_array_inputs/Prover.toml b/tooling/nargo_cli/tests/execution_success/struct_array_inputs/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_array_inputs/Prover.toml rename to tooling/nargo_cli/tests/execution_success/struct_array_inputs/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/struct_array_inputs/src/main.nr b/tooling/nargo_cli/tests/execution_success/struct_array_inputs/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_array_inputs/src/main.nr rename to tooling/nargo_cli/tests/execution_success/struct_array_inputs/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/struct_fields_ordering/Nargo.toml b/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_fields_ordering/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/struct_fields_ordering/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/struct_fields_ordering/Prover.toml b/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_fields_ordering/Prover.toml rename to tooling/nargo_cli/tests/execution_success/struct_fields_ordering/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/src/main.nr b/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/src/main.nr new file mode 100644 index 00000000000..5d4aa7c5a1e --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/src/main.nr @@ -0,0 +1,12 @@ +// Note that fields are not in alphabetical order. +// We want to check that this ordering is maintained +struct myStruct { + foo: u32, + bar: Field, +} + +fn main(y : pub myStruct) { + assert(y.foo == 5); + assert(y.bar == 7); +} + diff --git a/crates/nargo_cli/tests/execution_success/struct_inputs/Nargo.toml b/tooling/nargo_cli/tests/execution_success/struct_inputs/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_inputs/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/struct_inputs/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/struct_inputs/Prover.toml b/tooling/nargo_cli/tests/execution_success/struct_inputs/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_inputs/Prover.toml rename to tooling/nargo_cli/tests/execution_success/struct_inputs/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/struct_inputs/src/foo.nr b/tooling/nargo_cli/tests/execution_success/struct_inputs/src/foo.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_inputs/src/foo.nr rename to tooling/nargo_cli/tests/execution_success/struct_inputs/src/foo.nr diff --git a/crates/nargo_cli/tests/execution_success/struct_inputs/src/foo/bar.nr b/tooling/nargo_cli/tests/execution_success/struct_inputs/src/foo/bar.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/struct_inputs/src/foo/bar.nr rename to tooling/nargo_cli/tests/execution_success/struct_inputs/src/foo/bar.nr diff --git a/tooling/nargo_cli/tests/execution_success/struct_inputs/src/main.nr b/tooling/nargo_cli/tests/execution_success/struct_inputs/src/main.nr new file mode 100644 index 00000000000..68858d98998 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/struct_inputs/src/main.nr @@ -0,0 +1,34 @@ +mod foo; + +struct myStruct { + foo: u32, + bar: Field, + message: str<5>, +} + +fn main(x : Field, y : pub myStruct, z: pub foo::bar::barStruct, a: pub foo::fooStruct) -> pub Field { + let struct_from_bar = foo::bar::barStruct { val: 1, array: [0, 1], message: "hello" }; + + check_inner_struct(a, z); + + for i in 0 .. struct_from_bar.array.len() { + assert(struct_from_bar.array[i] == z.array[i]); + } + assert(z.val == struct_from_bar.val); + + assert((struct_from_bar.val * x) == x); + + assert(x != y.bar); + + assert(y.message == "hello"); + assert(a.bar_struct.message == struct_from_bar.message); + + a.bar_struct.array[1] +} + +fn check_inner_struct(a: foo::fooStruct, z: foo::bar::barStruct) { + assert(a.bar_struct.val == z.val); + for i in 0.. a.bar_struct.array.len() { + assert(a.bar_struct.array[i] == z.array[i]); + } +} diff --git a/crates/nargo_cli/tests/execution_success/submodules/Nargo.toml b/tooling/nargo_cli/tests/execution_success/submodules/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/submodules/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/submodules/Nargo.toml diff --git a/tooling/nargo_cli/tests/execution_success/submodules/Prover.toml b/tooling/nargo_cli/tests/execution_success/submodules/Prover.toml new file mode 100644 index 00000000000..b6626a67e19 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/submodules/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 0 diff --git a/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr b/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr new file mode 100644 index 00000000000..3b8807ddb37 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr @@ -0,0 +1,15 @@ +use mysubmodule::my_helper; + +fn main(x: u1, y: u1) { + my_helper(); + mysubmodule::my_bool_or(x, y); +} + +mod mysubmodule { + fn my_bool_or(x: u1, y: u1) { + assert(x | y == 1); + } + + fn my_helper() {} +} + diff --git a/crates/nargo_cli/tests/execution_success/to_be_bytes/Nargo.toml b/tooling/nargo_cli/tests/execution_success/to_be_bytes/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/to_be_bytes/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/to_be_bytes/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/to_be_bytes/Prover.toml b/tooling/nargo_cli/tests/execution_success/to_be_bytes/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/to_be_bytes/Prover.toml rename to tooling/nargo_cli/tests/execution_success/to_be_bytes/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/to_be_bytes/src/main.nr b/tooling/nargo_cli/tests/execution_success/to_be_bytes/src/main.nr new file mode 100644 index 00000000000..20e932c5073 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/to_be_bytes/src/main.nr @@ -0,0 +1,12 @@ +fn main(x : Field) -> pub [u8; 31] { + // The result of this byte array will be big-endian + let byte_array = x.to_be_bytes(31); + let mut bytes = [0; 31]; + for i in 0..31 { + bytes[i] = byte_array[i]; + } + assert(bytes[30] == 60); + assert(bytes[29] == 33); + assert(bytes[28] == 31); + bytes +} diff --git a/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Nargo.toml b/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Nargo.toml new file mode 100644 index 00000000000..65f95d159c8 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "to_bytes_consistent" +type = "bin" +authors = [""] +compiler_version = "0.10.3" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/to_le_bytes/Prover.toml b/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/to_le_bytes/Prover.toml rename to tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/src/main.nr b/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/src/main.nr new file mode 100644 index 00000000000..270491e132d --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/src/main.nr @@ -0,0 +1,14 @@ +// This test aims to check that we have consistent behavior +// between a `to_be_bytes` call (which is radix decomposition under the hood) +// with constant inputs or with witness inputs. + +// x = 2040124 +fn main(x : Field) { + let byte_array = x.to_be_bytes(31); + let x_as_constant = 2040124; + let constant_byte_array = x_as_constant.to_be_bytes(31); + assert(constant_byte_array.len() == byte_array.len()); + for i in 0..constant_byte_array.len() { + assert(constant_byte_array[i] == byte_array[i]); + } +} diff --git a/crates/nargo_cli/tests/execution_success/to_bytes_integration/Nargo.toml b/tooling/nargo_cli/tests/execution_success/to_bytes_integration/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/to_bytes_integration/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/to_bytes_integration/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/to_bytes_integration/Prover.toml b/tooling/nargo_cli/tests/execution_success/to_bytes_integration/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/to_bytes_integration/Prover.toml rename to tooling/nargo_cli/tests/execution_success/to_bytes_integration/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/to_bytes_integration/src/main.nr b/tooling/nargo_cli/tests/execution_success/to_bytes_integration/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/to_bytes_integration/src/main.nr rename to tooling/nargo_cli/tests/execution_success/to_bytes_integration/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/to_le_bytes/Nargo.toml b/tooling/nargo_cli/tests/execution_success/to_le_bytes/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/to_le_bytes/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/to_le_bytes/Nargo.toml diff --git a/tooling/nargo_cli/tests/execution_success/to_le_bytes/Prover.toml b/tooling/nargo_cli/tests/execution_success/to_le_bytes/Prover.toml new file mode 100644 index 00000000000..07fe857ac7c --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/to_le_bytes/Prover.toml @@ -0,0 +1 @@ +x = "2040124" diff --git a/tooling/nargo_cli/tests/execution_success/to_le_bytes/src/main.nr b/tooling/nargo_cli/tests/execution_success/to_le_bytes/src/main.nr new file mode 100644 index 00000000000..9d7eb403083 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/to_le_bytes/src/main.nr @@ -0,0 +1,11 @@ +fn main(x : Field) -> pub [u8; 31] { + // The result of this byte array will be little-endian + let byte_array = x.to_le_bytes(31); + assert(byte_array.len() == 31); + + let mut bytes = [0; 31]; + for i in 0..31 { + bytes[i] = byte_array[i]; + } + bytes +} diff --git a/tooling/nargo_cli/tests/execution_success/trait_default_implementation/Nargo.toml b/tooling/nargo_cli/tests/execution_success/trait_default_implementation/Nargo.toml new file mode 100644 index 00000000000..7fcb4d0281e --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/trait_default_implementation/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_default_implementation" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/execution_success/trait_default_implementation/Prover.toml b/tooling/nargo_cli/tests/execution_success/trait_default_implementation/Prover.toml new file mode 100644 index 00000000000..71805e71e8e --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/trait_default_implementation/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "1" \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/trait_default_implementation/src/main.nr b/tooling/nargo_cli/tests/execution_success/trait_default_implementation/src/main.nr new file mode 100644 index 00000000000..e1f29ce3f48 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/trait_default_implementation/src/main.nr @@ -0,0 +1,26 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; + + fn method2(x: Field) -> Field { + x + } + +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: x, array: [x,y] } + } +} + +fn main(x: Field) { + let first = Foo::method2(x); + assert(first == x); +} diff --git a/tooling/nargo_cli/tests/execution_success/trait_override_implementation/Nargo.toml b/tooling/nargo_cli/tests/execution_success/trait_override_implementation/Nargo.toml new file mode 100644 index 00000000000..7ab5a62b5ba --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/trait_override_implementation/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_override_implementation" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/execution_success/trait_override_implementation/Prover.toml b/tooling/nargo_cli/tests/execution_success/trait_override_implementation/Prover.toml new file mode 100644 index 00000000000..71805e71e8e --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/trait_override_implementation/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "1" \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/trait_override_implementation/src/main.nr b/tooling/nargo_cli/tests/execution_success/trait_override_implementation/src/main.nr new file mode 100644 index 00000000000..92e19f97d50 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/trait_override_implementation/src/main.nr @@ -0,0 +1,30 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; + + fn method2(x: Field) -> Field { + x + } + +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: x, array: [x,y] } + } + + fn method2(x: Field) -> Field { + x * 3 + } +} + +fn main(x: Field) { + let first = Foo::method2(x); + assert(first == 3 * x); +} diff --git a/crates/nargo_cli/tests/execution_success/tuples/Nargo.toml b/tooling/nargo_cli/tests/execution_success/tuples/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/tuples/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/tuples/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/tuples/Prover.toml b/tooling/nargo_cli/tests/execution_success/tuples/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/tuples/Prover.toml rename to tooling/nargo_cli/tests/execution_success/tuples/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/tuples/src/main.nr b/tooling/nargo_cli/tests/execution_success/tuples/src/main.nr new file mode 100644 index 00000000000..bfc943dfc07 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/tuples/src/main.nr @@ -0,0 +1,27 @@ +fn main(x: Field, y: Field) { + let pair = (x, y); + assert(pair.0 == 1); + assert(pair.1 == 0); + + let (a, b) = if true { (0, 1) } else { (2, 3) }; + assert(a == 0); + assert(b == 1); + + let (u,v) = if x as u32 < 1 { + (x, x + 1) + } else { + (x + 1, x) + }; + assert(u == x+1); + assert(v == x); + + // Test mutating tuples + let mut mutable = ((0, 0), 1, 2, 3); + mutable.0 = (x, y); + mutable.2 = 7; + assert(mutable.0.0 == 1); + assert(mutable.0.1 == 0); + assert(mutable.1 == 1); + assert(mutable.2 == 7); + assert(mutable.3 == 3); +} diff --git a/crates/nargo_cli/tests/execution_success/type_aliases/Nargo.toml b/tooling/nargo_cli/tests/execution_success/type_aliases/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/type_aliases/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/type_aliases/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/type_aliases/Prover.toml b/tooling/nargo_cli/tests/execution_success/type_aliases/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/type_aliases/Prover.toml rename to tooling/nargo_cli/tests/execution_success/type_aliases/Prover.toml diff --git a/tooling/nargo_cli/tests/execution_success/type_aliases/src/main.nr b/tooling/nargo_cli/tests/execution_success/type_aliases/src/main.nr new file mode 100644 index 00000000000..573a501367f --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/type_aliases/src/main.nr @@ -0,0 +1,36 @@ +type Foo = [T; 2]; + +type Bar = Field; + +type One = (A, B); +type Two = One; +type Three = Two; + +struct MyStruct { + foo: Bar, +} + +fn main(x : [Field; 2]) { + let a: Foo = [1, 2]; + assert(a[0] != x[0]); + + let b: Bar = 2; + assert(x[0] == b); + + let c: u8 = 1; + let d: u32 = 2; + let e: Three = (c, d); + assert(e.0 == 1); + + let s = MyStruct { + foo: 10 + }; + assert(s.foo == 10); + + let _regression2502: Regression2502Alias = Regression2502 {}; +} + +// An ICE was occurring if a type alias referred to a struct before it was initialized +// during name resolution. The fix was to initialize structs during def collection instead. +type Regression2502Alias = Regression2502; +struct Regression2502 {} diff --git a/crates/nargo_cli/tests/execution_success/workspace/Nargo.toml b/tooling/nargo_cli/tests/execution_success/workspace/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/workspace/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace/Prover.toml b/tooling/nargo_cli/tests/execution_success/workspace/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace/Prover.toml rename to tooling/nargo_cli/tests/execution_success/workspace/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace/crates/a/Nargo.toml b/tooling/nargo_cli/tests/execution_success/workspace/crates/a/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace/crates/a/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/workspace/crates/a/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace/crates/a/Prover.toml b/tooling/nargo_cli/tests/execution_success/workspace/crates/a/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace/crates/a/Prover.toml rename to tooling/nargo_cli/tests/execution_success/workspace/crates/a/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace/crates/a/src/main.nr b/tooling/nargo_cli/tests/execution_success/workspace/crates/a/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace/crates/a/src/main.nr rename to tooling/nargo_cli/tests/execution_success/workspace/crates/a/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/workspace/crates/b/Nargo.toml b/tooling/nargo_cli/tests/execution_success/workspace/crates/b/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace/crates/b/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/workspace/crates/b/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace/crates/b/Prover.toml b/tooling/nargo_cli/tests/execution_success/workspace/crates/b/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace/crates/b/Prover.toml rename to tooling/nargo_cli/tests/execution_success/workspace/crates/b/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace/crates/b/src/main.nr b/tooling/nargo_cli/tests/execution_success/workspace/crates/b/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace/crates/b/src/main.nr rename to tooling/nargo_cli/tests/execution_success/workspace/crates/b/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/workspace_default_member/Nargo.toml b/tooling/nargo_cli/tests/execution_success/workspace_default_member/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace_default_member/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/workspace_default_member/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace_default_member/Prover.toml b/tooling/nargo_cli/tests/execution_success/workspace_default_member/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace_default_member/Prover.toml rename to tooling/nargo_cli/tests/execution_success/workspace_default_member/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace_default_member/a/Nargo.toml b/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace_default_member/a/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/workspace_default_member/a/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace_default_member/a/Prover.toml b/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace_default_member/a/Prover.toml rename to tooling/nargo_cli/tests/execution_success/workspace_default_member/a/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace_default_member/a/src/main.nr b/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace_default_member/a/src/main.nr rename to tooling/nargo_cli/tests/execution_success/workspace_default_member/a/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/workspace_default_member/b/Nargo.toml b/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace_default_member/b/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/workspace_default_member/b/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace_default_member/b/Prover.toml b/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace_default_member/b/Prover.toml rename to tooling/nargo_cli/tests/execution_success/workspace_default_member/b/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/workspace_default_member/b/src/main.nr b/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/workspace_default_member/b/src/main.nr rename to tooling/nargo_cli/tests/execution_success/workspace_default_member/b/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/xor/Nargo.toml b/tooling/nargo_cli/tests/execution_success/xor/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/xor/Nargo.toml rename to tooling/nargo_cli/tests/execution_success/xor/Nargo.toml diff --git a/crates/nargo_cli/tests/execution_success/xor/Prover.toml b/tooling/nargo_cli/tests/execution_success/xor/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/execution_success/xor/Prover.toml rename to tooling/nargo_cli/tests/execution_success/xor/Prover.toml diff --git a/crates/nargo_cli/tests/execution_success/xor/src/main.nr b/tooling/nargo_cli/tests/execution_success/xor/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/execution_success/xor/src/main.nr rename to tooling/nargo_cli/tests/execution_success/xor/src/main.nr diff --git a/crates/nargo_cli/tests/hello_world.rs b/tooling/nargo_cli/tests/hello_world.rs similarity index 100% rename from crates/nargo_cli/tests/hello_world.rs rename to tooling/nargo_cli/tests/hello_world.rs diff --git a/tooling/nargo_cli/tests/rebuild.sh b/tooling/nargo_cli/tests/rebuild.sh new file mode 100755 index 00000000000..9e22455afa5 --- /dev/null +++ b/tooling/nargo_cli/tests/rebuild.sh @@ -0,0 +1,54 @@ +#!/bin/bash +set -e + +excluded_dirs=("workspace" "workspace_default_member") + +current_dir=$(pwd) +base_path="$current_dir/execution_success" + +# Ensure the base acir_artifacts directory exists +mkdir -p $current_dir/acir_artifacts + +# Loop over every directory +for dir in $base_path/*; do + if [[ ! -d $dir ]]; then + continue + fi + + dir_name=$(basename "$dir") + + if [[ ! " ${excluded_dirs[@]} " =~ " ${dir_name} " ]]; then + if [[ ! -d "$current_dir/acir_artifacts/$dir_name" ]]; then + mkdir -p $current_dir/acir_artifacts/$dir_name + fi + + cd $dir + if [ -d ./target/ ]; then + rm -r ./target/ + fi + nargo compile && nargo execute witness + + # Rename witness.tr to witness.gz + if [ -f ./target/witness.tr ]; then + mv ./target/witness.tr ./target/witness.gz + fi + + # Extract bytecode field from JSON, base64 decode it, and save it to the target directory + if [ -f ./target/${dir_name}.json ]; then + jq -r '.bytecode' ./target/${dir_name}.json | base64 -d > ./target/acir.gz + fi + + # Delete the JSON file after extracting bytecode field + rm ./target/${dir_name}.json + + # Delete the target directory in acir_artifacts if it exists + if [ -d "$current_dir/acir_artifacts/$dir_name/target" ]; then + rm -r "$current_dir/acir_artifacts/$dir_name/target" + fi + + # Move the target directory to the corresponding directory in acir_artifacts + mv ./target/ $current_dir/acir_artifacts/$dir_name/ + + cd $base_path + fi +done diff --git a/crates/nargo_cli/tests/test_libraries/bad_impl/Nargo.toml b/tooling/nargo_cli/tests/test_libraries/bad_impl/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/test_libraries/bad_impl/Nargo.toml rename to tooling/nargo_cli/tests/test_libraries/bad_impl/Nargo.toml diff --git a/crates/nargo_cli/tests/test_libraries/bad_impl/src/lib.nr b/tooling/nargo_cli/tests/test_libraries/bad_impl/src/lib.nr similarity index 100% rename from crates/nargo_cli/tests/test_libraries/bad_impl/src/lib.nr rename to tooling/nargo_cli/tests/test_libraries/bad_impl/src/lib.nr diff --git a/crates/nargo_cli/tests/test_libraries/bad_name/Nargo.toml b/tooling/nargo_cli/tests/test_libraries/bad_name/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/test_libraries/bad_name/Nargo.toml rename to tooling/nargo_cli/tests/test_libraries/bad_name/Nargo.toml diff --git a/tooling/nargo_cli/tests/test_libraries/bad_name/src/lib.nr b/tooling/nargo_cli/tests/test_libraries/bad_name/src/lib.nr new file mode 100644 index 00000000000..e69de29bb2d diff --git a/crates/nargo_cli/tests/test_libraries/bin_dep/Nargo.toml b/tooling/nargo_cli/tests/test_libraries/bin_dep/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/test_libraries/bin_dep/Nargo.toml rename to tooling/nargo_cli/tests/test_libraries/bin_dep/Nargo.toml diff --git a/tooling/nargo_cli/tests/test_libraries/bin_dep/src/main.nr b/tooling/nargo_cli/tests/test_libraries/bin_dep/src/main.nr new file mode 100644 index 00000000000..d469d3aafcb --- /dev/null +++ b/tooling/nargo_cli/tests/test_libraries/bin_dep/src/main.nr @@ -0,0 +1,3 @@ +fn call_dep1_then_dep2(x : Field, y : Field) { + assert(x == y); +} diff --git a/crates/nargo_cli/tests/test_libraries/diamond_deps_1/Nargo.toml b/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/test_libraries/diamond_deps_1/Nargo.toml rename to tooling/nargo_cli/tests/test_libraries/diamond_deps_1/Nargo.toml diff --git a/crates/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr b/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr similarity index 100% rename from crates/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr rename to tooling/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr diff --git a/crates/nargo_cli/tests/test_libraries/diamond_deps_2/Nargo.toml b/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/test_libraries/diamond_deps_2/Nargo.toml rename to tooling/nargo_cli/tests/test_libraries/diamond_deps_2/Nargo.toml diff --git a/crates/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr b/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr similarity index 100% rename from crates/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr rename to tooling/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr diff --git a/tooling/nargo_toml/Cargo.toml b/tooling/nargo_toml/Cargo.toml new file mode 100644 index 00000000000..d3767a0b038 --- /dev/null +++ b/tooling/nargo_toml/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "nargo_toml" +description = "Utilities for working with Nargo.toml files" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dirs.workspace = true +fm.workspace = true +nargo.workspace = true +noirc_frontend.workspace = true +serde.workspace = true +thiserror.workspace = true +toml.workspace = true +url.workspace = true + +[dev-dependencies] diff --git a/tooling/nargo_toml/src/errors.rs b/tooling/nargo_toml/src/errors.rs new file mode 100644 index 00000000000..9abeab97b61 --- /dev/null +++ b/tooling/nargo_toml/src/errors.rs @@ -0,0 +1,68 @@ +use std::path::PathBuf; + +use nargo::package::PackageType; +use noirc_frontend::graph::CrateName; +use thiserror::Error; + +/// Errors covering situations where a package is either missing or malformed. +#[derive(Debug, Error)] +pub enum ManifestError { + /// Package doesn't have a manifest file + #[error("cannot find a Nargo.toml for {0}")] + MissingFile(PathBuf), + + #[error("Cannot read file {0} - does it exist?")] + ReadFailed(PathBuf), + + #[error("Nargo.toml is missing a parent directory")] + MissingParent, + + #[error("Missing `type` field in {0}")] + MissingPackageType(PathBuf), + + #[error("Cannot use `{1}` for `type` field in {0}")] + InvalidPackageType(PathBuf, String), + + /// Package manifest is unreadable. + #[error("Nargo.toml is badly formed, could not parse.\n\n {0}")] + MalformedFile(#[from] toml::de::Error), + + #[error("Unexpected workspace definition found in {0}")] + UnexpectedWorkspace(PathBuf), + + #[error("Cannot find file {entry} which was specified as the `entry` field in {toml}")] + MissingEntryFile { toml: PathBuf, entry: PathBuf }, + + #[error( + r#"Cannot find file {entry} which is defaulted due to specifying `type = "{package_type}"` in {toml}"# + )] + MissingDefaultEntryFile { toml: PathBuf, entry: PathBuf, package_type: PackageType }, + + #[error("{} found in {toml}", if name.is_empty() { "Empty package name".into() } else { format!("Invalid package name `{name}`") })] + InvalidPackageName { toml: PathBuf, name: String }, + + #[error("{} found in {toml}", if name.is_empty() { "Empty dependency name".into() } else { format!("Invalid dependency name `{name}`") })] + InvalidDependencyName { toml: PathBuf, name: String }, + + #[error("Invalid directory path {directory} in {toml}: It must point to a subdirectory")] + InvalidDirectory { toml: PathBuf, directory: PathBuf }, + + /// Encountered error while downloading git repository. + #[error("{0}")] + GitError(String), + + #[error("Selected package `{0}` was not found")] + MissingSelectedPackage(CrateName), + + #[error("Default package was not found. Does {0} exist in your workspace?")] + MissingDefaultPackage(PathBuf), + + #[error("Package `{0}` has type `bin` but you cannot depend on binary packages")] + BinaryDependency(CrateName), + + #[error("Missing `name` field in {toml}")] + MissingNameField { toml: PathBuf }, + + #[error("No common ancestor between {root} and {current}")] + NoCommonAncestor { root: PathBuf, current: PathBuf }, +} diff --git a/crates/nargo_toml/src/git.rs b/tooling/nargo_toml/src/git.rs similarity index 100% rename from crates/nargo_toml/src/git.rs rename to tooling/nargo_toml/src/git.rs diff --git a/tooling/nargo_toml/src/lib.rs b/tooling/nargo_toml/src/lib.rs new file mode 100644 index 00000000000..1dd6ac0e695 --- /dev/null +++ b/tooling/nargo_toml/src/lib.rs @@ -0,0 +1,448 @@ +use std::{ + collections::BTreeMap, + path::{Component, Path, PathBuf}, +}; + +use fm::{NormalizePath, FILE_EXTENSION}; +use nargo::{ + package::{Dependency, Package, PackageType}, + workspace::Workspace, +}; +use noirc_frontend::graph::CrateName; +use serde::Deserialize; + +mod errors; +mod git; + +pub use errors::ManifestError; +use git::clone_git_repo; + +/// Returns the [PathBuf] of the directory containing the `Nargo.toml` by searching from `current_path` to the root of its [Path]. +/// +/// Returns a [ManifestError] if no parent directories of `current_path` contain a manifest file. +pub fn find_package_root(current_path: &Path) -> Result { + let root = path_root(current_path); + let manifest_path = find_package_manifest(&root, current_path)?; + + let package_root = + manifest_path.parent().expect("infallible: manifest file path can't be root directory"); + + Ok(package_root.to_path_buf()) +} + +// TODO(#2323): We are probably going to need a "filepath utils" crate soon +fn path_root(path: &Path) -> PathBuf { + let mut components = path.components(); + + match (components.next(), components.next()) { + // Preserve prefix if one exists + (Some(prefix @ Component::Prefix(_)), Some(root @ Component::RootDir)) => { + PathBuf::from(prefix.as_os_str()).join(root.as_os_str()) + } + (Some(root @ Component::RootDir), _) => PathBuf::from(root.as_os_str()), + _ => PathBuf::new(), + } +} + +/// Returns the [PathBuf] of the `Nargo.toml` file by searching from `current_path` and stopping at `root_path`. +/// +/// Returns a [ManifestError] if no parent directories of `current_path` contain a manifest file. +pub fn find_package_manifest( + root_path: &Path, + current_path: &Path, +) -> Result { + if current_path.starts_with(root_path) { + let mut found_toml_paths = Vec::new(); + for path in current_path.ancestors() { + if let Ok(toml_path) = get_package_manifest(path) { + found_toml_paths.push(toml_path); + } + // While traversing, break once we process the root specified + if path == root_path { + break; + } + } + + // Return the shallowest Nargo.toml, which will be the last in the list + found_toml_paths.pop().ok_or_else(|| ManifestError::MissingFile(current_path.to_path_buf())) + } else { + Err(ManifestError::NoCommonAncestor { + root: root_path.to_path_buf(), + current: current_path.to_path_buf(), + }) + } +} +/// Returns the [PathBuf] of the `Nargo.toml` file in the `current_path` directory. +/// +/// Returns a [ManifestError] if `current_path` does not contain a manifest file. +pub fn get_package_manifest(current_path: &Path) -> Result { + let toml_path = current_path.join("Nargo.toml"); + if toml_path.exists() { + Ok(toml_path) + } else { + Err(ManifestError::MissingFile(current_path.to_path_buf())) + } +} + +#[derive(Debug, Deserialize, Clone)] +struct PackageConfig { + package: PackageMetadata, + #[serde(default)] + dependencies: BTreeMap, +} + +impl PackageConfig { + fn resolve_to_package(&self, root_dir: &Path) -> Result { + let name = if let Some(name) = &self.package.name { + name.parse().map_err(|_| ManifestError::InvalidPackageName { + toml: root_dir.join("Nargo.toml"), + name: name.into(), + })? + } else { + return Err(ManifestError::MissingNameField { toml: root_dir.join("Nargo.toml") }); + }; + + let mut dependencies: BTreeMap = BTreeMap::new(); + for (name, dep_config) in self.dependencies.iter() { + let name = name.parse().map_err(|_| ManifestError::InvalidDependencyName { + toml: root_dir.join("Nargo.toml"), + name: name.into(), + })?; + let resolved_dep = dep_config.resolve_to_dependency(root_dir)?; + + dependencies.insert(name, resolved_dep); + } + + let package_type = match self.package.package_type.as_deref() { + Some("lib") => PackageType::Library, + Some("bin") => PackageType::Binary, + Some("contract") => PackageType::Contract, + Some(invalid) => { + return Err(ManifestError::InvalidPackageType( + root_dir.join("Nargo.toml"), + invalid.to_string(), + )) + } + None => return Err(ManifestError::MissingPackageType(root_dir.join("Nargo.toml"))), + }; + + let entry_path = if let Some(entry_path) = &self.package.entry { + let custom_entry_path = root_dir.join(entry_path); + if custom_entry_path.exists() { + custom_entry_path + } else { + return Err(ManifestError::MissingEntryFile { + toml: root_dir.join("Nargo.toml"), + entry: custom_entry_path, + }); + } + } else { + let default_entry_path = match package_type { + PackageType::Library => { + root_dir.join("src").join("lib").with_extension(FILE_EXTENSION) + } + PackageType::Binary | PackageType::Contract => { + root_dir.join("src").join("main").with_extension(FILE_EXTENSION) + } + }; + + if default_entry_path.exists() { + default_entry_path + } else { + return Err(ManifestError::MissingDefaultEntryFile { + toml: root_dir.join("Nargo.toml"), + entry: default_entry_path, + package_type, + }); + } + }; + + Ok(Package { + root_dir: root_dir.to_path_buf(), + entry_path, + package_type, + name, + dependencies, + }) + } +} + +/// Contains all the information about a package, as loaded from a `Nargo.toml`. +#[derive(Debug, Deserialize, Clone)] +#[serde(untagged)] +enum Config { + /// Represents a `Nargo.toml` with package fields. + Package { + #[serde(flatten)] + package_config: PackageConfig, + }, + /// Represents a `Nargo.toml` with workspace fields. + Workspace { + #[serde(alias = "workspace")] + workspace_config: WorkspaceConfig, + }, +} + +impl TryFrom for Config { + type Error = toml::de::Error; + + fn try_from(toml: String) -> Result { + toml::from_str(&toml) + } +} + +impl TryFrom<&str> for Config { + type Error = toml::de::Error; + + fn try_from(toml: &str) -> Result { + toml::from_str(toml) + } +} + +/// Tracks the root_dir of a `Nargo.toml` and the contents inside the file. +struct NargoToml { + root_dir: PathBuf, + config: Config, +} + +#[derive(Default, Debug, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] +struct WorkspaceConfig { + /// List of members in this workspace. + members: Vec, + /// Specifies the default crate to interact with in the context (similarly to how we have nargo as the default crate in this repository). + default_member: Option, +} + +#[allow(dead_code)] +#[derive(Default, Debug, Deserialize, Clone)] +struct PackageMetadata { + name: Option, + #[serde(alias = "type")] + package_type: Option, + entry: Option, + description: Option, + authors: Option>, + // If not compiler version is supplied, the latest is used + // For now, we state that all packages must be compiled under the same + // compiler version. + // We also state that ACIR and the compiler will upgrade in lockstep. + // so you will not need to supply an ACIR and compiler version + compiler_version: Option, + backend: Option, + license: Option, +} + +#[derive(Debug, Deserialize, Clone)] +#[serde(untagged)] +/// Enum representing the different types of ways to +/// supply a source for the dependency +enum DependencyConfig { + Github { git: String, tag: String, directory: Option }, + Path { path: String }, +} + +impl DependencyConfig { + fn resolve_to_dependency(&self, pkg_root: &Path) -> Result { + let dep = match self { + Self::Github { git, tag, directory } => { + let dir_path = clone_git_repo(git, tag).map_err(ManifestError::GitError)?; + let project_path = if let Some(directory) = directory { + let internal_path = dir_path.join(directory).normalize(); + if !internal_path.starts_with(&dir_path) { + return Err(ManifestError::InvalidDirectory { + toml: pkg_root.join("Nargo.toml"), + directory: directory.into(), + }); + } + internal_path + } else { + dir_path + }; + let toml_path = project_path.join("Nargo.toml"); + let package = resolve_package_from_toml(&toml_path)?; + Dependency::Remote { package } + } + Self::Path { path } => { + let dir_path = pkg_root.join(path); + let toml_path = dir_path.join("Nargo.toml"); + let package = resolve_package_from_toml(&toml_path)?; + Dependency::Local { package } + } + }; + + // Cannot depend on a binary + // TODO: Can we depend upon contracts? + if dep.is_binary() { + Err(ManifestError::BinaryDependency(dep.package_name().clone())) + } else { + Ok(dep) + } + } +} + +fn toml_to_workspace( + nargo_toml: NargoToml, + package_selection: PackageSelection, +) -> Result { + let workspace = match nargo_toml.config { + Config::Package { package_config } => { + let member = package_config.resolve_to_package(&nargo_toml.root_dir)?; + match &package_selection { + PackageSelection::Selected(selected_name) if selected_name != &member.name => { + return Err(ManifestError::MissingSelectedPackage(member.name)) + } + _ => Workspace { + root_dir: nargo_toml.root_dir, + selected_package_index: Some(0), + members: vec![member], + }, + } + } + Config::Workspace { workspace_config } => { + let mut members = Vec::new(); + let mut selected_package_index = None; + for (index, member_path) in workspace_config.members.into_iter().enumerate() { + let package_root_dir = nargo_toml.root_dir.join(&member_path); + let package_toml_path = package_root_dir.join("Nargo.toml"); + let member = resolve_package_from_toml(&package_toml_path)?; + + match &package_selection { + PackageSelection::Selected(selected_name) => { + if &member.name == selected_name { + selected_package_index = Some(index); + } + } + PackageSelection::DefaultOrAll => { + if Some(&member_path) == workspace_config.default_member.as_ref() { + selected_package_index = Some(index); + } + } + PackageSelection::All => selected_package_index = None, + } + + members.push(member); + } + + // If the selected_package_index is still `None` but we have see a default_member or selected package, + // we want to present an error to users + match package_selection { + PackageSelection::Selected(selected_name) => { + if selected_package_index.is_none() { + return Err(ManifestError::MissingSelectedPackage(selected_name)); + } + } + PackageSelection::DefaultOrAll => match workspace_config.default_member { + // If `default-member` is specified but we don't have a selected_package_index, we need to fail + Some(default_path) if selected_package_index.is_none() => { + return Err(ManifestError::MissingDefaultPackage(default_path)); + } + // However, if there wasn't a `default-member`, we select All, so no error is needed + _ => (), + }, + PackageSelection::All => (), + } + + Workspace { root_dir: nargo_toml.root_dir, members, selected_package_index } + } + }; + + Ok(workspace) +} + +fn read_toml(toml_path: &Path) -> Result { + let toml_path = toml_path.normalize(); + let toml_as_string = std::fs::read_to_string(&toml_path) + .map_err(|_| ManifestError::ReadFailed(toml_path.to_path_buf()))?; + let root_dir = toml_path.parent().ok_or(ManifestError::MissingParent)?; + let nargo_toml = + NargoToml { root_dir: root_dir.to_path_buf(), config: toml_as_string.try_into()? }; + + Ok(nargo_toml) +} + +/// Resolves a Nargo.toml file into a `Package` struct as defined by our `nargo` core. +fn resolve_package_from_toml(toml_path: &Path) -> Result { + let nargo_toml = read_toml(toml_path)?; + + match nargo_toml.config { + Config::Package { package_config } => { + package_config.resolve_to_package(&nargo_toml.root_dir) + } + Config::Workspace { .. } => { + Err(ManifestError::UnexpectedWorkspace(toml_path.to_path_buf())) + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub enum PackageSelection { + Selected(CrateName), + DefaultOrAll, + All, +} + +/// Resolves a Nargo.toml file into a `Workspace` struct as defined by our `nargo` core. +pub fn resolve_workspace_from_toml( + toml_path: &Path, + package_selection: PackageSelection, +) -> Result { + let nargo_toml = read_toml(toml_path)?; + + toml_to_workspace(nargo_toml, package_selection) +} + +#[test] +fn parse_standard_toml() { + let src = r#" + + [package] + name = "test" + authors = ["kev", "foo"] + compiler_version = "0.1" + + [dependencies] + rand = { tag = "next", git = "https://github.com/rust-lang-nursery/rand"} + cool = { tag = "next", git = "https://github.com/rust-lang-nursery/rand"} + hello = {path = "./noir_driver"} + "#; + + assert!(Config::try_from(String::from(src)).is_ok()); + assert!(Config::try_from(src).is_ok()); +} + +#[test] +fn parse_package_toml_no_deps() { + let src = r#" + [package] + name = "test" + authors = ["kev", "foo"] + compiler_version = "0.1" + "#; + + assert!(Config::try_from(String::from(src)).is_ok()); + assert!(Config::try_from(src).is_ok()); +} + +#[test] +fn parse_workspace_toml() { + let src = r#" + [workspace] + members = ["a", "b"] + "#; + + assert!(Config::try_from(String::from(src)).is_ok()); + assert!(Config::try_from(src).is_ok()); +} + +#[test] +fn parse_workspace_default_member_toml() { + let src = r#" + [workspace] + members = ["a", "b"] + default-member = "a" + "#; + + assert!(Config::try_from(String::from(src)).is_ok()); + assert!(Config::try_from(src).is_ok()); +} diff --git a/tooling/noirc_abi/Cargo.toml b/tooling/noirc_abi/Cargo.toml new file mode 100644 index 00000000000..b7fe1ef8084 --- /dev/null +++ b/tooling/noirc_abi/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "noirc_abi" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +acvm.workspace = true +iter-extended.workspace = true +noirc_frontend.workspace = true +toml.workspace = true +serde_json = "1.0" +serde.workspace = true +thiserror.workspace = true +num-bigint = "0.4" +num-traits = "0.2" + +[dev-dependencies] +strum = "0.24" +strum_macros = "0.24" diff --git a/crates/noirc_abi/src/errors.rs b/tooling/noirc_abi/src/errors.rs similarity index 100% rename from crates/noirc_abi/src/errors.rs rename to tooling/noirc_abi/src/errors.rs diff --git a/crates/noirc_abi/src/input_parser/json.rs b/tooling/noirc_abi/src/input_parser/json.rs similarity index 100% rename from crates/noirc_abi/src/input_parser/json.rs rename to tooling/noirc_abi/src/input_parser/json.rs diff --git a/tooling/noirc_abi/src/input_parser/mod.rs b/tooling/noirc_abi/src/input_parser/mod.rs new file mode 100644 index 00000000000..139f3276179 --- /dev/null +++ b/tooling/noirc_abi/src/input_parser/mod.rs @@ -0,0 +1,252 @@ +use num_bigint::BigUint; +use num_traits::Num; +use std::collections::BTreeMap; + +use acvm::FieldElement; +use serde::Serialize; + +use crate::errors::InputParserError; +use crate::{Abi, AbiType}; + +mod json; +mod toml; + +/// This is what all formats eventually transform into +/// For example, a toml file will parse into TomlTypes +/// and those TomlTypes will be mapped to Value +#[derive(Debug, Clone, Serialize, PartialEq)] +pub enum InputValue { + Field(FieldElement), + String(String), + Vec(Vec), + Struct(BTreeMap), +} + +impl InputValue { + /// Checks whether the ABI type matches the InputValue type + /// and also their arity + pub fn matches_abi(&self, abi_param: &AbiType) -> bool { + match (self, abi_param) { + (InputValue::Field(_), AbiType::Field) => true, + (InputValue::Field(field_element), AbiType::Integer { width, .. }) => { + field_element.num_bits() <= *width + } + (InputValue::Field(field_element), AbiType::Boolean) => { + field_element.is_one() || field_element.is_zero() + } + + (InputValue::Vec(array_elements), AbiType::Array { length, typ, .. }) => { + if array_elements.len() != *length as usize { + return false; + } + // Check that all of the array's elements' values match the ABI as well. + array_elements.iter().all(|input_value| input_value.matches_abi(typ)) + } + + (InputValue::String(string), AbiType::String { length }) => { + string.len() == *length as usize + } + + (InputValue::Struct(map), AbiType::Struct { fields, .. }) => { + if map.len() != fields.len() { + return false; + } + + let field_types = BTreeMap::from_iter(fields.iter().cloned()); + + // Check that all of the struct's fields' values match the ABI as well. + map.iter().all(|(field_name, field_value)| { + if let Some(field_type) = field_types.get(field_name) { + field_value.matches_abi(field_type) + } else { + false + } + }) + } + + // All other InputValue-AbiType combinations are fundamentally incompatible. + _ => false, + } + } +} + +/// The different formats that are supported when parsing +/// the initial witness values +#[cfg_attr(test, derive(strum_macros::EnumIter))] +pub enum Format { + Json, + Toml, +} + +impl Format { + pub fn ext(&self) -> &'static str { + match self { + Format::Json => "json", + Format::Toml => "toml", + } + } +} + +impl Format { + pub fn parse( + &self, + input_string: &str, + abi: &Abi, + ) -> Result, InputParserError> { + match self { + Format::Json => json::parse_json(input_string, abi), + Format::Toml => toml::parse_toml(input_string, abi), + } + } + + pub fn serialize( + &self, + input_map: &BTreeMap, + abi: &Abi, + ) -> Result { + match self { + Format::Json => json::serialize_to_json(input_map, abi), + Format::Toml => toml::serialize_to_toml(input_map, abi), + } + } +} + +#[cfg(test)] +mod serialization_tests { + use std::collections::BTreeMap; + + use acvm::FieldElement; + use strum::IntoEnumIterator; + + use crate::{ + input_parser::InputValue, Abi, AbiParameter, AbiType, AbiVisibility, Sign, MAIN_RETURN_NAME, + }; + + use super::Format; + + #[test] + fn serialization_round_trip() { + let abi = Abi { + parameters: vec![ + AbiParameter { + name: "foo".into(), + typ: AbiType::Field, + visibility: AbiVisibility::Private, + }, + AbiParameter { + name: "bar".into(), + typ: AbiType::Struct { + path: "MyStruct".into(), + fields: vec![ + ("field1".into(), AbiType::Integer { sign: Sign::Unsigned, width: 8 }), + ( + "field2".into(), + AbiType::Array { length: 2, typ: Box::new(AbiType::Boolean) }, + ), + ], + }, + visibility: AbiVisibility::Private, + }, + ], + return_type: Some(AbiType::String { length: 5 }), + // These two fields are unused when serializing/deserializing to file. + param_witnesses: BTreeMap::new(), + return_witnesses: Vec::new(), + }; + + let input_map: BTreeMap = BTreeMap::from([ + ("foo".into(), InputValue::Field(FieldElement::one())), + ( + "bar".into(), + InputValue::Struct(BTreeMap::from([ + ("field1".into(), InputValue::Field(255u128.into())), + ( + "field2".into(), + InputValue::Vec(vec![ + InputValue::Field(true.into()), + InputValue::Field(false.into()), + ]), + ), + ])), + ), + (MAIN_RETURN_NAME.into(), InputValue::String("hello".to_owned())), + ]); + + for format in Format::iter() { + let serialized_inputs = format.serialize(&input_map, &abi).unwrap(); + + let reconstructed_input_map = format.parse(&serialized_inputs, &abi).unwrap(); + + assert_eq!(input_map, reconstructed_input_map); + } + } +} + +fn parse_str_to_field(value: &str) -> Result { + if value.starts_with("0x") { + FieldElement::from_hex(value).ok_or_else(|| InputParserError::ParseHexStr(value.to_owned())) + } else { + BigUint::from_str_radix(value, 10) + .map_err(|err_msg| InputParserError::ParseStr(err_msg.to_string())) + .and_then(|bigint| { + if bigint < FieldElement::modulus() { + Ok(field_from_big_uint(bigint)) + } else { + Err(InputParserError::ParseStr(format!( + "Input exceeds field modulus. Values must fall within [0, {})", + FieldElement::modulus(), + ))) + } + }) + } +} + +fn field_from_big_uint(bigint: BigUint) -> FieldElement { + FieldElement::from_be_bytes_reduce(&bigint.to_bytes_be()) +} + +#[cfg(test)] +mod test { + use acvm::FieldElement; + use num_bigint::BigUint; + + use super::parse_str_to_field; + + fn big_uint_from_field(field: FieldElement) -> BigUint { + BigUint::from_bytes_be(&field.to_be_bytes()) + } + + #[test] + fn parse_empty_str_fails() { + // Check that this fails appropriately rather than being treated as 0, etc. + assert!(parse_str_to_field("").is_err()); + } + + #[test] + fn parse_fields_from_strings() { + let fields = vec![ + FieldElement::zero(), + FieldElement::one(), + FieldElement::from(u128::MAX) + FieldElement::one(), + // Equivalent to `FieldElement::modulus() - 1` + -FieldElement::one(), + ]; + + for field in fields { + let hex_field = format!("0x{}", field.to_hex()); + let field_from_hex = parse_str_to_field(&hex_field).unwrap(); + assert_eq!(field_from_hex, field); + + let dec_field = big_uint_from_field(field).to_string(); + let field_from_dec = parse_str_to_field(&dec_field).unwrap(); + assert_eq!(field_from_dec, field); + } + } + + #[test] + fn rejects_noncanonical_fields() { + let noncanonical_field = FieldElement::modulus().to_string(); + let parsed_field = parse_str_to_field(&noncanonical_field); + println!("{parsed_field:?}"); + } +} diff --git a/crates/noirc_abi/src/input_parser/toml.rs b/tooling/noirc_abi/src/input_parser/toml.rs similarity index 100% rename from crates/noirc_abi/src/input_parser/toml.rs rename to tooling/noirc_abi/src/input_parser/toml.rs diff --git a/tooling/noirc_abi/src/lib.rs b/tooling/noirc_abi/src/lib.rs new file mode 100644 index 00000000000..d0c7e4e58c1 --- /dev/null +++ b/tooling/noirc_abi/src/lib.rs @@ -0,0 +1,534 @@ +#![forbid(unsafe_code)] +#![warn(unused_crate_dependencies, unused_extern_crates)] +#![warn(unreachable_pub)] +#![warn(clippy::semicolon_if_nothing_returned)] + +use std::{collections::BTreeMap, str}; + +use acvm::{ + acir::native_types::{Witness, WitnessMap}, + FieldElement, +}; +use errors::AbiError; +use input_parser::InputValue; +use iter_extended::{try_btree_map, try_vecmap, vecmap}; +use noirc_frontend::{hir::Context, Signedness, Type, TypeBinding, TypeVariableKind, Visibility}; +use serde::{Deserialize, Serialize}; +// This is the ABI used to bridge the different TOML formats for the initial +// witness, the partial witness generator and the interpreter. +// +// This ABI has nothing to do with ACVM or ACIR. Although they implicitly have a relationship + +pub mod errors; +pub mod input_parser; +mod serialization; + +/// A map from the fields in an TOML/JSON file which correspond to some ABI to their values +pub type InputMap = BTreeMap; + +pub const MAIN_RETURN_NAME: &str = "return"; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(tag = "kind", rename_all = "lowercase")] +/// Types that are allowed in the (main function in binary) +/// +/// we use this separation so that we can have types like Strings +/// without needing to introduce this in the Noir types +/// +/// NOTE: If Strings are introduced as a native type, the translation will +/// be straightforward. Whether exotic types like String will be natively supported +/// depends on the types of programs that users want to do. I don't envision string manipulation +/// in programs, however it is possible to support, with many complications like encoding character set +/// support. +pub enum AbiType { + Field, + Array { + length: u64, + #[serde(rename = "type")] + typ: Box, + }, + Integer { + sign: Sign, + width: u32, + }, + Boolean, + Struct { + path: String, + #[serde( + serialize_with = "serialization::serialize_struct_fields", + deserialize_with = "serialization::deserialize_struct_fields" + )] + fields: Vec<(String, AbiType)>, + }, + String { + length: u64, + }, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +/// Represents whether the parameter is public or known only to the prover. +pub enum AbiVisibility { + Public, + // Constants are not allowed in the ABI for main at the moment. + // Constant, + Private, +} + +impl From for AbiVisibility { + fn from(value: Visibility) -> Self { + match value { + Visibility::Public => AbiVisibility::Public, + Visibility::Private => AbiVisibility::Private, + } + } +} + +impl From<&Visibility> for AbiVisibility { + fn from(value: &Visibility) -> Self { + match value { + Visibility::Public => AbiVisibility::Public, + Visibility::Private => AbiVisibility::Private, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +/// Represents whether the return value should compromise of unique witness indices such that no +/// index occurs within the program's abi more than once. +/// +/// This is useful for application stacks that require an uniform abi across across multiple +/// circuits. When index duplication is allowed, the compiler may identify that a public input +/// reaches the output unaltered and is thus referenced directly, causing the input and output +/// witness indices to overlap. Similarly, repetitions of copied values in the output may be +/// optimized away. +pub enum AbiDistinctness { + Distinct, + DuplicationAllowed, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum Sign { + Unsigned, + Signed, +} + +impl AbiType { + pub fn from_type(context: &Context, typ: &Type) -> Self { + // Note; use strict_eq instead of partial_eq when comparing field types + // in this method, you most likely want to distinguish between public and private + match typ { + Type::FieldElement => Self::Field, + Type::Array(size, typ) => { + let length = size + .evaluate_to_u64() + .expect("Cannot have variable sized arrays as a parameter to main"); + let typ = typ.as_ref(); + Self::Array { length, typ: Box::new(Self::from_type(context, typ)) } + } + Type::Integer(sign, bit_width) => { + let sign = match sign { + Signedness::Unsigned => Sign::Unsigned, + Signedness::Signed => Sign::Signed, + }; + + Self::Integer { sign, width: *bit_width } + } + Type::TypeVariable(binding, TypeVariableKind::IntegerOrField) => { + match &*binding.borrow() { + TypeBinding::Bound(typ) => Self::from_type(context, typ), + TypeBinding::Unbound(_) => Self::from_type(context, &Type::default_int_type()), + } + } + Type::Bool => Self::Boolean, + Type::String(size) => { + let size = size + .evaluate_to_u64() + .expect("Cannot have variable sized strings as a parameter to main"); + Self::String { length: size } + } + Type::FmtString(_, _) => unreachable!("format strings cannot be used in the abi"), + Type::Error => unreachable!(), + Type::Unit => unreachable!(), + Type::Constant(_) => unreachable!(), + Type::Struct(def, ref args) => { + let struct_type = def.borrow(); + let fields = struct_type.get_fields(args); + let fields = vecmap(fields, |(name, typ)| (name, Self::from_type(context, &typ))); + // For the ABI, we always want to resolve the struct paths from the root crate + let path = + context.fully_qualified_struct_path(context.root_crate_id(), struct_type.id); + Self::Struct { fields, path } + } + Type::Tuple(_) => todo!("AbiType::from_type not yet implemented for tuple types"), + Type::TypeVariable(_, _) => unreachable!(), + Type::NamedGeneric(..) => unreachable!(), + Type::Forall(..) => unreachable!(), + Type::Function(_, _, _) => unreachable!(), + Type::MutableReference(_) => unreachable!("&mut cannot be used in the abi"), + Type::NotConstant => unreachable!(), + } + } + + /// Returns the number of field elements required to represent the type once encoded. + pub fn field_count(&self) -> u32 { + match self { + AbiType::Field | AbiType::Integer { .. } | AbiType::Boolean => 1, + AbiType::Array { length, typ } => typ.field_count() * (*length as u32), + AbiType::Struct { fields, .. } => { + fields.iter().fold(0, |acc, (_, field_type)| acc + field_type.field_count()) + } + AbiType::String { length } => *length as u32, + } + } +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +/// An argument or return value of the circuit's `main` function. +pub struct AbiParameter { + pub name: String, + #[serde(rename = "type")] + pub typ: AbiType, + pub visibility: AbiVisibility, +} + +impl AbiParameter { + pub fn is_public(&self) -> bool { + self.visibility == AbiVisibility::Public + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Abi { + /// An ordered list of the arguments to the program's `main` function, specifying their types and visibility. + pub parameters: Vec, + /// A map from the ABI's parameters to the indices they are written to in the [`WitnessMap`]. + /// This defines how to convert between the [`InputMap`] and [`WitnessMap`]. + pub param_witnesses: BTreeMap>, + pub return_type: Option, + pub return_witnesses: Vec, +} + +impl Abi { + pub fn parameter_names(&self) -> Vec<&String> { + self.parameters.iter().map(|x| &x.name).collect() + } + + pub fn num_parameters(&self) -> usize { + self.parameters.len() + } + + /// Returns the number of field elements required to represent the ABI's input once encoded. + pub fn field_count(&self) -> u32 { + self.parameters.iter().map(|param| param.typ.field_count()).sum() + } + + /// Returns whether any values are needed to be made public for verification. + pub fn has_public_inputs(&self) -> bool { + self.return_type.is_some() || self.parameters.iter().any(|param| param.is_public()) + } + + /// Returns `true` if the ABI contains no parameters or return value. + pub fn is_empty(&self) -> bool { + self.return_type.is_none() && self.parameters.is_empty() + } + + pub fn to_btree_map(&self) -> BTreeMap { + let mut map = BTreeMap::new(); + for param in self.parameters.iter() { + map.insert(param.name.clone(), param.typ.clone()); + } + map + } + + /// ABI with only the public parameters + #[must_use] + pub fn public_abi(self) -> Abi { + let parameters: Vec<_> = + self.parameters.into_iter().filter(|param| param.is_public()).collect(); + let param_witnesses = self + .param_witnesses + .into_iter() + .filter(|(param_name, _)| parameters.iter().any(|param| ¶m.name == param_name)) + .collect(); + Abi { + parameters, + param_witnesses, + return_type: self.return_type, + return_witnesses: self.return_witnesses, + } + } + + /// Encode a set of inputs as described in the ABI into a `WitnessMap`. + pub fn encode( + &self, + input_map: &InputMap, + return_value: Option, + ) -> Result { + // Check that no extra witness values have been provided. + let param_names = self.parameter_names(); + if param_names.len() < input_map.len() { + let unexpected_params: Vec = + input_map.keys().filter(|param| !param_names.contains(param)).cloned().collect(); + return Err(AbiError::UnexpectedParams(unexpected_params)); + } + + // First encode each input separately, performing any input validation. + let encoded_input_map: BTreeMap> = self + .to_btree_map() + .into_iter() + .map(|(param_name, expected_type)| { + let value = input_map + .get(¶m_name) + .ok_or_else(|| AbiError::MissingParam(param_name.clone()))? + .clone(); + + if !value.matches_abi(&expected_type) { + let param = self + .parameters + .iter() + .find(|param| param.name == param_name) + .unwrap() + .clone(); + return Err(AbiError::TypeMismatch { param, value }); + } + + Self::encode_value(value, &expected_type).map(|v| (param_name, v)) + }) + .collect::>()?; + + // Write input field elements into witness indices specified in `self.param_witnesses`. + let mut witness_map: BTreeMap = encoded_input_map + .iter() + .flat_map(|(param_name, encoded_param_fields)| { + let param_witness_indices = &self.param_witnesses[param_name]; + param_witness_indices + .iter() + .zip(encoded_param_fields.iter()) + .map(|(&witness, &field_element)| (witness, field_element)) + }) + .collect(); + + // When encoding public inputs to be passed to the verifier, the user can must provide a return value + // to be inserted into the witness map. This is not needed when generating a witness when proving the circuit. + match (&self.return_type, return_value) { + (Some(return_type), Some(return_value)) => { + if !return_value.matches_abi(return_type) { + return Err(AbiError::ReturnTypeMismatch { + return_type: return_type.clone(), + value: return_value, + }); + } + let encoded_return_fields = Self::encode_value(return_value, return_type)?; + + // We need to be more careful when writing the return value's witness values. + // This is as it may share witness indices with other public inputs so we must check that when + // this occurs the witness values are consistent with each other. + self.return_witnesses.iter().zip(encoded_return_fields.iter()).try_for_each( + |(&witness, &field_element)| match witness_map.insert(witness, field_element) { + Some(existing_value) if existing_value != field_element => { + Err(AbiError::InconsistentWitnessAssignment(witness)) + } + _ => Ok(()), + }, + )?; + } + (None, Some(return_value)) => { + return Err(AbiError::UnexpectedReturnValue(return_value)) + } + // We allow not passing a return value despite the circuit defining one + // in order to generate the initial partial witness. + (_, None) => {} + } + + Ok(witness_map.into()) + } + + fn encode_value(value: InputValue, abi_type: &AbiType) -> Result, AbiError> { + let mut encoded_value = Vec::new(); + match (value, abi_type) { + (InputValue::Field(elem), _) => encoded_value.push(elem), + + (InputValue::Vec(vec_elements), AbiType::Array { typ, .. }) => { + for elem in vec_elements { + encoded_value.extend(Self::encode_value(elem, typ)?); + } + } + + (InputValue::String(string), _) => { + let str_as_fields = + string.bytes().map(|byte| FieldElement::from_be_bytes_reduce(&[byte])); + encoded_value.extend(str_as_fields); + } + + (InputValue::Struct(object), AbiType::Struct { fields, .. }) => { + for (field, typ) in fields { + encoded_value.extend(Self::encode_value(object[field].clone(), typ)?); + } + } + _ => unreachable!("value should have already been checked to match abi type"), + } + Ok(encoded_value) + } + + /// Decode a `WitnessMap` into the types specified in the ABI. + pub fn decode( + &self, + witness_map: &WitnessMap, + ) -> Result<(InputMap, Option), AbiError> { + let public_inputs_map = + try_btree_map(self.parameters.clone(), |AbiParameter { name, typ, .. }| { + let param_witness_values = + try_vecmap(self.param_witnesses[&name].clone(), |witness_index| { + witness_map + .get(&witness_index) + .ok_or_else(|| AbiError::MissingParamWitnessValue { + name: name.clone(), + witness_index, + }) + .copied() + })?; + + decode_value(&mut param_witness_values.into_iter(), &typ) + .map(|input_value| (name.clone(), input_value)) + })?; + + // We also attempt to decode the circuit's return value from `witness_map`. + let return_value = if let Some(return_type) = &self.return_type { + if let Ok(return_witness_values) = + try_vecmap(self.return_witnesses.clone(), |witness_index| { + witness_map + .get(&witness_index) + .ok_or_else(|| AbiError::MissingParamWitnessValue { + name: MAIN_RETURN_NAME.to_string(), + witness_index, + }) + .copied() + }) + { + Some(decode_value(&mut return_witness_values.into_iter(), return_type)?) + } else { + // Unlike for the circuit inputs, we tolerate not being able to find the witness values for the return value. + // This is because the user may be decoding a partial witness map for which is hasn't been calculated yet. + // If a return value is expected, this should be checked for by the user. + None + } + } else { + None + }; + + Ok((public_inputs_map, return_value)) + } +} + +fn decode_value( + field_iterator: &mut impl Iterator, + value_type: &AbiType, +) -> Result { + // This function assumes that `field_iterator` contains enough `FieldElement`s in order to decode a `value_type` + // `Abi.decode` enforces that the encoded inputs matches the expected length defined by the ABI so this is safe. + let value = match value_type { + AbiType::Field | AbiType::Integer { .. } | AbiType::Boolean => { + let field_element = field_iterator.next().unwrap(); + + InputValue::Field(field_element) + } + AbiType::Array { length, typ } => { + let length = *length as usize; + let mut array_elements = Vec::with_capacity(length); + for _ in 0..length { + array_elements.push(decode_value(field_iterator, typ)?); + } + + InputValue::Vec(array_elements) + } + AbiType::String { length } => { + let field_elements: Vec = field_iterator.take(*length as usize).collect(); + + InputValue::String(decode_string_value(&field_elements)) + } + AbiType::Struct { fields, .. } => { + let mut struct_map = BTreeMap::new(); + + for (field_key, param_type) in fields { + let field_value = decode_value(field_iterator, param_type)?; + + struct_map.insert(field_key.to_owned(), field_value); + } + + InputValue::Struct(struct_map) + } + }; + + Ok(value) +} + +fn decode_string_value(field_elements: &[FieldElement]) -> String { + let string_as_slice = vecmap(field_elements, |e| { + let mut field_as_bytes = e.to_be_bytes(); + let char_byte = field_as_bytes.pop().unwrap(); // A character in a string is represented by a u8, thus we just want the last byte of the element + assert!(field_as_bytes.into_iter().all(|b| b == 0)); // Assert that the rest of the field element's bytes are empty + char_byte + }); + + let final_string = str::from_utf8(&string_as_slice).unwrap(); + final_string.to_owned() +} + +#[cfg(test)] +mod test { + use std::collections::BTreeMap; + + use acvm::{acir::native_types::Witness, FieldElement}; + + use crate::{input_parser::InputValue, Abi, AbiParameter, AbiType, AbiVisibility, InputMap}; + + #[test] + fn witness_encoding_roundtrip() { + let abi = Abi { + parameters: vec![ + AbiParameter { + name: "thing1".to_string(), + typ: AbiType::Array { length: 2, typ: Box::new(AbiType::Field) }, + visibility: AbiVisibility::Public, + }, + AbiParameter { + name: "thing2".to_string(), + typ: AbiType::Field, + visibility: AbiVisibility::Public, + }, + ], + // Note that the return value shares a witness with `thing2` + param_witnesses: BTreeMap::from([ + ("thing1".to_string(), vec![Witness(1), Witness(2)]), + ("thing2".to_string(), vec![Witness(3)]), + ]), + return_type: Some(AbiType::Field), + return_witnesses: vec![Witness(3)], + }; + + // Note we omit return value from inputs + let inputs: InputMap = BTreeMap::from([ + ( + "thing1".to_string(), + InputValue::Vec(vec![ + InputValue::Field(FieldElement::one()), + InputValue::Field(FieldElement::one()), + ]), + ), + ("thing2".to_string(), InputValue::Field(FieldElement::zero())), + ]); + + let witness_map = abi.encode(&inputs, None).unwrap(); + let (reconstructed_inputs, return_value) = abi.decode(&witness_map).unwrap(); + + for (key, expected_value) in inputs { + assert_eq!(reconstructed_inputs[&key], expected_value); + } + + // We also decode the return value (we can do this immediately as we know it shares a witness with an input). + assert_eq!(return_value.unwrap(), reconstructed_inputs["thing2"]); + } +} diff --git a/crates/noirc_abi/src/serialization.rs b/tooling/noirc_abi/src/serialization.rs similarity index 97% rename from crates/noirc_abi/src/serialization.rs rename to tooling/noirc_abi/src/serialization.rs index 7d32874bb7e..ed838803fab 100644 --- a/crates/noirc_abi/src/serialization.rs +++ b/tooling/noirc_abi/src/serialization.rs @@ -88,11 +88,11 @@ mod tests { let deserialized_array: AbiParameter = serde_json::from_str(serialized_array).unwrap(); assert_eq!(deserialized_array, expected_array); - let serialized_struct = "{ + let serialized_struct = "{ \"name\":\"thing3\", \"type\": { \"kind\":\"struct\", - \"name\": \"MyStruct\", + \"path\": \"MyStruct\", \"fields\": [ { \"name\": \"field1\", @@ -120,7 +120,7 @@ mod tests { let expected_struct = AbiParameter { name: "thing3".to_string(), typ: AbiType::Struct { - name: "MyStruct".to_string(), + path: "MyStruct".to_string(), fields: vec![ ("field1".to_string(), AbiType::Integer { sign: Sign::Unsigned, width: 3 }), ( diff --git a/tooling/noirc_abi_wasm/.eslintignore b/tooling/noirc_abi_wasm/.eslintignore new file mode 100644 index 00000000000..200ae222150 --- /dev/null +++ b/tooling/noirc_abi_wasm/.eslintignore @@ -0,0 +1,2 @@ +node_modules +pkg \ No newline at end of file diff --git a/tooling/noirc_abi_wasm/.eslintrc.js b/tooling/noirc_abi_wasm/.eslintrc.js new file mode 100644 index 00000000000..b1346a8792f --- /dev/null +++ b/tooling/noirc_abi_wasm/.eslintrc.js @@ -0,0 +1,19 @@ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint", "prettier"], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + rules: { + "comma-spacing": ["error", { before: false, after: true }], + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", // or "error" + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + caughtErrorsIgnorePattern: "^_", + }, + ], + "prettier/prettier": "error", + }, +}; diff --git a/tooling/noirc_abi_wasm/.gitignore b/tooling/noirc_abi_wasm/.gitignore new file mode 100644 index 00000000000..07c883e0b8a --- /dev/null +++ b/tooling/noirc_abi_wasm/.gitignore @@ -0,0 +1,8 @@ +# Yarn +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions \ No newline at end of file diff --git a/tooling/noirc_abi_wasm/.mocharc.json b/tooling/noirc_abi_wasm/.mocharc.json new file mode 100644 index 00000000000..27273835070 --- /dev/null +++ b/tooling/noirc_abi_wasm/.mocharc.json @@ -0,0 +1,5 @@ +{ + "extension": ["ts"], + "spec": "test/node/**/*.test.ts", + "require": "ts-node/register" +} \ No newline at end of file diff --git a/tooling/noirc_abi_wasm/.yarn/releases/yarn-3.5.1.cjs b/tooling/noirc_abi_wasm/.yarn/releases/yarn-3.5.1.cjs new file mode 100755 index 00000000000..97eed758032 --- /dev/null +++ b/tooling/noirc_abi_wasm/.yarn/releases/yarn-3.5.1.cjs @@ -0,0 +1,873 @@ +#!/usr/bin/env node +/* eslint-disable */ +//prettier-ignore +(()=>{var Sge=Object.create;var lS=Object.defineProperty;var vge=Object.getOwnPropertyDescriptor;var xge=Object.getOwnPropertyNames;var Pge=Object.getPrototypeOf,Dge=Object.prototype.hasOwnProperty;var J=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+r+'" is not supported')});var kge=(r,e)=>()=>(r&&(e=r(r=0)),e);var w=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),ut=(r,e)=>{for(var t in e)lS(r,t,{get:e[t],enumerable:!0})},Rge=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of xge(e))!Dge.call(r,n)&&n!==t&&lS(r,n,{get:()=>e[n],enumerable:!(i=vge(e,n))||i.enumerable});return r};var Pe=(r,e,t)=>(t=r!=null?Sge(Pge(r)):{},Rge(e||!r||!r.__esModule?lS(t,"default",{value:r,enumerable:!0}):t,r));var vU=w((j7e,SU)=>{SU.exports=bU;bU.sync=$ge;var BU=J("fs");function _ge(r,e){var t=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!t||(t=t.split(";"),t.indexOf("")!==-1))return!0;for(var i=0;i{kU.exports=PU;PU.sync=efe;var xU=J("fs");function PU(r,e,t){xU.stat(r,function(i,n){t(i,i?!1:DU(n,e))})}function efe(r,e){return DU(xU.statSync(r),e)}function DU(r,e){return r.isFile()&&tfe(r,e)}function tfe(r,e){var t=r.mode,i=r.uid,n=r.gid,s=e.uid!==void 0?e.uid:process.getuid&&process.getuid(),o=e.gid!==void 0?e.gid:process.getgid&&process.getgid(),a=parseInt("100",8),l=parseInt("010",8),c=parseInt("001",8),u=a|l,g=t&c||t&l&&n===o||t&a&&i===s||t&u&&s===0;return g}});var NU=w((W7e,FU)=>{var J7e=J("fs"),lI;process.platform==="win32"||global.TESTING_WINDOWS?lI=vU():lI=RU();FU.exports=SS;SS.sync=rfe;function SS(r,e,t){if(typeof e=="function"&&(t=e,e={}),!t){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(i,n){SS(r,e||{},function(s,o){s?n(s):i(o)})})}lI(r,e||{},function(i,n){i&&(i.code==="EACCES"||e&&e.ignoreErrors)&&(i=null,n=!1),t(i,n)})}function rfe(r,e){try{return lI.sync(r,e||{})}catch(t){if(e&&e.ignoreErrors||t.code==="EACCES")return!1;throw t}}});var HU=w((z7e,KU)=>{var Dg=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",LU=J("path"),ife=Dg?";":":",TU=NU(),OU=r=>Object.assign(new Error(`not found: ${r}`),{code:"ENOENT"}),MU=(r,e)=>{let t=e.colon||ife,i=r.match(/\//)||Dg&&r.match(/\\/)?[""]:[...Dg?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(t)],n=Dg?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=Dg?n.split(t):[""];return Dg&&r.indexOf(".")!==-1&&s[0]!==""&&s.unshift(""),{pathEnv:i,pathExt:s,pathExtExe:n}},UU=(r,e,t)=>{typeof e=="function"&&(t=e,e={}),e||(e={});let{pathEnv:i,pathExt:n,pathExtExe:s}=MU(r,e),o=[],a=c=>new Promise((u,g)=>{if(c===i.length)return e.all&&o.length?u(o):g(OU(r));let f=i[c],h=/^".*"$/.test(f)?f.slice(1,-1):f,p=LU.join(h,r),C=!h&&/^\.[\\\/]/.test(r)?r.slice(0,2)+p:p;u(l(C,c,0))}),l=(c,u,g)=>new Promise((f,h)=>{if(g===n.length)return f(a(u+1));let p=n[g];TU(c+p,{pathExt:s},(C,y)=>{if(!C&&y)if(e.all)o.push(c+p);else return f(c+p);return f(l(c,u,g+1))})});return t?a(0).then(c=>t(null,c),t):a(0)},nfe=(r,e)=>{e=e||{};let{pathEnv:t,pathExt:i,pathExtExe:n}=MU(r,e),s=[];for(let o=0;o{"use strict";var GU=(r={})=>{let e=r.env||process.env;return(r.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(i=>i.toUpperCase()==="PATH")||"Path"};vS.exports=GU;vS.exports.default=GU});var WU=w((X7e,JU)=>{"use strict";var jU=J("path"),sfe=HU(),ofe=YU();function qU(r,e){let t=r.options.env||process.env,i=process.cwd(),n=r.options.cwd!=null,s=n&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(r.options.cwd)}catch{}let o;try{o=sfe.sync(r.command,{path:t[ofe({env:t})],pathExt:e?jU.delimiter:void 0})}catch{}finally{s&&process.chdir(i)}return o&&(o=jU.resolve(n?r.options.cwd:"",o)),o}function afe(r){return qU(r)||qU(r,!0)}JU.exports=afe});var zU=w((Z7e,PS)=>{"use strict";var xS=/([()\][%!^"`<>&|;, *?])/g;function Afe(r){return r=r.replace(xS,"^$1"),r}function lfe(r,e){return r=`${r}`,r=r.replace(/(\\*)"/g,'$1$1\\"'),r=r.replace(/(\\*)$/,"$1$1"),r=`"${r}"`,r=r.replace(xS,"^$1"),e&&(r=r.replace(xS,"^$1")),r}PS.exports.command=Afe;PS.exports.argument=lfe});var XU=w((_7e,VU)=>{"use strict";VU.exports=/^#!(.*)/});var _U=w(($7e,ZU)=>{"use strict";var cfe=XU();ZU.exports=(r="")=>{let e=r.match(cfe);if(!e)return null;let[t,i]=e[0].replace(/#! ?/,"").split(" "),n=t.split("/").pop();return n==="env"?i:i?`${n} ${i}`:n}});var eK=w((eZe,$U)=>{"use strict";var DS=J("fs"),ufe=_U();function gfe(r){let t=Buffer.alloc(150),i;try{i=DS.openSync(r,"r"),DS.readSync(i,t,0,150,0),DS.closeSync(i)}catch{}return ufe(t.toString())}$U.exports=gfe});var nK=w((tZe,iK)=>{"use strict";var ffe=J("path"),tK=WU(),rK=zU(),hfe=eK(),pfe=process.platform==="win32",dfe=/\.(?:com|exe)$/i,Cfe=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function mfe(r){r.file=tK(r);let e=r.file&&hfe(r.file);return e?(r.args.unshift(r.file),r.command=e,tK(r)):r.file}function Efe(r){if(!pfe)return r;let e=mfe(r),t=!dfe.test(e);if(r.options.forceShell||t){let i=Cfe.test(e);r.command=ffe.normalize(r.command),r.command=rK.command(r.command),r.args=r.args.map(s=>rK.argument(s,i));let n=[r.command].concat(r.args).join(" ");r.args=["/d","/s","/c",`"${n}"`],r.command=process.env.comspec||"cmd.exe",r.options.windowsVerbatimArguments=!0}return r}function Ife(r,e,t){e&&!Array.isArray(e)&&(t=e,e=null),e=e?e.slice(0):[],t=Object.assign({},t);let i={command:r,args:e,options:t,file:void 0,original:{command:r,args:e}};return t.shell?i:Efe(i)}iK.exports=Ife});var aK=w((rZe,oK)=>{"use strict";var kS=process.platform==="win32";function RS(r,e){return Object.assign(new Error(`${e} ${r.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${r.command}`,path:r.command,spawnargs:r.args})}function yfe(r,e){if(!kS)return;let t=r.emit;r.emit=function(i,n){if(i==="exit"){let s=sK(n,e,"spawn");if(s)return t.call(r,"error",s)}return t.apply(r,arguments)}}function sK(r,e){return kS&&r===1&&!e.file?RS(e.original,"spawn"):null}function wfe(r,e){return kS&&r===1&&!e.file?RS(e.original,"spawnSync"):null}oK.exports={hookChildProcess:yfe,verifyENOENT:sK,verifyENOENTSync:wfe,notFoundError:RS}});var LS=w((iZe,kg)=>{"use strict";var AK=J("child_process"),FS=nK(),NS=aK();function lK(r,e,t){let i=FS(r,e,t),n=AK.spawn(i.command,i.args,i.options);return NS.hookChildProcess(n,i),n}function Bfe(r,e,t){let i=FS(r,e,t),n=AK.spawnSync(i.command,i.args,i.options);return n.error=n.error||NS.verifyENOENTSync(n.status,i),n}kg.exports=lK;kg.exports.spawn=lK;kg.exports.sync=Bfe;kg.exports._parse=FS;kg.exports._enoent=NS});var uK=w((nZe,cK)=>{"use strict";function Qfe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function Zl(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,Zl)}Qfe(Zl,Error);Zl.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g>",ie=me(">>",!1),de=">&",_e=me(">&",!1),Pt=">",It=me(">",!1),Or="<<<",ii=me("<<<",!1),gi="<&",hr=me("<&",!1),fi="<",ni=me("<",!1),Us=function(m){return{type:"argument",segments:[].concat(...m)}},pr=function(m){return m},Ii="$'",rs=me("$'",!1),ga="'",dA=me("'",!1),cg=function(m){return[{type:"text",text:m}]},is='""',CA=me('""',!1),fa=function(){return{type:"text",text:""}},wp='"',mA=me('"',!1),EA=function(m){return m},wr=function(m){return{type:"arithmetic",arithmetic:m,quoted:!0}},Ll=function(m){return{type:"shell",shell:m,quoted:!0}},ug=function(m){return{type:"variable",...m,quoted:!0}},Io=function(m){return{type:"text",text:m}},gg=function(m){return{type:"arithmetic",arithmetic:m,quoted:!1}},Bp=function(m){return{type:"shell",shell:m,quoted:!1}},Qp=function(m){return{type:"variable",...m,quoted:!1}},vr=function(m){return{type:"glob",pattern:m}},se=/^[^']/,yo=Je(["'"],!0,!1),Rn=function(m){return m.join("")},fg=/^[^$"]/,Qt=Je(["$",'"'],!0,!1),Tl=`\\ +`,Fn=me(`\\ +`,!1),ns=function(){return""},ss="\\",gt=me("\\",!1),wo=/^[\\$"`]/,At=Je(["\\","$",'"',"`"],!1,!1),An=function(m){return m},S="\\a",Tt=me("\\a",!1),hg=function(){return"a"},Ol="\\b",bp=me("\\b",!1),Sp=function(){return"\b"},vp=/^[Ee]/,xp=Je(["E","e"],!1,!1),Pp=function(){return"\x1B"},G="\\f",yt=me("\\f",!1),IA=function(){return"\f"},Wi="\\n",Ml=me("\\n",!1),Xe=function(){return` +`},ha="\\r",pg=me("\\r",!1),OE=function(){return"\r"},Dp="\\t",ME=me("\\t",!1),ar=function(){return" "},Nn="\\v",Ul=me("\\v",!1),kp=function(){return"\v"},Ks=/^[\\'"?]/,pa=Je(["\\","'",'"',"?"],!1,!1),ln=function(m){return String.fromCharCode(parseInt(m,16))},Te="\\x",dg=me("\\x",!1),Kl="\\u",Hs=me("\\u",!1),Hl="\\U",yA=me("\\U",!1),Cg=function(m){return String.fromCodePoint(parseInt(m,16))},mg=/^[0-7]/,da=Je([["0","7"]],!1,!1),Ca=/^[0-9a-fA-f]/,rt=Je([["0","9"],["a","f"],["A","f"]],!1,!1),Bo=nt(),wA="-",Gl=me("-",!1),Gs="+",Yl=me("+",!1),UE=".",Rp=me(".",!1),Eg=function(m,b,N){return{type:"number",value:(m==="-"?-1:1)*parseFloat(b.join("")+"."+N.join(""))}},Fp=function(m,b){return{type:"number",value:(m==="-"?-1:1)*parseInt(b.join(""))}},KE=function(m){return{type:"variable",...m}},jl=function(m){return{type:"variable",name:m}},HE=function(m){return m},Ig="*",BA=me("*",!1),Rr="/",GE=me("/",!1),Ys=function(m,b,N){return{type:b==="*"?"multiplication":"division",right:N}},js=function(m,b){return b.reduce((N,K)=>({left:N,...K}),m)},yg=function(m,b,N){return{type:b==="+"?"addition":"subtraction",right:N}},QA="$((",R=me("$((",!1),q="))",Ce=me("))",!1),Ue=function(m){return m},Re="$(",ze=me("$(",!1),dt=function(m){return m},Ft="${",Ln=me("${",!1),Jb=":-",P1=me(":-",!1),D1=function(m,b){return{name:m,defaultValue:b}},Wb=":-}",k1=me(":-}",!1),R1=function(m){return{name:m,defaultValue:[]}},zb=":+",F1=me(":+",!1),N1=function(m,b){return{name:m,alternativeValue:b}},Vb=":+}",L1=me(":+}",!1),T1=function(m){return{name:m,alternativeValue:[]}},Xb=function(m){return{name:m}},O1="$",M1=me("$",!1),U1=function(m){return e.isGlobPattern(m)},K1=function(m){return m},Zb=/^[a-zA-Z0-9_]/,_b=Je([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),$b=function(){return T()},eS=/^[$@*?#a-zA-Z0-9_\-]/,tS=Je(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),H1=/^[(){}<>$|&; \t"']/,wg=Je(["(",")","{","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),rS=/^[<>&; \t"']/,iS=Je(["<",">","&",";"," "," ",'"',"'"],!1,!1),YE=/^[ \t]/,jE=Je([" "," "],!1,!1),Q=0,Me=0,bA=[{line:1,column:1}],d=0,E=[],I=0,k;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function T(){return r.substring(Me,Q)}function Z(){return Et(Me,Q)}function te(m,b){throw b=b!==void 0?b:Et(Me,Q),Ri([lt(m)],r.substring(Me,Q),b)}function we(m,b){throw b=b!==void 0?b:Et(Me,Q),Tn(m,b)}function me(m,b){return{type:"literal",text:m,ignoreCase:b}}function Je(m,b,N){return{type:"class",parts:m,inverted:b,ignoreCase:N}}function nt(){return{type:"any"}}function wt(){return{type:"end"}}function lt(m){return{type:"other",description:m}}function it(m){var b=bA[m],N;if(b)return b;for(N=m-1;!bA[N];)N--;for(b=bA[N],b={line:b.line,column:b.column};Nd&&(d=Q,E=[]),E.push(m))}function Tn(m,b){return new Zl(m,null,null,b)}function Ri(m,b,N){return new Zl(Zl.buildMessage(m,b),m,b,N)}function SA(){var m,b;return m=Q,b=Mr(),b===t&&(b=null),b!==t&&(Me=m,b=s(b)),m=b,m}function Mr(){var m,b,N,K,ce;if(m=Q,b=Ur(),b!==t){for(N=[],K=He();K!==t;)N.push(K),K=He();N!==t?(K=ma(),K!==t?(ce=os(),ce===t&&(ce=null),ce!==t?(Me=m,b=o(b,K,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;if(m===t)if(m=Q,b=Ur(),b!==t){for(N=[],K=He();K!==t;)N.push(K),K=He();N!==t?(K=ma(),K===t&&(K=null),K!==t?(Me=m,b=a(b,K),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;return m}function os(){var m,b,N,K,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=Mr(),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();K!==t?(Me=m,b=l(N),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;return m}function ma(){var m;return r.charCodeAt(Q)===59?(m=c,Q++):(m=t,I===0&&Qe(u)),m===t&&(r.charCodeAt(Q)===38?(m=g,Q++):(m=t,I===0&&Qe(f))),m}function Ur(){var m,b,N;return m=Q,b=G1(),b!==t?(N=lge(),N===t&&(N=null),N!==t?(Me=m,b=h(b,N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function lge(){var m,b,N,K,ce,Se,ht;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=cge(),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t)if(ce=Ur(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=p(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;return m}function cge(){var m;return r.substr(Q,2)===C?(m=C,Q+=2):(m=t,I===0&&Qe(y)),m===t&&(r.substr(Q,2)===B?(m=B,Q+=2):(m=t,I===0&&Qe(v))),m}function G1(){var m,b,N;return m=Q,b=fge(),b!==t?(N=uge(),N===t&&(N=null),N!==t?(Me=m,b=D(b,N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function uge(){var m,b,N,K,ce,Se,ht;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=gge(),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t)if(ce=G1(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=L(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;return m}function gge(){var m;return r.substr(Q,2)===H?(m=H,Q+=2):(m=t,I===0&&Qe(j)),m===t&&(r.charCodeAt(Q)===124?(m=$,Q++):(m=t,I===0&&Qe(V))),m}function qE(){var m,b,N,K,ce,Se;if(m=Q,b=eU(),b!==t)if(r.charCodeAt(Q)===61?(N=W,Q++):(N=t,I===0&&Qe(_)),N!==t)if(K=q1(),K!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(Me=m,b=A(b,K),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;else Q=m,m=t;if(m===t)if(m=Q,b=eU(),b!==t)if(r.charCodeAt(Q)===61?(N=W,Q++):(N=t,I===0&&Qe(_)),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();K!==t?(Me=m,b=Ae(b),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;return m}function fge(){var m,b,N,K,ce,Se,ht,Bt,Jr,hi,as;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(r.charCodeAt(Q)===40?(N=ge,Q++):(N=t,I===0&&Qe(re)),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t)if(ce=Mr(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();if(Se!==t)if(r.charCodeAt(Q)===41?(ht=O,Q++):(ht=t,I===0&&Qe(F)),ht!==t){for(Bt=[],Jr=He();Jr!==t;)Bt.push(Jr),Jr=He();if(Bt!==t){for(Jr=[],hi=Np();hi!==t;)Jr.push(hi),hi=Np();if(Jr!==t){for(hi=[],as=He();as!==t;)hi.push(as),as=He();hi!==t?(Me=m,b=ue(ce,Jr),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(r.charCodeAt(Q)===123?(N=pe,Q++):(N=t,I===0&&Qe(ke)),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t)if(ce=Mr(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();if(Se!==t)if(r.charCodeAt(Q)===125?(ht=Fe,Q++):(ht=t,I===0&&Qe(Ne)),ht!==t){for(Bt=[],Jr=He();Jr!==t;)Bt.push(Jr),Jr=He();if(Bt!==t){for(Jr=[],hi=Np();hi!==t;)Jr.push(hi),hi=Np();if(Jr!==t){for(hi=[],as=He();as!==t;)hi.push(as),as=He();hi!==t?(Me=m,b=oe(ce,Jr),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){for(N=[],K=qE();K!==t;)N.push(K),K=qE();if(N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t){if(ce=[],Se=j1(),Se!==t)for(;Se!==t;)ce.push(Se),Se=j1();else ce=t;if(ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=le(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){if(N=[],K=qE(),K!==t)for(;K!==t;)N.push(K),K=qE();else N=t;if(N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();K!==t?(Me=m,b=Be(N),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}}}return m}function Y1(){var m,b,N,K,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){if(N=[],K=JE(),K!==t)for(;K!==t;)N.push(K),K=JE();else N=t;if(N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();K!==t?(Me=m,b=fe(N),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t;return m}function j1(){var m,b,N;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t?(N=Np(),N!==t?(Me=m,b=ae(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();b!==t?(N=JE(),N!==t?(Me=m,b=ae(N),m=b):(Q=m,m=t)):(Q=m,m=t)}return m}function Np(){var m,b,N,K,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();return b!==t?(qe.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(ne)),N===t&&(N=null),N!==t?(K=hge(),K!==t?(ce=JE(),ce!==t?(Me=m,b=Y(N,K,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function hge(){var m;return r.substr(Q,2)===he?(m=he,Q+=2):(m=t,I===0&&Qe(ie)),m===t&&(r.substr(Q,2)===de?(m=de,Q+=2):(m=t,I===0&&Qe(_e)),m===t&&(r.charCodeAt(Q)===62?(m=Pt,Q++):(m=t,I===0&&Qe(It)),m===t&&(r.substr(Q,3)===Or?(m=Or,Q+=3):(m=t,I===0&&Qe(ii)),m===t&&(r.substr(Q,2)===gi?(m=gi,Q+=2):(m=t,I===0&&Qe(hr)),m===t&&(r.charCodeAt(Q)===60?(m=fi,Q++):(m=t,I===0&&Qe(ni))))))),m}function JE(){var m,b,N;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();return b!==t?(N=q1(),N!==t?(Me=m,b=ae(N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function q1(){var m,b,N;if(m=Q,b=[],N=J1(),N!==t)for(;N!==t;)b.push(N),N=J1();else b=t;return b!==t&&(Me=m,b=Us(b)),m=b,m}function J1(){var m,b;return m=Q,b=pge(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=dge(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=Cge(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=mge(),b!==t&&(Me=m,b=pr(b)),m=b))),m}function pge(){var m,b,N,K;return m=Q,r.substr(Q,2)===Ii?(b=Ii,Q+=2):(b=t,I===0&&Qe(rs)),b!==t?(N=yge(),N!==t?(r.charCodeAt(Q)===39?(K=ga,Q++):(K=t,I===0&&Qe(dA)),K!==t?(Me=m,b=cg(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function dge(){var m,b,N,K;return m=Q,r.charCodeAt(Q)===39?(b=ga,Q++):(b=t,I===0&&Qe(dA)),b!==t?(N=Ege(),N!==t?(r.charCodeAt(Q)===39?(K=ga,Q++):(K=t,I===0&&Qe(dA)),K!==t?(Me=m,b=cg(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function Cge(){var m,b,N,K;if(m=Q,r.substr(Q,2)===is?(b=is,Q+=2):(b=t,I===0&&Qe(CA)),b!==t&&(Me=m,b=fa()),m=b,m===t)if(m=Q,r.charCodeAt(Q)===34?(b=wp,Q++):(b=t,I===0&&Qe(mA)),b!==t){for(N=[],K=W1();K!==t;)N.push(K),K=W1();N!==t?(r.charCodeAt(Q)===34?(K=wp,Q++):(K=t,I===0&&Qe(mA)),K!==t?(Me=m,b=EA(N),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;return m}function mge(){var m,b,N;if(m=Q,b=[],N=z1(),N!==t)for(;N!==t;)b.push(N),N=z1();else b=t;return b!==t&&(Me=m,b=EA(b)),m=b,m}function W1(){var m,b;return m=Q,b=_1(),b!==t&&(Me=m,b=wr(b)),m=b,m===t&&(m=Q,b=$1(),b!==t&&(Me=m,b=Ll(b)),m=b,m===t&&(m=Q,b=aS(),b!==t&&(Me=m,b=ug(b)),m=b,m===t&&(m=Q,b=Ige(),b!==t&&(Me=m,b=Io(b)),m=b))),m}function z1(){var m,b;return m=Q,b=_1(),b!==t&&(Me=m,b=gg(b)),m=b,m===t&&(m=Q,b=$1(),b!==t&&(Me=m,b=Bp(b)),m=b,m===t&&(m=Q,b=aS(),b!==t&&(Me=m,b=Qp(b)),m=b,m===t&&(m=Q,b=Qge(),b!==t&&(Me=m,b=vr(b)),m=b,m===t&&(m=Q,b=Bge(),b!==t&&(Me=m,b=Io(b)),m=b)))),m}function Ege(){var m,b,N;for(m=Q,b=[],se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(yo));N!==t;)b.push(N),se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(yo));return b!==t&&(Me=m,b=Rn(b)),m=b,m}function Ige(){var m,b,N;if(m=Q,b=[],N=V1(),N===t&&(fg.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Qt))),N!==t)for(;N!==t;)b.push(N),N=V1(),N===t&&(fg.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Qt)));else b=t;return b!==t&&(Me=m,b=Rn(b)),m=b,m}function V1(){var m,b,N;return m=Q,r.substr(Q,2)===Tl?(b=Tl,Q+=2):(b=t,I===0&&Qe(Fn)),b!==t&&(Me=m,b=ns()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=ss,Q++):(b=t,I===0&&Qe(gt)),b!==t?(wo.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(At)),N!==t?(Me=m,b=An(N),m=b):(Q=m,m=t)):(Q=m,m=t)),m}function yge(){var m,b,N;for(m=Q,b=[],N=X1(),N===t&&(se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(yo)));N!==t;)b.push(N),N=X1(),N===t&&(se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(yo)));return b!==t&&(Me=m,b=Rn(b)),m=b,m}function X1(){var m,b,N;return m=Q,r.substr(Q,2)===S?(b=S,Q+=2):(b=t,I===0&&Qe(Tt)),b!==t&&(Me=m,b=hg()),m=b,m===t&&(m=Q,r.substr(Q,2)===Ol?(b=Ol,Q+=2):(b=t,I===0&&Qe(bp)),b!==t&&(Me=m,b=Sp()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=ss,Q++):(b=t,I===0&&Qe(gt)),b!==t?(vp.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(xp)),N!==t?(Me=m,b=Pp(),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===G?(b=G,Q+=2):(b=t,I===0&&Qe(yt)),b!==t&&(Me=m,b=IA()),m=b,m===t&&(m=Q,r.substr(Q,2)===Wi?(b=Wi,Q+=2):(b=t,I===0&&Qe(Ml)),b!==t&&(Me=m,b=Xe()),m=b,m===t&&(m=Q,r.substr(Q,2)===ha?(b=ha,Q+=2):(b=t,I===0&&Qe(pg)),b!==t&&(Me=m,b=OE()),m=b,m===t&&(m=Q,r.substr(Q,2)===Dp?(b=Dp,Q+=2):(b=t,I===0&&Qe(ME)),b!==t&&(Me=m,b=ar()),m=b,m===t&&(m=Q,r.substr(Q,2)===Nn?(b=Nn,Q+=2):(b=t,I===0&&Qe(Ul)),b!==t&&(Me=m,b=kp()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=ss,Q++):(b=t,I===0&&Qe(gt)),b!==t?(Ks.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(pa)),N!==t?(Me=m,b=An(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=wge()))))))))),m}function wge(){var m,b,N,K,ce,Se,ht,Bt,Jr,hi,as,AS;return m=Q,r.charCodeAt(Q)===92?(b=ss,Q++):(b=t,I===0&&Qe(gt)),b!==t?(N=nS(),N!==t?(Me=m,b=ln(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Te?(b=Te,Q+=2):(b=t,I===0&&Qe(dg)),b!==t?(N=Q,K=Q,ce=nS(),ce!==t?(Se=On(),Se!==t?(ce=[ce,Se],K=ce):(Q=K,K=t)):(Q=K,K=t),K===t&&(K=nS()),K!==t?N=r.substring(N,Q):N=K,N!==t?(Me=m,b=ln(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Kl?(b=Kl,Q+=2):(b=t,I===0&&Qe(Hs)),b!==t?(N=Q,K=Q,ce=On(),ce!==t?(Se=On(),Se!==t?(ht=On(),ht!==t?(Bt=On(),Bt!==t?(ce=[ce,Se,ht,Bt],K=ce):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t),K!==t?N=r.substring(N,Q):N=K,N!==t?(Me=m,b=ln(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Hl?(b=Hl,Q+=2):(b=t,I===0&&Qe(yA)),b!==t?(N=Q,K=Q,ce=On(),ce!==t?(Se=On(),Se!==t?(ht=On(),ht!==t?(Bt=On(),Bt!==t?(Jr=On(),Jr!==t?(hi=On(),hi!==t?(as=On(),as!==t?(AS=On(),AS!==t?(ce=[ce,Se,ht,Bt,Jr,hi,as,AS],K=ce):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t),K!==t?N=r.substring(N,Q):N=K,N!==t?(Me=m,b=Cg(N),m=b):(Q=m,m=t)):(Q=m,m=t)))),m}function nS(){var m;return mg.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(da)),m}function On(){var m;return Ca.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(rt)),m}function Bge(){var m,b,N,K,ce;if(m=Q,b=[],N=Q,r.charCodeAt(Q)===92?(K=ss,Q++):(K=t,I===0&&Qe(gt)),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t),N===t&&(N=Q,K=Q,I++,ce=tU(),I--,ce===t?K=void 0:(Q=K,K=t),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t)),N!==t)for(;N!==t;)b.push(N),N=Q,r.charCodeAt(Q)===92?(K=ss,Q++):(K=t,I===0&&Qe(gt)),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t),N===t&&(N=Q,K=Q,I++,ce=tU(),I--,ce===t?K=void 0:(Q=K,K=t),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t));else b=t;return b!==t&&(Me=m,b=Rn(b)),m=b,m}function sS(){var m,b,N,K,ce,Se;if(m=Q,r.charCodeAt(Q)===45?(b=wA,Q++):(b=t,I===0&&Qe(Gl)),b===t&&(r.charCodeAt(Q)===43?(b=Gs,Q++):(b=t,I===0&&Qe(Yl))),b===t&&(b=null),b!==t){if(N=[],qe.test(r.charAt(Q))?(K=r.charAt(Q),Q++):(K=t,I===0&&Qe(ne)),K!==t)for(;K!==t;)N.push(K),qe.test(r.charAt(Q))?(K=r.charAt(Q),Q++):(K=t,I===0&&Qe(ne));else N=t;if(N!==t)if(r.charCodeAt(Q)===46?(K=UE,Q++):(K=t,I===0&&Qe(Rp)),K!==t){if(ce=[],qe.test(r.charAt(Q))?(Se=r.charAt(Q),Q++):(Se=t,I===0&&Qe(ne)),Se!==t)for(;Se!==t;)ce.push(Se),qe.test(r.charAt(Q))?(Se=r.charAt(Q),Q++):(Se=t,I===0&&Qe(ne));else ce=t;ce!==t?(Me=m,b=Eg(b,N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;if(m===t){if(m=Q,r.charCodeAt(Q)===45?(b=wA,Q++):(b=t,I===0&&Qe(Gl)),b===t&&(r.charCodeAt(Q)===43?(b=Gs,Q++):(b=t,I===0&&Qe(Yl))),b===t&&(b=null),b!==t){if(N=[],qe.test(r.charAt(Q))?(K=r.charAt(Q),Q++):(K=t,I===0&&Qe(ne)),K!==t)for(;K!==t;)N.push(K),qe.test(r.charAt(Q))?(K=r.charAt(Q),Q++):(K=t,I===0&&Qe(ne));else N=t;N!==t?(Me=m,b=Fp(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;if(m===t&&(m=Q,b=aS(),b!==t&&(Me=m,b=KE(b)),m=b,m===t&&(m=Q,b=ql(),b!==t&&(Me=m,b=jl(b)),m=b,m===t)))if(m=Q,r.charCodeAt(Q)===40?(b=ge,Q++):(b=t,I===0&&Qe(re)),b!==t){for(N=[],K=He();K!==t;)N.push(K),K=He();if(N!==t)if(K=Z1(),K!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(r.charCodeAt(Q)===41?(Se=O,Q++):(Se=t,I===0&&Qe(F)),Se!==t?(Me=m,b=HE(K),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t}return m}function oS(){var m,b,N,K,ce,Se,ht,Bt;if(m=Q,b=sS(),b!==t){for(N=[],K=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===42?(Se=Ig,Q++):(Se=t,I===0&&Qe(BA)),Se===t&&(r.charCodeAt(Q)===47?(Se=Rr,Q++):(Se=t,I===0&&Qe(GE))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=sS(),Bt!==t?(Me=K,ce=Ys(b,Se,Bt),K=ce):(Q=K,K=t)):(Q=K,K=t)}else Q=K,K=t;else Q=K,K=t;for(;K!==t;){for(N.push(K),K=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===42?(Se=Ig,Q++):(Se=t,I===0&&Qe(BA)),Se===t&&(r.charCodeAt(Q)===47?(Se=Rr,Q++):(Se=t,I===0&&Qe(GE))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=sS(),Bt!==t?(Me=K,ce=Ys(b,Se,Bt),K=ce):(Q=K,K=t)):(Q=K,K=t)}else Q=K,K=t;else Q=K,K=t}N!==t?(Me=m,b=js(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;return m}function Z1(){var m,b,N,K,ce,Se,ht,Bt;if(m=Q,b=oS(),b!==t){for(N=[],K=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===43?(Se=Gs,Q++):(Se=t,I===0&&Qe(Yl)),Se===t&&(r.charCodeAt(Q)===45?(Se=wA,Q++):(Se=t,I===0&&Qe(Gl))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=oS(),Bt!==t?(Me=K,ce=yg(b,Se,Bt),K=ce):(Q=K,K=t)):(Q=K,K=t)}else Q=K,K=t;else Q=K,K=t;for(;K!==t;){for(N.push(K),K=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===43?(Se=Gs,Q++):(Se=t,I===0&&Qe(Yl)),Se===t&&(r.charCodeAt(Q)===45?(Se=wA,Q++):(Se=t,I===0&&Qe(Gl))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=oS(),Bt!==t?(Me=K,ce=yg(b,Se,Bt),K=ce):(Q=K,K=t)):(Q=K,K=t)}else Q=K,K=t;else Q=K,K=t}N!==t?(Me=m,b=js(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;return m}function _1(){var m,b,N,K,ce,Se;if(m=Q,r.substr(Q,3)===QA?(b=QA,Q+=3):(b=t,I===0&&Qe(R)),b!==t){for(N=[],K=He();K!==t;)N.push(K),K=He();if(N!==t)if(K=Z1(),K!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(r.substr(Q,2)===q?(Se=q,Q+=2):(Se=t,I===0&&Qe(Ce)),Se!==t?(Me=m,b=Ue(K),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;return m}function $1(){var m,b,N,K;return m=Q,r.substr(Q,2)===Re?(b=Re,Q+=2):(b=t,I===0&&Qe(ze)),b!==t?(N=Mr(),N!==t?(r.charCodeAt(Q)===41?(K=O,Q++):(K=t,I===0&&Qe(F)),K!==t?(Me=m,b=dt(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function aS(){var m,b,N,K,ce,Se;return m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.substr(Q,2)===Jb?(K=Jb,Q+=2):(K=t,I===0&&Qe(P1)),K!==t?(ce=Y1(),ce!==t?(r.charCodeAt(Q)===125?(Se=Fe,Q++):(Se=t,I===0&&Qe(Ne)),Se!==t?(Me=m,b=D1(N,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.substr(Q,3)===Wb?(K=Wb,Q+=3):(K=t,I===0&&Qe(k1)),K!==t?(Me=m,b=R1(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.substr(Q,2)===zb?(K=zb,Q+=2):(K=t,I===0&&Qe(F1)),K!==t?(ce=Y1(),ce!==t?(r.charCodeAt(Q)===125?(Se=Fe,Q++):(Se=t,I===0&&Qe(Ne)),Se!==t?(Me=m,b=N1(N,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.substr(Q,3)===Vb?(K=Vb,Q+=3):(K=t,I===0&&Qe(L1)),K!==t?(Me=m,b=T1(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.charCodeAt(Q)===125?(K=Fe,Q++):(K=t,I===0&&Qe(Ne)),K!==t?(Me=m,b=Xb(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.charCodeAt(Q)===36?(b=O1,Q++):(b=t,I===0&&Qe(M1)),b!==t?(N=ql(),N!==t?(Me=m,b=Xb(N),m=b):(Q=m,m=t)):(Q=m,m=t)))))),m}function Qge(){var m,b,N;return m=Q,b=bge(),b!==t?(Me=Q,N=U1(b),N?N=void 0:N=t,N!==t?(Me=m,b=K1(b),m=b):(Q=m,m=t)):(Q=m,m=t),m}function bge(){var m,b,N,K,ce;if(m=Q,b=[],N=Q,K=Q,I++,ce=rU(),I--,ce===t?K=void 0:(Q=K,K=t),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t),N!==t)for(;N!==t;)b.push(N),N=Q,K=Q,I++,ce=rU(),I--,ce===t?K=void 0:(Q=K,K=t),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t);else b=t;return b!==t&&(Me=m,b=Rn(b)),m=b,m}function eU(){var m,b,N;if(m=Q,b=[],Zb.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(_b)),N!==t)for(;N!==t;)b.push(N),Zb.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(_b));else b=t;return b!==t&&(Me=m,b=$b()),m=b,m}function ql(){var m,b,N;if(m=Q,b=[],eS.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(tS)),N!==t)for(;N!==t;)b.push(N),eS.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(tS));else b=t;return b!==t&&(Me=m,b=$b()),m=b,m}function tU(){var m;return H1.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(wg)),m}function rU(){var m;return rS.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(iS)),m}function He(){var m,b;if(m=[],YE.test(r.charAt(Q))?(b=r.charAt(Q),Q++):(b=t,I===0&&Qe(jE)),b!==t)for(;b!==t;)m.push(b),YE.test(r.charAt(Q))?(b=r.charAt(Q),Q++):(b=t,I===0&&Qe(jE));else m=t;return m}if(k=n(),k!==t&&Q===r.length)return k;throw k!==t&&Q{"use strict";function Sfe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function $l(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,$l)}Sfe($l,Error);$l.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;gH&&(H=v,j=[]),j.push(ne))}function Ne(ne,Y){return new $l(ne,null,null,Y)}function oe(ne,Y,he){return new $l($l.buildMessage(ne,Y),ne,Y,he)}function le(){var ne,Y,he,ie;return ne=v,Y=Be(),Y!==t?(r.charCodeAt(v)===47?(he=s,v++):(he=t,$===0&&Fe(o)),he!==t?(ie=Be(),ie!==t?(D=ne,Y=a(Y,ie),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=Be(),Y!==t&&(D=ne,Y=l(Y)),ne=Y),ne}function Be(){var ne,Y,he,ie;return ne=v,Y=fe(),Y!==t?(r.charCodeAt(v)===64?(he=c,v++):(he=t,$===0&&Fe(u)),he!==t?(ie=qe(),ie!==t?(D=ne,Y=g(Y,ie),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=fe(),Y!==t&&(D=ne,Y=f(Y)),ne=Y),ne}function fe(){var ne,Y,he,ie,de;return ne=v,r.charCodeAt(v)===64?(Y=c,v++):(Y=t,$===0&&Fe(u)),Y!==t?(he=ae(),he!==t?(r.charCodeAt(v)===47?(ie=s,v++):(ie=t,$===0&&Fe(o)),ie!==t?(de=ae(),de!==t?(D=ne,Y=h(),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=ae(),Y!==t&&(D=ne,Y=h()),ne=Y),ne}function ae(){var ne,Y,he;if(ne=v,Y=[],p.test(r.charAt(v))?(he=r.charAt(v),v++):(he=t,$===0&&Fe(C)),he!==t)for(;he!==t;)Y.push(he),p.test(r.charAt(v))?(he=r.charAt(v),v++):(he=t,$===0&&Fe(C));else Y=t;return Y!==t&&(D=ne,Y=h()),ne=Y,ne}function qe(){var ne,Y,he;if(ne=v,Y=[],y.test(r.charAt(v))?(he=r.charAt(v),v++):(he=t,$===0&&Fe(B)),he!==t)for(;he!==t;)Y.push(he),y.test(r.charAt(v))?(he=r.charAt(v),v++):(he=t,$===0&&Fe(B));else Y=t;return Y!==t&&(D=ne,Y=h()),ne=Y,ne}if(V=n(),V!==t&&v===r.length)return V;throw V!==t&&v{"use strict";function dK(r){return typeof r>"u"||r===null}function xfe(r){return typeof r=="object"&&r!==null}function Pfe(r){return Array.isArray(r)?r:dK(r)?[]:[r]}function Dfe(r,e){var t,i,n,s;if(e)for(s=Object.keys(e),t=0,i=s.length;t{"use strict";function Vp(r,e){Error.call(this),this.name="YAMLException",this.reason=r,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}Vp.prototype=Object.create(Error.prototype);Vp.prototype.constructor=Vp;Vp.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t};CK.exports=Vp});var IK=w((wZe,EK)=>{"use strict";var mK=tc();function HS(r,e,t,i,n){this.name=r,this.buffer=e,this.position=t,this.line=i,this.column=n}HS.prototype.getSnippet=function(e,t){var i,n,s,o,a;if(!this.buffer)return null;for(e=e||4,t=t||75,i="",n=this.position;n>0&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(n-1))===-1;)if(n-=1,this.position-n>t/2-1){i=" ... ",n+=5;break}for(s="",o=this.position;ot/2-1){s=" ... ",o-=5;break}return a=this.buffer.slice(n,o),mK.repeat(" ",e)+i+a+s+` +`+mK.repeat(" ",e+this.position-n+i.length)+"^"};HS.prototype.toString=function(e){var t,i="";return this.name&&(i+='in "'+this.name+'" '),i+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(i+=`: +`+t)),i};EK.exports=HS});var si=w((BZe,wK)=>{"use strict";var yK=Ng(),Ffe=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],Nfe=["scalar","sequence","mapping"];function Lfe(r){var e={};return r!==null&&Object.keys(r).forEach(function(t){r[t].forEach(function(i){e[String(i)]=t})}),e}function Tfe(r,e){if(e=e||{},Object.keys(e).forEach(function(t){if(Ffe.indexOf(t)===-1)throw new yK('Unknown option "'+t+'" is met in definition of "'+r+'" YAML type.')}),this.tag=r,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=Lfe(e.styleAliases||null),Nfe.indexOf(this.kind)===-1)throw new yK('Unknown kind "'+this.kind+'" is specified for "'+r+'" YAML type.')}wK.exports=Tfe});var rc=w((QZe,QK)=>{"use strict";var BK=tc(),dI=Ng(),Ofe=si();function GS(r,e,t){var i=[];return r.include.forEach(function(n){t=GS(n,e,t)}),r[e].forEach(function(n){t.forEach(function(s,o){s.tag===n.tag&&s.kind===n.kind&&i.push(o)}),t.push(n)}),t.filter(function(n,s){return i.indexOf(s)===-1})}function Mfe(){var r={scalar:{},sequence:{},mapping:{},fallback:{}},e,t;function i(n){r[n.kind][n.tag]=r.fallback[n.tag]=n}for(e=0,t=arguments.length;e{"use strict";var Ufe=si();bK.exports=new Ufe("tag:yaml.org,2002:str",{kind:"scalar",construct:function(r){return r!==null?r:""}})});var xK=w((SZe,vK)=>{"use strict";var Kfe=si();vK.exports=new Kfe("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(r){return r!==null?r:[]}})});var DK=w((vZe,PK)=>{"use strict";var Hfe=si();PK.exports=new Hfe("tag:yaml.org,2002:map",{kind:"mapping",construct:function(r){return r!==null?r:{}}})});var CI=w((xZe,kK)=>{"use strict";var Gfe=rc();kK.exports=new Gfe({explicit:[SK(),xK(),DK()]})});var FK=w((PZe,RK)=>{"use strict";var Yfe=si();function jfe(r){if(r===null)return!0;var e=r.length;return e===1&&r==="~"||e===4&&(r==="null"||r==="Null"||r==="NULL")}function qfe(){return null}function Jfe(r){return r===null}RK.exports=new Yfe("tag:yaml.org,2002:null",{kind:"scalar",resolve:jfe,construct:qfe,predicate:Jfe,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var LK=w((DZe,NK)=>{"use strict";var Wfe=si();function zfe(r){if(r===null)return!1;var e=r.length;return e===4&&(r==="true"||r==="True"||r==="TRUE")||e===5&&(r==="false"||r==="False"||r==="FALSE")}function Vfe(r){return r==="true"||r==="True"||r==="TRUE"}function Xfe(r){return Object.prototype.toString.call(r)==="[object Boolean]"}NK.exports=new Wfe("tag:yaml.org,2002:bool",{kind:"scalar",resolve:zfe,construct:Vfe,predicate:Xfe,represent:{lowercase:function(r){return r?"true":"false"},uppercase:function(r){return r?"TRUE":"FALSE"},camelcase:function(r){return r?"True":"False"}},defaultStyle:"lowercase"})});var OK=w((kZe,TK)=>{"use strict";var Zfe=tc(),_fe=si();function $fe(r){return 48<=r&&r<=57||65<=r&&r<=70||97<=r&&r<=102}function ehe(r){return 48<=r&&r<=55}function the(r){return 48<=r&&r<=57}function rhe(r){if(r===null)return!1;var e=r.length,t=0,i=!1,n;if(!e)return!1;if(n=r[t],(n==="-"||n==="+")&&(n=r[++t]),n==="0"){if(t+1===e)return!0;if(n=r[++t],n==="b"){for(t++;t=0?"0b"+r.toString(2):"-0b"+r.toString(2).slice(1)},octal:function(r){return r>=0?"0"+r.toString(8):"-0"+r.toString(8).slice(1)},decimal:function(r){return r.toString(10)},hexadecimal:function(r){return r>=0?"0x"+r.toString(16).toUpperCase():"-0x"+r.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var KK=w((RZe,UK)=>{"use strict";var MK=tc(),she=si(),ohe=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function ahe(r){return!(r===null||!ohe.test(r)||r[r.length-1]==="_")}function Ahe(r){var e,t,i,n;return e=r.replace(/_/g,"").toLowerCase(),t=e[0]==="-"?-1:1,n=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?t===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:e.indexOf(":")>=0?(e.split(":").forEach(function(s){n.unshift(parseFloat(s,10))}),e=0,i=1,n.forEach(function(s){e+=s*i,i*=60}),t*e):t*parseFloat(e,10)}var lhe=/^[-+]?[0-9]+e/;function che(r,e){var t;if(isNaN(r))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===r)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===r)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(MK.isNegativeZero(r))return"-0.0";return t=r.toString(10),lhe.test(t)?t.replace("e",".e"):t}function uhe(r){return Object.prototype.toString.call(r)==="[object Number]"&&(r%1!==0||MK.isNegativeZero(r))}UK.exports=new she("tag:yaml.org,2002:float",{kind:"scalar",resolve:ahe,construct:Ahe,predicate:uhe,represent:che,defaultStyle:"lowercase"})});var YS=w((FZe,HK)=>{"use strict";var ghe=rc();HK.exports=new ghe({include:[CI()],implicit:[FK(),LK(),OK(),KK()]})});var jS=w((NZe,GK)=>{"use strict";var fhe=rc();GK.exports=new fhe({include:[YS()]})});var JK=w((LZe,qK)=>{"use strict";var hhe=si(),YK=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),jK=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function phe(r){return r===null?!1:YK.exec(r)!==null||jK.exec(r)!==null}function dhe(r){var e,t,i,n,s,o,a,l=0,c=null,u,g,f;if(e=YK.exec(r),e===null&&(e=jK.exec(r)),e===null)throw new Error("Date resolve error");if(t=+e[1],i=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(t,i,n));if(s=+e[4],o=+e[5],a=+e[6],e[7]){for(l=e[7].slice(0,3);l.length<3;)l+="0";l=+l}return e[9]&&(u=+e[10],g=+(e[11]||0),c=(u*60+g)*6e4,e[9]==="-"&&(c=-c)),f=new Date(Date.UTC(t,i,n,s,o,a,l)),c&&f.setTime(f.getTime()-c),f}function Che(r){return r.toISOString()}qK.exports=new hhe("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:phe,construct:dhe,instanceOf:Date,represent:Che})});var zK=w((TZe,WK)=>{"use strict";var mhe=si();function Ehe(r){return r==="<<"||r===null}WK.exports=new mhe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:Ehe})});var ZK=w((OZe,XK)=>{"use strict";var ic;try{VK=J,ic=VK("buffer").Buffer}catch{}var VK,Ihe=si(),qS=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function yhe(r){if(r===null)return!1;var e,t,i=0,n=r.length,s=qS;for(t=0;t64)){if(e<0)return!1;i+=6}return i%8===0}function whe(r){var e,t,i=r.replace(/[\r\n=]/g,""),n=i.length,s=qS,o=0,a=[];for(e=0;e>16&255),a.push(o>>8&255),a.push(o&255)),o=o<<6|s.indexOf(i.charAt(e));return t=n%4*6,t===0?(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)):t===18?(a.push(o>>10&255),a.push(o>>2&255)):t===12&&a.push(o>>4&255),ic?ic.from?ic.from(a):new ic(a):a}function Bhe(r){var e="",t=0,i,n,s=r.length,o=qS;for(i=0;i>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]),t=(t<<8)+r[i];return n=s%3,n===0?(e+=o[t>>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]):n===2?(e+=o[t>>10&63],e+=o[t>>4&63],e+=o[t<<2&63],e+=o[64]):n===1&&(e+=o[t>>2&63],e+=o[t<<4&63],e+=o[64],e+=o[64]),e}function Qhe(r){return ic&&ic.isBuffer(r)}XK.exports=new Ihe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:yhe,construct:whe,predicate:Qhe,represent:Bhe})});var $K=w((UZe,_K)=>{"use strict";var bhe=si(),She=Object.prototype.hasOwnProperty,vhe=Object.prototype.toString;function xhe(r){if(r===null)return!0;var e=[],t,i,n,s,o,a=r;for(t=0,i=a.length;t{"use strict";var Dhe=si(),khe=Object.prototype.toString;function Rhe(r){if(r===null)return!0;var e,t,i,n,s,o=r;for(s=new Array(o.length),e=0,t=o.length;e{"use strict";var Nhe=si(),Lhe=Object.prototype.hasOwnProperty;function The(r){if(r===null)return!0;var e,t=r;for(e in t)if(Lhe.call(t,e)&&t[e]!==null)return!1;return!0}function Ohe(r){return r!==null?r:{}}r2.exports=new Nhe("tag:yaml.org,2002:set",{kind:"mapping",resolve:The,construct:Ohe})});var Tg=w((GZe,n2)=>{"use strict";var Mhe=rc();n2.exports=new Mhe({include:[jS()],implicit:[JK(),zK()],explicit:[ZK(),$K(),t2(),i2()]})});var o2=w((YZe,s2)=>{"use strict";var Uhe=si();function Khe(){return!0}function Hhe(){}function Ghe(){return""}function Yhe(r){return typeof r>"u"}s2.exports=new Uhe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:Khe,construct:Hhe,predicate:Yhe,represent:Ghe})});var A2=w((jZe,a2)=>{"use strict";var jhe=si();function qhe(r){if(r===null||r.length===0)return!1;var e=r,t=/\/([gim]*)$/.exec(r),i="";return!(e[0]==="/"&&(t&&(i=t[1]),i.length>3||e[e.length-i.length-1]!=="/"))}function Jhe(r){var e=r,t=/\/([gim]*)$/.exec(r),i="";return e[0]==="/"&&(t&&(i=t[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function Whe(r){var e="/"+r.source+"/";return r.global&&(e+="g"),r.multiline&&(e+="m"),r.ignoreCase&&(e+="i"),e}function zhe(r){return Object.prototype.toString.call(r)==="[object RegExp]"}a2.exports=new jhe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:qhe,construct:Jhe,predicate:zhe,represent:Whe})});var u2=w((qZe,c2)=>{"use strict";var mI;try{l2=J,mI=l2("esprima")}catch{typeof window<"u"&&(mI=window.esprima)}var l2,Vhe=si();function Xhe(r){if(r===null)return!1;try{var e="("+r+")",t=mI.parse(e,{range:!0});return!(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")}catch{return!1}}function Zhe(r){var e="("+r+")",t=mI.parse(e,{range:!0}),i=[],n;if(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return t.body[0].expression.params.forEach(function(s){i.push(s.name)}),n=t.body[0].expression.body.range,t.body[0].expression.body.type==="BlockStatement"?new Function(i,e.slice(n[0]+1,n[1]-1)):new Function(i,"return "+e.slice(n[0],n[1]))}function _he(r){return r.toString()}function $he(r){return Object.prototype.toString.call(r)==="[object Function]"}c2.exports=new Vhe("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:Xhe,construct:Zhe,predicate:$he,represent:_he})});var Xp=w((WZe,f2)=>{"use strict";var g2=rc();f2.exports=g2.DEFAULT=new g2({include:[Tg()],explicit:[o2(),A2(),u2()]})});var R2=w((zZe,Zp)=>{"use strict";var wa=tc(),I2=Ng(),epe=IK(),y2=Tg(),tpe=Xp(),kA=Object.prototype.hasOwnProperty,EI=1,w2=2,B2=3,II=4,JS=1,rpe=2,h2=3,ipe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,npe=/[\x85\u2028\u2029]/,spe=/[,\[\]\{\}]/,Q2=/^(?:!|!!|![a-z\-]+!)$/i,b2=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function p2(r){return Object.prototype.toString.call(r)}function vo(r){return r===10||r===13}function sc(r){return r===9||r===32}function gn(r){return r===9||r===32||r===10||r===13}function Og(r){return r===44||r===91||r===93||r===123||r===125}function ope(r){var e;return 48<=r&&r<=57?r-48:(e=r|32,97<=e&&e<=102?e-97+10:-1)}function ape(r){return r===120?2:r===117?4:r===85?8:0}function Ape(r){return 48<=r&&r<=57?r-48:-1}function d2(r){return r===48?"\0":r===97?"\x07":r===98?"\b":r===116||r===9?" ":r===110?` +`:r===118?"\v":r===102?"\f":r===114?"\r":r===101?"\x1B":r===32?" ":r===34?'"':r===47?"/":r===92?"\\":r===78?"\x85":r===95?"\xA0":r===76?"\u2028":r===80?"\u2029":""}function lpe(r){return r<=65535?String.fromCharCode(r):String.fromCharCode((r-65536>>10)+55296,(r-65536&1023)+56320)}var S2=new Array(256),v2=new Array(256);for(nc=0;nc<256;nc++)S2[nc]=d2(nc)?1:0,v2[nc]=d2(nc);var nc;function cpe(r,e){this.input=r,this.filename=e.filename||null,this.schema=e.schema||tpe,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=r.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function x2(r,e){return new I2(e,new epe(r.filename,r.input,r.position,r.line,r.position-r.lineStart))}function ft(r,e){throw x2(r,e)}function yI(r,e){r.onWarning&&r.onWarning.call(null,x2(r,e))}var C2={YAML:function(e,t,i){var n,s,o;e.version!==null&&ft(e,"duplication of %YAML directive"),i.length!==1&&ft(e,"YAML directive accepts exactly one argument"),n=/^([0-9]+)\.([0-9]+)$/.exec(i[0]),n===null&&ft(e,"ill-formed argument of the YAML directive"),s=parseInt(n[1],10),o=parseInt(n[2],10),s!==1&&ft(e,"unacceptable YAML version of the document"),e.version=i[0],e.checkLineBreaks=o<2,o!==1&&o!==2&&yI(e,"unsupported YAML version of the document")},TAG:function(e,t,i){var n,s;i.length!==2&&ft(e,"TAG directive accepts exactly two arguments"),n=i[0],s=i[1],Q2.test(n)||ft(e,"ill-formed tag handle (first argument) of the TAG directive"),kA.call(e.tagMap,n)&&ft(e,'there is a previously declared suffix for "'+n+'" tag handle'),b2.test(s)||ft(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[n]=s}};function DA(r,e,t,i){var n,s,o,a;if(e1&&(r.result+=wa.repeat(` +`,e-1))}function upe(r,e,t){var i,n,s,o,a,l,c,u,g=r.kind,f=r.result,h;if(h=r.input.charCodeAt(r.position),gn(h)||Og(h)||h===35||h===38||h===42||h===33||h===124||h===62||h===39||h===34||h===37||h===64||h===96||(h===63||h===45)&&(n=r.input.charCodeAt(r.position+1),gn(n)||t&&Og(n)))return!1;for(r.kind="scalar",r.result="",s=o=r.position,a=!1;h!==0;){if(h===58){if(n=r.input.charCodeAt(r.position+1),gn(n)||t&&Og(n))break}else if(h===35){if(i=r.input.charCodeAt(r.position-1),gn(i))break}else{if(r.position===r.lineStart&&wI(r)||t&&Og(h))break;if(vo(h))if(l=r.line,c=r.lineStart,u=r.lineIndent,zr(r,!1,-1),r.lineIndent>=e){a=!0,h=r.input.charCodeAt(r.position);continue}else{r.position=o,r.line=l,r.lineStart=c,r.lineIndent=u;break}}a&&(DA(r,s,o,!1),zS(r,r.line-l),s=o=r.position,a=!1),sc(h)||(o=r.position+1),h=r.input.charCodeAt(++r.position)}return DA(r,s,o,!1),r.result?!0:(r.kind=g,r.result=f,!1)}function gpe(r,e){var t,i,n;if(t=r.input.charCodeAt(r.position),t!==39)return!1;for(r.kind="scalar",r.result="",r.position++,i=n=r.position;(t=r.input.charCodeAt(r.position))!==0;)if(t===39)if(DA(r,i,r.position,!0),t=r.input.charCodeAt(++r.position),t===39)i=r.position,r.position++,n=r.position;else return!0;else vo(t)?(DA(r,i,n,!0),zS(r,zr(r,!1,e)),i=n=r.position):r.position===r.lineStart&&wI(r)?ft(r,"unexpected end of the document within a single quoted scalar"):(r.position++,n=r.position);ft(r,"unexpected end of the stream within a single quoted scalar")}function fpe(r,e){var t,i,n,s,o,a;if(a=r.input.charCodeAt(r.position),a!==34)return!1;for(r.kind="scalar",r.result="",r.position++,t=i=r.position;(a=r.input.charCodeAt(r.position))!==0;){if(a===34)return DA(r,t,r.position,!0),r.position++,!0;if(a===92){if(DA(r,t,r.position,!0),a=r.input.charCodeAt(++r.position),vo(a))zr(r,!1,e);else if(a<256&&S2[a])r.result+=v2[a],r.position++;else if((o=ape(a))>0){for(n=o,s=0;n>0;n--)a=r.input.charCodeAt(++r.position),(o=ope(a))>=0?s=(s<<4)+o:ft(r,"expected hexadecimal character");r.result+=lpe(s),r.position++}else ft(r,"unknown escape sequence");t=i=r.position}else vo(a)?(DA(r,t,i,!0),zS(r,zr(r,!1,e)),t=i=r.position):r.position===r.lineStart&&wI(r)?ft(r,"unexpected end of the document within a double quoted scalar"):(r.position++,i=r.position)}ft(r,"unexpected end of the stream within a double quoted scalar")}function hpe(r,e){var t=!0,i,n=r.tag,s,o=r.anchor,a,l,c,u,g,f={},h,p,C,y;if(y=r.input.charCodeAt(r.position),y===91)l=93,g=!1,s=[];else if(y===123)l=125,g=!0,s={};else return!1;for(r.anchor!==null&&(r.anchorMap[r.anchor]=s),y=r.input.charCodeAt(++r.position);y!==0;){if(zr(r,!0,e),y=r.input.charCodeAt(r.position),y===l)return r.position++,r.tag=n,r.anchor=o,r.kind=g?"mapping":"sequence",r.result=s,!0;t||ft(r,"missed comma between flow collection entries"),p=h=C=null,c=u=!1,y===63&&(a=r.input.charCodeAt(r.position+1),gn(a)&&(c=u=!0,r.position++,zr(r,!0,e))),i=r.line,Ug(r,e,EI,!1,!0),p=r.tag,h=r.result,zr(r,!0,e),y=r.input.charCodeAt(r.position),(u||r.line===i)&&y===58&&(c=!0,y=r.input.charCodeAt(++r.position),zr(r,!0,e),Ug(r,e,EI,!1,!0),C=r.result),g?Mg(r,s,f,p,h,C):c?s.push(Mg(r,null,f,p,h,C)):s.push(h),zr(r,!0,e),y=r.input.charCodeAt(r.position),y===44?(t=!0,y=r.input.charCodeAt(++r.position)):t=!1}ft(r,"unexpected end of the stream within a flow collection")}function ppe(r,e){var t,i,n=JS,s=!1,o=!1,a=e,l=0,c=!1,u,g;if(g=r.input.charCodeAt(r.position),g===124)i=!1;else if(g===62)i=!0;else return!1;for(r.kind="scalar",r.result="";g!==0;)if(g=r.input.charCodeAt(++r.position),g===43||g===45)JS===n?n=g===43?h2:rpe:ft(r,"repeat of a chomping mode identifier");else if((u=Ape(g))>=0)u===0?ft(r,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?ft(r,"repeat of an indentation width identifier"):(a=e+u-1,o=!0);else break;if(sc(g)){do g=r.input.charCodeAt(++r.position);while(sc(g));if(g===35)do g=r.input.charCodeAt(++r.position);while(!vo(g)&&g!==0)}for(;g!==0;){for(WS(r),r.lineIndent=0,g=r.input.charCodeAt(r.position);(!o||r.lineIndenta&&(a=r.lineIndent),vo(g)){l++;continue}if(r.lineIndente)&&l!==0)ft(r,"bad indentation of a sequence entry");else if(r.lineIndente)&&(Ug(r,e,II,!0,n)&&(p?f=r.result:h=r.result),p||(Mg(r,c,u,g,f,h,s,o),g=f=h=null),zr(r,!0,-1),y=r.input.charCodeAt(r.position)),r.lineIndent>e&&y!==0)ft(r,"bad indentation of a mapping entry");else if(r.lineIndente?l=1:r.lineIndent===e?l=0:r.lineIndente?l=1:r.lineIndent===e?l=0:r.lineIndent tag; it should be "scalar", not "'+r.kind+'"'),g=0,f=r.implicitTypes.length;g tag; it should be "'+h.kind+'", not "'+r.kind+'"'),h.resolve(r.result)?(r.result=h.construct(r.result),r.anchor!==null&&(r.anchorMap[r.anchor]=r.result)):ft(r,"cannot resolve a node with !<"+r.tag+"> explicit tag")):ft(r,"unknown tag !<"+r.tag+">");return r.listener!==null&&r.listener("close",r),r.tag!==null||r.anchor!==null||u}function Ipe(r){var e=r.position,t,i,n,s=!1,o;for(r.version=null,r.checkLineBreaks=r.legacy,r.tagMap={},r.anchorMap={};(o=r.input.charCodeAt(r.position))!==0&&(zr(r,!0,-1),o=r.input.charCodeAt(r.position),!(r.lineIndent>0||o!==37));){for(s=!0,o=r.input.charCodeAt(++r.position),t=r.position;o!==0&&!gn(o);)o=r.input.charCodeAt(++r.position);for(i=r.input.slice(t,r.position),n=[],i.length<1&&ft(r,"directive name must not be less than one character in length");o!==0;){for(;sc(o);)o=r.input.charCodeAt(++r.position);if(o===35){do o=r.input.charCodeAt(++r.position);while(o!==0&&!vo(o));break}if(vo(o))break;for(t=r.position;o!==0&&!gn(o);)o=r.input.charCodeAt(++r.position);n.push(r.input.slice(t,r.position))}o!==0&&WS(r),kA.call(C2,i)?C2[i](r,i,n):yI(r,'unknown document directive "'+i+'"')}if(zr(r,!0,-1),r.lineIndent===0&&r.input.charCodeAt(r.position)===45&&r.input.charCodeAt(r.position+1)===45&&r.input.charCodeAt(r.position+2)===45?(r.position+=3,zr(r,!0,-1)):s&&ft(r,"directives end mark is expected"),Ug(r,r.lineIndent-1,II,!1,!0),zr(r,!0,-1),r.checkLineBreaks&&npe.test(r.input.slice(e,r.position))&&yI(r,"non-ASCII line breaks are interpreted as content"),r.documents.push(r.result),r.position===r.lineStart&&wI(r)){r.input.charCodeAt(r.position)===46&&(r.position+=3,zr(r,!0,-1));return}if(r.position"u"&&(t=e,e=null);var i=P2(r,t);if(typeof e!="function")return i;for(var n=0,s=i.length;n"u"&&(t=e,e=null),D2(r,e,wa.extend({schema:y2},t))}function wpe(r,e){return k2(r,wa.extend({schema:y2},e))}Zp.exports.loadAll=D2;Zp.exports.load=k2;Zp.exports.safeLoadAll=ype;Zp.exports.safeLoad=wpe});var tH=w((VZe,_S)=>{"use strict";var $p=tc(),ed=Ng(),Bpe=Xp(),Qpe=Tg(),K2=Object.prototype.toString,H2=Object.prototype.hasOwnProperty,bpe=9,_p=10,Spe=13,vpe=32,xpe=33,Ppe=34,G2=35,Dpe=37,kpe=38,Rpe=39,Fpe=42,Y2=44,Npe=45,j2=58,Lpe=61,Tpe=62,Ope=63,Mpe=64,q2=91,J2=93,Upe=96,W2=123,Kpe=124,z2=125,Ni={};Ni[0]="\\0";Ni[7]="\\a";Ni[8]="\\b";Ni[9]="\\t";Ni[10]="\\n";Ni[11]="\\v";Ni[12]="\\f";Ni[13]="\\r";Ni[27]="\\e";Ni[34]='\\"';Ni[92]="\\\\";Ni[133]="\\N";Ni[160]="\\_";Ni[8232]="\\L";Ni[8233]="\\P";var Hpe=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function Gpe(r,e){var t,i,n,s,o,a,l;if(e===null)return{};for(t={},i=Object.keys(e),n=0,s=i.length;n0?r.charCodeAt(s-1):null,f=f&&L2(o,a)}else{for(s=0;si&&r[g+1]!==" ",g=s);else if(!Kg(o))return BI;a=s>0?r.charCodeAt(s-1):null,f=f&&L2(o,a)}c=c||u&&s-g-1>i&&r[g+1]!==" "}return!l&&!c?f&&!n(r)?X2:Z2:t>9&&V2(r)?BI:c?$2:_2}function zpe(r,e,t,i){r.dump=function(){if(e.length===0)return"''";if(!r.noCompatMode&&Hpe.indexOf(e)!==-1)return"'"+e+"'";var n=r.indent*Math.max(1,t),s=r.lineWidth===-1?-1:Math.max(Math.min(r.lineWidth,40),r.lineWidth-n),o=i||r.flowLevel>-1&&t>=r.flowLevel;function a(l){return jpe(r,l)}switch(Wpe(e,o,r.indent,s,a)){case X2:return e;case Z2:return"'"+e.replace(/'/g,"''")+"'";case _2:return"|"+T2(e,r.indent)+O2(N2(e,n));case $2:return">"+T2(e,r.indent)+O2(N2(Vpe(e,s),n));case BI:return'"'+Xpe(e,s)+'"';default:throw new ed("impossible error: invalid scalar style")}}()}function T2(r,e){var t=V2(r)?String(e):"",i=r[r.length-1]===` +`,n=i&&(r[r.length-2]===` +`||r===` +`),s=n?"+":i?"":"-";return t+s+` +`}function O2(r){return r[r.length-1]===` +`?r.slice(0,-1):r}function Vpe(r,e){for(var t=/(\n+)([^\n]*)/g,i=function(){var c=r.indexOf(` +`);return c=c!==-1?c:r.length,t.lastIndex=c,M2(r.slice(0,c),e)}(),n=r[0]===` +`||r[0]===" ",s,o;o=t.exec(r);){var a=o[1],l=o[2];s=l[0]===" ",i+=a+(!n&&!s&&l!==""?` +`:"")+M2(l,e),n=s}return i}function M2(r,e){if(r===""||r[0]===" ")return r;for(var t=/ [^ ]/g,i,n=0,s,o=0,a=0,l="";i=t.exec(r);)a=i.index,a-n>e&&(s=o>n?o:a,l+=` +`+r.slice(n,s),n=s+1),o=a;return l+=` +`,r.length-n>e&&o>n?l+=r.slice(n,o)+` +`+r.slice(o+1):l+=r.slice(n),l.slice(1)}function Xpe(r){for(var e="",t,i,n,s=0;s=55296&&t<=56319&&(i=r.charCodeAt(s+1),i>=56320&&i<=57343)){e+=F2((t-55296)*1024+i-56320+65536),s++;continue}n=Ni[t],e+=!n&&Kg(t)?r[s]:n||F2(t)}return e}function Zpe(r,e,t){var i="",n=r.tag,s,o;for(s=0,o=t.length;s1024&&(u+="? "),u+=r.dump+(r.condenseFlow?'"':"")+":"+(r.condenseFlow?"":" "),oc(r,e,c,!1,!1)&&(u+=r.dump,i+=u));r.tag=n,r.dump="{"+i+"}"}function ede(r,e,t,i){var n="",s=r.tag,o=Object.keys(t),a,l,c,u,g,f;if(r.sortKeys===!0)o.sort();else if(typeof r.sortKeys=="function")o.sort(r.sortKeys);else if(r.sortKeys)throw new ed("sortKeys must be a boolean or a function");for(a=0,l=o.length;a1024,g&&(r.dump&&_p===r.dump.charCodeAt(0)?f+="?":f+="? "),f+=r.dump,g&&(f+=VS(r,e)),oc(r,e+1,u,!0,g)&&(r.dump&&_p===r.dump.charCodeAt(0)?f+=":":f+=": ",f+=r.dump,n+=f));r.tag=s,r.dump=n||"{}"}function U2(r,e,t){var i,n,s,o,a,l;for(n=t?r.explicitTypes:r.implicitTypes,s=0,o=n.length;s tag resolver accepts not "'+l+'" style');r.dump=i}return!0}return!1}function oc(r,e,t,i,n,s){r.tag=null,r.dump=t,U2(r,t,!1)||U2(r,t,!0);var o=K2.call(r.dump);i&&(i=r.flowLevel<0||r.flowLevel>e);var a=o==="[object Object]"||o==="[object Array]",l,c;if(a&&(l=r.duplicates.indexOf(t),c=l!==-1),(r.tag!==null&&r.tag!=="?"||c||r.indent!==2&&e>0)&&(n=!1),c&&r.usedDuplicates[l])r.dump="*ref_"+l;else{if(a&&c&&!r.usedDuplicates[l]&&(r.usedDuplicates[l]=!0),o==="[object Object]")i&&Object.keys(r.dump).length!==0?(ede(r,e,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):($pe(r,e,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump));else if(o==="[object Array]"){var u=r.noArrayIndent&&e>0?e-1:e;i&&r.dump.length!==0?(_pe(r,u,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(Zpe(r,u,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump))}else if(o==="[object String]")r.tag!=="?"&&zpe(r,r.dump,e,s);else{if(r.skipInvalid)return!1;throw new ed("unacceptable kind of an object to dump "+o)}r.tag!==null&&r.tag!=="?"&&(r.dump="!<"+r.tag+"> "+r.dump)}return!0}function tde(r,e){var t=[],i=[],n,s;for(XS(r,t,i),n=0,s=i.length;n{"use strict";var QI=R2(),rH=tH();function bI(r){return function(){throw new Error("Function "+r+" is deprecated and cannot be used.")}}Fr.exports.Type=si();Fr.exports.Schema=rc();Fr.exports.FAILSAFE_SCHEMA=CI();Fr.exports.JSON_SCHEMA=YS();Fr.exports.CORE_SCHEMA=jS();Fr.exports.DEFAULT_SAFE_SCHEMA=Tg();Fr.exports.DEFAULT_FULL_SCHEMA=Xp();Fr.exports.load=QI.load;Fr.exports.loadAll=QI.loadAll;Fr.exports.safeLoad=QI.safeLoad;Fr.exports.safeLoadAll=QI.safeLoadAll;Fr.exports.dump=rH.dump;Fr.exports.safeDump=rH.safeDump;Fr.exports.YAMLException=Ng();Fr.exports.MINIMAL_SCHEMA=CI();Fr.exports.SAFE_SCHEMA=Tg();Fr.exports.DEFAULT_SCHEMA=Xp();Fr.exports.scan=bI("scan");Fr.exports.parse=bI("parse");Fr.exports.compose=bI("compose");Fr.exports.addConstructor=bI("addConstructor")});var sH=w((ZZe,nH)=>{"use strict";var ide=iH();nH.exports=ide});var aH=w((_Ze,oH)=>{"use strict";function nde(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function ac(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,ac)}nde(ac,Error);ac.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g({[Ue]:Ce})))},H=function(R){return R},j=function(R){return R},$=Ks("correct indentation"),V=" ",W=ar(" ",!1),_=function(R){return R.length===QA*yg},A=function(R){return R.length===(QA+1)*yg},Ae=function(){return QA++,!0},ge=function(){return QA--,!0},re=function(){return pg()},O=Ks("pseudostring"),F=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,ue=Nn(["\r",` +`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),pe=/^[^\r\n\t ,\][{}:#"']/,ke=Nn(["\r",` +`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),Fe=function(){return pg().replace(/^ *| *$/g,"")},Ne="--",oe=ar("--",!1),le=/^[a-zA-Z\/0-9]/,Be=Nn([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),fe=/^[^\r\n\t :,]/,ae=Nn(["\r",` +`," "," ",":",","],!0,!1),qe="null",ne=ar("null",!1),Y=function(){return null},he="true",ie=ar("true",!1),de=function(){return!0},_e="false",Pt=ar("false",!1),It=function(){return!1},Or=Ks("string"),ii='"',gi=ar('"',!1),hr=function(){return""},fi=function(R){return R},ni=function(R){return R.join("")},Us=/^[^"\\\0-\x1F\x7F]/,pr=Nn(['"',"\\",["\0",""],"\x7F"],!0,!1),Ii='\\"',rs=ar('\\"',!1),ga=function(){return'"'},dA="\\\\",cg=ar("\\\\",!1),is=function(){return"\\"},CA="\\/",fa=ar("\\/",!1),wp=function(){return"/"},mA="\\b",EA=ar("\\b",!1),wr=function(){return"\b"},Ll="\\f",ug=ar("\\f",!1),Io=function(){return"\f"},gg="\\n",Bp=ar("\\n",!1),Qp=function(){return` +`},vr="\\r",se=ar("\\r",!1),yo=function(){return"\r"},Rn="\\t",fg=ar("\\t",!1),Qt=function(){return" "},Tl="\\u",Fn=ar("\\u",!1),ns=function(R,q,Ce,Ue){return String.fromCharCode(parseInt(`0x${R}${q}${Ce}${Ue}`))},ss=/^[0-9a-fA-F]/,gt=Nn([["0","9"],["a","f"],["A","F"]],!1,!1),wo=Ks("blank space"),At=/^[ \t]/,An=Nn([" "," "],!1,!1),S=Ks("white space"),Tt=/^[ \t\n\r]/,hg=Nn([" "," ",` +`,"\r"],!1,!1),Ol=`\r +`,bp=ar(`\r +`,!1),Sp=` +`,vp=ar(` +`,!1),xp="\r",Pp=ar("\r",!1),G=0,yt=0,IA=[{line:1,column:1}],Wi=0,Ml=[],Xe=0,ha;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function pg(){return r.substring(yt,G)}function OE(){return ln(yt,G)}function Dp(R,q){throw q=q!==void 0?q:ln(yt,G),Kl([Ks(R)],r.substring(yt,G),q)}function ME(R,q){throw q=q!==void 0?q:ln(yt,G),dg(R,q)}function ar(R,q){return{type:"literal",text:R,ignoreCase:q}}function Nn(R,q,Ce){return{type:"class",parts:R,inverted:q,ignoreCase:Ce}}function Ul(){return{type:"any"}}function kp(){return{type:"end"}}function Ks(R){return{type:"other",description:R}}function pa(R){var q=IA[R],Ce;if(q)return q;for(Ce=R-1;!IA[Ce];)Ce--;for(q=IA[Ce],q={line:q.line,column:q.column};CeWi&&(Wi=G,Ml=[]),Ml.push(R))}function dg(R,q){return new ac(R,null,null,q)}function Kl(R,q,Ce){return new ac(ac.buildMessage(R,q),R,q,Ce)}function Hs(){var R;return R=Cg(),R}function Hl(){var R,q,Ce;for(R=G,q=[],Ce=yA();Ce!==t;)q.push(Ce),Ce=yA();return q!==t&&(yt=R,q=s(q)),R=q,R}function yA(){var R,q,Ce,Ue,Re;return R=G,q=Ca(),q!==t?(r.charCodeAt(G)===45?(Ce=o,G++):(Ce=t,Xe===0&&Te(a)),Ce!==t?(Ue=Rr(),Ue!==t?(Re=da(),Re!==t?(yt=R,q=l(Re),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R}function Cg(){var R,q,Ce;for(R=G,q=[],Ce=mg();Ce!==t;)q.push(Ce),Ce=mg();return q!==t&&(yt=R,q=c(q)),R=q,R}function mg(){var R,q,Ce,Ue,Re,ze,dt,Ft,Ln;if(R=G,q=Rr(),q===t&&(q=null),q!==t){if(Ce=G,r.charCodeAt(G)===35?(Ue=u,G++):(Ue=t,Xe===0&&Te(g)),Ue!==t){if(Re=[],ze=G,dt=G,Xe++,Ft=js(),Xe--,Ft===t?dt=void 0:(G=dt,dt=t),dt!==t?(r.length>G?(Ft=r.charAt(G),G++):(Ft=t,Xe===0&&Te(f)),Ft!==t?(dt=[dt,Ft],ze=dt):(G=ze,ze=t)):(G=ze,ze=t),ze!==t)for(;ze!==t;)Re.push(ze),ze=G,dt=G,Xe++,Ft=js(),Xe--,Ft===t?dt=void 0:(G=dt,dt=t),dt!==t?(r.length>G?(Ft=r.charAt(G),G++):(Ft=t,Xe===0&&Te(f)),Ft!==t?(dt=[dt,Ft],ze=dt):(G=ze,ze=t)):(G=ze,ze=t);else Re=t;Re!==t?(Ue=[Ue,Re],Ce=Ue):(G=Ce,Ce=t)}else G=Ce,Ce=t;if(Ce===t&&(Ce=null),Ce!==t){if(Ue=[],Re=Ys(),Re!==t)for(;Re!==t;)Ue.push(Re),Re=Ys();else Ue=t;Ue!==t?(yt=R,q=h(),R=q):(G=R,R=t)}else G=R,R=t}else G=R,R=t;if(R===t&&(R=G,q=Ca(),q!==t?(Ce=Gl(),Ce!==t?(Ue=Rr(),Ue===t&&(Ue=null),Ue!==t?(r.charCodeAt(G)===58?(Re=p,G++):(Re=t,Xe===0&&Te(C)),Re!==t?(ze=Rr(),ze===t&&(ze=null),ze!==t?(dt=da(),dt!==t?(yt=R,q=y(Ce,dt),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,q=Ca(),q!==t?(Ce=Gs(),Ce!==t?(Ue=Rr(),Ue===t&&(Ue=null),Ue!==t?(r.charCodeAt(G)===58?(Re=p,G++):(Re=t,Xe===0&&Te(C)),Re!==t?(ze=Rr(),ze===t&&(ze=null),ze!==t?(dt=da(),dt!==t?(yt=R,q=y(Ce,dt),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t))){if(R=G,q=Ca(),q!==t)if(Ce=Gs(),Ce!==t)if(Ue=Rr(),Ue!==t)if(Re=UE(),Re!==t){if(ze=[],dt=Ys(),dt!==t)for(;dt!==t;)ze.push(dt),dt=Ys();else ze=t;ze!==t?(yt=R,q=y(Ce,Re),R=q):(G=R,R=t)}else G=R,R=t;else G=R,R=t;else G=R,R=t;else G=R,R=t;if(R===t)if(R=G,q=Ca(),q!==t)if(Ce=Gs(),Ce!==t){if(Ue=[],Re=G,ze=Rr(),ze===t&&(ze=null),ze!==t?(r.charCodeAt(G)===44?(dt=B,G++):(dt=t,Xe===0&&Te(v)),dt!==t?(Ft=Rr(),Ft===t&&(Ft=null),Ft!==t?(Ln=Gs(),Ln!==t?(yt=Re,ze=D(Ce,Ln),Re=ze):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t),Re!==t)for(;Re!==t;)Ue.push(Re),Re=G,ze=Rr(),ze===t&&(ze=null),ze!==t?(r.charCodeAt(G)===44?(dt=B,G++):(dt=t,Xe===0&&Te(v)),dt!==t?(Ft=Rr(),Ft===t&&(Ft=null),Ft!==t?(Ln=Gs(),Ln!==t?(yt=Re,ze=D(Ce,Ln),Re=ze):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t);else Ue=t;Ue!==t?(Re=Rr(),Re===t&&(Re=null),Re!==t?(r.charCodeAt(G)===58?(ze=p,G++):(ze=t,Xe===0&&Te(C)),ze!==t?(dt=Rr(),dt===t&&(dt=null),dt!==t?(Ft=da(),Ft!==t?(yt=R,q=L(Ce,Ue,Ft),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)}else G=R,R=t;else G=R,R=t}return R}function da(){var R,q,Ce,Ue,Re,ze,dt;if(R=G,q=G,Xe++,Ce=G,Ue=js(),Ue!==t?(Re=rt(),Re!==t?(r.charCodeAt(G)===45?(ze=o,G++):(ze=t,Xe===0&&Te(a)),ze!==t?(dt=Rr(),dt!==t?(Ue=[Ue,Re,ze,dt],Ce=Ue):(G=Ce,Ce=t)):(G=Ce,Ce=t)):(G=Ce,Ce=t)):(G=Ce,Ce=t),Xe--,Ce!==t?(G=q,q=void 0):q=t,q!==t?(Ce=Ys(),Ce!==t?(Ue=Bo(),Ue!==t?(Re=Hl(),Re!==t?(ze=wA(),ze!==t?(yt=R,q=H(Re),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,q=js(),q!==t?(Ce=Bo(),Ce!==t?(Ue=Cg(),Ue!==t?(Re=wA(),Re!==t?(yt=R,q=H(Ue),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t))if(R=G,q=Yl(),q!==t){if(Ce=[],Ue=Ys(),Ue!==t)for(;Ue!==t;)Ce.push(Ue),Ue=Ys();else Ce=t;Ce!==t?(yt=R,q=j(q),R=q):(G=R,R=t)}else G=R,R=t;return R}function Ca(){var R,q,Ce;for(Xe++,R=G,q=[],r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));Ce!==t;)q.push(Ce),r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));return q!==t?(yt=G,Ce=_(q),Ce?Ce=void 0:Ce=t,Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)):(G=R,R=t),Xe--,R===t&&(q=t,Xe===0&&Te($)),R}function rt(){var R,q,Ce;for(R=G,q=[],r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));Ce!==t;)q.push(Ce),r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));return q!==t?(yt=G,Ce=A(q),Ce?Ce=void 0:Ce=t,Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)):(G=R,R=t),R}function Bo(){var R;return yt=G,R=Ae(),R?R=void 0:R=t,R}function wA(){var R;return yt=G,R=ge(),R?R=void 0:R=t,R}function Gl(){var R;return R=jl(),R===t&&(R=Rp()),R}function Gs(){var R,q,Ce;if(R=jl(),R===t){if(R=G,q=[],Ce=Eg(),Ce!==t)for(;Ce!==t;)q.push(Ce),Ce=Eg();else q=t;q!==t&&(yt=R,q=re()),R=q}return R}function Yl(){var R;return R=Fp(),R===t&&(R=KE(),R===t&&(R=jl(),R===t&&(R=Rp()))),R}function UE(){var R;return R=Fp(),R===t&&(R=jl(),R===t&&(R=Eg())),R}function Rp(){var R,q,Ce,Ue,Re,ze;if(Xe++,R=G,F.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(ue)),q!==t){for(Ce=[],Ue=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(pe.test(r.charAt(G))?(ze=r.charAt(G),G++):(ze=t,Xe===0&&Te(ke)),ze!==t?(Re=[Re,ze],Ue=Re):(G=Ue,Ue=t)):(G=Ue,Ue=t);Ue!==t;)Ce.push(Ue),Ue=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(pe.test(r.charAt(G))?(ze=r.charAt(G),G++):(ze=t,Xe===0&&Te(ke)),ze!==t?(Re=[Re,ze],Ue=Re):(G=Ue,Ue=t)):(G=Ue,Ue=t);Ce!==t?(yt=R,q=Fe(),R=q):(G=R,R=t)}else G=R,R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(O)),R}function Eg(){var R,q,Ce,Ue,Re;if(R=G,r.substr(G,2)===Ne?(q=Ne,G+=2):(q=t,Xe===0&&Te(oe)),q===t&&(q=null),q!==t)if(le.test(r.charAt(G))?(Ce=r.charAt(G),G++):(Ce=t,Xe===0&&Te(Be)),Ce!==t){for(Ue=[],fe.test(r.charAt(G))?(Re=r.charAt(G),G++):(Re=t,Xe===0&&Te(ae));Re!==t;)Ue.push(Re),fe.test(r.charAt(G))?(Re=r.charAt(G),G++):(Re=t,Xe===0&&Te(ae));Ue!==t?(yt=R,q=Fe(),R=q):(G=R,R=t)}else G=R,R=t;else G=R,R=t;return R}function Fp(){var R,q;return R=G,r.substr(G,4)===qe?(q=qe,G+=4):(q=t,Xe===0&&Te(ne)),q!==t&&(yt=R,q=Y()),R=q,R}function KE(){var R,q;return R=G,r.substr(G,4)===he?(q=he,G+=4):(q=t,Xe===0&&Te(ie)),q!==t&&(yt=R,q=de()),R=q,R===t&&(R=G,r.substr(G,5)===_e?(q=_e,G+=5):(q=t,Xe===0&&Te(Pt)),q!==t&&(yt=R,q=It()),R=q),R}function jl(){var R,q,Ce,Ue;return Xe++,R=G,r.charCodeAt(G)===34?(q=ii,G++):(q=t,Xe===0&&Te(gi)),q!==t?(r.charCodeAt(G)===34?(Ce=ii,G++):(Ce=t,Xe===0&&Te(gi)),Ce!==t?(yt=R,q=hr(),R=q):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,r.charCodeAt(G)===34?(q=ii,G++):(q=t,Xe===0&&Te(gi)),q!==t?(Ce=HE(),Ce!==t?(r.charCodeAt(G)===34?(Ue=ii,G++):(Ue=t,Xe===0&&Te(gi)),Ue!==t?(yt=R,q=fi(Ce),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)),Xe--,R===t&&(q=t,Xe===0&&Te(Or)),R}function HE(){var R,q,Ce;if(R=G,q=[],Ce=Ig(),Ce!==t)for(;Ce!==t;)q.push(Ce),Ce=Ig();else q=t;return q!==t&&(yt=R,q=ni(q)),R=q,R}function Ig(){var R,q,Ce,Ue,Re,ze;return Us.test(r.charAt(G))?(R=r.charAt(G),G++):(R=t,Xe===0&&Te(pr)),R===t&&(R=G,r.substr(G,2)===Ii?(q=Ii,G+=2):(q=t,Xe===0&&Te(rs)),q!==t&&(yt=R,q=ga()),R=q,R===t&&(R=G,r.substr(G,2)===dA?(q=dA,G+=2):(q=t,Xe===0&&Te(cg)),q!==t&&(yt=R,q=is()),R=q,R===t&&(R=G,r.substr(G,2)===CA?(q=CA,G+=2):(q=t,Xe===0&&Te(fa)),q!==t&&(yt=R,q=wp()),R=q,R===t&&(R=G,r.substr(G,2)===mA?(q=mA,G+=2):(q=t,Xe===0&&Te(EA)),q!==t&&(yt=R,q=wr()),R=q,R===t&&(R=G,r.substr(G,2)===Ll?(q=Ll,G+=2):(q=t,Xe===0&&Te(ug)),q!==t&&(yt=R,q=Io()),R=q,R===t&&(R=G,r.substr(G,2)===gg?(q=gg,G+=2):(q=t,Xe===0&&Te(Bp)),q!==t&&(yt=R,q=Qp()),R=q,R===t&&(R=G,r.substr(G,2)===vr?(q=vr,G+=2):(q=t,Xe===0&&Te(se)),q!==t&&(yt=R,q=yo()),R=q,R===t&&(R=G,r.substr(G,2)===Rn?(q=Rn,G+=2):(q=t,Xe===0&&Te(fg)),q!==t&&(yt=R,q=Qt()),R=q,R===t&&(R=G,r.substr(G,2)===Tl?(q=Tl,G+=2):(q=t,Xe===0&&Te(Fn)),q!==t?(Ce=BA(),Ce!==t?(Ue=BA(),Ue!==t?(Re=BA(),Re!==t?(ze=BA(),ze!==t?(yt=R,q=ns(Ce,Ue,Re,ze),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)))))))))),R}function BA(){var R;return ss.test(r.charAt(G))?(R=r.charAt(G),G++):(R=t,Xe===0&&Te(gt)),R}function Rr(){var R,q;if(Xe++,R=[],At.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(An)),q!==t)for(;q!==t;)R.push(q),At.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(An));else R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(wo)),R}function GE(){var R,q;if(Xe++,R=[],Tt.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(hg)),q!==t)for(;q!==t;)R.push(q),Tt.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(hg));else R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(S)),R}function Ys(){var R,q,Ce,Ue,Re,ze;if(R=G,q=js(),q!==t){for(Ce=[],Ue=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(ze=js(),ze!==t?(Re=[Re,ze],Ue=Re):(G=Ue,Ue=t)):(G=Ue,Ue=t);Ue!==t;)Ce.push(Ue),Ue=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(ze=js(),ze!==t?(Re=[Re,ze],Ue=Re):(G=Ue,Ue=t)):(G=Ue,Ue=t);Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)}else G=R,R=t;return R}function js(){var R;return r.substr(G,2)===Ol?(R=Ol,G+=2):(R=t,Xe===0&&Te(bp)),R===t&&(r.charCodeAt(G)===10?(R=Sp,G++):(R=t,Xe===0&&Te(vp)),R===t&&(r.charCodeAt(G)===13?(R=xp,G++):(R=t,Xe===0&&Te(Pp)))),R}let yg=2,QA=0;if(ha=n(),ha!==t&&G===r.length)return ha;throw ha!==t&&G{"use strict";var cde=r=>{let e=!1,t=!1,i=!1;for(let n=0;n{if(!(typeof r=="string"||Array.isArray(r)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let t=n=>e.pascalCase?n.charAt(0).toUpperCase()+n.slice(1):n;return Array.isArray(r)?r=r.map(n=>n.trim()).filter(n=>n.length).join("-"):r=r.trim(),r.length===0?"":r.length===1?e.pascalCase?r.toUpperCase():r.toLowerCase():(r!==r.toLowerCase()&&(r=cde(r)),r=r.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(n,s)=>s.toUpperCase()).replace(/\d+(\w|$)/g,n=>n.toUpperCase()),t(r))};ev.exports=gH;ev.exports.default=gH});var hH=w((n_e,ude)=>{ude.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vercel",constant:"VERCEL",env:"NOW_BUILDER"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"}]});var Ac=w(Un=>{"use strict";var dH=hH(),xo=process.env;Object.defineProperty(Un,"_vendors",{value:dH.map(function(r){return r.constant})});Un.name=null;Un.isPR=null;dH.forEach(function(r){let t=(Array.isArray(r.env)?r.env:[r.env]).every(function(i){return pH(i)});if(Un[r.constant]=t,t)switch(Un.name=r.name,typeof r.pr){case"string":Un.isPR=!!xo[r.pr];break;case"object":"env"in r.pr?Un.isPR=r.pr.env in xo&&xo[r.pr.env]!==r.pr.ne:"any"in r.pr?Un.isPR=r.pr.any.some(function(i){return!!xo[i]}):Un.isPR=pH(r.pr);break;default:Un.isPR=null}});Un.isCI=!!(xo.CI||xo.CONTINUOUS_INTEGRATION||xo.BUILD_NUMBER||xo.RUN_ID||Un.name);function pH(r){return typeof r=="string"?!!xo[r]:Object.keys(r).every(function(e){return xo[e]===r[e]})}});var fn={};ut(fn,{KeyRelationship:()=>lc,applyCascade:()=>od,base64RegExp:()=>yH,colorStringAlphaRegExp:()=>IH,colorStringRegExp:()=>EH,computeKey:()=>RA,getPrintable:()=>Vr,hasExactLength:()=>SH,hasForbiddenKeys:()=>Yde,hasKeyRelationship:()=>av,hasMaxLength:()=>Sde,hasMinLength:()=>bde,hasMutuallyExclusiveKeys:()=>jde,hasRequiredKeys:()=>Gde,hasUniqueItems:()=>vde,isArray:()=>Cde,isAtLeast:()=>Dde,isAtMost:()=>kde,isBase64:()=>Kde,isBoolean:()=>hde,isDate:()=>dde,isDict:()=>Ede,isEnum:()=>Xi,isHexColor:()=>Ude,isISO8601:()=>Mde,isInExclusiveRange:()=>Fde,isInInclusiveRange:()=>Rde,isInstanceOf:()=>yde,isInteger:()=>Nde,isJSON:()=>Hde,isLiteral:()=>gde,isLowerCase:()=>Lde,isNegative:()=>xde,isNullable:()=>Qde,isNumber:()=>pde,isObject:()=>Ide,isOneOf:()=>wde,isOptional:()=>Bde,isPositive:()=>Pde,isString:()=>sd,isTuple:()=>mde,isUUID4:()=>Ode,isUnknown:()=>bH,isUpperCase:()=>Tde,iso8601RegExp:()=>ov,makeCoercionFn:()=>cc,makeSetter:()=>QH,makeTrait:()=>BH,makeValidator:()=>bt,matchesRegExp:()=>ad,plural:()=>kI,pushError:()=>pt,simpleKeyRegExp:()=>mH,uuid4RegExp:()=>wH});function bt({test:r}){return BH(r)()}function Vr(r){return r===null?"null":r===void 0?"undefined":r===""?"an empty string":JSON.stringify(r)}function RA(r,e){var t,i,n;return typeof e=="number"?`${(t=r==null?void 0:r.p)!==null&&t!==void 0?t:"."}[${e}]`:mH.test(e)?`${(i=r==null?void 0:r.p)!==null&&i!==void 0?i:""}.${e}`:`${(n=r==null?void 0:r.p)!==null&&n!==void 0?n:"."}[${JSON.stringify(e)}]`}function cc(r,e){return t=>{let i=r[e];return r[e]=t,cc(r,e).bind(null,i)}}function QH(r,e){return t=>{r[e]=t}}function kI(r,e,t){return r===1?e:t}function pt({errors:r,p:e}={},t){return r==null||r.push(`${e!=null?e:"."}: ${t}`),!1}function gde(r){return bt({test:(e,t)=>e!==r?pt(t,`Expected a literal (got ${Vr(r)})`):!0})}function Xi(r){let e=Array.isArray(r)?r:Object.values(r),t=new Set(e);return bt({test:(i,n)=>t.has(i)?!0:pt(n,`Expected a valid enumeration value (got ${Vr(i)})`)})}var mH,EH,IH,yH,wH,ov,BH,bH,sd,fde,hde,pde,dde,Cde,mde,Ede,Ide,yde,wde,od,Bde,Qde,bde,Sde,SH,vde,xde,Pde,Dde,kde,Rde,Fde,Nde,ad,Lde,Tde,Ode,Mde,Ude,Kde,Hde,Gde,Yde,jde,lc,qde,av,ls=kge(()=>{mH=/^[a-zA-Z_][a-zA-Z0-9_]*$/,EH=/^#[0-9a-f]{6}$/i,IH=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,yH=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,wH=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,ov=/^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/,BH=r=>()=>r;bH=()=>bt({test:(r,e)=>!0});sd=()=>bt({test:(r,e)=>typeof r!="string"?pt(e,`Expected a string (got ${Vr(r)})`):!0});fde=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]),hde=()=>bt({test:(r,e)=>{var t;if(typeof r!="boolean"){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i=fde.get(r);if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a boolean (got ${Vr(r)})`)}return!0}}),pde=()=>bt({test:(r,e)=>{var t;if(typeof r!="number"){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i;if(typeof r=="string"){let n;try{n=JSON.parse(r)}catch{}if(typeof n=="number")if(JSON.stringify(n)===r)i=n;else return pt(e,`Received a number that can't be safely represented by the runtime (${r})`)}if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a number (got ${Vr(r)})`)}return!0}}),dde=()=>bt({test:(r,e)=>{var t;if(!(r instanceof Date)){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i;if(typeof r=="string"&&ov.test(r))i=new Date(r);else{let n;if(typeof r=="string"){let s;try{s=JSON.parse(r)}catch{}typeof s=="number"&&(n=s)}else typeof r=="number"&&(n=r);if(typeof n<"u")if(Number.isSafeInteger(n)||!Number.isSafeInteger(n*1e3))i=new Date(n*1e3);else return pt(e,`Received a timestamp that can't be safely represented by the runtime (${r})`)}if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a date (got ${Vr(r)})`)}return!0}}),Cde=(r,{delimiter:e}={})=>bt({test:(t,i)=>{var n;if(typeof t=="string"&&typeof e<"u"&&typeof(i==null?void 0:i.coercions)<"u"){if(typeof(i==null?void 0:i.coercion)>"u")return pt(i,"Unbound coercion result");t=t.split(e),i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,t)])}if(!Array.isArray(t))return pt(i,`Expected an array (got ${Vr(t)})`);let s=!0;for(let o=0,a=t.length;o{let t=SH(r.length);return bt({test:(i,n)=>{var s;if(typeof i=="string"&&typeof e<"u"&&typeof(n==null?void 0:n.coercions)<"u"){if(typeof(n==null?void 0:n.coercion)>"u")return pt(n,"Unbound coercion result");i=i.split(e),n.coercions.push([(s=n.p)!==null&&s!==void 0?s:".",n.coercion.bind(null,i)])}if(!Array.isArray(i))return pt(n,`Expected a tuple (got ${Vr(i)})`);let o=t(i,Object.assign({},n));for(let a=0,l=i.length;abt({test:(t,i)=>{if(typeof t!="object"||t===null)return pt(i,`Expected an object (got ${Vr(t)})`);let n=Object.keys(t),s=!0;for(let o=0,a=n.length;o{let t=Object.keys(r);return bt({test:(i,n)=>{if(typeof i!="object"||i===null)return pt(n,`Expected an object (got ${Vr(i)})`);let s=new Set([...t,...Object.keys(i)]),o={},a=!0;for(let l of s){if(l==="constructor"||l==="__proto__")a=pt(Object.assign(Object.assign({},n),{p:RA(n,l)}),"Unsafe property name");else{let c=Object.prototype.hasOwnProperty.call(r,l)?r[l]:void 0,u=Object.prototype.hasOwnProperty.call(i,l)?i[l]:void 0;typeof c<"u"?a=c(u,Object.assign(Object.assign({},n),{p:RA(n,l),coercion:cc(i,l)}))&&a:e===null?a=pt(Object.assign(Object.assign({},n),{p:RA(n,l)}),`Extraneous property (got ${Vr(u)})`):Object.defineProperty(o,l,{enumerable:!0,get:()=>u,set:QH(i,l)})}if(!a&&(n==null?void 0:n.errors)==null)break}return e!==null&&(a||(n==null?void 0:n.errors)!=null)&&(a=e(o,n)&&a),a}})},yde=r=>bt({test:(e,t)=>e instanceof r?!0:pt(t,`Expected an instance of ${r.name} (got ${Vr(e)})`)}),wde=(r,{exclusive:e=!1}={})=>bt({test:(t,i)=>{var n,s,o;let a=[],l=typeof(i==null?void 0:i.errors)<"u"?[]:void 0;for(let c=0,u=r.length;c1?pt(i,`Expected to match exactly a single predicate (matched ${a.join(", ")})`):(o=i==null?void 0:i.errors)===null||o===void 0||o.push(...l),!1}}),od=(r,e)=>bt({test:(t,i)=>{var n,s;let o={value:t},a=typeof(i==null?void 0:i.coercions)<"u"?cc(o,"value"):void 0,l=typeof(i==null?void 0:i.coercions)<"u"?[]:void 0;if(!r(t,Object.assign(Object.assign({},i),{coercion:a,coercions:l})))return!1;let c=[];if(typeof l<"u")for(let[,u]of l)c.push(u());try{if(typeof(i==null?void 0:i.coercions)<"u"){if(o.value!==t){if(typeof(i==null?void 0:i.coercion)>"u")return pt(i,"Unbound coercion result");i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,o.value)])}(s=i==null?void 0:i.coercions)===null||s===void 0||s.push(...l)}return e.every(u=>u(o.value,i))}finally{for(let u of c)u()}}}),Bde=r=>bt({test:(e,t)=>typeof e>"u"?!0:r(e,t)}),Qde=r=>bt({test:(e,t)=>e===null?!0:r(e,t)}),bde=r=>bt({test:(e,t)=>e.length>=r?!0:pt(t,`Expected to have a length of at least ${r} elements (got ${e.length})`)}),Sde=r=>bt({test:(e,t)=>e.length<=r?!0:pt(t,`Expected to have a length of at most ${r} elements (got ${e.length})`)}),SH=r=>bt({test:(e,t)=>e.length!==r?pt(t,`Expected to have a length of exactly ${r} elements (got ${e.length})`):!0}),vde=({map:r}={})=>bt({test:(e,t)=>{let i=new Set,n=new Set;for(let s=0,o=e.length;sbt({test:(r,e)=>r<=0?!0:pt(e,`Expected to be negative (got ${r})`)}),Pde=()=>bt({test:(r,e)=>r>=0?!0:pt(e,`Expected to be positive (got ${r})`)}),Dde=r=>bt({test:(e,t)=>e>=r?!0:pt(t,`Expected to be at least ${r} (got ${e})`)}),kde=r=>bt({test:(e,t)=>e<=r?!0:pt(t,`Expected to be at most ${r} (got ${e})`)}),Rde=(r,e)=>bt({test:(t,i)=>t>=r&&t<=e?!0:pt(i,`Expected to be in the [${r}; ${e}] range (got ${t})`)}),Fde=(r,e)=>bt({test:(t,i)=>t>=r&&tbt({test:(e,t)=>e!==Math.round(e)?pt(t,`Expected to be an integer (got ${e})`):Number.isSafeInteger(e)?!0:pt(t,`Expected to be a safe integer (got ${e})`)}),ad=r=>bt({test:(e,t)=>r.test(e)?!0:pt(t,`Expected to match the pattern ${r.toString()} (got ${Vr(e)})`)}),Lde=()=>bt({test:(r,e)=>r!==r.toLowerCase()?pt(e,`Expected to be all-lowercase (got ${r})`):!0}),Tde=()=>bt({test:(r,e)=>r!==r.toUpperCase()?pt(e,`Expected to be all-uppercase (got ${r})`):!0}),Ode=()=>bt({test:(r,e)=>wH.test(r)?!0:pt(e,`Expected to be a valid UUID v4 (got ${Vr(r)})`)}),Mde=()=>bt({test:(r,e)=>ov.test(r)?!1:pt(e,`Expected to be a valid ISO 8601 date string (got ${Vr(r)})`)}),Ude=({alpha:r=!1})=>bt({test:(e,t)=>(r?EH.test(e):IH.test(e))?!0:pt(t,`Expected to be a valid hexadecimal color string (got ${Vr(e)})`)}),Kde=()=>bt({test:(r,e)=>yH.test(r)?!0:pt(e,`Expected to be a valid base 64 string (got ${Vr(r)})`)}),Hde=(r=bH())=>bt({test:(e,t)=>{let i;try{i=JSON.parse(e)}catch{return pt(t,`Expected to be a valid JSON string (got ${Vr(e)})`)}return r(i,t)}}),Gde=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)||s.push(o);return s.length>0?pt(i,`Missing required ${kI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},Yde=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>0?pt(i,`Forbidden ${kI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},jde=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>1?pt(i,`Mutually exclusive properties ${s.map(o=>`"${o}"`).join(", ")}`):!0}})};(function(r){r.Forbids="Forbids",r.Requires="Requires"})(lc||(lc={}));qde={[lc.Forbids]:{expect:!1,message:"forbids using"},[lc.Requires]:{expect:!0,message:"requires using"}},av=(r,e,t,{ignore:i=[]}={})=>{let n=new Set(i),s=new Set(t),o=qde[e];return bt({test:(a,l)=>{let c=new Set(Object.keys(a));if(!c.has(r)||n.has(a[r]))return!0;let u=[];for(let g of s)(c.has(g)&&!n.has(a[g]))!==o.expect&&u.push(g);return u.length>=1?pt(l,`Property "${r}" ${o.message} ${kI(u.length,"property","properties")} ${u.map(g=>`"${g}"`).join(", ")}`):!0}})}});var YH=w((n$e,GH)=>{"use strict";GH.exports=(r,...e)=>new Promise(t=>{t(r(...e))})});var Jg=w((s$e,pv)=>{"use strict";var ACe=YH(),jH=r=>{if(r<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],t=0,i=()=>{t--,e.length>0&&e.shift()()},n=(a,l,...c)=>{t++;let u=ACe(a,...c);l(u),u.then(i,i)},s=(a,l,...c)=>{tnew Promise(c=>s(a,c,...l));return Object.defineProperties(o,{activeCount:{get:()=>t},pendingCount:{get:()=>e.length}}),o};pv.exports=jH;pv.exports.default=jH});var gd=w((a$e,qH)=>{var lCe="2.0.0",cCe=Number.MAX_SAFE_INTEGER||9007199254740991,uCe=16;qH.exports={SEMVER_SPEC_VERSION:lCe,MAX_LENGTH:256,MAX_SAFE_INTEGER:cCe,MAX_SAFE_COMPONENT_LENGTH:uCe}});var fd=w((A$e,JH)=>{var gCe=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...r)=>console.error("SEMVER",...r):()=>{};JH.exports=gCe});var uc=w((NA,WH)=>{var{MAX_SAFE_COMPONENT_LENGTH:dv}=gd(),fCe=fd();NA=WH.exports={};var hCe=NA.re=[],et=NA.src=[],tt=NA.t={},pCe=0,St=(r,e,t)=>{let i=pCe++;fCe(i,e),tt[r]=i,et[i]=e,hCe[i]=new RegExp(e,t?"g":void 0)};St("NUMERICIDENTIFIER","0|[1-9]\\d*");St("NUMERICIDENTIFIERLOOSE","[0-9]+");St("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*");St("MAINVERSION",`(${et[tt.NUMERICIDENTIFIER]})\\.(${et[tt.NUMERICIDENTIFIER]})\\.(${et[tt.NUMERICIDENTIFIER]})`);St("MAINVERSIONLOOSE",`(${et[tt.NUMERICIDENTIFIERLOOSE]})\\.(${et[tt.NUMERICIDENTIFIERLOOSE]})\\.(${et[tt.NUMERICIDENTIFIERLOOSE]})`);St("PRERELEASEIDENTIFIER",`(?:${et[tt.NUMERICIDENTIFIER]}|${et[tt.NONNUMERICIDENTIFIER]})`);St("PRERELEASEIDENTIFIERLOOSE",`(?:${et[tt.NUMERICIDENTIFIERLOOSE]}|${et[tt.NONNUMERICIDENTIFIER]})`);St("PRERELEASE",`(?:-(${et[tt.PRERELEASEIDENTIFIER]}(?:\\.${et[tt.PRERELEASEIDENTIFIER]})*))`);St("PRERELEASELOOSE",`(?:-?(${et[tt.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${et[tt.PRERELEASEIDENTIFIERLOOSE]})*))`);St("BUILDIDENTIFIER","[0-9A-Za-z-]+");St("BUILD",`(?:\\+(${et[tt.BUILDIDENTIFIER]}(?:\\.${et[tt.BUILDIDENTIFIER]})*))`);St("FULLPLAIN",`v?${et[tt.MAINVERSION]}${et[tt.PRERELEASE]}?${et[tt.BUILD]}?`);St("FULL",`^${et[tt.FULLPLAIN]}$`);St("LOOSEPLAIN",`[v=\\s]*${et[tt.MAINVERSIONLOOSE]}${et[tt.PRERELEASELOOSE]}?${et[tt.BUILD]}?`);St("LOOSE",`^${et[tt.LOOSEPLAIN]}$`);St("GTLT","((?:<|>)?=?)");St("XRANGEIDENTIFIERLOOSE",`${et[tt.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);St("XRANGEIDENTIFIER",`${et[tt.NUMERICIDENTIFIER]}|x|X|\\*`);St("XRANGEPLAIN",`[v=\\s]*(${et[tt.XRANGEIDENTIFIER]})(?:\\.(${et[tt.XRANGEIDENTIFIER]})(?:\\.(${et[tt.XRANGEIDENTIFIER]})(?:${et[tt.PRERELEASE]})?${et[tt.BUILD]}?)?)?`);St("XRANGEPLAINLOOSE",`[v=\\s]*(${et[tt.XRANGEIDENTIFIERLOOSE]})(?:\\.(${et[tt.XRANGEIDENTIFIERLOOSE]})(?:\\.(${et[tt.XRANGEIDENTIFIERLOOSE]})(?:${et[tt.PRERELEASELOOSE]})?${et[tt.BUILD]}?)?)?`);St("XRANGE",`^${et[tt.GTLT]}\\s*${et[tt.XRANGEPLAIN]}$`);St("XRANGELOOSE",`^${et[tt.GTLT]}\\s*${et[tt.XRANGEPLAINLOOSE]}$`);St("COERCE",`(^|[^\\d])(\\d{1,${dv}})(?:\\.(\\d{1,${dv}}))?(?:\\.(\\d{1,${dv}}))?(?:$|[^\\d])`);St("COERCERTL",et[tt.COERCE],!0);St("LONETILDE","(?:~>?)");St("TILDETRIM",`(\\s*)${et[tt.LONETILDE]}\\s+`,!0);NA.tildeTrimReplace="$1~";St("TILDE",`^${et[tt.LONETILDE]}${et[tt.XRANGEPLAIN]}$`);St("TILDELOOSE",`^${et[tt.LONETILDE]}${et[tt.XRANGEPLAINLOOSE]}$`);St("LONECARET","(?:\\^)");St("CARETTRIM",`(\\s*)${et[tt.LONECARET]}\\s+`,!0);NA.caretTrimReplace="$1^";St("CARET",`^${et[tt.LONECARET]}${et[tt.XRANGEPLAIN]}$`);St("CARETLOOSE",`^${et[tt.LONECARET]}${et[tt.XRANGEPLAINLOOSE]}$`);St("COMPARATORLOOSE",`^${et[tt.GTLT]}\\s*(${et[tt.LOOSEPLAIN]})$|^$`);St("COMPARATOR",`^${et[tt.GTLT]}\\s*(${et[tt.FULLPLAIN]})$|^$`);St("COMPARATORTRIM",`(\\s*)${et[tt.GTLT]}\\s*(${et[tt.LOOSEPLAIN]}|${et[tt.XRANGEPLAIN]})`,!0);NA.comparatorTrimReplace="$1$2$3";St("HYPHENRANGE",`^\\s*(${et[tt.XRANGEPLAIN]})\\s+-\\s+(${et[tt.XRANGEPLAIN]})\\s*$`);St("HYPHENRANGELOOSE",`^\\s*(${et[tt.XRANGEPLAINLOOSE]})\\s+-\\s+(${et[tt.XRANGEPLAINLOOSE]})\\s*$`);St("STAR","(<|>)?=?\\s*\\*");St("GTE0","^\\s*>=\\s*0.0.0\\s*$");St("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")});var hd=w((l$e,zH)=>{var dCe=["includePrerelease","loose","rtl"],CCe=r=>r?typeof r!="object"?{loose:!0}:dCe.filter(e=>r[e]).reduce((e,t)=>(e[t]=!0,e),{}):{};zH.exports=CCe});var OI=w((c$e,ZH)=>{var VH=/^[0-9]+$/,XH=(r,e)=>{let t=VH.test(r),i=VH.test(e);return t&&i&&(r=+r,e=+e),r===e?0:t&&!i?-1:i&&!t?1:rXH(e,r);ZH.exports={compareIdentifiers:XH,rcompareIdentifiers:mCe}});var Ti=w((u$e,tG)=>{var MI=fd(),{MAX_LENGTH:_H,MAX_SAFE_INTEGER:UI}=gd(),{re:$H,t:eG}=uc(),ECe=hd(),{compareIdentifiers:pd}=OI(),Gn=class{constructor(e,t){if(t=ECe(t),e instanceof Gn){if(e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid Version: ${e}`);if(e.length>_H)throw new TypeError(`version is longer than ${_H} characters`);MI("SemVer",e,t),this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease;let i=e.trim().match(t.loose?$H[eG.LOOSE]:$H[eG.FULL]);if(!i)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>UI||this.major<0)throw new TypeError("Invalid major version");if(this.minor>UI||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>UI||this.patch<0)throw new TypeError("Invalid patch version");i[4]?this.prerelease=i[4].split(".").map(n=>{if(/^[0-9]+$/.test(n)){let s=+n;if(s>=0&&s=0;)typeof this.prerelease[i]=="number"&&(this.prerelease[i]++,i=-2);i===-1&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error(`invalid increment argument: ${e}`)}return this.format(),this.raw=this.version,this}};tG.exports=Gn});var gc=w((g$e,sG)=>{var{MAX_LENGTH:ICe}=gd(),{re:rG,t:iG}=uc(),nG=Ti(),yCe=hd(),wCe=(r,e)=>{if(e=yCe(e),r instanceof nG)return r;if(typeof r!="string"||r.length>ICe||!(e.loose?rG[iG.LOOSE]:rG[iG.FULL]).test(r))return null;try{return new nG(r,e)}catch{return null}};sG.exports=wCe});var aG=w((f$e,oG)=>{var BCe=gc(),QCe=(r,e)=>{let t=BCe(r,e);return t?t.version:null};oG.exports=QCe});var lG=w((h$e,AG)=>{var bCe=gc(),SCe=(r,e)=>{let t=bCe(r.trim().replace(/^[=v]+/,""),e);return t?t.version:null};AG.exports=SCe});var uG=w((p$e,cG)=>{var vCe=Ti(),xCe=(r,e,t,i)=>{typeof t=="string"&&(i=t,t=void 0);try{return new vCe(r,t).inc(e,i).version}catch{return null}};cG.exports=xCe});var cs=w((d$e,fG)=>{var gG=Ti(),PCe=(r,e,t)=>new gG(r,t).compare(new gG(e,t));fG.exports=PCe});var KI=w((C$e,hG)=>{var DCe=cs(),kCe=(r,e,t)=>DCe(r,e,t)===0;hG.exports=kCe});var CG=w((m$e,dG)=>{var pG=gc(),RCe=KI(),FCe=(r,e)=>{if(RCe(r,e))return null;{let t=pG(r),i=pG(e),n=t.prerelease.length||i.prerelease.length,s=n?"pre":"",o=n?"prerelease":"";for(let a in t)if((a==="major"||a==="minor"||a==="patch")&&t[a]!==i[a])return s+a;return o}};dG.exports=FCe});var EG=w((E$e,mG)=>{var NCe=Ti(),LCe=(r,e)=>new NCe(r,e).major;mG.exports=LCe});var yG=w((I$e,IG)=>{var TCe=Ti(),OCe=(r,e)=>new TCe(r,e).minor;IG.exports=OCe});var BG=w((y$e,wG)=>{var MCe=Ti(),UCe=(r,e)=>new MCe(r,e).patch;wG.exports=UCe});var bG=w((w$e,QG)=>{var KCe=gc(),HCe=(r,e)=>{let t=KCe(r,e);return t&&t.prerelease.length?t.prerelease:null};QG.exports=HCe});var vG=w((B$e,SG)=>{var GCe=cs(),YCe=(r,e,t)=>GCe(e,r,t);SG.exports=YCe});var PG=w((Q$e,xG)=>{var jCe=cs(),qCe=(r,e)=>jCe(r,e,!0);xG.exports=qCe});var HI=w((b$e,kG)=>{var DG=Ti(),JCe=(r,e,t)=>{let i=new DG(r,t),n=new DG(e,t);return i.compare(n)||i.compareBuild(n)};kG.exports=JCe});var FG=w((S$e,RG)=>{var WCe=HI(),zCe=(r,e)=>r.sort((t,i)=>WCe(t,i,e));RG.exports=zCe});var LG=w((v$e,NG)=>{var VCe=HI(),XCe=(r,e)=>r.sort((t,i)=>VCe(i,t,e));NG.exports=XCe});var dd=w((x$e,TG)=>{var ZCe=cs(),_Ce=(r,e,t)=>ZCe(r,e,t)>0;TG.exports=_Ce});var GI=w((P$e,OG)=>{var $Ce=cs(),eme=(r,e,t)=>$Ce(r,e,t)<0;OG.exports=eme});var Cv=w((D$e,MG)=>{var tme=cs(),rme=(r,e,t)=>tme(r,e,t)!==0;MG.exports=rme});var YI=w((k$e,UG)=>{var ime=cs(),nme=(r,e,t)=>ime(r,e,t)>=0;UG.exports=nme});var jI=w((R$e,KG)=>{var sme=cs(),ome=(r,e,t)=>sme(r,e,t)<=0;KG.exports=ome});var mv=w((F$e,HG)=>{var ame=KI(),Ame=Cv(),lme=dd(),cme=YI(),ume=GI(),gme=jI(),fme=(r,e,t,i)=>{switch(e){case"===":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r===t;case"!==":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r!==t;case"":case"=":case"==":return ame(r,t,i);case"!=":return Ame(r,t,i);case">":return lme(r,t,i);case">=":return cme(r,t,i);case"<":return ume(r,t,i);case"<=":return gme(r,t,i);default:throw new TypeError(`Invalid operator: ${e}`)}};HG.exports=fme});var YG=w((N$e,GG)=>{var hme=Ti(),pme=gc(),{re:qI,t:JI}=uc(),dme=(r,e)=>{if(r instanceof hme)return r;if(typeof r=="number"&&(r=String(r)),typeof r!="string")return null;e=e||{};let t=null;if(!e.rtl)t=r.match(qI[JI.COERCE]);else{let i;for(;(i=qI[JI.COERCERTL].exec(r))&&(!t||t.index+t[0].length!==r.length);)(!t||i.index+i[0].length!==t.index+t[0].length)&&(t=i),qI[JI.COERCERTL].lastIndex=i.index+i[1].length+i[2].length;qI[JI.COERCERTL].lastIndex=-1}return t===null?null:pme(`${t[2]}.${t[3]||"0"}.${t[4]||"0"}`,e)};GG.exports=dme});var qG=w((L$e,jG)=>{"use strict";jG.exports=function(r){r.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var WI=w((T$e,JG)=>{"use strict";JG.exports=Ht;Ht.Node=fc;Ht.create=Ht;function Ht(r){var e=this;if(e instanceof Ht||(e=new Ht),e.tail=null,e.head=null,e.length=0,r&&typeof r.forEach=="function")r.forEach(function(n){e.push(n)});else if(arguments.length>0)for(var t=0,i=arguments.length;t1)t=e;else if(this.head)i=this.head.next,t=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;i!==null;n++)t=r(t,i.value,n),i=i.next;return t};Ht.prototype.reduceReverse=function(r,e){var t,i=this.tail;if(arguments.length>1)t=e;else if(this.tail)i=this.tail.prev,t=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=this.length-1;i!==null;n--)t=r(t,i.value,n),i=i.prev;return t};Ht.prototype.toArray=function(){for(var r=new Array(this.length),e=0,t=this.head;t!==null;e++)r[e]=t.value,t=t.next;return r};Ht.prototype.toArrayReverse=function(){for(var r=new Array(this.length),e=0,t=this.tail;t!==null;e++)r[e]=t.value,t=t.prev;return r};Ht.prototype.slice=function(r,e){e=e||this.length,e<0&&(e+=this.length),r=r||0,r<0&&(r+=this.length);var t=new Ht;if(ethis.length&&(e=this.length);for(var i=0,n=this.head;n!==null&&ithis.length&&(e=this.length);for(var i=this.length,n=this.tail;n!==null&&i>e;i--)n=n.prev;for(;n!==null&&i>r;i--,n=n.prev)t.push(n.value);return t};Ht.prototype.splice=function(r,e,...t){r>this.length&&(r=this.length-1),r<0&&(r=this.length+r);for(var i=0,n=this.head;n!==null&&i{"use strict";var Ime=WI(),hc=Symbol("max"),Sa=Symbol("length"),Wg=Symbol("lengthCalculator"),md=Symbol("allowStale"),pc=Symbol("maxAge"),ba=Symbol("dispose"),WG=Symbol("noDisposeOnSet"),di=Symbol("lruList"),Zs=Symbol("cache"),VG=Symbol("updateAgeOnGet"),Ev=()=>1,yv=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let t=this[hc]=e.max||1/0,i=e.length||Ev;if(this[Wg]=typeof i!="function"?Ev:i,this[md]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[pc]=e.maxAge||0,this[ba]=e.dispose,this[WG]=e.noDisposeOnSet||!1,this[VG]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[hc]=e||1/0,Cd(this)}get max(){return this[hc]}set allowStale(e){this[md]=!!e}get allowStale(){return this[md]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[pc]=e,Cd(this)}get maxAge(){return this[pc]}set lengthCalculator(e){typeof e!="function"&&(e=Ev),e!==this[Wg]&&(this[Wg]=e,this[Sa]=0,this[di].forEach(t=>{t.length=this[Wg](t.value,t.key),this[Sa]+=t.length})),Cd(this)}get lengthCalculator(){return this[Wg]}get length(){return this[Sa]}get itemCount(){return this[di].length}rforEach(e,t){t=t||this;for(let i=this[di].tail;i!==null;){let n=i.prev;zG(this,e,i,t),i=n}}forEach(e,t){t=t||this;for(let i=this[di].head;i!==null;){let n=i.next;zG(this,e,i,t),i=n}}keys(){return this[di].toArray().map(e=>e.key)}values(){return this[di].toArray().map(e=>e.value)}reset(){this[ba]&&this[di]&&this[di].length&&this[di].forEach(e=>this[ba](e.key,e.value)),this[Zs]=new Map,this[di]=new Ime,this[Sa]=0}dump(){return this[di].map(e=>zI(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[di]}set(e,t,i){if(i=i||this[pc],i&&typeof i!="number")throw new TypeError("maxAge must be a number");let n=i?Date.now():0,s=this[Wg](t,e);if(this[Zs].has(e)){if(s>this[hc])return zg(this,this[Zs].get(e)),!1;let l=this[Zs].get(e).value;return this[ba]&&(this[WG]||this[ba](e,l.value)),l.now=n,l.maxAge=i,l.value=t,this[Sa]+=s-l.length,l.length=s,this.get(e),Cd(this),!0}let o=new wv(e,t,s,n,i);return o.length>this[hc]?(this[ba]&&this[ba](e,t),!1):(this[Sa]+=o.length,this[di].unshift(o),this[Zs].set(e,this[di].head),Cd(this),!0)}has(e){if(!this[Zs].has(e))return!1;let t=this[Zs].get(e).value;return!zI(this,t)}get(e){return Iv(this,e,!0)}peek(e){return Iv(this,e,!1)}pop(){let e=this[di].tail;return e?(zg(this,e),e.value):null}del(e){zg(this,this[Zs].get(e))}load(e){this.reset();let t=Date.now();for(let i=e.length-1;i>=0;i--){let n=e[i],s=n.e||0;if(s===0)this.set(n.k,n.v);else{let o=s-t;o>0&&this.set(n.k,n.v,o)}}}prune(){this[Zs].forEach((e,t)=>Iv(this,t,!1))}},Iv=(r,e,t)=>{let i=r[Zs].get(e);if(i){let n=i.value;if(zI(r,n)){if(zg(r,i),!r[md])return}else t&&(r[VG]&&(i.value.now=Date.now()),r[di].unshiftNode(i));return n.value}},zI=(r,e)=>{if(!e||!e.maxAge&&!r[pc])return!1;let t=Date.now()-e.now;return e.maxAge?t>e.maxAge:r[pc]&&t>r[pc]},Cd=r=>{if(r[Sa]>r[hc])for(let e=r[di].tail;r[Sa]>r[hc]&&e!==null;){let t=e.prev;zg(r,e),e=t}},zg=(r,e)=>{if(e){let t=e.value;r[ba]&&r[ba](t.key,t.value),r[Sa]-=t.length,r[Zs].delete(t.key),r[di].removeNode(e)}},wv=class{constructor(e,t,i,n,s){this.key=e,this.value=t,this.length=i,this.now=n,this.maxAge=s||0}},zG=(r,e,t,i)=>{let n=t.value;zI(r,n)&&(zg(r,t),r[md]||(n=void 0)),n&&e.call(i,n.value,n.key,r)};XG.exports=yv});var us=w((M$e,tY)=>{var dc=class{constructor(e,t){if(t=wme(t),e instanceof dc)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new dc(e.raw,t);if(e instanceof Bv)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(i=>this.parseRange(i.trim())).filter(i=>i.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${e}`);if(this.set.length>1){let i=this.set[0];if(this.set=this.set.filter(n=>!$G(n[0])),this.set.length===0)this.set=[i];else if(this.set.length>1){for(let n of this.set)if(n.length===1&&vme(n[0])){this.set=[n];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){e=e.trim();let i=`parseRange:${Object.keys(this.options).join(",")}:${e}`,n=_G.get(i);if(n)return n;let s=this.options.loose,o=s?Oi[Qi.HYPHENRANGELOOSE]:Oi[Qi.HYPHENRANGE];e=e.replace(o,Ome(this.options.includePrerelease)),Gr("hyphen replace",e),e=e.replace(Oi[Qi.COMPARATORTRIM],Qme),Gr("comparator trim",e,Oi[Qi.COMPARATORTRIM]),e=e.replace(Oi[Qi.TILDETRIM],bme),e=e.replace(Oi[Qi.CARETTRIM],Sme),e=e.split(/\s+/).join(" ");let a=s?Oi[Qi.COMPARATORLOOSE]:Oi[Qi.COMPARATOR],l=e.split(" ").map(f=>xme(f,this.options)).join(" ").split(/\s+/).map(f=>Tme(f,this.options)).filter(this.options.loose?f=>!!f.match(a):()=>!0).map(f=>new Bv(f,this.options)),c=l.length,u=new Map;for(let f of l){if($G(f))return[f];u.set(f.value,f)}u.size>1&&u.has("")&&u.delete("");let g=[...u.values()];return _G.set(i,g),g}intersects(e,t){if(!(e instanceof dc))throw new TypeError("a Range is required");return this.set.some(i=>eY(i,t)&&e.set.some(n=>eY(n,t)&&i.every(s=>n.every(o=>s.intersects(o,t)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new Bme(e,this.options)}catch{return!1}for(let t=0;tr.value==="<0.0.0-0",vme=r=>r.value==="",eY=(r,e)=>{let t=!0,i=r.slice(),n=i.pop();for(;t&&i.length;)t=i.every(s=>n.intersects(s,e)),n=i.pop();return t},xme=(r,e)=>(Gr("comp",r,e),r=kme(r,e),Gr("caret",r),r=Pme(r,e),Gr("tildes",r),r=Fme(r,e),Gr("xrange",r),r=Lme(r,e),Gr("stars",r),r),_i=r=>!r||r.toLowerCase()==="x"||r==="*",Pme=(r,e)=>r.trim().split(/\s+/).map(t=>Dme(t,e)).join(" "),Dme=(r,e)=>{let t=e.loose?Oi[Qi.TILDELOOSE]:Oi[Qi.TILDE];return r.replace(t,(i,n,s,o,a)=>{Gr("tilde",r,i,n,s,o,a);let l;return _i(n)?l="":_i(s)?l=`>=${n}.0.0 <${+n+1}.0.0-0`:_i(o)?l=`>=${n}.${s}.0 <${n}.${+s+1}.0-0`:a?(Gr("replaceTilde pr",a),l=`>=${n}.${s}.${o}-${a} <${n}.${+s+1}.0-0`):l=`>=${n}.${s}.${o} <${n}.${+s+1}.0-0`,Gr("tilde return",l),l})},kme=(r,e)=>r.trim().split(/\s+/).map(t=>Rme(t,e)).join(" "),Rme=(r,e)=>{Gr("caret",r,e);let t=e.loose?Oi[Qi.CARETLOOSE]:Oi[Qi.CARET],i=e.includePrerelease?"-0":"";return r.replace(t,(n,s,o,a,l)=>{Gr("caret",r,n,s,o,a,l);let c;return _i(s)?c="":_i(o)?c=`>=${s}.0.0${i} <${+s+1}.0.0-0`:_i(a)?s==="0"?c=`>=${s}.${o}.0${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.0${i} <${+s+1}.0.0-0`:l?(Gr("replaceCaret pr",l),s==="0"?o==="0"?c=`>=${s}.${o}.${a}-${l} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}-${l} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a}-${l} <${+s+1}.0.0-0`):(Gr("no pr"),s==="0"?o==="0"?c=`>=${s}.${o}.${a}${i} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a} <${+s+1}.0.0-0`),Gr("caret return",c),c})},Fme=(r,e)=>(Gr("replaceXRanges",r,e),r.split(/\s+/).map(t=>Nme(t,e)).join(" ")),Nme=(r,e)=>{r=r.trim();let t=e.loose?Oi[Qi.XRANGELOOSE]:Oi[Qi.XRANGE];return r.replace(t,(i,n,s,o,a,l)=>{Gr("xRange",r,i,n,s,o,a,l);let c=_i(s),u=c||_i(o),g=u||_i(a),f=g;return n==="="&&f&&(n=""),l=e.includePrerelease?"-0":"",c?n===">"||n==="<"?i="<0.0.0-0":i="*":n&&f?(u&&(o=0),a=0,n===">"?(n=">=",u?(s=+s+1,o=0,a=0):(o=+o+1,a=0)):n==="<="&&(n="<",u?s=+s+1:o=+o+1),n==="<"&&(l="-0"),i=`${n+s}.${o}.${a}${l}`):u?i=`>=${s}.0.0${l} <${+s+1}.0.0-0`:g&&(i=`>=${s}.${o}.0${l} <${s}.${+o+1}.0-0`),Gr("xRange return",i),i})},Lme=(r,e)=>(Gr("replaceStars",r,e),r.trim().replace(Oi[Qi.STAR],"")),Tme=(r,e)=>(Gr("replaceGTE0",r,e),r.trim().replace(Oi[e.includePrerelease?Qi.GTE0PRE:Qi.GTE0],"")),Ome=r=>(e,t,i,n,s,o,a,l,c,u,g,f,h)=>(_i(i)?t="":_i(n)?t=`>=${i}.0.0${r?"-0":""}`:_i(s)?t=`>=${i}.${n}.0${r?"-0":""}`:o?t=`>=${t}`:t=`>=${t}${r?"-0":""}`,_i(c)?l="":_i(u)?l=`<${+c+1}.0.0-0`:_i(g)?l=`<${c}.${+u+1}.0-0`:f?l=`<=${c}.${u}.${g}-${f}`:r?l=`<${c}.${u}.${+g+1}-0`:l=`<=${l}`,`${t} ${l}`.trim()),Mme=(r,e,t)=>{for(let i=0;i0){let n=r[i].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0}});var Ed=w((U$e,oY)=>{var Id=Symbol("SemVer ANY"),Vg=class{static get ANY(){return Id}constructor(e,t){if(t=Ume(t),e instanceof Vg){if(e.loose===!!t.loose)return e;e=e.value}bv("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===Id?this.value="":this.value=this.operator+this.semver.version,bv("comp",this)}parse(e){let t=this.options.loose?rY[iY.COMPARATORLOOSE]:rY[iY.COMPARATOR],i=e.match(t);if(!i)throw new TypeError(`Invalid comparator: ${e}`);this.operator=i[1]!==void 0?i[1]:"",this.operator==="="&&(this.operator=""),i[2]?this.semver=new nY(i[2],this.options.loose):this.semver=Id}toString(){return this.value}test(e){if(bv("Comparator.test",e,this.options.loose),this.semver===Id||e===Id)return!0;if(typeof e=="string")try{e=new nY(e,this.options)}catch{return!1}return Qv(e,this.operator,this.semver,this.options)}intersects(e,t){if(!(e instanceof Vg))throw new TypeError("a Comparator is required");if((!t||typeof t!="object")&&(t={loose:!!t,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new sY(e.value,t).test(this.value);if(e.operator==="")return e.value===""?!0:new sY(this.value,t).test(e.semver);let i=(this.operator===">="||this.operator===">")&&(e.operator===">="||e.operator===">"),n=(this.operator==="<="||this.operator==="<")&&(e.operator==="<="||e.operator==="<"),s=this.semver.version===e.semver.version,o=(this.operator===">="||this.operator==="<=")&&(e.operator===">="||e.operator==="<="),a=Qv(this.semver,"<",e.semver,t)&&(this.operator===">="||this.operator===">")&&(e.operator==="<="||e.operator==="<"),l=Qv(this.semver,">",e.semver,t)&&(this.operator==="<="||this.operator==="<")&&(e.operator===">="||e.operator===">");return i||n||s&&o||a||l}};oY.exports=Vg;var Ume=hd(),{re:rY,t:iY}=uc(),Qv=mv(),bv=fd(),nY=Ti(),sY=us()});var yd=w((K$e,aY)=>{var Kme=us(),Hme=(r,e,t)=>{try{e=new Kme(e,t)}catch{return!1}return e.test(r)};aY.exports=Hme});var lY=w((H$e,AY)=>{var Gme=us(),Yme=(r,e)=>new Gme(r,e).set.map(t=>t.map(i=>i.value).join(" ").trim().split(" "));AY.exports=Yme});var uY=w((G$e,cY)=>{var jme=Ti(),qme=us(),Jme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new qme(e,t)}catch{return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===-1)&&(i=o,n=new jme(i,t))}),i};cY.exports=Jme});var fY=w((Y$e,gY)=>{var Wme=Ti(),zme=us(),Vme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new zme(e,t)}catch{return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===1)&&(i=o,n=new Wme(i,t))}),i};gY.exports=Vme});var dY=w((j$e,pY)=>{var Sv=Ti(),Xme=us(),hY=dd(),Zme=(r,e)=>{r=new Xme(r,e);let t=new Sv("0.0.0");if(r.test(t)||(t=new Sv("0.0.0-0"),r.test(t)))return t;t=null;for(let i=0;i{let a=new Sv(o.semver.version);switch(o.operator){case">":a.prerelease.length===0?a.patch++:a.prerelease.push(0),a.raw=a.format();case"":case">=":(!s||hY(a,s))&&(s=a);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${o.operator}`)}}),s&&(!t||hY(t,s))&&(t=s)}return t&&r.test(t)?t:null};pY.exports=Zme});var mY=w((q$e,CY)=>{var _me=us(),$me=(r,e)=>{try{return new _me(r,e).range||"*"}catch{return null}};CY.exports=$me});var VI=w((J$e,wY)=>{var eEe=Ti(),yY=Ed(),{ANY:tEe}=yY,rEe=us(),iEe=yd(),EY=dd(),IY=GI(),nEe=jI(),sEe=YI(),oEe=(r,e,t,i)=>{r=new eEe(r,i),e=new rEe(e,i);let n,s,o,a,l;switch(t){case">":n=EY,s=nEe,o=IY,a=">",l=">=";break;case"<":n=IY,s=sEe,o=EY,a="<",l="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(iEe(r,e,i))return!1;for(let c=0;c{h.semver===tEe&&(h=new yY(">=0.0.0")),g=g||h,f=f||h,n(h.semver,g.semver,i)?g=h:o(h.semver,f.semver,i)&&(f=h)}),g.operator===a||g.operator===l||(!f.operator||f.operator===a)&&s(r,f.semver))return!1;if(f.operator===l&&o(r,f.semver))return!1}return!0};wY.exports=oEe});var QY=w((W$e,BY)=>{var aEe=VI(),AEe=(r,e,t)=>aEe(r,e,">",t);BY.exports=AEe});var SY=w((z$e,bY)=>{var lEe=VI(),cEe=(r,e,t)=>lEe(r,e,"<",t);bY.exports=cEe});var PY=w((V$e,xY)=>{var vY=us(),uEe=(r,e,t)=>(r=new vY(r,t),e=new vY(e,t),r.intersects(e));xY.exports=uEe});var kY=w((X$e,DY)=>{var gEe=yd(),fEe=cs();DY.exports=(r,e,t)=>{let i=[],n=null,s=null,o=r.sort((u,g)=>fEe(u,g,t));for(let u of o)gEe(u,e,t)?(s=u,n||(n=u)):(s&&i.push([n,s]),s=null,n=null);n&&i.push([n,null]);let a=[];for(let[u,g]of i)u===g?a.push(u):!g&&u===o[0]?a.push("*"):g?u===o[0]?a.push(`<=${g}`):a.push(`${u} - ${g}`):a.push(`>=${u}`);let l=a.join(" || "),c=typeof e.raw=="string"?e.raw:String(e);return l.length{var RY=us(),XI=Ed(),{ANY:vv}=XI,wd=yd(),xv=cs(),hEe=(r,e,t={})=>{if(r===e)return!0;r=new RY(r,t),e=new RY(e,t);let i=!1;e:for(let n of r.set){for(let s of e.set){let o=pEe(n,s,t);if(i=i||o!==null,o)continue e}if(i)return!1}return!0},pEe=(r,e,t)=>{if(r===e)return!0;if(r.length===1&&r[0].semver===vv){if(e.length===1&&e[0].semver===vv)return!0;t.includePrerelease?r=[new XI(">=0.0.0-0")]:r=[new XI(">=0.0.0")]}if(e.length===1&&e[0].semver===vv){if(t.includePrerelease)return!0;e=[new XI(">=0.0.0")]}let i=new Set,n,s;for(let h of r)h.operator===">"||h.operator===">="?n=FY(n,h,t):h.operator==="<"||h.operator==="<="?s=NY(s,h,t):i.add(h.semver);if(i.size>1)return null;let o;if(n&&s){if(o=xv(n.semver,s.semver,t),o>0)return null;if(o===0&&(n.operator!==">="||s.operator!=="<="))return null}for(let h of i){if(n&&!wd(h,String(n),t)||s&&!wd(h,String(s),t))return null;for(let p of e)if(!wd(h,String(p),t))return!1;return!0}let a,l,c,u,g=s&&!t.includePrerelease&&s.semver.prerelease.length?s.semver:!1,f=n&&!t.includePrerelease&&n.semver.prerelease.length?n.semver:!1;g&&g.prerelease.length===1&&s.operator==="<"&&g.prerelease[0]===0&&(g=!1);for(let h of e){if(u=u||h.operator===">"||h.operator===">=",c=c||h.operator==="<"||h.operator==="<=",n){if(f&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===f.major&&h.semver.minor===f.minor&&h.semver.patch===f.patch&&(f=!1),h.operator===">"||h.operator===">="){if(a=FY(n,h,t),a===h&&a!==n)return!1}else if(n.operator===">="&&!wd(n.semver,String(h),t))return!1}if(s){if(g&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===g.major&&h.semver.minor===g.minor&&h.semver.patch===g.patch&&(g=!1),h.operator==="<"||h.operator==="<="){if(l=NY(s,h,t),l===h&&l!==s)return!1}else if(s.operator==="<="&&!wd(s.semver,String(h),t))return!1}if(!h.operator&&(s||n)&&o!==0)return!1}return!(n&&c&&!s&&o!==0||s&&u&&!n&&o!==0||f||g)},FY=(r,e,t)=>{if(!r)return e;let i=xv(r.semver,e.semver,t);return i>0?r:i<0||e.operator===">"&&r.operator===">="?e:r},NY=(r,e,t)=>{if(!r)return e;let i=xv(r.semver,e.semver,t);return i<0?r:i>0||e.operator==="<"&&r.operator==="<="?e:r};LY.exports=hEe});var Xr=w((_$e,OY)=>{var Pv=uc();OY.exports={re:Pv.re,src:Pv.src,tokens:Pv.t,SEMVER_SPEC_VERSION:gd().SEMVER_SPEC_VERSION,SemVer:Ti(),compareIdentifiers:OI().compareIdentifiers,rcompareIdentifiers:OI().rcompareIdentifiers,parse:gc(),valid:aG(),clean:lG(),inc:uG(),diff:CG(),major:EG(),minor:yG(),patch:BG(),prerelease:bG(),compare:cs(),rcompare:vG(),compareLoose:PG(),compareBuild:HI(),sort:FG(),rsort:LG(),gt:dd(),lt:GI(),eq:KI(),neq:Cv(),gte:YI(),lte:jI(),cmp:mv(),coerce:YG(),Comparator:Ed(),Range:us(),satisfies:yd(),toComparators:lY(),maxSatisfying:uY(),minSatisfying:fY(),minVersion:dY(),validRange:mY(),outside:VI(),gtr:QY(),ltr:SY(),intersects:PY(),simplifyRange:kY(),subset:TY()}});var Dv=w(ZI=>{"use strict";Object.defineProperty(ZI,"__esModule",{value:!0});ZI.VERSION=void 0;ZI.VERSION="9.1.0"});var Gt=w((exports,module)=>{"use strict";var __spreadArray=exports&&exports.__spreadArray||function(r,e,t){if(t||arguments.length===2)for(var i=0,n=e.length,s;i{(function(r,e){typeof define=="function"&&define.amd?define([],e):typeof _I=="object"&&_I.exports?_I.exports=e():r.regexpToAst=e()})(typeof self<"u"?self:MY,function(){function r(){}r.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},r.prototype.restoreState=function(p){this.idx=p.idx,this.input=p.input,this.groupIdx=p.groupIdx},r.prototype.pattern=function(p){this.idx=0,this.input=p,this.groupIdx=0,this.consumeChar("/");var C=this.disjunction();this.consumeChar("/");for(var y={type:"Flags",loc:{begin:this.idx,end:p.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};this.isRegExpFlag();)switch(this.popChar()){case"g":o(y,"global");break;case"i":o(y,"ignoreCase");break;case"m":o(y,"multiLine");break;case"u":o(y,"unicode");break;case"y":o(y,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:y,value:C,loc:this.loc(0)}},r.prototype.disjunction=function(){var p=[],C=this.idx;for(p.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),p.push(this.alternative());return{type:"Disjunction",value:p,loc:this.loc(C)}},r.prototype.alternative=function(){for(var p=[],C=this.idx;this.isTerm();)p.push(this.term());return{type:"Alternative",value:p,loc:this.loc(C)}},r.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},r.prototype.assertion=function(){var p=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(p)};case"$":return{type:"EndAnchor",loc:this.loc(p)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(p)};case"B":return{type:"NonWordBoundary",loc:this.loc(p)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");var C;switch(this.popChar()){case"=":C="Lookahead";break;case"!":C="NegativeLookahead";break}a(C);var y=this.disjunction();return this.consumeChar(")"),{type:C,value:y,loc:this.loc(p)}}l()},r.prototype.quantifier=function(p){var C,y=this.idx;switch(this.popChar()){case"*":C={atLeast:0,atMost:1/0};break;case"+":C={atLeast:1,atMost:1/0};break;case"?":C={atLeast:0,atMost:1};break;case"{":var B=this.integerIncludingZero();switch(this.popChar()){case"}":C={atLeast:B,atMost:B};break;case",":var v;this.isDigit()?(v=this.integerIncludingZero(),C={atLeast:B,atMost:v}):C={atLeast:B,atMost:1/0},this.consumeChar("}");break}if(p===!0&&C===void 0)return;a(C);break}if(!(p===!0&&C===void 0))return a(C),this.peekChar(0)==="?"?(this.consumeChar("?"),C.greedy=!1):C.greedy=!0,C.type="Quantifier",C.loc=this.loc(y),C},r.prototype.atom=function(){var p,C=this.idx;switch(this.peekChar()){case".":p=this.dotAll();break;case"\\":p=this.atomEscape();break;case"[":p=this.characterClass();break;case"(":p=this.group();break}return p===void 0&&this.isPatternCharacter()&&(p=this.patternCharacter()),a(p),p.loc=this.loc(C),this.isQuantifier()&&(p.quantifier=this.quantifier()),p},r.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[n(` +`),n("\r"),n("\u2028"),n("\u2029")]}},r.prototype.atomEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},r.prototype.decimalEscapeAtom=function(){var p=this.positiveInteger();return{type:"GroupBackReference",value:p}},r.prototype.characterClassEscape=function(){var p,C=!1;switch(this.popChar()){case"d":p=u;break;case"D":p=u,C=!0;break;case"s":p=f;break;case"S":p=f,C=!0;break;case"w":p=g;break;case"W":p=g,C=!0;break}return a(p),{type:"Set",value:p,complement:C}},r.prototype.controlEscapeAtom=function(){var p;switch(this.popChar()){case"f":p=n("\f");break;case"n":p=n(` +`);break;case"r":p=n("\r");break;case"t":p=n(" ");break;case"v":p=n("\v");break}return a(p),{type:"Character",value:p}},r.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var p=this.popChar();if(/[a-zA-Z]/.test(p)===!1)throw Error("Invalid ");var C=p.toUpperCase().charCodeAt(0)-64;return{type:"Character",value:C}},r.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:n("\0")}},r.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},r.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},r.prototype.identityEscapeAtom=function(){var p=this.popChar();return{type:"Character",value:n(p)}},r.prototype.classPatternCharacterAtom=function(){switch(this.peekChar()){case` +`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:var p=this.popChar();return{type:"Character",value:n(p)}}},r.prototype.characterClass=function(){var p=[],C=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),C=!0);this.isClassAtom();){var y=this.classAtom(),B=y.type==="Character";if(B&&this.isRangeDash()){this.consumeChar("-");var v=this.classAtom(),D=v.type==="Character";if(D){if(v.value=this.input.length)throw Error("Unexpected end of input");this.idx++},r.prototype.loc=function(p){return{begin:p,end:this.idx}};var e=/[0-9a-fA-F]/,t=/[0-9]/,i=/[1-9]/;function n(p){return p.charCodeAt(0)}function s(p,C){p.length!==void 0?p.forEach(function(y){C.push(y)}):C.push(p)}function o(p,C){if(p[C]===!0)throw"duplicate flag "+C;p[C]=!0}function a(p){if(p===void 0)throw Error("Internal Error - Should never get here!")}function l(){throw Error("Internal Error - Should never get here!")}var c,u=[];for(c=n("0");c<=n("9");c++)u.push(c);var g=[n("_")].concat(u);for(c=n("a");c<=n("z");c++)g.push(c);for(c=n("A");c<=n("Z");c++)g.push(c);var f=[n(" "),n("\f"),n(` +`),n("\r"),n(" "),n("\v"),n(" "),n("\xA0"),n("\u1680"),n("\u2000"),n("\u2001"),n("\u2002"),n("\u2003"),n("\u2004"),n("\u2005"),n("\u2006"),n("\u2007"),n("\u2008"),n("\u2009"),n("\u200A"),n("\u2028"),n("\u2029"),n("\u202F"),n("\u205F"),n("\u3000"),n("\uFEFF")];function h(){}return h.prototype.visitChildren=function(p){for(var C in p){var y=p[C];p.hasOwnProperty(C)&&(y.type!==void 0?this.visit(y):Array.isArray(y)&&y.forEach(function(B){this.visit(B)},this))}},h.prototype.visit=function(p){switch(p.type){case"Pattern":this.visitPattern(p);break;case"Flags":this.visitFlags(p);break;case"Disjunction":this.visitDisjunction(p);break;case"Alternative":this.visitAlternative(p);break;case"StartAnchor":this.visitStartAnchor(p);break;case"EndAnchor":this.visitEndAnchor(p);break;case"WordBoundary":this.visitWordBoundary(p);break;case"NonWordBoundary":this.visitNonWordBoundary(p);break;case"Lookahead":this.visitLookahead(p);break;case"NegativeLookahead":this.visitNegativeLookahead(p);break;case"Character":this.visitCharacter(p);break;case"Set":this.visitSet(p);break;case"Group":this.visitGroup(p);break;case"GroupBackReference":this.visitGroupBackReference(p);break;case"Quantifier":this.visitQuantifier(p);break}this.visitChildren(p)},h.prototype.visitPattern=function(p){},h.prototype.visitFlags=function(p){},h.prototype.visitDisjunction=function(p){},h.prototype.visitAlternative=function(p){},h.prototype.visitStartAnchor=function(p){},h.prototype.visitEndAnchor=function(p){},h.prototype.visitWordBoundary=function(p){},h.prototype.visitNonWordBoundary=function(p){},h.prototype.visitLookahead=function(p){},h.prototype.visitNegativeLookahead=function(p){},h.prototype.visitCharacter=function(p){},h.prototype.visitSet=function(p){},h.prototype.visitGroup=function(p){},h.prototype.visitGroupBackReference=function(p){},h.prototype.visitQuantifier=function(p){},{RegExpParser:r,BaseRegExpVisitor:h,VERSION:"0.5.0"}})});var ty=w(Xg=>{"use strict";Object.defineProperty(Xg,"__esModule",{value:!0});Xg.clearRegExpParserCache=Xg.getRegExpAst=void 0;var dEe=$I(),ey={},CEe=new dEe.RegExpParser;function mEe(r){var e=r.toString();if(ey.hasOwnProperty(e))return ey[e];var t=CEe.pattern(e);return ey[e]=t,t}Xg.getRegExpAst=mEe;function EEe(){ey={}}Xg.clearRegExpParserCache=EEe});var YY=w(dn=>{"use strict";var IEe=dn&&dn.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(dn,"__esModule",{value:!0});dn.canMatchCharCode=dn.firstCharOptimizedIndices=dn.getOptimizedStartCodesIndices=dn.failedOptimizationPrefixMsg=void 0;var KY=$I(),gs=Gt(),HY=ty(),va=Rv(),GY="Complement Sets are not supported for first char optimization";dn.failedOptimizationPrefixMsg=`Unable to use "first char" lexer optimizations: +`;function yEe(r,e){e===void 0&&(e=!1);try{var t=(0,HY.getRegExpAst)(r),i=iy(t.value,{},t.flags.ignoreCase);return i}catch(s){if(s.message===GY)e&&(0,gs.PRINT_WARNING)(""+dn.failedOptimizationPrefixMsg+(" Unable to optimize: < "+r.toString()+` > +`)+` Complement Sets cannot be automatically optimized. + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{var n="";e&&(n=` + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),(0,gs.PRINT_ERROR)(dn.failedOptimizationPrefixMsg+` +`+(" Failed parsing: < "+r.toString()+` > +`)+(" Using the regexp-to-ast library version: "+KY.VERSION+` +`)+" Please open an issue at: https://github.com/bd82/regexp-to-ast/issues"+n)}}return[]}dn.getOptimizedStartCodesIndices=yEe;function iy(r,e,t){switch(r.type){case"Disjunction":for(var i=0;i=va.minOptimizationVal)for(var f=u.from>=va.minOptimizationVal?u.from:va.minOptimizationVal,h=u.to,p=(0,va.charCodeToOptimizedIndex)(f),C=(0,va.charCodeToOptimizedIndex)(h),y=p;y<=C;y++)e[y]=y}}});break;case"Group":iy(o.value,e,t);break;default:throw Error("Non Exhaustive Match")}var a=o.quantifier!==void 0&&o.quantifier.atLeast===0;if(o.type==="Group"&&kv(o)===!1||o.type!=="Group"&&a===!1)break}break;default:throw Error("non exhaustive match!")}return(0,gs.values)(e)}dn.firstCharOptimizedIndices=iy;function ry(r,e,t){var i=(0,va.charCodeToOptimizedIndex)(r);e[i]=i,t===!0&&wEe(r,e)}function wEe(r,e){var t=String.fromCharCode(r),i=t.toUpperCase();if(i!==t){var n=(0,va.charCodeToOptimizedIndex)(i.charCodeAt(0));e[n]=n}else{var s=t.toLowerCase();if(s!==t){var n=(0,va.charCodeToOptimizedIndex)(s.charCodeAt(0));e[n]=n}}}function UY(r,e){return(0,gs.find)(r.value,function(t){if(typeof t=="number")return(0,gs.contains)(e,t);var i=t;return(0,gs.find)(e,function(n){return i.from<=n&&n<=i.to})!==void 0})}function kv(r){return r.quantifier&&r.quantifier.atLeast===0?!0:r.value?(0,gs.isArray)(r.value)?(0,gs.every)(r.value,kv):kv(r.value):!1}var BEe=function(r){IEe(e,r);function e(t){var i=r.call(this)||this;return i.targetCharCodes=t,i.found=!1,i}return e.prototype.visitChildren=function(t){if(this.found!==!0){switch(t.type){case"Lookahead":this.visitLookahead(t);return;case"NegativeLookahead":this.visitNegativeLookahead(t);return}r.prototype.visitChildren.call(this,t)}},e.prototype.visitCharacter=function(t){(0,gs.contains)(this.targetCharCodes,t.value)&&(this.found=!0)},e.prototype.visitSet=function(t){t.complement?UY(t,this.targetCharCodes)===void 0&&(this.found=!0):UY(t,this.targetCharCodes)!==void 0&&(this.found=!0)},e}(KY.BaseRegExpVisitor);function QEe(r,e){if(e instanceof RegExp){var t=(0,HY.getRegExpAst)(e),i=new BEe(r);return i.visit(t),i.found}else return(0,gs.find)(e,function(n){return(0,gs.contains)(r,n.charCodeAt(0))})!==void 0}dn.canMatchCharCode=QEe});var Rv=w(Ve=>{"use strict";var jY=Ve&&Ve.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Ve,"__esModule",{value:!0});Ve.charCodeToOptimizedIndex=Ve.minOptimizationVal=Ve.buildLineBreakIssueMessage=Ve.LineTerminatorOptimizedTester=Ve.isShortPattern=Ve.isCustomPattern=Ve.cloneEmptyGroups=Ve.performWarningRuntimeChecks=Ve.performRuntimeChecks=Ve.addStickyFlag=Ve.addStartOfInput=Ve.findUnreachablePatterns=Ve.findModesThatDoNotExist=Ve.findInvalidGroupType=Ve.findDuplicatePatterns=Ve.findUnsupportedFlags=Ve.findStartOfInputAnchor=Ve.findEmptyMatchRegExps=Ve.findEndOfInputAnchor=Ve.findInvalidPatterns=Ve.findMissingPatterns=Ve.validatePatterns=Ve.analyzeTokenTypes=Ve.enableSticky=Ve.disableSticky=Ve.SUPPORT_STICKY=Ve.MODES=Ve.DEFAULT_MODE=void 0;var qY=$I(),ir=Bd(),xe=Gt(),Zg=YY(),JY=ty(),Do="PATTERN";Ve.DEFAULT_MODE="defaultMode";Ve.MODES="modes";Ve.SUPPORT_STICKY=typeof new RegExp("(?:)").sticky=="boolean";function bEe(){Ve.SUPPORT_STICKY=!1}Ve.disableSticky=bEe;function SEe(){Ve.SUPPORT_STICKY=!0}Ve.enableSticky=SEe;function vEe(r,e){e=(0,xe.defaults)(e,{useSticky:Ve.SUPPORT_STICKY,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` +`],tracer:function(v,D){return D()}});var t=e.tracer;t("initCharCodeToOptimizedIndexMap",function(){OEe()});var i;t("Reject Lexer.NA",function(){i=(0,xe.reject)(r,function(v){return v[Do]===ir.Lexer.NA})});var n=!1,s;t("Transform Patterns",function(){n=!1,s=(0,xe.map)(i,function(v){var D=v[Do];if((0,xe.isRegExp)(D)){var L=D.source;return L.length===1&&L!=="^"&&L!=="$"&&L!=="."&&!D.ignoreCase?L:L.length===2&&L[0]==="\\"&&!(0,xe.contains)(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],L[1])?L[1]:e.useSticky?Lv(D):Nv(D)}else{if((0,xe.isFunction)(D))return n=!0,{exec:D};if((0,xe.has)(D,"exec"))return n=!0,D;if(typeof D=="string"){if(D.length===1)return D;var H=D.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),j=new RegExp(H);return e.useSticky?Lv(j):Nv(j)}else throw Error("non exhaustive match")}})});var o,a,l,c,u;t("misc mapping",function(){o=(0,xe.map)(i,function(v){return v.tokenTypeIdx}),a=(0,xe.map)(i,function(v){var D=v.GROUP;if(D!==ir.Lexer.SKIPPED){if((0,xe.isString)(D))return D;if((0,xe.isUndefined)(D))return!1;throw Error("non exhaustive match")}}),l=(0,xe.map)(i,function(v){var D=v.LONGER_ALT;if(D){var L=(0,xe.isArray)(D)?(0,xe.map)(D,function(H){return(0,xe.indexOf)(i,H)}):[(0,xe.indexOf)(i,D)];return L}}),c=(0,xe.map)(i,function(v){return v.PUSH_MODE}),u=(0,xe.map)(i,function(v){return(0,xe.has)(v,"POP_MODE")})});var g;t("Line Terminator Handling",function(){var v=oj(e.lineTerminatorCharacters);g=(0,xe.map)(i,function(D){return!1}),e.positionTracking!=="onlyOffset"&&(g=(0,xe.map)(i,function(D){if((0,xe.has)(D,"LINE_BREAKS"))return D.LINE_BREAKS;if(nj(D,v)===!1)return(0,Zg.canMatchCharCode)(v,D.PATTERN)}))});var f,h,p,C;t("Misc Mapping #2",function(){f=(0,xe.map)(i,Ov),h=(0,xe.map)(s,ij),p=(0,xe.reduce)(i,function(v,D){var L=D.GROUP;return(0,xe.isString)(L)&&L!==ir.Lexer.SKIPPED&&(v[L]=[]),v},{}),C=(0,xe.map)(s,function(v,D){return{pattern:s[D],longerAlt:l[D],canLineTerminator:g[D],isCustom:f[D],short:h[D],group:a[D],push:c[D],pop:u[D],tokenTypeIdx:o[D],tokenType:i[D]}})});var y=!0,B=[];return e.safeMode||t("First Char Optimization",function(){B=(0,xe.reduce)(i,function(v,D,L){if(typeof D.PATTERN=="string"){var H=D.PATTERN.charCodeAt(0),j=Tv(H);Fv(v,j,C[L])}else if((0,xe.isArray)(D.START_CHARS_HINT)){var $;(0,xe.forEach)(D.START_CHARS_HINT,function(W){var _=typeof W=="string"?W.charCodeAt(0):W,A=Tv(_);$!==A&&($=A,Fv(v,A,C[L]))})}else if((0,xe.isRegExp)(D.PATTERN))if(D.PATTERN.unicode)y=!1,e.ensureOptimizations&&(0,xe.PRINT_ERROR)(""+Zg.failedOptimizationPrefixMsg+(" Unable to analyze < "+D.PATTERN.toString()+` > pattern. +`)+` The regexp unicode flag is not currently supported by the regexp-to-ast library. + This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{var V=(0,Zg.getOptimizedStartCodesIndices)(D.PATTERN,e.ensureOptimizations);(0,xe.isEmpty)(V)&&(y=!1),(0,xe.forEach)(V,function(W){Fv(v,W,C[L])})}else e.ensureOptimizations&&(0,xe.PRINT_ERROR)(""+Zg.failedOptimizationPrefixMsg+(" TokenType: <"+D.name+`> is using a custom token pattern without providing parameter. +`)+` This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),y=!1;return v},[])}),t("ArrayPacking",function(){B=(0,xe.packArray)(B)}),{emptyGroups:p,patternIdxToConfig:C,charCodeToPatternIdxToConfig:B,hasCustom:n,canBeOptimized:y}}Ve.analyzeTokenTypes=vEe;function xEe(r,e){var t=[],i=WY(r);t=t.concat(i.errors);var n=zY(i.valid),s=n.valid;return t=t.concat(n.errors),t=t.concat(PEe(s)),t=t.concat(ej(s)),t=t.concat(tj(s,e)),t=t.concat(rj(s)),t}Ve.validatePatterns=xEe;function PEe(r){var e=[],t=(0,xe.filter)(r,function(i){return(0,xe.isRegExp)(i[Do])});return e=e.concat(VY(t)),e=e.concat(ZY(t)),e=e.concat(_Y(t)),e=e.concat($Y(t)),e=e.concat(XY(t)),e}function WY(r){var e=(0,xe.filter)(r,function(n){return!(0,xe.has)(n,Do)}),t=(0,xe.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- missing static 'PATTERN' property",type:ir.LexerDefinitionErrorType.MISSING_PATTERN,tokenTypes:[n]}}),i=(0,xe.difference)(r,e);return{errors:t,valid:i}}Ve.findMissingPatterns=WY;function zY(r){var e=(0,xe.filter)(r,function(n){var s=n[Do];return!(0,xe.isRegExp)(s)&&!(0,xe.isFunction)(s)&&!(0,xe.has)(s,"exec")&&!(0,xe.isString)(s)}),t=(0,xe.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:ir.LexerDefinitionErrorType.INVALID_PATTERN,tokenTypes:[n]}}),i=(0,xe.difference)(r,e);return{errors:t,valid:i}}Ve.findInvalidPatterns=zY;var DEe=/[^\\][\$]/;function VY(r){var e=function(n){jY(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitEndAnchor=function(o){this.found=!0},s}(qY.BaseRegExpVisitor),t=(0,xe.filter)(r,function(n){var s=n[Do];try{var o=(0,JY.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch{return DEe.test(s.source)}}),i=(0,xe.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain end of input anchor '$' + See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:ir.LexerDefinitionErrorType.EOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ve.findEndOfInputAnchor=VY;function XY(r){var e=(0,xe.filter)(r,function(i){var n=i[Do];return n.test("")}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' must not match an empty string",type:ir.LexerDefinitionErrorType.EMPTY_MATCH_PATTERN,tokenTypes:[i]}});return t}Ve.findEmptyMatchRegExps=XY;var kEe=/[^\\[][\^]|^\^/;function ZY(r){var e=function(n){jY(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitStartAnchor=function(o){this.found=!0},s}(qY.BaseRegExpVisitor),t=(0,xe.filter)(r,function(n){var s=n[Do];try{var o=(0,JY.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch{return kEe.test(s.source)}}),i=(0,xe.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain start of input anchor '^' + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:ir.LexerDefinitionErrorType.SOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ve.findStartOfInputAnchor=ZY;function _Y(r){var e=(0,xe.filter)(r,function(i){var n=i[Do];return n instanceof RegExp&&(n.multiline||n.global)}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:ir.LexerDefinitionErrorType.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[i]}});return t}Ve.findUnsupportedFlags=_Y;function $Y(r){var e=[],t=(0,xe.map)(r,function(s){return(0,xe.reduce)(r,function(o,a){return s.PATTERN.source===a.PATTERN.source&&!(0,xe.contains)(e,a)&&a.PATTERN!==ir.Lexer.NA&&(e.push(a),o.push(a)),o},[])});t=(0,xe.compact)(t);var i=(0,xe.filter)(t,function(s){return s.length>1}),n=(0,xe.map)(i,function(s){var o=(0,xe.map)(s,function(l){return l.name}),a=(0,xe.first)(s).PATTERN;return{message:"The same RegExp pattern ->"+a+"<-"+("has been used in all of the following Token Types: "+o.join(", ")+" <-"),type:ir.LexerDefinitionErrorType.DUPLICATE_PATTERNS_FOUND,tokenTypes:s}});return n}Ve.findDuplicatePatterns=$Y;function ej(r){var e=(0,xe.filter)(r,function(i){if(!(0,xe.has)(i,"GROUP"))return!1;var n=i.GROUP;return n!==ir.Lexer.SKIPPED&&n!==ir.Lexer.NA&&!(0,xe.isString)(n)}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:ir.LexerDefinitionErrorType.INVALID_GROUP_TYPE_FOUND,tokenTypes:[i]}});return t}Ve.findInvalidGroupType=ej;function tj(r,e){var t=(0,xe.filter)(r,function(n){return n.PUSH_MODE!==void 0&&!(0,xe.contains)(e,n.PUSH_MODE)}),i=(0,xe.map)(t,function(n){var s="Token Type: ->"+n.name+"<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->"+n.PUSH_MODE+"<-which does not exist";return{message:s,type:ir.LexerDefinitionErrorType.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[n]}});return i}Ve.findModesThatDoNotExist=tj;function rj(r){var e=[],t=(0,xe.reduce)(r,function(i,n,s){var o=n.PATTERN;return o===ir.Lexer.NA||((0,xe.isString)(o)?i.push({str:o,idx:s,tokenType:n}):(0,xe.isRegExp)(o)&&FEe(o)&&i.push({str:o.source,idx:s,tokenType:n})),i},[]);return(0,xe.forEach)(r,function(i,n){(0,xe.forEach)(t,function(s){var o=s.str,a=s.idx,l=s.tokenType;if(n"+i.name+"<-")+`in the lexer's definition. +See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:c,type:ir.LexerDefinitionErrorType.UNREACHABLE_PATTERN,tokenTypes:[i,l]})}})}),e}Ve.findUnreachablePatterns=rj;function REe(r,e){if((0,xe.isRegExp)(e)){var t=e.exec(r);return t!==null&&t.index===0}else{if((0,xe.isFunction)(e))return e(r,0,[],{});if((0,xe.has)(e,"exec"))return e.exec(r,0,[],{});if(typeof e=="string")return e===r;throw Error("non exhaustive match")}}function FEe(r){var e=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return(0,xe.find)(e,function(t){return r.source.indexOf(t)!==-1})===void 0}function Nv(r){var e=r.ignoreCase?"i":"";return new RegExp("^(?:"+r.source+")",e)}Ve.addStartOfInput=Nv;function Lv(r){var e=r.ignoreCase?"iy":"y";return new RegExp(""+r.source,e)}Ve.addStickyFlag=Lv;function NEe(r,e,t){var i=[];return(0,xe.has)(r,Ve.DEFAULT_MODE)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ve.DEFAULT_MODE+`> property in its definition +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,xe.has)(r,Ve.MODES)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ve.MODES+`> property in its definition +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,xe.has)(r,Ve.MODES)&&(0,xe.has)(r,Ve.DEFAULT_MODE)&&!(0,xe.has)(r.modes,r.defaultMode)&&i.push({message:"A MultiMode Lexer cannot be initialized with a "+Ve.DEFAULT_MODE+": <"+r.defaultMode+`>which does not exist +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,xe.has)(r,Ve.MODES)&&(0,xe.forEach)(r.modes,function(n,s){(0,xe.forEach)(n,function(o,a){(0,xe.isUndefined)(o)&&i.push({message:"A Lexer cannot be initialized using an undefined Token Type. Mode:"+("<"+s+"> at index: <"+a+`> +`),type:ir.LexerDefinitionErrorType.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED})})}),i}Ve.performRuntimeChecks=NEe;function LEe(r,e,t){var i=[],n=!1,s=(0,xe.compact)((0,xe.flatten)((0,xe.mapValues)(r.modes,function(l){return l}))),o=(0,xe.reject)(s,function(l){return l[Do]===ir.Lexer.NA}),a=oj(t);return e&&(0,xe.forEach)(o,function(l){var c=nj(l,a);if(c!==!1){var u=sj(l,c),g={message:u,type:c.issue,tokenType:l};i.push(g)}else(0,xe.has)(l,"LINE_BREAKS")?l.LINE_BREAKS===!0&&(n=!0):(0,Zg.canMatchCharCode)(a,l.PATTERN)&&(n=!0)}),e&&!n&&i.push({message:`Warning: No LINE_BREAKS Found. + This Lexer has been defined to track line and column information, + But none of the Token Types can be identified as matching a line terminator. + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS + for details.`,type:ir.LexerDefinitionErrorType.NO_LINE_BREAKS_FLAGS}),i}Ve.performWarningRuntimeChecks=LEe;function TEe(r){var e={},t=(0,xe.keys)(r);return(0,xe.forEach)(t,function(i){var n=r[i];if((0,xe.isArray)(n))e[i]=[];else throw Error("non exhaustive match")}),e}Ve.cloneEmptyGroups=TEe;function Ov(r){var e=r.PATTERN;if((0,xe.isRegExp)(e))return!1;if((0,xe.isFunction)(e))return!0;if((0,xe.has)(e,"exec"))return!0;if((0,xe.isString)(e))return!1;throw Error("non exhaustive match")}Ve.isCustomPattern=Ov;function ij(r){return(0,xe.isString)(r)&&r.length===1?r.charCodeAt(0):!1}Ve.isShortPattern=ij;Ve.LineTerminatorOptimizedTester={test:function(r){for(var e=r.length,t=this.lastIndex;t Token Type +`)+(" Root cause: "+e.errMsg+`. +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR";if(e.issue===ir.LexerDefinitionErrorType.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the option. +`+(" The problem is in the <"+r.name+`> Token Type +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK";throw Error("non exhaustive match")}Ve.buildLineBreakIssueMessage=sj;function oj(r){var e=(0,xe.map)(r,function(t){return(0,xe.isString)(t)&&t.length>0?t.charCodeAt(0):t});return e}function Fv(r,e,t){r[e]===void 0?r[e]=[t]:r[e].push(t)}Ve.minOptimizationVal=256;var ny=[];function Tv(r){return r255?255+~~(r/255):r}}});var _g=w(Nt=>{"use strict";Object.defineProperty(Nt,"__esModule",{value:!0});Nt.isTokenType=Nt.hasExtendingTokensTypesMapProperty=Nt.hasExtendingTokensTypesProperty=Nt.hasCategoriesProperty=Nt.hasShortKeyProperty=Nt.singleAssignCategoriesToksMap=Nt.assignCategoriesMapProp=Nt.assignCategoriesTokensProp=Nt.assignTokenDefaultProps=Nt.expandCategories=Nt.augmentTokenTypes=Nt.tokenIdxToClass=Nt.tokenShortNameIdx=Nt.tokenStructuredMatcherNoCategories=Nt.tokenStructuredMatcher=void 0;var Zr=Gt();function MEe(r,e){var t=r.tokenTypeIdx;return t===e.tokenTypeIdx?!0:e.isParent===!0&&e.categoryMatchesMap[t]===!0}Nt.tokenStructuredMatcher=MEe;function UEe(r,e){return r.tokenTypeIdx===e.tokenTypeIdx}Nt.tokenStructuredMatcherNoCategories=UEe;Nt.tokenShortNameIdx=1;Nt.tokenIdxToClass={};function KEe(r){var e=aj(r);Aj(e),cj(e),lj(e),(0,Zr.forEach)(e,function(t){t.isParent=t.categoryMatches.length>0})}Nt.augmentTokenTypes=KEe;function aj(r){for(var e=(0,Zr.cloneArr)(r),t=r,i=!0;i;){t=(0,Zr.compact)((0,Zr.flatten)((0,Zr.map)(t,function(s){return s.CATEGORIES})));var n=(0,Zr.difference)(t,e);e=e.concat(n),(0,Zr.isEmpty)(n)?i=!1:t=n}return e}Nt.expandCategories=aj;function Aj(r){(0,Zr.forEach)(r,function(e){uj(e)||(Nt.tokenIdxToClass[Nt.tokenShortNameIdx]=e,e.tokenTypeIdx=Nt.tokenShortNameIdx++),Mv(e)&&!(0,Zr.isArray)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),Mv(e)||(e.CATEGORIES=[]),gj(e)||(e.categoryMatches=[]),fj(e)||(e.categoryMatchesMap={})})}Nt.assignTokenDefaultProps=Aj;function lj(r){(0,Zr.forEach)(r,function(e){e.categoryMatches=[],(0,Zr.forEach)(e.categoryMatchesMap,function(t,i){e.categoryMatches.push(Nt.tokenIdxToClass[i].tokenTypeIdx)})})}Nt.assignCategoriesTokensProp=lj;function cj(r){(0,Zr.forEach)(r,function(e){Uv([],e)})}Nt.assignCategoriesMapProp=cj;function Uv(r,e){(0,Zr.forEach)(r,function(t){e.categoryMatchesMap[t.tokenTypeIdx]=!0}),(0,Zr.forEach)(e.CATEGORIES,function(t){var i=r.concat(e);(0,Zr.contains)(i,t)||Uv(i,t)})}Nt.singleAssignCategoriesToksMap=Uv;function uj(r){return(0,Zr.has)(r,"tokenTypeIdx")}Nt.hasShortKeyProperty=uj;function Mv(r){return(0,Zr.has)(r,"CATEGORIES")}Nt.hasCategoriesProperty=Mv;function gj(r){return(0,Zr.has)(r,"categoryMatches")}Nt.hasExtendingTokensTypesProperty=gj;function fj(r){return(0,Zr.has)(r,"categoryMatchesMap")}Nt.hasExtendingTokensTypesMapProperty=fj;function HEe(r){return(0,Zr.has)(r,"tokenTypeIdx")}Nt.isTokenType=HEe});var Kv=w(sy=>{"use strict";Object.defineProperty(sy,"__esModule",{value:!0});sy.defaultLexerErrorProvider=void 0;sy.defaultLexerErrorProvider={buildUnableToPopLexerModeMessage:function(r){return"Unable to pop Lexer Mode after encountering Token ->"+r.image+"<- The Mode Stack is empty"},buildUnexpectedCharactersMessage:function(r,e,t,i,n){return"unexpected character: ->"+r.charAt(e)+"<- at offset: "+e+","+(" skipped "+t+" characters.")}}});var Bd=w(Cc=>{"use strict";Object.defineProperty(Cc,"__esModule",{value:!0});Cc.Lexer=Cc.LexerDefinitionErrorType=void 0;var _s=Rv(),nr=Gt(),GEe=_g(),YEe=Kv(),jEe=ty(),qEe;(function(r){r[r.MISSING_PATTERN=0]="MISSING_PATTERN",r[r.INVALID_PATTERN=1]="INVALID_PATTERN",r[r.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",r[r.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",r[r.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",r[r.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",r[r.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",r[r.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",r[r.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",r[r.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",r[r.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",r[r.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",r[r.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",r[r.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",r[r.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",r[r.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",r[r.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK"})(qEe=Cc.LexerDefinitionErrorType||(Cc.LexerDefinitionErrorType={}));var Qd={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` +`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:YEe.defaultLexerErrorProvider,traceInitPerf:!1,skipValidations:!1};Object.freeze(Qd);var JEe=function(){function r(e,t){var i=this;if(t===void 0&&(t=Qd),this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.config=void 0,this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},typeof t=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object. +a boolean 2nd argument is no longer supported`);this.config=(0,nr.merge)(Qd,t);var n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",function(){var s,o=!0;i.TRACE_INIT("Lexer Config handling",function(){if(i.config.lineTerminatorsPattern===Qd.lineTerminatorsPattern)i.config.lineTerminatorsPattern=_s.LineTerminatorOptimizedTester;else if(i.config.lineTerminatorCharacters===Qd.lineTerminatorCharacters)throw Error(`Error: Missing property on the Lexer config. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(t.safeMode&&t.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');i.trackStartLines=/full|onlyStart/i.test(i.config.positionTracking),i.trackEndLines=/full/i.test(i.config.positionTracking),(0,nr.isArray)(e)?(s={modes:{}},s.modes[_s.DEFAULT_MODE]=(0,nr.cloneArr)(e),s[_s.DEFAULT_MODE]=_s.DEFAULT_MODE):(o=!1,s=(0,nr.cloneObj)(e))}),i.config.skipValidations===!1&&(i.TRACE_INIT("performRuntimeChecks",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,_s.performRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))}),i.TRACE_INIT("performWarningRuntimeChecks",function(){i.lexerDefinitionWarning=i.lexerDefinitionWarning.concat((0,_s.performWarningRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))})),s.modes=s.modes?s.modes:{},(0,nr.forEach)(s.modes,function(u,g){s.modes[g]=(0,nr.reject)(u,function(f){return(0,nr.isUndefined)(f)})});var a=(0,nr.keys)(s.modes);if((0,nr.forEach)(s.modes,function(u,g){i.TRACE_INIT("Mode: <"+g+"> processing",function(){if(i.modes.push(g),i.config.skipValidations===!1&&i.TRACE_INIT("validatePatterns",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,_s.validatePatterns)(u,a))}),(0,nr.isEmpty)(i.lexerDefinitionErrors)){(0,GEe.augmentTokenTypes)(u);var f;i.TRACE_INIT("analyzeTokenTypes",function(){f=(0,_s.analyzeTokenTypes)(u,{lineTerminatorCharacters:i.config.lineTerminatorCharacters,positionTracking:t.positionTracking,ensureOptimizations:t.ensureOptimizations,safeMode:t.safeMode,tracer:i.TRACE_INIT.bind(i)})}),i.patternIdxToConfig[g]=f.patternIdxToConfig,i.charCodeToPatternIdxToConfig[g]=f.charCodeToPatternIdxToConfig,i.emptyGroups=(0,nr.merge)(i.emptyGroups,f.emptyGroups),i.hasCustom=f.hasCustom||i.hasCustom,i.canModeBeOptimized[g]=f.canBeOptimized}})}),i.defaultMode=s.defaultMode,!(0,nr.isEmpty)(i.lexerDefinitionErrors)&&!i.config.deferDefinitionErrorsHandling){var l=(0,nr.map)(i.lexerDefinitionErrors,function(u){return u.message}),c=l.join(`----------------------- +`);throw new Error(`Errors detected in definition of Lexer: +`+c)}(0,nr.forEach)(i.lexerDefinitionWarning,function(u){(0,nr.PRINT_WARNING)(u.message)}),i.TRACE_INIT("Choosing sub-methods implementations",function(){if(_s.SUPPORT_STICKY?(i.chopInput=nr.IDENTITY,i.match=i.matchWithTest):(i.updateLastIndex=nr.NOOP,i.match=i.matchWithExec),o&&(i.handleModes=nr.NOOP),i.trackStartLines===!1&&(i.computeNewColumn=nr.IDENTITY),i.trackEndLines===!1&&(i.updateTokenEndLineColumnLocation=nr.NOOP),/full/i.test(i.config.positionTracking))i.createTokenInstance=i.createFullToken;else if(/onlyStart/i.test(i.config.positionTracking))i.createTokenInstance=i.createStartOnlyToken;else if(/onlyOffset/i.test(i.config.positionTracking))i.createTokenInstance=i.createOffsetOnlyToken;else throw Error('Invalid config option: "'+i.config.positionTracking+'"');i.hasCustom?(i.addToken=i.addTokenUsingPush,i.handlePayload=i.handlePayloadWithCustom):(i.addToken=i.addTokenUsingMemberAccess,i.handlePayload=i.handlePayloadNoCustom)}),i.TRACE_INIT("Failed Optimization Warnings",function(){var u=(0,nr.reduce)(i.canModeBeOptimized,function(g,f,h){return f===!1&&g.push(h),g},[]);if(t.ensureOptimizations&&!(0,nr.isEmpty)(u))throw Error("Lexer Modes: < "+u.join(", ")+` > cannot be optimized. + Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode. + Or inspect the console log for details on how to resolve these issues.`)}),i.TRACE_INIT("clearRegExpParserCache",function(){(0,jEe.clearRegExpParserCache)()}),i.TRACE_INIT("toFastProperties",function(){(0,nr.toFastProperties)(i)})})}return r.prototype.tokenize=function(e,t){if(t===void 0&&(t=this.defaultMode),!(0,nr.isEmpty)(this.lexerDefinitionErrors)){var i=(0,nr.map)(this.lexerDefinitionErrors,function(o){return o.message}),n=i.join(`----------------------- +`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer: +`+n)}var s=this.tokenizeInternal(e,t);return s},r.prototype.tokenizeInternal=function(e,t){var i=this,n,s,o,a,l,c,u,g,f,h,p,C,y,B,v,D,L=e,H=L.length,j=0,$=0,V=this.hasCustom?0:Math.floor(e.length/10),W=new Array(V),_=[],A=this.trackStartLines?1:void 0,Ae=this.trackStartLines?1:void 0,ge=(0,_s.cloneEmptyGroups)(this.emptyGroups),re=this.trackStartLines,O=this.config.lineTerminatorsPattern,F=0,ue=[],pe=[],ke=[],Fe=[];Object.freeze(Fe);var Ne=void 0;function oe(){return ue}function le(pr){var Ii=(0,_s.charCodeToOptimizedIndex)(pr),rs=pe[Ii];return rs===void 0?Fe:rs}var Be=function(pr){if(ke.length===1&&pr.tokenType.PUSH_MODE===void 0){var Ii=i.config.errorMessageProvider.buildUnableToPopLexerModeMessage(pr);_.push({offset:pr.startOffset,line:pr.startLine!==void 0?pr.startLine:void 0,column:pr.startColumn!==void 0?pr.startColumn:void 0,length:pr.image.length,message:Ii})}else{ke.pop();var rs=(0,nr.last)(ke);ue=i.patternIdxToConfig[rs],pe=i.charCodeToPatternIdxToConfig[rs],F=ue.length;var ga=i.canModeBeOptimized[rs]&&i.config.safeMode===!1;pe&&ga?Ne=le:Ne=oe}};function fe(pr){ke.push(pr),pe=this.charCodeToPatternIdxToConfig[pr],ue=this.patternIdxToConfig[pr],F=ue.length,F=ue.length;var Ii=this.canModeBeOptimized[pr]&&this.config.safeMode===!1;pe&&Ii?Ne=le:Ne=oe}fe.call(this,t);for(var ae;jc.length){c=a,u=g,ae=_e;break}}}break}}if(c!==null){if(f=c.length,h=ae.group,h!==void 0&&(p=ae.tokenTypeIdx,C=this.createTokenInstance(c,j,p,ae.tokenType,A,Ae,f),this.handlePayload(C,u),h===!1?$=this.addToken(W,$,C):ge[h].push(C)),e=this.chopInput(e,f),j=j+f,Ae=this.computeNewColumn(Ae,f),re===!0&&ae.canLineTerminator===!0){var It=0,Or=void 0,ii=void 0;O.lastIndex=0;do Or=O.test(c),Or===!0&&(ii=O.lastIndex-1,It++);while(Or===!0);It!==0&&(A=A+It,Ae=f-ii,this.updateTokenEndLineColumnLocation(C,h,ii,It,A,Ae,f))}this.handleModes(ae,Be,fe,C)}else{for(var gi=j,hr=A,fi=Ae,ni=!1;!ni&&j <"+e+">");var n=(0,nr.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.",r.NA=/NOT_APPLICABLE/,r}();Cc.Lexer=JEe});var LA=w(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.tokenMatcher=bi.createTokenInstance=bi.EOF=bi.createToken=bi.hasTokenLabel=bi.tokenName=bi.tokenLabel=void 0;var $s=Gt(),WEe=Bd(),Hv=_g();function zEe(r){return wj(r)?r.LABEL:r.name}bi.tokenLabel=zEe;function VEe(r){return r.name}bi.tokenName=VEe;function wj(r){return(0,$s.isString)(r.LABEL)&&r.LABEL!==""}bi.hasTokenLabel=wj;var XEe="parent",hj="categories",pj="label",dj="group",Cj="push_mode",mj="pop_mode",Ej="longer_alt",Ij="line_breaks",yj="start_chars_hint";function Bj(r){return ZEe(r)}bi.createToken=Bj;function ZEe(r){var e=r.pattern,t={};if(t.name=r.name,(0,$s.isUndefined)(e)||(t.PATTERN=e),(0,$s.has)(r,XEe))throw`The parent property is no longer supported. +See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.`;return(0,$s.has)(r,hj)&&(t.CATEGORIES=r[hj]),(0,Hv.augmentTokenTypes)([t]),(0,$s.has)(r,pj)&&(t.LABEL=r[pj]),(0,$s.has)(r,dj)&&(t.GROUP=r[dj]),(0,$s.has)(r,mj)&&(t.POP_MODE=r[mj]),(0,$s.has)(r,Cj)&&(t.PUSH_MODE=r[Cj]),(0,$s.has)(r,Ej)&&(t.LONGER_ALT=r[Ej]),(0,$s.has)(r,Ij)&&(t.LINE_BREAKS=r[Ij]),(0,$s.has)(r,yj)&&(t.START_CHARS_HINT=r[yj]),t}bi.EOF=Bj({name:"EOF",pattern:WEe.Lexer.NA});(0,Hv.augmentTokenTypes)([bi.EOF]);function _Ee(r,e,t,i,n,s,o,a){return{image:e,startOffset:t,endOffset:i,startLine:n,endLine:s,startColumn:o,endColumn:a,tokenTypeIdx:r.tokenTypeIdx,tokenType:r}}bi.createTokenInstance=_Ee;function $Ee(r,e){return(0,Hv.tokenStructuredMatcher)(r,e)}bi.tokenMatcher=$Ee});var Cn=w(zt=>{"use strict";var xa=zt&&zt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(zt,"__esModule",{value:!0});zt.serializeProduction=zt.serializeGrammar=zt.Terminal=zt.Alternation=zt.RepetitionWithSeparator=zt.Repetition=zt.RepetitionMandatoryWithSeparator=zt.RepetitionMandatory=zt.Option=zt.Alternative=zt.Rule=zt.NonTerminal=zt.AbstractProduction=void 0;var Ar=Gt(),eIe=LA(),ko=function(){function r(e){this._definition=e}return Object.defineProperty(r.prototype,"definition",{get:function(){return this._definition},set:function(e){this._definition=e},enumerable:!1,configurable:!0}),r.prototype.accept=function(e){e.visit(this),(0,Ar.forEach)(this.definition,function(t){t.accept(e)})},r}();zt.AbstractProduction=ko;var Qj=function(r){xa(e,r);function e(t){var i=r.call(this,[])||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this.referencedRule!==void 0?this.referencedRule.definition:[]},set:function(t){},enumerable:!1,configurable:!0}),e.prototype.accept=function(t){t.visit(this)},e}(ko);zt.NonTerminal=Qj;var bj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.orgText="",(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.Rule=bj;var Sj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.ignoreAmbiguities=!1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.Alternative=Sj;var vj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.Option=vj;var xj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.RepetitionMandatory=xj;var Pj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.RepetitionMandatoryWithSeparator=Pj;var Dj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.Repetition=Dj;var kj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.RepetitionWithSeparator=kj;var Rj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,i.ignoreAmbiguities=!1,i.hasPredicates=!1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this._definition},set:function(t){this._definition=t},enumerable:!1,configurable:!0}),e}(ko);zt.Alternation=Rj;var oy=function(){function r(e){this.idx=1,(0,Ar.assign)(this,(0,Ar.pick)(e,function(t){return t!==void 0}))}return r.prototype.accept=function(e){e.visit(this)},r}();zt.Terminal=oy;function tIe(r){return(0,Ar.map)(r,bd)}zt.serializeGrammar=tIe;function bd(r){function e(s){return(0,Ar.map)(s,bd)}if(r instanceof Qj){var t={type:"NonTerminal",name:r.nonTerminalName,idx:r.idx};return(0,Ar.isString)(r.label)&&(t.label=r.label),t}else{if(r instanceof Sj)return{type:"Alternative",definition:e(r.definition)};if(r instanceof vj)return{type:"Option",idx:r.idx,definition:e(r.definition)};if(r instanceof xj)return{type:"RepetitionMandatory",idx:r.idx,definition:e(r.definition)};if(r instanceof Pj)return{type:"RepetitionMandatoryWithSeparator",idx:r.idx,separator:bd(new oy({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof kj)return{type:"RepetitionWithSeparator",idx:r.idx,separator:bd(new oy({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof Dj)return{type:"Repetition",idx:r.idx,definition:e(r.definition)};if(r instanceof Rj)return{type:"Alternation",idx:r.idx,definition:e(r.definition)};if(r instanceof oy){var i={type:"Terminal",name:r.terminalType.name,label:(0,eIe.tokenLabel)(r.terminalType),idx:r.idx};(0,Ar.isString)(r.label)&&(i.terminalLabel=r.label);var n=r.terminalType.PATTERN;return r.terminalType.PATTERN&&(i.pattern=(0,Ar.isRegExp)(n)?n.source:n),i}else{if(r instanceof bj)return{type:"Rule",name:r.name,orgText:r.orgText,definition:e(r.definition)};throw Error("non exhaustive match")}}}zt.serializeProduction=bd});var Ay=w(ay=>{"use strict";Object.defineProperty(ay,"__esModule",{value:!0});ay.RestWalker=void 0;var Gv=Gt(),mn=Cn(),rIe=function(){function r(){}return r.prototype.walk=function(e,t){var i=this;t===void 0&&(t=[]),(0,Gv.forEach)(e.definition,function(n,s){var o=(0,Gv.drop)(e.definition,s+1);if(n instanceof mn.NonTerminal)i.walkProdRef(n,o,t);else if(n instanceof mn.Terminal)i.walkTerminal(n,o,t);else if(n instanceof mn.Alternative)i.walkFlat(n,o,t);else if(n instanceof mn.Option)i.walkOption(n,o,t);else if(n instanceof mn.RepetitionMandatory)i.walkAtLeastOne(n,o,t);else if(n instanceof mn.RepetitionMandatoryWithSeparator)i.walkAtLeastOneSep(n,o,t);else if(n instanceof mn.RepetitionWithSeparator)i.walkManySep(n,o,t);else if(n instanceof mn.Repetition)i.walkMany(n,o,t);else if(n instanceof mn.Alternation)i.walkOr(n,o,t);else throw Error("non exhaustive match")})},r.prototype.walkTerminal=function(e,t,i){},r.prototype.walkProdRef=function(e,t,i){},r.prototype.walkFlat=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkOption=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkAtLeastOne=function(e,t,i){var n=[new mn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkAtLeastOneSep=function(e,t,i){var n=Fj(e,t,i);this.walk(e,n)},r.prototype.walkMany=function(e,t,i){var n=[new mn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkManySep=function(e,t,i){var n=Fj(e,t,i);this.walk(e,n)},r.prototype.walkOr=function(e,t,i){var n=this,s=t.concat(i);(0,Gv.forEach)(e.definition,function(o){var a=new mn.Alternative({definition:[o]});n.walk(a,s)})},r}();ay.RestWalker=rIe;function Fj(r,e,t){var i=[new mn.Option({definition:[new mn.Terminal({terminalType:r.separator})].concat(r.definition)})],n=i.concat(e,t);return n}});var $g=w(ly=>{"use strict";Object.defineProperty(ly,"__esModule",{value:!0});ly.GAstVisitor=void 0;var Ro=Cn(),iIe=function(){function r(){}return r.prototype.visit=function(e){var t=e;switch(t.constructor){case Ro.NonTerminal:return this.visitNonTerminal(t);case Ro.Alternative:return this.visitAlternative(t);case Ro.Option:return this.visitOption(t);case Ro.RepetitionMandatory:return this.visitRepetitionMandatory(t);case Ro.RepetitionMandatoryWithSeparator:return this.visitRepetitionMandatoryWithSeparator(t);case Ro.RepetitionWithSeparator:return this.visitRepetitionWithSeparator(t);case Ro.Repetition:return this.visitRepetition(t);case Ro.Alternation:return this.visitAlternation(t);case Ro.Terminal:return this.visitTerminal(t);case Ro.Rule:return this.visitRule(t);default:throw Error("non exhaustive match")}},r.prototype.visitNonTerminal=function(e){},r.prototype.visitAlternative=function(e){},r.prototype.visitOption=function(e){},r.prototype.visitRepetition=function(e){},r.prototype.visitRepetitionMandatory=function(e){},r.prototype.visitRepetitionMandatoryWithSeparator=function(e){},r.prototype.visitRepetitionWithSeparator=function(e){},r.prototype.visitAlternation=function(e){},r.prototype.visitTerminal=function(e){},r.prototype.visitRule=function(e){},r}();ly.GAstVisitor=iIe});var vd=w(Mi=>{"use strict";var nIe=Mi&&Mi.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Mi,"__esModule",{value:!0});Mi.collectMethods=Mi.DslMethodsCollectorVisitor=Mi.getProductionDslName=Mi.isBranchingProd=Mi.isOptionalProd=Mi.isSequenceProd=void 0;var Sd=Gt(),Qr=Cn(),sIe=$g();function oIe(r){return r instanceof Qr.Alternative||r instanceof Qr.Option||r instanceof Qr.Repetition||r instanceof Qr.RepetitionMandatory||r instanceof Qr.RepetitionMandatoryWithSeparator||r instanceof Qr.RepetitionWithSeparator||r instanceof Qr.Terminal||r instanceof Qr.Rule}Mi.isSequenceProd=oIe;function Yv(r,e){e===void 0&&(e=[]);var t=r instanceof Qr.Option||r instanceof Qr.Repetition||r instanceof Qr.RepetitionWithSeparator;return t?!0:r instanceof Qr.Alternation?(0,Sd.some)(r.definition,function(i){return Yv(i,e)}):r instanceof Qr.NonTerminal&&(0,Sd.contains)(e,r)?!1:r instanceof Qr.AbstractProduction?(r instanceof Qr.NonTerminal&&e.push(r),(0,Sd.every)(r.definition,function(i){return Yv(i,e)})):!1}Mi.isOptionalProd=Yv;function aIe(r){return r instanceof Qr.Alternation}Mi.isBranchingProd=aIe;function AIe(r){if(r instanceof Qr.NonTerminal)return"SUBRULE";if(r instanceof Qr.Option)return"OPTION";if(r instanceof Qr.Alternation)return"OR";if(r instanceof Qr.RepetitionMandatory)return"AT_LEAST_ONE";if(r instanceof Qr.RepetitionMandatoryWithSeparator)return"AT_LEAST_ONE_SEP";if(r instanceof Qr.RepetitionWithSeparator)return"MANY_SEP";if(r instanceof Qr.Repetition)return"MANY";if(r instanceof Qr.Terminal)return"CONSUME";throw Error("non exhaustive match")}Mi.getProductionDslName=AIe;var Nj=function(r){nIe(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.separator="-",t.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]},t}return e.prototype.reset=function(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}},e.prototype.visitTerminal=function(t){var i=t.terminalType.name+this.separator+"Terminal";(0,Sd.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitNonTerminal=function(t){var i=t.nonTerminalName+this.separator+"Terminal";(0,Sd.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitOption=function(t){this.dslMethods.option.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.dslMethods.repetitionWithSeparator.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.dslMethods.repetitionMandatory.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.dslMethods.repetitionMandatoryWithSeparator.push(t)},e.prototype.visitRepetition=function(t){this.dslMethods.repetition.push(t)},e.prototype.visitAlternation=function(t){this.dslMethods.alternation.push(t)},e}(sIe.GAstVisitor);Mi.DslMethodsCollectorVisitor=Nj;var cy=new Nj;function lIe(r){cy.reset(),r.accept(cy);var e=cy.dslMethods;return cy.reset(),e}Mi.collectMethods=lIe});var qv=w(Fo=>{"use strict";Object.defineProperty(Fo,"__esModule",{value:!0});Fo.firstForTerminal=Fo.firstForBranching=Fo.firstForSequence=Fo.first=void 0;var uy=Gt(),Lj=Cn(),jv=vd();function gy(r){if(r instanceof Lj.NonTerminal)return gy(r.referencedRule);if(r instanceof Lj.Terminal)return Mj(r);if((0,jv.isSequenceProd)(r))return Tj(r);if((0,jv.isBranchingProd)(r))return Oj(r);throw Error("non exhaustive match")}Fo.first=gy;function Tj(r){for(var e=[],t=r.definition,i=0,n=t.length>i,s,o=!0;n&&o;)s=t[i],o=(0,jv.isOptionalProd)(s),e=e.concat(gy(s)),i=i+1,n=t.length>i;return(0,uy.uniq)(e)}Fo.firstForSequence=Tj;function Oj(r){var e=(0,uy.map)(r.definition,function(t){return gy(t)});return(0,uy.uniq)((0,uy.flatten)(e))}Fo.firstForBranching=Oj;function Mj(r){return[r.terminalType]}Fo.firstForTerminal=Mj});var Jv=w(fy=>{"use strict";Object.defineProperty(fy,"__esModule",{value:!0});fy.IN=void 0;fy.IN="_~IN~_"});var Yj=w(fs=>{"use strict";var cIe=fs&&fs.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(fs,"__esModule",{value:!0});fs.buildInProdFollowPrefix=fs.buildBetweenProdsFollowPrefix=fs.computeAllProdsFollows=fs.ResyncFollowsWalker=void 0;var uIe=Ay(),gIe=qv(),Uj=Gt(),Kj=Jv(),fIe=Cn(),Hj=function(r){cIe(e,r);function e(t){var i=r.call(this)||this;return i.topProd=t,i.follows={},i}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.follows},e.prototype.walkTerminal=function(t,i,n){},e.prototype.walkProdRef=function(t,i,n){var s=Gj(t.referencedRule,t.idx)+this.topProd.name,o=i.concat(n),a=new fIe.Alternative({definition:o}),l=(0,gIe.first)(a);this.follows[s]=l},e}(uIe.RestWalker);fs.ResyncFollowsWalker=Hj;function hIe(r){var e={};return(0,Uj.forEach)(r,function(t){var i=new Hj(t).startWalking();(0,Uj.assign)(e,i)}),e}fs.computeAllProdsFollows=hIe;function Gj(r,e){return r.name+e+Kj.IN}fs.buildBetweenProdsFollowPrefix=Gj;function pIe(r){var e=r.terminalType.name;return e+r.idx+Kj.IN}fs.buildInProdFollowPrefix=pIe});var xd=w(Pa=>{"use strict";Object.defineProperty(Pa,"__esModule",{value:!0});Pa.defaultGrammarValidatorErrorProvider=Pa.defaultGrammarResolverErrorProvider=Pa.defaultParserErrorProvider=void 0;var ef=LA(),dIe=Gt(),eo=Gt(),Wv=Cn(),jj=vd();Pa.defaultParserErrorProvider={buildMismatchTokenMessage:function(r){var e=r.expected,t=r.actual,i=r.previous,n=r.ruleName,s=(0,ef.hasTokenLabel)(e),o=s?"--> "+(0,ef.tokenLabel)(e)+" <--":"token of type --> "+e.name+" <--",a="Expecting "+o+" but found --> '"+t.image+"' <--";return a},buildNotAllInputParsedMessage:function(r){var e=r.firstRedundant,t=r.ruleName;return"Redundant input, expecting EOF but found: "+e.image},buildNoViableAltMessage:function(r){var e=r.expectedPathsPerAlt,t=r.actual,i=r.previous,n=r.customUserDescription,s=r.ruleName,o="Expecting: ",a=(0,eo.first)(t).image,l=` +but found: '`+a+"'";if(n)return o+n+l;var c=(0,eo.reduce)(e,function(h,p){return h.concat(p)},[]),u=(0,eo.map)(c,function(h){return"["+(0,eo.map)(h,function(p){return(0,ef.tokenLabel)(p)}).join(", ")+"]"}),g=(0,eo.map)(u,function(h,p){return" "+(p+1)+". "+h}),f=`one of these possible Token sequences: +`+g.join(` +`);return o+f+l},buildEarlyExitMessage:function(r){var e=r.expectedIterationPaths,t=r.actual,i=r.customUserDescription,n=r.ruleName,s="Expecting: ",o=(0,eo.first)(t).image,a=` +but found: '`+o+"'";if(i)return s+i+a;var l=(0,eo.map)(e,function(u){return"["+(0,eo.map)(u,function(g){return(0,ef.tokenLabel)(g)}).join(",")+"]"}),c=`expecting at least one iteration which starts with one of these possible Token sequences:: + `+("<"+l.join(" ,")+">");return s+c+a}};Object.freeze(Pa.defaultParserErrorProvider);Pa.defaultGrammarResolverErrorProvider={buildRuleNotFoundError:function(r,e){var t="Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- +inside top level rule: ->`+r.name+"<-";return t}};Pa.defaultGrammarValidatorErrorProvider={buildDuplicateFoundError:function(r,e){function t(u){return u instanceof Wv.Terminal?u.terminalType.name:u instanceof Wv.NonTerminal?u.nonTerminalName:""}var i=r.name,n=(0,eo.first)(e),s=n.idx,o=(0,jj.getProductionDslName)(n),a=t(n),l=s>0,c="->"+o+(l?s:"")+"<- "+(a?"with argument: ->"+a+"<-":"")+` + appears more than once (`+e.length+" times) in the top level rule: ->"+i+`<-. + For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES + `;return c=c.replace(/[ \t]+/g," "),c=c.replace(/\s\s+/g,` +`),c},buildNamespaceConflictError:function(r){var e=`Namespace conflict found in grammar. +`+("The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <"+r.name+`>. +`)+`To resolve this make sure each Terminal and Non-Terminal names are unique +This is easy to accomplish by using the convention that Terminal names start with an uppercase letter +and Non-Terminal names start with a lower case letter.`;return e},buildAlternationPrefixAmbiguityError:function(r){var e=(0,eo.map)(r.prefixPath,function(n){return(0,ef.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous alternatives: <"+r.ambiguityIndices.join(" ,")+`> due to common lookahead prefix +`+("in inside <"+r.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`)+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX +For Further details.`;return i},buildAlternationAmbiguityError:function(r){var e=(0,eo.map)(r.prefixPath,function(n){return(0,ef.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous Alternatives Detected: <"+r.ambiguityIndices.join(" ,")+"> in "+(" inside <"+r.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`);return i=i+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES +For Further details.`,i},buildEmptyRepetitionError:function(r){var e=(0,jj.getProductionDslName)(r.repetition);r.repetition.idx!==0&&(e+=r.repetition.idx);var t="The repetition <"+e+"> within Rule <"+r.topLevelRule.name+`> can never consume any tokens. +This could lead to an infinite loop.`;return t},buildTokenNameError:function(r){return"deprecated"},buildEmptyAlternationError:function(r){var e="Ambiguous empty alternative: <"+(r.emptyChoiceIdx+1)+">"+(" in inside <"+r.topLevelRule.name+`> Rule. +`)+"Only the last alternative may be an empty alternative.";return e},buildTooManyAlternativesError:function(r){var e=`An Alternation cannot have more than 256 alternatives: +`+(" inside <"+r.topLevelRule.name+`> Rule. + has `+(r.alternation.definition.length+1)+" alternatives.");return e},buildLeftRecursionError:function(r){var e=r.topLevelRule.name,t=dIe.map(r.leftRecursionPath,function(s){return s.name}),i=e+" --> "+t.concat([e]).join(" --> "),n=`Left Recursion found in grammar. +`+("rule: <"+e+`> can be invoked from itself (directly or indirectly) +`)+(`without consuming any Tokens. The grammar path that causes this is: + `+i+` +`)+` To fix this refactor your grammar to remove the left recursion. +see: https://en.wikipedia.org/wiki/LL_parser#Left_Factoring.`;return n},buildInvalidRuleNameError:function(r){return"deprecated"},buildDuplicateRuleNameError:function(r){var e;r.topLevelRule instanceof Wv.Rule?e=r.topLevelRule.name:e=r.topLevelRule;var t="Duplicate definition, rule: ->"+e+"<- is already defined in the grammar: ->"+r.grammarName+"<-";return t}}});var Wj=w(TA=>{"use strict";var CIe=TA&&TA.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(TA,"__esModule",{value:!0});TA.GastRefResolverVisitor=TA.resolveGrammar=void 0;var mIe=Yn(),qj=Gt(),EIe=$g();function IIe(r,e){var t=new Jj(r,e);return t.resolveRefs(),t.errors}TA.resolveGrammar=IIe;var Jj=function(r){CIe(e,r);function e(t,i){var n=r.call(this)||this;return n.nameToTopRule=t,n.errMsgProvider=i,n.errors=[],n}return e.prototype.resolveRefs=function(){var t=this;(0,qj.forEach)((0,qj.values)(this.nameToTopRule),function(i){t.currTopLevel=i,i.accept(t)})},e.prototype.visitNonTerminal=function(t){var i=this.nameToTopRule[t.nonTerminalName];if(i)t.referencedRule=i;else{var n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,t);this.errors.push({message:n,type:mIe.ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:t.nonTerminalName})}},e}(EIe.GAstVisitor);TA.GastRefResolverVisitor=Jj});var Dd=w(Nr=>{"use strict";var mc=Nr&&Nr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Nr,"__esModule",{value:!0});Nr.nextPossibleTokensAfter=Nr.possiblePathsFrom=Nr.NextTerminalAfterAtLeastOneSepWalker=Nr.NextTerminalAfterAtLeastOneWalker=Nr.NextTerminalAfterManySepWalker=Nr.NextTerminalAfterManyWalker=Nr.AbstractNextTerminalAfterProductionWalker=Nr.NextAfterTokenWalker=Nr.AbstractNextPossibleTokensWalker=void 0;var zj=Ay(),Ut=Gt(),yIe=qv(),kt=Cn(),Vj=function(r){mc(e,r);function e(t,i){var n=r.call(this)||this;return n.topProd=t,n.path=i,n.possibleTokTypes=[],n.nextProductionName="",n.nextProductionOccurrence=0,n.found=!1,n.isAtEndOfPath=!1,n}return e.prototype.startWalking=function(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=(0,Ut.cloneArr)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,Ut.cloneArr)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes},e.prototype.walk=function(t,i){i===void 0&&(i=[]),this.found||r.prototype.walk.call(this,t,i)},e.prototype.walkProdRef=function(t,i,n){if(t.referencedRule.name===this.nextProductionName&&t.idx===this.nextProductionOccurrence){var s=i.concat(n);this.updateExpectedNext(),this.walk(t.referencedRule,s)}},e.prototype.updateExpectedNext=function(){(0,Ut.isEmpty)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())},e}(zj.RestWalker);Nr.AbstractNextPossibleTokensWalker=Vj;var wIe=function(r){mc(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.path=i,n.nextTerminalName="",n.nextTerminalOccurrence=0,n.nextTerminalName=n.path.lastTok.name,n.nextTerminalOccurrence=n.path.lastTokOccurrence,n}return e.prototype.walkTerminal=function(t,i,n){if(this.isAtEndOfPath&&t.terminalType.name===this.nextTerminalName&&t.idx===this.nextTerminalOccurrence&&!this.found){var s=i.concat(n),o=new kt.Alternative({definition:s});this.possibleTokTypes=(0,yIe.first)(o),this.found=!0}},e}(Vj);Nr.NextAfterTokenWalker=wIe;var Pd=function(r){mc(e,r);function e(t,i){var n=r.call(this)||this;return n.topRule=t,n.occurrence=i,n.result={token:void 0,occurrence:void 0,isEndOfRule:void 0},n}return e.prototype.startWalking=function(){return this.walk(this.topRule),this.result},e}(zj.RestWalker);Nr.AbstractNextTerminalAfterProductionWalker=Pd;var BIe=function(r){mc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkMany=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkMany.call(this,t,i,n)},e}(Pd);Nr.NextTerminalAfterManyWalker=BIe;var QIe=function(r){mc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkManySep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkManySep.call(this,t,i,n)},e}(Pd);Nr.NextTerminalAfterManySepWalker=QIe;var bIe=function(r){mc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOne=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOne.call(this,t,i,n)},e}(Pd);Nr.NextTerminalAfterAtLeastOneWalker=bIe;var SIe=function(r){mc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOneSep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOneSep.call(this,t,i,n)},e}(Pd);Nr.NextTerminalAfterAtLeastOneSepWalker=SIe;function Xj(r,e,t){t===void 0&&(t=[]),t=(0,Ut.cloneArr)(t);var i=[],n=0;function s(c){return c.concat((0,Ut.drop)(r,n+1))}function o(c){var u=Xj(s(c),e,t);return i.concat(u)}for(;t.length=0;ge--){var re=B.definition[ge],O={idx:p,def:re.definition.concat((0,Ut.drop)(h)),ruleStack:C,occurrenceStack:y};g.push(O),g.push(o)}else if(B instanceof kt.Alternative)g.push({idx:p,def:B.definition.concat((0,Ut.drop)(h)),ruleStack:C,occurrenceStack:y});else if(B instanceof kt.Rule)g.push(xIe(B,p,C,y));else throw Error("non exhaustive match")}}return u}Nr.nextPossibleTokensAfter=vIe;function xIe(r,e,t,i){var n=(0,Ut.cloneArr)(t);n.push(r.name);var s=(0,Ut.cloneArr)(i);return s.push(1),{idx:e,def:r.definition,ruleStack:n,occurrenceStack:s}}});var kd=w(Zt=>{"use strict";var $j=Zt&&Zt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Zt,"__esModule",{value:!0});Zt.areTokenCategoriesNotUsed=Zt.isStrictPrefixOfPath=Zt.containsPath=Zt.getLookaheadPathsForOptionalProd=Zt.getLookaheadPathsForOr=Zt.lookAheadSequenceFromAlternatives=Zt.buildSingleAlternativeLookaheadFunction=Zt.buildAlternativesLookAheadFunc=Zt.buildLookaheadFuncForOptionalProd=Zt.buildLookaheadFuncForOr=Zt.getProdType=Zt.PROD_TYPE=void 0;var sr=Gt(),Zj=Dd(),PIe=Ay(),hy=_g(),OA=Cn(),DIe=$g(),oi;(function(r){r[r.OPTION=0]="OPTION",r[r.REPETITION=1]="REPETITION",r[r.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",r[r.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",r[r.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",r[r.ALTERNATION=5]="ALTERNATION"})(oi=Zt.PROD_TYPE||(Zt.PROD_TYPE={}));function kIe(r){if(r instanceof OA.Option)return oi.OPTION;if(r instanceof OA.Repetition)return oi.REPETITION;if(r instanceof OA.RepetitionMandatory)return oi.REPETITION_MANDATORY;if(r instanceof OA.RepetitionMandatoryWithSeparator)return oi.REPETITION_MANDATORY_WITH_SEPARATOR;if(r instanceof OA.RepetitionWithSeparator)return oi.REPETITION_WITH_SEPARATOR;if(r instanceof OA.Alternation)return oi.ALTERNATION;throw Error("non exhaustive match")}Zt.getProdType=kIe;function RIe(r,e,t,i,n,s){var o=tq(r,e,t),a=Xv(o)?hy.tokenStructuredMatcherNoCategories:hy.tokenStructuredMatcher;return s(o,i,a,n)}Zt.buildLookaheadFuncForOr=RIe;function FIe(r,e,t,i,n,s){var o=rq(r,e,n,t),a=Xv(o)?hy.tokenStructuredMatcherNoCategories:hy.tokenStructuredMatcher;return s(o[0],a,i)}Zt.buildLookaheadFuncForOptionalProd=FIe;function NIe(r,e,t,i){var n=r.length,s=(0,sr.every)(r,function(l){return(0,sr.every)(l,function(c){return c.length===1})});if(e)return function(l){for(var c=(0,sr.map)(l,function(D){return D.GATE}),u=0;u{"use strict";var Zv=Vt&&Vt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Vt,"__esModule",{value:!0});Vt.checkPrefixAlternativesAmbiguities=Vt.validateSomeNonEmptyLookaheadPath=Vt.validateTooManyAlts=Vt.RepetionCollector=Vt.validateAmbiguousAlternationAlternatives=Vt.validateEmptyOrAlternative=Vt.getFirstNoneTerminal=Vt.validateNoLeftRecursion=Vt.validateRuleIsOverridden=Vt.validateRuleDoesNotAlreadyExist=Vt.OccurrenceValidationCollector=Vt.identifyProductionForDuplicates=Vt.validateGrammar=void 0;var er=Gt(),br=Gt(),No=Yn(),_v=vd(),tf=kd(),UIe=Dd(),to=Cn(),$v=$g();function KIe(r,e,t,i,n){var s=er.map(r,function(h){return HIe(h,i)}),o=er.map(r,function(h){return ex(h,h,i)}),a=[],l=[],c=[];(0,br.every)(o,br.isEmpty)&&(a=(0,br.map)(r,function(h){return Aq(h,i)}),l=(0,br.map)(r,function(h){return lq(h,e,i)}),c=gq(r,e,i));var u=jIe(r,t,i),g=(0,br.map)(r,function(h){return uq(h,i)}),f=(0,br.map)(r,function(h){return aq(h,r,n,i)});return er.flatten(s.concat(c,o,a,l,u,g,f))}Vt.validateGrammar=KIe;function HIe(r,e){var t=new oq;r.accept(t);var i=t.allProductions,n=er.groupBy(i,nq),s=er.pick(n,function(a){return a.length>1}),o=er.map(er.values(s),function(a){var l=er.first(a),c=e.buildDuplicateFoundError(r,a),u=(0,_v.getProductionDslName)(l),g={message:c,type:No.ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,ruleName:r.name,dslName:u,occurrence:l.idx},f=sq(l);return f&&(g.parameter=f),g});return o}function nq(r){return(0,_v.getProductionDslName)(r)+"_#_"+r.idx+"_#_"+sq(r)}Vt.identifyProductionForDuplicates=nq;function sq(r){return r instanceof to.Terminal?r.terminalType.name:r instanceof to.NonTerminal?r.nonTerminalName:""}var oq=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitNonTerminal=function(t){this.allProductions.push(t)},e.prototype.visitOption=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e.prototype.visitAlternation=function(t){this.allProductions.push(t)},e.prototype.visitTerminal=function(t){this.allProductions.push(t)},e}($v.GAstVisitor);Vt.OccurrenceValidationCollector=oq;function aq(r,e,t,i){var n=[],s=(0,br.reduce)(e,function(a,l){return l.name===r.name?a+1:a},0);if(s>1){var o=i.buildDuplicateRuleNameError({topLevelRule:r,grammarName:t});n.push({message:o,type:No.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:r.name})}return n}Vt.validateRuleDoesNotAlreadyExist=aq;function GIe(r,e,t){var i=[],n;return er.contains(e,r)||(n="Invalid rule override, rule: ->"+r+"<- cannot be overridden in the grammar: ->"+t+"<-as it is not defined in any of the super grammars ",i.push({message:n,type:No.ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,ruleName:r})),i}Vt.validateRuleIsOverridden=GIe;function ex(r,e,t,i){i===void 0&&(i=[]);var n=[],s=Rd(e.definition);if(er.isEmpty(s))return[];var o=r.name,a=er.contains(s,r);a&&n.push({message:t.buildLeftRecursionError({topLevelRule:r,leftRecursionPath:i}),type:No.ParserDefinitionErrorType.LEFT_RECURSION,ruleName:o});var l=er.difference(s,i.concat([r])),c=er.map(l,function(u){var g=er.cloneArr(i);return g.push(u),ex(r,u,t,g)});return n.concat(er.flatten(c))}Vt.validateNoLeftRecursion=ex;function Rd(r){var e=[];if(er.isEmpty(r))return e;var t=er.first(r);if(t instanceof to.NonTerminal)e.push(t.referencedRule);else if(t instanceof to.Alternative||t instanceof to.Option||t instanceof to.RepetitionMandatory||t instanceof to.RepetitionMandatoryWithSeparator||t instanceof to.RepetitionWithSeparator||t instanceof to.Repetition)e=e.concat(Rd(t.definition));else if(t instanceof to.Alternation)e=er.flatten(er.map(t.definition,function(o){return Rd(o.definition)}));else if(!(t instanceof to.Terminal))throw Error("non exhaustive match");var i=(0,_v.isOptionalProd)(t),n=r.length>1;if(i&&n){var s=er.drop(r);return e.concat(Rd(s))}else return e}Vt.getFirstNoneTerminal=Rd;var tx=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.alternations=[],t}return e.prototype.visitAlternation=function(t){this.alternations.push(t)},e}($v.GAstVisitor);function Aq(r,e){var t=new tx;r.accept(t);var i=t.alternations,n=er.reduce(i,function(s,o){var a=er.dropRight(o.definition),l=er.map(a,function(c,u){var g=(0,UIe.nextPossibleTokensAfter)([c],[],null,1);return er.isEmpty(g)?{message:e.buildEmptyAlternationError({topLevelRule:r,alternation:o,emptyChoiceIdx:u}),type:No.ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,ruleName:r.name,occurrence:o.idx,alternative:u+1}:null});return s.concat(er.compact(l))},[]);return n}Vt.validateEmptyOrAlternative=Aq;function lq(r,e,t){var i=new tx;r.accept(i);var n=i.alternations;n=(0,br.reject)(n,function(o){return o.ignoreAmbiguities===!0});var s=er.reduce(n,function(o,a){var l=a.idx,c=a.maxLookahead||e,u=(0,tf.getLookaheadPathsForOr)(l,r,c,a),g=YIe(u,a,r,t),f=fq(u,a,r,t);return o.concat(g,f)},[]);return s}Vt.validateAmbiguousAlternationAlternatives=lq;var cq=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e}($v.GAstVisitor);Vt.RepetionCollector=cq;function uq(r,e){var t=new tx;r.accept(t);var i=t.alternations,n=er.reduce(i,function(s,o){return o.definition.length>255&&s.push({message:e.buildTooManyAlternativesError({topLevelRule:r,alternation:o}),type:No.ParserDefinitionErrorType.TOO_MANY_ALTS,ruleName:r.name,occurrence:o.idx}),s},[]);return n}Vt.validateTooManyAlts=uq;function gq(r,e,t){var i=[];return(0,br.forEach)(r,function(n){var s=new cq;n.accept(s);var o=s.allProductions;(0,br.forEach)(o,function(a){var l=(0,tf.getProdType)(a),c=a.maxLookahead||e,u=a.idx,g=(0,tf.getLookaheadPathsForOptionalProd)(u,n,l,c),f=g[0];if((0,br.isEmpty)((0,br.flatten)(f))){var h=t.buildEmptyRepetitionError({topLevelRule:n,repetition:a});i.push({message:h,type:No.ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,ruleName:n.name})}})}),i}Vt.validateSomeNonEmptyLookaheadPath=gq;function YIe(r,e,t,i){var n=[],s=(0,br.reduce)(r,function(a,l,c){return e.definition[c].ignoreAmbiguities===!0||(0,br.forEach)(l,function(u){var g=[c];(0,br.forEach)(r,function(f,h){c!==h&&(0,tf.containsPath)(f,u)&&e.definition[h].ignoreAmbiguities!==!0&&g.push(h)}),g.length>1&&!(0,tf.containsPath)(n,u)&&(n.push(u),a.push({alts:g,path:u}))}),a},[]),o=er.map(s,function(a){var l=(0,br.map)(a.alts,function(u){return u+1}),c=i.buildAlternationAmbiguityError({topLevelRule:t,alternation:e,ambiguityIndices:l,prefixPath:a.path});return{message:c,type:No.ParserDefinitionErrorType.AMBIGUOUS_ALTS,ruleName:t.name,occurrence:e.idx,alternatives:[a.alts]}});return o}function fq(r,e,t,i){var n=[],s=(0,br.reduce)(r,function(o,a,l){var c=(0,br.map)(a,function(u){return{idx:l,path:u}});return o.concat(c)},[]);return(0,br.forEach)(s,function(o){var a=e.definition[o.idx];if(a.ignoreAmbiguities!==!0){var l=o.idx,c=o.path,u=(0,br.findAll)(s,function(f){return e.definition[f.idx].ignoreAmbiguities!==!0&&f.idx{"use strict";Object.defineProperty(rf,"__esModule",{value:!0});rf.validateGrammar=rf.resolveGrammar=void 0;var ix=Gt(),qIe=Wj(),JIe=rx(),hq=xd();function WIe(r){r=(0,ix.defaults)(r,{errMsgProvider:hq.defaultGrammarResolverErrorProvider});var e={};return(0,ix.forEach)(r.rules,function(t){e[t.name]=t}),(0,qIe.resolveGrammar)(e,r.errMsgProvider)}rf.resolveGrammar=WIe;function zIe(r){return r=(0,ix.defaults)(r,{errMsgProvider:hq.defaultGrammarValidatorErrorProvider}),(0,JIe.validateGrammar)(r.rules,r.maxLookahead,r.tokenTypes,r.errMsgProvider,r.grammarName)}rf.validateGrammar=zIe});var nf=w(En=>{"use strict";var Fd=En&&En.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(En,"__esModule",{value:!0});En.EarlyExitException=En.NotAllInputParsedException=En.NoViableAltException=En.MismatchedTokenException=En.isRecognitionException=void 0;var VIe=Gt(),dq="MismatchedTokenException",Cq="NoViableAltException",mq="EarlyExitException",Eq="NotAllInputParsedException",Iq=[dq,Cq,mq,Eq];Object.freeze(Iq);function XIe(r){return(0,VIe.contains)(Iq,r.name)}En.isRecognitionException=XIe;var py=function(r){Fd(e,r);function e(t,i){var n=this.constructor,s=r.call(this,t)||this;return s.token=i,s.resyncedTokens=[],Object.setPrototypeOf(s,n.prototype),Error.captureStackTrace&&Error.captureStackTrace(s,s.constructor),s}return e}(Error),ZIe=function(r){Fd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=dq,s}return e}(py);En.MismatchedTokenException=ZIe;var _Ie=function(r){Fd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=Cq,s}return e}(py);En.NoViableAltException=_Ie;var $Ie=function(r){Fd(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.name=Eq,n}return e}(py);En.NotAllInputParsedException=$Ie;var eye=function(r){Fd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=mq,s}return e}(py);En.EarlyExitException=eye});var sx=w(Ui=>{"use strict";Object.defineProperty(Ui,"__esModule",{value:!0});Ui.attemptInRepetitionRecovery=Ui.Recoverable=Ui.InRuleRecoveryException=Ui.IN_RULE_RECOVERY_EXCEPTION=Ui.EOF_FOLLOW_KEY=void 0;var dy=LA(),hs=Gt(),tye=nf(),rye=Jv(),iye=Yn();Ui.EOF_FOLLOW_KEY={};Ui.IN_RULE_RECOVERY_EXCEPTION="InRuleRecoveryException";function nx(r){this.name=Ui.IN_RULE_RECOVERY_EXCEPTION,this.message=r}Ui.InRuleRecoveryException=nx;nx.prototype=Error.prototype;var nye=function(){function r(){}return r.prototype.initRecoverable=function(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,hs.has)(e,"recoveryEnabled")?e.recoveryEnabled:iye.DEFAULT_PARSER_CONFIG.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=yq)},r.prototype.getTokenToInsert=function(e){var t=(0,dy.createTokenInstance)(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return t.isInsertedInRecovery=!0,t},r.prototype.canTokenTypeBeInsertedInRecovery=function(e){return!0},r.prototype.tryInRepetitionRecovery=function(e,t,i,n){for(var s=this,o=this.findReSyncTokenType(),a=this.exportLexerState(),l=[],c=!1,u=this.LA(1),g=this.LA(1),f=function(){var h=s.LA(0),p=s.errorMessageProvider.buildMismatchTokenMessage({expected:n,actual:u,previous:h,ruleName:s.getCurrRuleFullName()}),C=new tye.MismatchedTokenException(p,u,s.LA(0));C.resyncedTokens=(0,hs.dropRight)(l),s.SAVE_ERROR(C)};!c;)if(this.tokenMatcher(g,n)){f();return}else if(i.call(this)){f(),e.apply(this,t);return}else this.tokenMatcher(g,o)?c=!0:(g=this.SKIP_TOKEN(),this.addToResyncTokens(g,l));this.importLexerState(a)},r.prototype.shouldInRepetitionRecoveryBeTried=function(e,t,i){return!(i===!1||e===void 0||t===void 0||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,t)))},r.prototype.getFollowsForInRuleRecovery=function(e,t){var i=this.getCurrentGrammarPath(e,t),n=this.getNextPossibleTokenTypes(i);return n},r.prototype.tryInRuleRecovery=function(e,t){if(this.canRecoverWithSingleTokenInsertion(e,t)){var i=this.getTokenToInsert(e);return i}if(this.canRecoverWithSingleTokenDeletion(e)){var n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new nx("sad sad panda")},r.prototype.canPerformInRuleRecovery=function(e,t){return this.canRecoverWithSingleTokenInsertion(e,t)||this.canRecoverWithSingleTokenDeletion(e)},r.prototype.canRecoverWithSingleTokenInsertion=function(e,t){var i=this;if(!this.canTokenTypeBeInsertedInRecovery(e)||(0,hs.isEmpty)(t))return!1;var n=this.LA(1),s=(0,hs.find)(t,function(o){return i.tokenMatcher(n,o)})!==void 0;return s},r.prototype.canRecoverWithSingleTokenDeletion=function(e){var t=this.tokenMatcher(this.LA(2),e);return t},r.prototype.isInCurrentRuleReSyncSet=function(e){var t=this.getCurrFollowKey(),i=this.getFollowSetFromFollowKey(t);return(0,hs.contains)(i,e)},r.prototype.findReSyncTokenType=function(){for(var e=this.flattenFollowSet(),t=this.LA(1),i=2;;){var n=t.tokenType;if((0,hs.contains)(e,n))return n;t=this.LA(i),i++}},r.prototype.getCurrFollowKey=function(){if(this.RULE_STACK.length===1)return Ui.EOF_FOLLOW_KEY;var e=this.getLastExplicitRuleShortName(),t=this.getLastExplicitRuleOccurrenceIndex(),i=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:t,inRule:this.shortRuleNameToFullName(i)}},r.prototype.buildFullFollowKeyStack=function(){var e=this,t=this.RULE_STACK,i=this.RULE_OCCURRENCE_STACK;return(0,hs.map)(t,function(n,s){return s===0?Ui.EOF_FOLLOW_KEY:{ruleName:e.shortRuleNameToFullName(n),idxInCallingRule:i[s],inRule:e.shortRuleNameToFullName(t[s-1])}})},r.prototype.flattenFollowSet=function(){var e=this,t=(0,hs.map)(this.buildFullFollowKeyStack(),function(i){return e.getFollowSetFromFollowKey(i)});return(0,hs.flatten)(t)},r.prototype.getFollowSetFromFollowKey=function(e){if(e===Ui.EOF_FOLLOW_KEY)return[dy.EOF];var t=e.ruleName+e.idxInCallingRule+rye.IN+e.inRule;return this.resyncFollows[t]},r.prototype.addToResyncTokens=function(e,t){return this.tokenMatcher(e,dy.EOF)||t.push(e),t},r.prototype.reSyncTo=function(e){for(var t=[],i=this.LA(1);this.tokenMatcher(i,e)===!1;)i=this.SKIP_TOKEN(),this.addToResyncTokens(i,t);return(0,hs.dropRight)(t)},r.prototype.attemptInRepetitionRecovery=function(e,t,i,n,s,o,a){},r.prototype.getCurrentGrammarPath=function(e,t){var i=this.getHumanReadableRuleStack(),n=(0,hs.cloneArr)(this.RULE_OCCURRENCE_STACK),s={ruleStack:i,occurrenceStack:n,lastTok:e,lastTokOccurrence:t};return s},r.prototype.getHumanReadableRuleStack=function(){var e=this;return(0,hs.map)(this.RULE_STACK,function(t){return e.shortRuleNameToFullName(t)})},r}();Ui.Recoverable=nye;function yq(r,e,t,i,n,s,o){var a=this.getKeyForAutomaticLookahead(i,n),l=this.firstAfterRepMap[a];if(l===void 0){var c=this.getCurrRuleFullName(),u=this.getGAstProductions()[c],g=new s(u,n);l=g.startWalking(),this.firstAfterRepMap[a]=l}var f=l.token,h=l.occurrence,p=l.isEndOfRule;this.RULE_STACK.length===1&&p&&f===void 0&&(f=dy.EOF,h=1),this.shouldInRepetitionRecoveryBeTried(f,h,o)&&this.tryInRepetitionRecovery(r,e,t,f)}Ui.attemptInRepetitionRecovery=yq});var Cy=w(Jt=>{"use strict";Object.defineProperty(Jt,"__esModule",{value:!0});Jt.getKeyForAutomaticLookahead=Jt.AT_LEAST_ONE_SEP_IDX=Jt.MANY_SEP_IDX=Jt.AT_LEAST_ONE_IDX=Jt.MANY_IDX=Jt.OPTION_IDX=Jt.OR_IDX=Jt.BITS_FOR_ALT_IDX=Jt.BITS_FOR_RULE_IDX=Jt.BITS_FOR_OCCURRENCE_IDX=Jt.BITS_FOR_METHOD_TYPE=void 0;Jt.BITS_FOR_METHOD_TYPE=4;Jt.BITS_FOR_OCCURRENCE_IDX=8;Jt.BITS_FOR_RULE_IDX=12;Jt.BITS_FOR_ALT_IDX=8;Jt.OR_IDX=1<{"use strict";Object.defineProperty(my,"__esModule",{value:!0});my.LooksAhead=void 0;var Da=kd(),ro=Gt(),wq=Yn(),ka=Cy(),Ec=vd(),oye=function(){function r(){}return r.prototype.initLooksAhead=function(e){this.dynamicTokensEnabled=(0,ro.has)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:wq.DEFAULT_PARSER_CONFIG.dynamicTokensEnabled,this.maxLookahead=(0,ro.has)(e,"maxLookahead")?e.maxLookahead:wq.DEFAULT_PARSER_CONFIG.maxLookahead,this.lookAheadFuncsCache=(0,ro.isES2015MapSupported)()?new Map:[],(0,ro.isES2015MapSupported)()?(this.getLaFuncFromCache=this.getLaFuncFromMap,this.setLaFuncCache=this.setLaFuncCacheUsingMap):(this.getLaFuncFromCache=this.getLaFuncFromObj,this.setLaFuncCache=this.setLaFuncUsingObj)},r.prototype.preComputeLookaheadFunctions=function(e){var t=this;(0,ro.forEach)(e,function(i){t.TRACE_INIT(i.name+" Rule Lookahead",function(){var n=(0,Ec.collectMethods)(i),s=n.alternation,o=n.repetition,a=n.option,l=n.repetitionMandatory,c=n.repetitionMandatoryWithSeparator,u=n.repetitionWithSeparator;(0,ro.forEach)(s,function(g){var f=g.idx===0?"":g.idx;t.TRACE_INIT(""+(0,Ec.getProductionDslName)(g)+f,function(){var h=(0,Da.buildLookaheadFuncForOr)(g.idx,i,g.maxLookahead||t.maxLookahead,g.hasPredicates,t.dynamicTokensEnabled,t.lookAheadBuilderForAlternatives),p=(0,ka.getKeyForAutomaticLookahead)(t.fullRuleNameToShort[i.name],ka.OR_IDX,g.idx);t.setLaFuncCache(p,h)})}),(0,ro.forEach)(o,function(g){t.computeLookaheadFunc(i,g.idx,ka.MANY_IDX,Da.PROD_TYPE.REPETITION,g.maxLookahead,(0,Ec.getProductionDslName)(g))}),(0,ro.forEach)(a,function(g){t.computeLookaheadFunc(i,g.idx,ka.OPTION_IDX,Da.PROD_TYPE.OPTION,g.maxLookahead,(0,Ec.getProductionDslName)(g))}),(0,ro.forEach)(l,function(g){t.computeLookaheadFunc(i,g.idx,ka.AT_LEAST_ONE_IDX,Da.PROD_TYPE.REPETITION_MANDATORY,g.maxLookahead,(0,Ec.getProductionDslName)(g))}),(0,ro.forEach)(c,function(g){t.computeLookaheadFunc(i,g.idx,ka.AT_LEAST_ONE_SEP_IDX,Da.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,g.maxLookahead,(0,Ec.getProductionDslName)(g))}),(0,ro.forEach)(u,function(g){t.computeLookaheadFunc(i,g.idx,ka.MANY_SEP_IDX,Da.PROD_TYPE.REPETITION_WITH_SEPARATOR,g.maxLookahead,(0,Ec.getProductionDslName)(g))})})})},r.prototype.computeLookaheadFunc=function(e,t,i,n,s,o){var a=this;this.TRACE_INIT(""+o+(t===0?"":t),function(){var l=(0,Da.buildLookaheadFuncForOptionalProd)(t,e,s||a.maxLookahead,a.dynamicTokensEnabled,n,a.lookAheadBuilderForOptional),c=(0,ka.getKeyForAutomaticLookahead)(a.fullRuleNameToShort[e.name],i,t);a.setLaFuncCache(c,l)})},r.prototype.lookAheadBuilderForOptional=function(e,t,i){return(0,Da.buildSingleAlternativeLookaheadFunction)(e,t,i)},r.prototype.lookAheadBuilderForAlternatives=function(e,t,i,n){return(0,Da.buildAlternativesLookAheadFunc)(e,t,i,n)},r.prototype.getKeyForAutomaticLookahead=function(e,t){var i=this.getLastExplicitRuleShortName();return(0,ka.getKeyForAutomaticLookahead)(i,e,t)},r.prototype.getLaFuncFromCache=function(e){},r.prototype.getLaFuncFromMap=function(e){return this.lookAheadFuncsCache.get(e)},r.prototype.getLaFuncFromObj=function(e){return this.lookAheadFuncsCache[e]},r.prototype.setLaFuncCache=function(e,t){},r.prototype.setLaFuncCacheUsingMap=function(e,t){this.lookAheadFuncsCache.set(e,t)},r.prototype.setLaFuncUsingObj=function(e,t){this.lookAheadFuncsCache[e]=t},r}();my.LooksAhead=oye});var Qq=w(Lo=>{"use strict";Object.defineProperty(Lo,"__esModule",{value:!0});Lo.addNoneTerminalToCst=Lo.addTerminalToCst=Lo.setNodeLocationFull=Lo.setNodeLocationOnlyOffset=void 0;function aye(r,e){isNaN(r.startOffset)===!0?(r.startOffset=e.startOffset,r.endOffset=e.endOffset):r.endOffset{"use strict";Object.defineProperty(MA,"__esModule",{value:!0});MA.defineNameProp=MA.functionName=MA.classNameFromInstance=void 0;var uye=Gt();function gye(r){return Sq(r.constructor)}MA.classNameFromInstance=gye;var bq="name";function Sq(r){var e=r.name;return e||"anonymous"}MA.functionName=Sq;function fye(r,e){var t=Object.getOwnPropertyDescriptor(r,bq);return(0,uye.isUndefined)(t)||t.configurable?(Object.defineProperty(r,bq,{enumerable:!1,configurable:!0,writable:!1,value:e}),!0):!1}MA.defineNameProp=fye});var kq=w(Si=>{"use strict";Object.defineProperty(Si,"__esModule",{value:!0});Si.validateRedundantMethods=Si.validateMissingCstMethods=Si.validateVisitor=Si.CstVisitorDefinitionError=Si.createBaseVisitorConstructorWithDefaults=Si.createBaseSemanticVisitorConstructor=Si.defaultVisit=void 0;var ps=Gt(),Nd=ox();function vq(r,e){for(var t=(0,ps.keys)(r),i=t.length,n=0;n: + `+(""+s.join(` + +`).replace(/\n/g,` + `)))}}};return t.prototype=i,t.prototype.constructor=t,t._RULE_NAMES=e,t}Si.createBaseSemanticVisitorConstructor=hye;function pye(r,e,t){var i=function(){};(0,Nd.defineNameProp)(i,r+"BaseSemanticsWithDefaults");var n=Object.create(t.prototype);return(0,ps.forEach)(e,function(s){n[s]=vq}),i.prototype=n,i.prototype.constructor=i,i}Si.createBaseVisitorConstructorWithDefaults=pye;var ax;(function(r){r[r.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",r[r.MISSING_METHOD=1]="MISSING_METHOD"})(ax=Si.CstVisitorDefinitionError||(Si.CstVisitorDefinitionError={}));function xq(r,e){var t=Pq(r,e),i=Dq(r,e);return t.concat(i)}Si.validateVisitor=xq;function Pq(r,e){var t=(0,ps.map)(e,function(i){if(!(0,ps.isFunction)(r[i]))return{msg:"Missing visitor method: <"+i+"> on "+(0,Nd.functionName)(r.constructor)+" CST Visitor.",type:ax.MISSING_METHOD,methodName:i}});return(0,ps.compact)(t)}Si.validateMissingCstMethods=Pq;var dye=["constructor","visit","validateVisitor"];function Dq(r,e){var t=[];for(var i in r)(0,ps.isFunction)(r[i])&&!(0,ps.contains)(dye,i)&&!(0,ps.contains)(e,i)&&t.push({msg:"Redundant visitor method: <"+i+"> on "+(0,Nd.functionName)(r.constructor)+` CST Visitor +There is no Grammar Rule corresponding to this method's name. +`,type:ax.REDUNDANT_METHOD,methodName:i});return t}Si.validateRedundantMethods=Dq});var Fq=w(Ey=>{"use strict";Object.defineProperty(Ey,"__esModule",{value:!0});Ey.TreeBuilder=void 0;var sf=Qq(),_r=Gt(),Rq=kq(),Cye=Yn(),mye=function(){function r(){}return r.prototype.initTreeBuilder=function(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,_r.has)(e,"nodeLocationTracking")?e.nodeLocationTracking:Cye.DEFAULT_PARSER_CONFIG.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=_r.NOOP,this.cstFinallyStateUpdate=_r.NOOP,this.cstPostTerminal=_r.NOOP,this.cstPostNonTerminal=_r.NOOP,this.cstPostRule=_r.NOOP;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=sf.setNodeLocationFull,this.setNodeLocationFromNode=sf.setNodeLocationFull,this.cstPostRule=_r.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=_r.NOOP,this.setNodeLocationFromNode=_r.NOOP,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=sf.setNodeLocationOnlyOffset,this.setNodeLocationFromNode=sf.setNodeLocationOnlyOffset,this.cstPostRule=_r.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=_r.NOOP,this.setNodeLocationFromNode=_r.NOOP,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=_r.NOOP,this.setNodeLocationFromNode=_r.NOOP,this.cstPostRule=_r.NOOP,this.setInitialNodeLocation=_r.NOOP;else throw Error('Invalid config option: "'+e.nodeLocationTracking+'"')},r.prototype.setInitialNodeLocationOnlyOffsetRecovery=function(e){e.location={startOffset:NaN,endOffset:NaN}},r.prototype.setInitialNodeLocationOnlyOffsetRegular=function(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}},r.prototype.setInitialNodeLocationFullRecovery=function(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.setInitialNodeLocationFullRegular=function(e){var t=this.LA(1);e.location={startOffset:t.startOffset,startLine:t.startLine,startColumn:t.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.cstInvocationStateUpdate=function(e,t){var i={name:e,children:{}};this.setInitialNodeLocation(i),this.CST_STACK.push(i)},r.prototype.cstFinallyStateUpdate=function(){this.CST_STACK.pop()},r.prototype.cstPostRuleFull=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?(i.endOffset=t.endOffset,i.endLine=t.endLine,i.endColumn=t.endColumn):(i.startOffset=NaN,i.startLine=NaN,i.startColumn=NaN)},r.prototype.cstPostRuleOnlyOffset=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?i.endOffset=t.endOffset:i.startOffset=NaN},r.prototype.cstPostTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,sf.addTerminalToCst)(i,t,e),this.setNodeLocationFromToken(i.location,t)},r.prototype.cstPostNonTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,sf.addNoneTerminalToCst)(i,t,e),this.setNodeLocationFromNode(i.location,e.location)},r.prototype.getBaseCstVisitorConstructor=function(){if((0,_r.isUndefined)(this.baseCstVisitorConstructor)){var e=(0,Rq.createBaseSemanticVisitorConstructor)(this.className,(0,_r.keys)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor},r.prototype.getBaseCstVisitorConstructorWithDefaults=function(){if((0,_r.isUndefined)(this.baseCstVisitorWithDefaultsConstructor)){var e=(0,Rq.createBaseVisitorConstructorWithDefaults)(this.className,(0,_r.keys)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor},r.prototype.getLastExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-1]},r.prototype.getPreviousExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-2]},r.prototype.getLastExplicitRuleOccurrenceIndex=function(){var e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]},r}();Ey.TreeBuilder=mye});var Lq=w(Iy=>{"use strict";Object.defineProperty(Iy,"__esModule",{value:!0});Iy.LexerAdapter=void 0;var Nq=Yn(),Eye=function(){function r(){}return r.prototype.initLexerAdapter=function(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1},Object.defineProperty(r.prototype,"input",{get:function(){return this.tokVector},set:function(e){if(this.selfAnalysisDone!==!0)throw Error("Missing invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length},enumerable:!1,configurable:!0}),r.prototype.SKIP_TOKEN=function(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):Nq.END_OF_FILE},r.prototype.LA=function(e){var t=this.currIdx+e;return t<0||this.tokVectorLength<=t?Nq.END_OF_FILE:this.tokVector[t]},r.prototype.consumeToken=function(){this.currIdx++},r.prototype.exportLexerState=function(){return this.currIdx},r.prototype.importLexerState=function(e){this.currIdx=e},r.prototype.resetLexerState=function(){this.currIdx=-1},r.prototype.moveToTerminatedState=function(){this.currIdx=this.tokVector.length-1},r.prototype.getLexerPosition=function(){return this.exportLexerState()},r}();Iy.LexerAdapter=Eye});var Oq=w(yy=>{"use strict";Object.defineProperty(yy,"__esModule",{value:!0});yy.RecognizerApi=void 0;var Tq=Gt(),Iye=nf(),Ax=Yn(),yye=xd(),wye=rx(),Bye=Cn(),Qye=function(){function r(){}return r.prototype.ACTION=function(e){return e.call(this)},r.prototype.consume=function(e,t,i){return this.consumeInternal(t,e,i)},r.prototype.subrule=function(e,t,i){return this.subruleInternal(t,e,i)},r.prototype.option=function(e,t){return this.optionInternal(t,e)},r.prototype.or=function(e,t){return this.orInternal(t,e)},r.prototype.many=function(e,t){return this.manyInternal(e,t)},r.prototype.atLeastOne=function(e,t){return this.atLeastOneInternal(e,t)},r.prototype.CONSUME=function(e,t){return this.consumeInternal(e,0,t)},r.prototype.CONSUME1=function(e,t){return this.consumeInternal(e,1,t)},r.prototype.CONSUME2=function(e,t){return this.consumeInternal(e,2,t)},r.prototype.CONSUME3=function(e,t){return this.consumeInternal(e,3,t)},r.prototype.CONSUME4=function(e,t){return this.consumeInternal(e,4,t)},r.prototype.CONSUME5=function(e,t){return this.consumeInternal(e,5,t)},r.prototype.CONSUME6=function(e,t){return this.consumeInternal(e,6,t)},r.prototype.CONSUME7=function(e,t){return this.consumeInternal(e,7,t)},r.prototype.CONSUME8=function(e,t){return this.consumeInternal(e,8,t)},r.prototype.CONSUME9=function(e,t){return this.consumeInternal(e,9,t)},r.prototype.SUBRULE=function(e,t){return this.subruleInternal(e,0,t)},r.prototype.SUBRULE1=function(e,t){return this.subruleInternal(e,1,t)},r.prototype.SUBRULE2=function(e,t){return this.subruleInternal(e,2,t)},r.prototype.SUBRULE3=function(e,t){return this.subruleInternal(e,3,t)},r.prototype.SUBRULE4=function(e,t){return this.subruleInternal(e,4,t)},r.prototype.SUBRULE5=function(e,t){return this.subruleInternal(e,5,t)},r.prototype.SUBRULE6=function(e,t){return this.subruleInternal(e,6,t)},r.prototype.SUBRULE7=function(e,t){return this.subruleInternal(e,7,t)},r.prototype.SUBRULE8=function(e,t){return this.subruleInternal(e,8,t)},r.prototype.SUBRULE9=function(e,t){return this.subruleInternal(e,9,t)},r.prototype.OPTION=function(e){return this.optionInternal(e,0)},r.prototype.OPTION1=function(e){return this.optionInternal(e,1)},r.prototype.OPTION2=function(e){return this.optionInternal(e,2)},r.prototype.OPTION3=function(e){return this.optionInternal(e,3)},r.prototype.OPTION4=function(e){return this.optionInternal(e,4)},r.prototype.OPTION5=function(e){return this.optionInternal(e,5)},r.prototype.OPTION6=function(e){return this.optionInternal(e,6)},r.prototype.OPTION7=function(e){return this.optionInternal(e,7)},r.prototype.OPTION8=function(e){return this.optionInternal(e,8)},r.prototype.OPTION9=function(e){return this.optionInternal(e,9)},r.prototype.OR=function(e){return this.orInternal(e,0)},r.prototype.OR1=function(e){return this.orInternal(e,1)},r.prototype.OR2=function(e){return this.orInternal(e,2)},r.prototype.OR3=function(e){return this.orInternal(e,3)},r.prototype.OR4=function(e){return this.orInternal(e,4)},r.prototype.OR5=function(e){return this.orInternal(e,5)},r.prototype.OR6=function(e){return this.orInternal(e,6)},r.prototype.OR7=function(e){return this.orInternal(e,7)},r.prototype.OR8=function(e){return this.orInternal(e,8)},r.prototype.OR9=function(e){return this.orInternal(e,9)},r.prototype.MANY=function(e){this.manyInternal(0,e)},r.prototype.MANY1=function(e){this.manyInternal(1,e)},r.prototype.MANY2=function(e){this.manyInternal(2,e)},r.prototype.MANY3=function(e){this.manyInternal(3,e)},r.prototype.MANY4=function(e){this.manyInternal(4,e)},r.prototype.MANY5=function(e){this.manyInternal(5,e)},r.prototype.MANY6=function(e){this.manyInternal(6,e)},r.prototype.MANY7=function(e){this.manyInternal(7,e)},r.prototype.MANY8=function(e){this.manyInternal(8,e)},r.prototype.MANY9=function(e){this.manyInternal(9,e)},r.prototype.MANY_SEP=function(e){this.manySepFirstInternal(0,e)},r.prototype.MANY_SEP1=function(e){this.manySepFirstInternal(1,e)},r.prototype.MANY_SEP2=function(e){this.manySepFirstInternal(2,e)},r.prototype.MANY_SEP3=function(e){this.manySepFirstInternal(3,e)},r.prototype.MANY_SEP4=function(e){this.manySepFirstInternal(4,e)},r.prototype.MANY_SEP5=function(e){this.manySepFirstInternal(5,e)},r.prototype.MANY_SEP6=function(e){this.manySepFirstInternal(6,e)},r.prototype.MANY_SEP7=function(e){this.manySepFirstInternal(7,e)},r.prototype.MANY_SEP8=function(e){this.manySepFirstInternal(8,e)},r.prototype.MANY_SEP9=function(e){this.manySepFirstInternal(9,e)},r.prototype.AT_LEAST_ONE=function(e){this.atLeastOneInternal(0,e)},r.prototype.AT_LEAST_ONE1=function(e){return this.atLeastOneInternal(1,e)},r.prototype.AT_LEAST_ONE2=function(e){this.atLeastOneInternal(2,e)},r.prototype.AT_LEAST_ONE3=function(e){this.atLeastOneInternal(3,e)},r.prototype.AT_LEAST_ONE4=function(e){this.atLeastOneInternal(4,e)},r.prototype.AT_LEAST_ONE5=function(e){this.atLeastOneInternal(5,e)},r.prototype.AT_LEAST_ONE6=function(e){this.atLeastOneInternal(6,e)},r.prototype.AT_LEAST_ONE7=function(e){this.atLeastOneInternal(7,e)},r.prototype.AT_LEAST_ONE8=function(e){this.atLeastOneInternal(8,e)},r.prototype.AT_LEAST_ONE9=function(e){this.atLeastOneInternal(9,e)},r.prototype.AT_LEAST_ONE_SEP=function(e){this.atLeastOneSepFirstInternal(0,e)},r.prototype.AT_LEAST_ONE_SEP1=function(e){this.atLeastOneSepFirstInternal(1,e)},r.prototype.AT_LEAST_ONE_SEP2=function(e){this.atLeastOneSepFirstInternal(2,e)},r.prototype.AT_LEAST_ONE_SEP3=function(e){this.atLeastOneSepFirstInternal(3,e)},r.prototype.AT_LEAST_ONE_SEP4=function(e){this.atLeastOneSepFirstInternal(4,e)},r.prototype.AT_LEAST_ONE_SEP5=function(e){this.atLeastOneSepFirstInternal(5,e)},r.prototype.AT_LEAST_ONE_SEP6=function(e){this.atLeastOneSepFirstInternal(6,e)},r.prototype.AT_LEAST_ONE_SEP7=function(e){this.atLeastOneSepFirstInternal(7,e)},r.prototype.AT_LEAST_ONE_SEP8=function(e){this.atLeastOneSepFirstInternal(8,e)},r.prototype.AT_LEAST_ONE_SEP9=function(e){this.atLeastOneSepFirstInternal(9,e)},r.prototype.RULE=function(e,t,i){if(i===void 0&&(i=Ax.DEFAULT_RULE_CONFIG),(0,Tq.contains)(this.definedRulesNames,e)){var n=yye.defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),s={message:n,type:Ax.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);var o=this.defineRule(e,t,i);return this[e]=o,o},r.prototype.OVERRIDE_RULE=function(e,t,i){i===void 0&&(i=Ax.DEFAULT_RULE_CONFIG);var n=[];n=n.concat((0,wye.validateRuleIsOverridden)(e,this.definedRulesNames,this.className)),this.definitionErrors=this.definitionErrors.concat(n);var s=this.defineRule(e,t,i);return this[e]=s,s},r.prototype.BACKTRACK=function(e,t){return function(){this.isBackTrackingStack.push(1);var i=this.saveRecogState();try{return e.apply(this,t),!0}catch(n){if((0,Iye.isRecognitionException)(n))return!1;throw n}finally{this.reloadRecogState(i),this.isBackTrackingStack.pop()}}},r.prototype.getGAstProductions=function(){return this.gastProductionsCache},r.prototype.getSerializedGastProductions=function(){return(0,Bye.serializeGrammar)((0,Tq.values)(this.gastProductionsCache))},r}();yy.RecognizerApi=Qye});var Hq=w(By=>{"use strict";Object.defineProperty(By,"__esModule",{value:!0});By.RecognizerEngine=void 0;var Pr=Gt(),jn=Cy(),wy=nf(),Mq=kd(),of=Dd(),Uq=Yn(),bye=sx(),Kq=LA(),Ld=_g(),Sye=ox(),vye=function(){function r(){}return r.prototype.initRecognizerEngine=function(e,t){if(this.className=(0,Sye.classNameFromInstance)(this),this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=Ld.tokenStructuredMatcherNoCategories,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,Pr.has)(t,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a property. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0 + For Further details.`);if((0,Pr.isArray)(e)){if((0,Pr.isEmpty)(e))throw Error(`A Token Vocabulary cannot be empty. + Note that the first argument for the parser constructor + is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0 + For Further details.`)}if((0,Pr.isArray)(e))this.tokensMap=(0,Pr.reduce)(e,function(o,a){return o[a.name]=a,o},{});else if((0,Pr.has)(e,"modes")&&(0,Pr.every)((0,Pr.flatten)((0,Pr.values)(e.modes)),Ld.isTokenType)){var i=(0,Pr.flatten)((0,Pr.values)(e.modes)),n=(0,Pr.uniq)(i);this.tokensMap=(0,Pr.reduce)(n,function(o,a){return o[a.name]=a,o},{})}else if((0,Pr.isObject)(e))this.tokensMap=(0,Pr.cloneObj)(e);else throw new Error(" argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=Kq.EOF;var s=(0,Pr.every)((0,Pr.values)(e),function(o){return(0,Pr.isEmpty)(o.categoryMatches)});this.tokenMatcher=s?Ld.tokenStructuredMatcherNoCategories:Ld.tokenStructuredMatcher,(0,Ld.augmentTokenTypes)((0,Pr.values)(this.tokensMap))},r.prototype.defineRule=function(e,t,i){if(this.selfAnalysisDone)throw Error("Grammar rule <"+e+`> may not be defined after the 'performSelfAnalysis' method has been called' +Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);var n=(0,Pr.has)(i,"resyncEnabled")?i.resyncEnabled:Uq.DEFAULT_RULE_CONFIG.resyncEnabled,s=(0,Pr.has)(i,"recoveryValueFunc")?i.recoveryValueFunc:Uq.DEFAULT_RULE_CONFIG.recoveryValueFunc,o=this.ruleShortNameIdx<t},r.prototype.orInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(jn.OR_IDX,t),n=(0,Pr.isArray)(e)?e:e.DEF,s=this.getLaFuncFromCache(i),o=s.call(this,n);if(o!==void 0){var a=n[o];return a.ALT.call(this)}this.raiseNoAltException(t,e.ERR_MSG)},r.prototype.ruleFinallyStateUpdate=function(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){var e=this.LA(1),t=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new wy.NotAllInputParsedException(t,e))}},r.prototype.subruleInternal=function(e,t,i){var n;try{var s=i!==void 0?i.ARGS:void 0;return n=e.call(this,t,s),this.cstPostNonTerminal(n,i!==void 0&&i.LABEL!==void 0?i.LABEL:e.ruleName),n}catch(o){this.subruleInternalError(o,i,e.ruleName)}},r.prototype.subruleInternalError=function(e,t,i){throw(0,wy.isRecognitionException)(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,t!==void 0&&t.LABEL!==void 0?t.LABEL:i),delete e.partialCstResult),e},r.prototype.consumeInternal=function(e,t,i){var n;try{var s=this.LA(1);this.tokenMatcher(s,e)===!0?(this.consumeToken(),n=s):this.consumeInternalError(e,s,i)}catch(o){n=this.consumeInternalRecovery(e,t,o)}return this.cstPostTerminal(i!==void 0&&i.LABEL!==void 0?i.LABEL:e.name,n),n},r.prototype.consumeInternalError=function(e,t,i){var n,s=this.LA(0);throw i!==void 0&&i.ERR_MSG?n=i.ERR_MSG:n=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:t,previous:s,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new wy.MismatchedTokenException(n,t,s))},r.prototype.consumeInternalRecovery=function(e,t,i){if(this.recoveryEnabled&&i.name==="MismatchedTokenException"&&!this.isBackTracking()){var n=this.getFollowsForInRuleRecovery(e,t);try{return this.tryInRuleRecovery(e,n)}catch(s){throw s.name===bye.IN_RULE_RECOVERY_EXCEPTION?i:s}}else throw i},r.prototype.saveRecogState=function(){var e=this.errors,t=(0,Pr.cloneArr)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:t,CST_STACK:this.CST_STACK}},r.prototype.reloadRecogState=function(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK},r.prototype.ruleInvocationStateUpdate=function(e,t,i){this.RULE_OCCURRENCE_STACK.push(i),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(t,e)},r.prototype.isBackTracking=function(){return this.isBackTrackingStack.length!==0},r.prototype.getCurrRuleFullName=function(){var e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]},r.prototype.shortRuleNameToFullName=function(e){return this.shortRuleNameToFull[e]},r.prototype.isAtEndOfInput=function(){return this.tokenMatcher(this.LA(1),Kq.EOF)},r.prototype.reset=function(){this.resetLexerState(),this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]},r}();By.RecognizerEngine=vye});var Yq=w(Qy=>{"use strict";Object.defineProperty(Qy,"__esModule",{value:!0});Qy.ErrorHandler=void 0;var lx=nf(),cx=Gt(),Gq=kd(),xye=Yn(),Pye=function(){function r(){}return r.prototype.initErrorHandler=function(e){this._errors=[],this.errorMessageProvider=(0,cx.has)(e,"errorMessageProvider")?e.errorMessageProvider:xye.DEFAULT_PARSER_CONFIG.errorMessageProvider},r.prototype.SAVE_ERROR=function(e){if((0,lx.isRecognitionException)(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,cx.cloneArr)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")},Object.defineProperty(r.prototype,"errors",{get:function(){return(0,cx.cloneArr)(this._errors)},set:function(e){this._errors=e},enumerable:!1,configurable:!0}),r.prototype.raiseEarlyExitException=function(e,t,i){for(var n=this.getCurrRuleFullName(),s=this.getGAstProductions()[n],o=(0,Gq.getLookaheadPathsForOptionalProd)(e,s,t,this.maxLookahead),a=o[0],l=[],c=1;c<=this.maxLookahead;c++)l.push(this.LA(c));var u=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:a,actual:l,previous:this.LA(0),customUserDescription:i,ruleName:n});throw this.SAVE_ERROR(new lx.EarlyExitException(u,this.LA(1),this.LA(0)))},r.prototype.raiseNoAltException=function(e,t){for(var i=this.getCurrRuleFullName(),n=this.getGAstProductions()[i],s=(0,Gq.getLookaheadPathsForOr)(e,n,this.maxLookahead),o=[],a=1;a<=this.maxLookahead;a++)o.push(this.LA(a));var l=this.LA(0),c=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:s,actual:o,previous:l,customUserDescription:t,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new lx.NoViableAltException(c,this.LA(1),l))},r}();Qy.ErrorHandler=Pye});var Jq=w(by=>{"use strict";Object.defineProperty(by,"__esModule",{value:!0});by.ContentAssist=void 0;var jq=Dd(),qq=Gt(),Dye=function(){function r(){}return r.prototype.initContentAssist=function(){},r.prototype.computeContentAssist=function(e,t){var i=this.gastProductionsCache[e];if((0,qq.isUndefined)(i))throw Error("Rule ->"+e+"<- does not exist in this grammar.");return(0,jq.nextPossibleTokensAfter)([i],t,this.tokenMatcher,this.maxLookahead)},r.prototype.getNextPossibleTokenTypes=function(e){var t=(0,qq.first)(e.ruleStack),i=this.getGAstProductions(),n=i[t],s=new jq.NextAfterTokenWalker(n,e).startWalking();return s},r}();by.ContentAssist=Dye});var eJ=w(xy=>{"use strict";Object.defineProperty(xy,"__esModule",{value:!0});xy.GastRecorder=void 0;var In=Gt(),To=Cn(),kye=Bd(),Xq=_g(),Zq=LA(),Rye=Yn(),Fye=Cy(),vy={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(vy);var Wq=!0,zq=Math.pow(2,Fye.BITS_FOR_OCCURRENCE_IDX)-1,_q=(0,Zq.createToken)({name:"RECORDING_PHASE_TOKEN",pattern:kye.Lexer.NA});(0,Xq.augmentTokenTypes)([_q]);var $q=(0,Zq.createTokenInstance)(_q,`This IToken indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze($q);var Nye={name:`This CSTNode indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},Lye=function(){function r(){}return r.prototype.initGastRecorder=function(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1},r.prototype.enableRecording=function(){var e=this;this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",function(){for(var t=function(n){var s=n>0?n:"";e["CONSUME"+s]=function(o,a){return this.consumeInternalRecord(o,n,a)},e["SUBRULE"+s]=function(o,a){return this.subruleInternalRecord(o,n,a)},e["OPTION"+s]=function(o){return this.optionInternalRecord(o,n)},e["OR"+s]=function(o){return this.orInternalRecord(o,n)},e["MANY"+s]=function(o){this.manyInternalRecord(n,o)},e["MANY_SEP"+s]=function(o){this.manySepFirstInternalRecord(n,o)},e["AT_LEAST_ONE"+s]=function(o){this.atLeastOneInternalRecord(n,o)},e["AT_LEAST_ONE_SEP"+s]=function(o){this.atLeastOneSepFirstInternalRecord(n,o)}},i=0;i<10;i++)t(i);e.consume=function(n,s,o){return this.consumeInternalRecord(s,n,o)},e.subrule=function(n,s,o){return this.subruleInternalRecord(s,n,o)},e.option=function(n,s){return this.optionInternalRecord(s,n)},e.or=function(n,s){return this.orInternalRecord(s,n)},e.many=function(n,s){this.manyInternalRecord(n,s)},e.atLeastOne=function(n,s){this.atLeastOneInternalRecord(n,s)},e.ACTION=e.ACTION_RECORD,e.BACKTRACK=e.BACKTRACK_RECORD,e.LA=e.LA_RECORD})},r.prototype.disableRecording=function(){var e=this;this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",function(){for(var t=0;t<10;t++){var i=t>0?t:"";delete e["CONSUME"+i],delete e["SUBRULE"+i],delete e["OPTION"+i],delete e["OR"+i],delete e["MANY"+i],delete e["MANY_SEP"+i],delete e["AT_LEAST_ONE"+i],delete e["AT_LEAST_ONE_SEP"+i]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})},r.prototype.ACTION_RECORD=function(e){},r.prototype.BACKTRACK_RECORD=function(e,t){return function(){return!0}},r.prototype.LA_RECORD=function(e){return Rye.END_OF_FILE},r.prototype.topLevelRuleRecord=function(e,t){try{var i=new To.Rule({definition:[],name:e});return i.name=e,this.recordingProdStack.push(i),t.call(this),this.recordingProdStack.pop(),i}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+` + This error was thrown during the "grammar recording phase" For more info see: + https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch{throw n}throw n}},r.prototype.optionInternalRecord=function(e,t){return Td.call(this,To.Option,e,t)},r.prototype.atLeastOneInternalRecord=function(e,t){Td.call(this,To.RepetitionMandatory,t,e)},r.prototype.atLeastOneSepFirstInternalRecord=function(e,t){Td.call(this,To.RepetitionMandatoryWithSeparator,t,e,Wq)},r.prototype.manyInternalRecord=function(e,t){Td.call(this,To.Repetition,t,e)},r.prototype.manySepFirstInternalRecord=function(e,t){Td.call(this,To.RepetitionWithSeparator,t,e,Wq)},r.prototype.orInternalRecord=function(e,t){return Tye.call(this,e,t)},r.prototype.subruleInternalRecord=function(e,t,i){if(Sy(t),!e||(0,In.has)(e,"ruleName")===!1){var n=new Error(" argument is invalid"+(" expecting a Parser method reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,In.peek)(this.recordingProdStack),o=e.ruleName,a=new To.NonTerminal({idx:t,nonTerminalName:o,label:i==null?void 0:i.LABEL,referencedRule:void 0});return s.definition.push(a),this.outputCst?Nye:vy},r.prototype.consumeInternalRecord=function(e,t,i){if(Sy(t),!(0,Xq.hasShortKeyProperty)(e)){var n=new Error(" argument is invalid"+(" expecting a TokenType reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,In.peek)(this.recordingProdStack),o=new To.Terminal({idx:t,terminalType:e,label:i==null?void 0:i.LABEL});return s.definition.push(o),$q},r}();xy.GastRecorder=Lye;function Td(r,e,t,i){i===void 0&&(i=!1),Sy(t);var n=(0,In.peek)(this.recordingProdStack),s=(0,In.isFunction)(e)?e:e.DEF,o=new r({definition:[],idx:t});return i&&(o.separator=e.SEP),(0,In.has)(e,"MAX_LOOKAHEAD")&&(o.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(o),s.call(this),n.definition.push(o),this.recordingProdStack.pop(),vy}function Tye(r,e){var t=this;Sy(e);var i=(0,In.peek)(this.recordingProdStack),n=(0,In.isArray)(r)===!1,s=n===!1?r:r.DEF,o=new To.Alternation({definition:[],idx:e,ignoreAmbiguities:n&&r.IGNORE_AMBIGUITIES===!0});(0,In.has)(r,"MAX_LOOKAHEAD")&&(o.maxLookahead=r.MAX_LOOKAHEAD);var a=(0,In.some)(s,function(l){return(0,In.isFunction)(l.GATE)});return o.hasPredicates=a,i.definition.push(o),(0,In.forEach)(s,function(l){var c=new To.Alternative({definition:[]});o.definition.push(c),(0,In.has)(l,"IGNORE_AMBIGUITIES")?c.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:(0,In.has)(l,"GATE")&&(c.ignoreAmbiguities=!0),t.recordingProdStack.push(c),l.ALT.call(t),t.recordingProdStack.pop()}),vy}function Vq(r){return r===0?"":""+r}function Sy(r){if(r<0||r>zq){var e=new Error("Invalid DSL Method idx value: <"+r+`> + `+("Idx value must be a none negative value smaller than "+(zq+1)));throw e.KNOWN_RECORDER_ERROR=!0,e}}});var rJ=w(Py=>{"use strict";Object.defineProperty(Py,"__esModule",{value:!0});Py.PerformanceTracer=void 0;var tJ=Gt(),Oye=Yn(),Mye=function(){function r(){}return r.prototype.initPerformanceTracer=function(e){if((0,tJ.has)(e,"traceInitPerf")){var t=e.traceInitPerf,i=typeof t=="number";this.traceInitMaxIdent=i?t:1/0,this.traceInitPerf=i?t>0:t}else this.traceInitMaxIdent=0,this.traceInitPerf=Oye.DEFAULT_PARSER_CONFIG.traceInitPerf;this.traceInitIndent=-1},r.prototype.TRACE_INIT=function(e,t){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <"+e+">");var n=(0,tJ.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r}();Py.PerformanceTracer=Mye});var iJ=w(Dy=>{"use strict";Object.defineProperty(Dy,"__esModule",{value:!0});Dy.applyMixins=void 0;function Uye(r,e){e.forEach(function(t){var i=t.prototype;Object.getOwnPropertyNames(i).forEach(function(n){if(n!=="constructor"){var s=Object.getOwnPropertyDescriptor(i,n);s&&(s.get||s.set)?Object.defineProperty(r.prototype,n,s):r.prototype[n]=t.prototype[n]}})})}Dy.applyMixins=Uye});var Yn=w(dr=>{"use strict";var oJ=dr&&dr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(dr,"__esModule",{value:!0});dr.EmbeddedActionsParser=dr.CstParser=dr.Parser=dr.EMPTY_ALT=dr.ParserDefinitionErrorType=dr.DEFAULT_RULE_CONFIG=dr.DEFAULT_PARSER_CONFIG=dr.END_OF_FILE=void 0;var $i=Gt(),Kye=Yj(),nJ=LA(),aJ=xd(),sJ=pq(),Hye=sx(),Gye=Bq(),Yye=Fq(),jye=Lq(),qye=Oq(),Jye=Hq(),Wye=Yq(),zye=Jq(),Vye=eJ(),Xye=rJ(),Zye=iJ();dr.END_OF_FILE=(0,nJ.createTokenInstance)(nJ.EOF,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(dr.END_OF_FILE);dr.DEFAULT_PARSER_CONFIG=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:aJ.defaultParserErrorProvider,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1});dr.DEFAULT_RULE_CONFIG=Object.freeze({recoveryValueFunc:function(){},resyncEnabled:!0});var _ye;(function(r){r[r.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",r[r.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",r[r.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",r[r.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",r[r.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",r[r.LEFT_RECURSION=5]="LEFT_RECURSION",r[r.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",r[r.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",r[r.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",r[r.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",r[r.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",r[r.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",r[r.TOO_MANY_ALTS=12]="TOO_MANY_ALTS"})(_ye=dr.ParserDefinitionErrorType||(dr.ParserDefinitionErrorType={}));function $ye(r){return r===void 0&&(r=void 0),function(){return r}}dr.EMPTY_ALT=$ye;var ky=function(){function r(e,t){this.definitionErrors=[],this.selfAnalysisDone=!1;var i=this;if(i.initErrorHandler(t),i.initLexerAdapter(),i.initLooksAhead(t),i.initRecognizerEngine(e,t),i.initRecoverable(t),i.initTreeBuilder(t),i.initContentAssist(),i.initGastRecorder(t),i.initPerformanceTracer(t),(0,$i.has)(t,"ignoredIssues"))throw new Error(`The IParserConfig property has been deprecated. + Please use the flag on the relevant DSL method instead. + See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES + For further details.`);this.skipValidations=(0,$i.has)(t,"skipValidations")?t.skipValidations:dr.DEFAULT_PARSER_CONFIG.skipValidations}return r.performSelfAnalysis=function(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")},r.prototype.performSelfAnalysis=function(){var e=this;this.TRACE_INIT("performSelfAnalysis",function(){var t;e.selfAnalysisDone=!0;var i=e.className;e.TRACE_INIT("toFastProps",function(){(0,$i.toFastProperties)(e)}),e.TRACE_INIT("Grammar Recording",function(){try{e.enableRecording(),(0,$i.forEach)(e.definedRulesNames,function(s){var o=e[s],a=o.originalGrammarAction,l=void 0;e.TRACE_INIT(s+" Rule",function(){l=e.topLevelRuleRecord(s,a)}),e.gastProductionsCache[s]=l})}finally{e.disableRecording()}});var n=[];if(e.TRACE_INIT("Grammar Resolving",function(){n=(0,sJ.resolveGrammar)({rules:(0,$i.values)(e.gastProductionsCache)}),e.definitionErrors=e.definitionErrors.concat(n)}),e.TRACE_INIT("Grammar Validations",function(){if((0,$i.isEmpty)(n)&&e.skipValidations===!1){var s=(0,sJ.validateGrammar)({rules:(0,$i.values)(e.gastProductionsCache),maxLookahead:e.maxLookahead,tokenTypes:(0,$i.values)(e.tokensMap),errMsgProvider:aJ.defaultGrammarValidatorErrorProvider,grammarName:i});e.definitionErrors=e.definitionErrors.concat(s)}}),(0,$i.isEmpty)(e.definitionErrors)&&(e.recoveryEnabled&&e.TRACE_INIT("computeAllProdsFollows",function(){var s=(0,Kye.computeAllProdsFollows)((0,$i.values)(e.gastProductionsCache));e.resyncFollows=s}),e.TRACE_INIT("ComputeLookaheadFunctions",function(){e.preComputeLookaheadFunctions((0,$i.values)(e.gastProductionsCache))})),!r.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,$i.isEmpty)(e.definitionErrors))throw t=(0,$i.map)(e.definitionErrors,function(s){return s.message}),new Error(`Parser Definition Errors detected: + `+t.join(` +------------------------------- +`))})},r.DEFER_DEFINITION_ERRORS_HANDLING=!1,r}();dr.Parser=ky;(0,Zye.applyMixins)(ky,[Hye.Recoverable,Gye.LooksAhead,Yye.TreeBuilder,jye.LexerAdapter,Jye.RecognizerEngine,qye.RecognizerApi,Wye.ErrorHandler,zye.ContentAssist,Vye.GastRecorder,Xye.PerformanceTracer]);var ewe=function(r){oJ(e,r);function e(t,i){i===void 0&&(i=dr.DEFAULT_PARSER_CONFIG);var n=this,s=(0,$i.cloneObj)(i);return s.outputCst=!0,n=r.call(this,t,s)||this,n}return e}(ky);dr.CstParser=ewe;var twe=function(r){oJ(e,r);function e(t,i){i===void 0&&(i=dr.DEFAULT_PARSER_CONFIG);var n=this,s=(0,$i.cloneObj)(i);return s.outputCst=!1,n=r.call(this,t,s)||this,n}return e}(ky);dr.EmbeddedActionsParser=twe});var lJ=w(Ry=>{"use strict";Object.defineProperty(Ry,"__esModule",{value:!0});Ry.createSyntaxDiagramsCode=void 0;var AJ=Dv();function rwe(r,e){var t=e===void 0?{}:e,i=t.resourceBase,n=i===void 0?"https://unpkg.com/chevrotain@"+AJ.VERSION+"/diagrams/":i,s=t.css,o=s===void 0?"https://unpkg.com/chevrotain@"+AJ.VERSION+"/diagrams/diagrams.css":s,a=` + + + + + +`,l=` + +`,c=` +